【转载】Android应用框架及常用工具类总结

转载自:Android应用框架 http://www.tuicool.com/articles/feqmQj

    常用工具类总结    http://blog.csdn.net/krislight/article/details/11354119

一、 UML类图复习:

UML类图中有些标记很容易混淆,这里先复习下,请大家看下面这幅图:

注:这幅图来自《大话设计模式》这本书中的插图。

二、应用框架:

A、基本概念

抽象(抽出共同之现象)——在同领域的程序中,常含有许多类别,这些类别有其共同点,我们将类别之共同结构抽离出来,称为抽象类别。其抽象之步骤是: 1、观察几个相似的类别;2、分辨它们的异同点;3、把它们的共同点抽离出来。

衍生(与众不同之现象)——基于通用结构里的抽象类别,添加些特殊功能(扩展),使之成为具体类别,再诞生对象。

所以抽象类别的存在目的,是要用其衍生子类别,而不是由它本身来诞生对象。由于抽象类别本身不诞生对象,所以有些方法并不完整。反之,类别之内的方法,皆是完整的,而且要用来诞生对象,就称它为具体类别。所谓不完整就是方法的方法体从缺,只有方法的描述。

B、打造自己的专属应用框架之类图:

C、 打造自己的专属应用框架之编码实现:

BaseApplication类源码如下:

package com.lbt.hairdesigner;

import java.util.ArrayList;

import android.app.Activity;
import android.app.Application;

/**
 * 功能描述:用于存放全局变量和公用的资源等
 * @author android_ls
 */
public class BaseApplication extends Application {

    /**
     * Activity集合
     */
    private static ArrayList<BaseActivity> activitys = new ArrayList<BaseActivity>();

    @Override
    public void onCreate() {

    }

    /**
     * 添加Activity到ArrayList<Activity>管理集合
     * @param activity
     */
    public void addActivity(BaseActivity activity) {
        String className = activity.getClass().getName();
        for (Activity at : activitys) {
            if (className.equals(at.getClass().getName())) {
                activitys.remove(at);
                break;
            }
        }
        activitys.add(activity);
    }

    /**
     * 退出应用程序的时候,手动调用
     */
    @Override
    public void onTerminate() {
        for (BaseActivity activity : activitys) {
            activity.defaultFinish();
        }
    }

}

BaseActivity类源码如下:

package com.lbt.hairdesigner;

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.view.Window;
import android.widget.Toast;

import com.lbt.hairdesigner.utils.LogUtil;

/**
 * 功能描述:对Activity类进行扩展
 * @author android_ls
 */
public abstract class BaseActivity extends Activity {

    /**
     * LOG打印标签
     */
    private static final String TAG = BaseActivity.class.getSimpleName();

    /**
     * 全局的Context {@link #mContext = this.getApplicationContext();}
     */
    protected Context mContext;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        requestWindowFeature(Window.FEATURE_NO_TITLE);

        int layoutId = getLayoutId();
        if (layoutId != 0) {
            setContentView(layoutId);
            // 删除窗口背景
            getWindow().setBackgroundDrawable(null);
        }

        mContext = this.getApplicationContext();
        ((BaseApplication) this.getApplication()).addActivity(this);

        // 向用户展示信息前的准备工作在这个方法里处理
        preliminary();
    }

    /**
     * 向用户展示信息前的准备工作在这个方法里处理
     */
    protected void preliminary() {
        // 初始化组件
        setupViews();

        // 初始化数据
        initialized();
    }

    /**
     * 获取全局的Context
     * @return {@link #mContext = this.getApplicationContext();}
     */
    public Context getContext() {
        return mContext;
    }

    /**
     * 布局文件ID
     * @return
     */
    protected abstract int getLayoutId();

    /**
     * 初始化组件
     */
    protected abstract void setupViews();

    /**
     * 初始化数据
     */
    protected abstract void initialized();

    /**
     * Debug输出Log信息
     * @param tag
     * @param msg
     */
    protected void debugLog(String msg) {
        LogUtil.d(TAG, msg);
    }

    /**
     * Error输出Log信息
     * @param msg
     */
    protected void errorLog(String msg) {
        LogUtil.e(TAG, msg);
    }

    /**
     * Info输出Log信息
     * @param msg
     */
    protected void showLog(String msg) {
        LogUtil.i(TAG, msg);
    }

    /**
     * 长时间显示Toast提示(来自String)
     * @param message
     */
    protected void showToast(String message) {
        Toast.makeText(mContext, message, Toast.LENGTH_LONG).show();
    }

    /**
     * 长时间显示Toast提示(来自res)
     * @param resId
     */
    protected void showToast(int resId) {
        Toast.makeText(mContext, getString(resId), Toast.LENGTH_LONG).show();
    }

    /**
     * 短暂显示Toast提示(来自res)
     * @param resId
     */
    protected void showShortToast(int resId) {
        Toast.makeText(mContext, getString(resId), Toast.LENGTH_SHORT).show();
    }

    /**
     * 短暂显示Toast提示(来自String)
     * @param text
     */
    protected void showShortToast(String text) {
        Toast.makeText(mContext, text, Toast.LENGTH_SHORT).show();
    }

    /**
     * 通过Class跳转界面
     **/
    public void startActivity(Class<?> cls) {
        startActivity(cls, null);
    }

    /**
     * 含有Bundle通过Class跳转界面
     **/
    public void startActivity(Class<?> cls, Bundle bundle) {
        Intent intent = new Intent();
        intent.setClass(this, cls);
        if (bundle != null) {
            intent.putExtras(bundle);
        }
        startActivity(intent);
        overridePendingTransition(R.anim.push_left_in, R.anim.push_left_out);
    }

    /**
     * 通过Action跳转界面
     **/
    public void startActivity(String action) {
        startActivity(action, null);
    }

    /**
     * 含有Bundle通过Action跳转界面
     **/
    public void startActivity(String action, Bundle bundle) {
        Intent intent = new Intent();
        intent.setAction(action);
        if (bundle != null) {
            intent.putExtras(bundle);
        }
        startActivity(intent);
        overridePendingTransition(R.anim.push_left_in, R.anim.push_left_out);
    }

    /**
     * 含有Bundle通过Class打开编辑界面
     **/
    public void startActivityForResult(Class<?> cls, Bundle bundle, int requestCode) {
        Intent intent = new Intent();
        intent.setClass(this, cls);
        if (bundle != null) {
            intent.putExtras(bundle);
        }
        startActivityForResult(intent, requestCode);
        overridePendingTransition(R.anim.push_left_in, R.anim.push_left_out);
    }

    /**
     * 带有右进右出动画的退出
     */
    @Override
    public void finish() {
        super.finish();
        overridePendingTransition(R.anim.push_right_in, R.anim.push_right_out);
    }

    /**
     * 默认退出
     */
    public void defaultFinish() {
        super.finish();
    }

}

BaseNetworkActivity类源码如下:

package com.lbt.hairdesigner;

import java.util.ArrayList;
import java.util.List;

import android.os.Bundle;
import android.os.Handler;

import com.lbt.hairdesigner.net.AsyncBaseRequest;
import com.lbt.hairdesigner.net.DefaultThreadPool;

/**
 * 功能描述:应用中需要访问网络的Activity基类
 * @author android_ls
 */
public abstract class BaseNetworkActivity extends BaseActivity {

    /**
     * 当前activity所持有的所有网络请求
     */
    protected List<AsyncBaseRequest> mAsyncRequests;

    /**
     * 当前activity所持有的Handler
     */
    protected Handler mHandler;

    /**
     * 当前activity所持有的线程池对象
     */
    protected DefaultThreadPool mDefaultThreadPool;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    }

    /**
     * 向用户展示信息前的准备工作在这个方法里处理
     */
    protected void preliminary() {
        mHandler = new Handler();
        mAsyncRequests = new ArrayList<AsyncBaseRequest>();
        mDefaultThreadPool = DefaultThreadPool.getInstance();

        // 初始化组件
        setupViews();

        // 初始化数据
        initialized();
    }

    public List<AsyncBaseRequest> getAsyncRequests() {
        return mAsyncRequests;
    }

    public Handler getHandler() {
        return mHandler;
    }

    public DefaultThreadPool getDefaultThreadPool() {
        return mDefaultThreadPool;
    }

    @Override
    protected void onPause() {
        /**
         * 在activity暂停的时候,同时设置终止标识,终止异步线程
         */
        cancelAllRequest();
        super.onPause();
    }

    @Override
    protected void onDestroy() {
        /**
         * 在activity销毁的时候,同时设置终止标识,终止异步线程
         */
        cancelAllRequest();
        super.onDestroy();
    }

    /**
     * 取消当前Activity相关的网络请求
     */
    private void cancelAllRequest() {
        if (mAsyncRequests != null && mAsyncRequests.size() > 0) {
            try {
                int size = mAsyncRequests.size();
                for (int i = 0; i < size; i++) {
                    AsyncBaseRequest request = mAsyncRequests.get(i);
                    request.setInterrupted(true);

                    mAsyncRequests.remove(request);
                    size = mAsyncRequests.size();
                }
            } catch (Exception e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }

}

PhotoNetworkActivity类源码如下:

package com.lbt.hairdesigner;

import java.io.File;

import android.app.Activity;
import android.content.Intent;
import android.graphics.Bitmap;
import android.net.Uri;
import android.os.Bundle;

import com.lbt.hairdesigner.utils.Constant;

/**
 * 功能描述:内置网络请求接口和照片处理的Activity基类
 * @author android_ls
 */
public abstract class PhotoNetworkActivity extends BaseNetworkActivity {

    /**
     * 照片存储路径
     * @return
     */
    protected abstract String getPhotoPath();

    /**
     * 照片处理完成后的结果
     * @param bitmap
     */
    protected abstract void onPhotoResult(Bitmap bitmap);

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        if (Constant.REQUEST_CAMERA_CODE == requestCode) {
            if (resultCode == Activity.RESULT_OK) {

                System.err.println("getPhotoPath() = " + getPhotoPath());

                File file = new File(getPhotoPath());
                if (file.exists()) {
                    showToast("拍摄的照片已存好");
                    cropPhoto(Uri.fromFile(file));
                }
            } else {
                showToast("取消了拍照");
            }
        } else if (Constant.REQUEST_GALLERY_CODE == requestCode) {
            if (resultCode == Activity.RESULT_OK) {
                Uri uri = data.getData();
                showToast("照片已选取");
                cropPhoto(uri);
            } else {
                showToast("取消了选取照片");
            }
        } else if (Constant.REQUEST_CROP_PHOTO_CODE == requestCode) {
            if (resultCode == Activity.RESULT_OK) {
                photoCropResult(data);
            } else {
                showToast("取消了剪裁照片");
            }
        }

    }

    /**
     * 调用系统裁剪照片应用
     * @param uri Uri
     */
    private void cropPhoto(Uri uri) {
        Intent intent = new Intent("com.android.camera.action.CROP");
        intent.setDataAndType(uri, "image/*");
        intent.putExtra("crop", "true");
        intent.putExtra("aspectX", 1);
        intent.putExtra("aspectY", 1);
        intent.putExtra("outputX", 200);
        intent.putExtra("outputY", 200);
        intent.putExtra("scale", true);
        intent.putExtra("noFaceDetection", true);
        intent.putExtra("return-data", true);
        startActivityForResult(intent, Constant.REQUEST_CROP_PHOTO_CODE);
    }

    /**
     * 剪裁完成后返回的Bitmap
     * @param data Intent
     */
    private void photoCropResult(Intent intent) {
        Bundle extras = intent.getExtras();
        if (extras != null) {
            Bitmap bitmap = extras.getParcelable("data");
            if (bitmap != null) {
                showToast("裁剪照片成功");
                onPhotoResult(bitmap);
            }
        } else {
            showToast("获取裁剪照片出错");
        }
    }

}

BaseFrameLayout类源码如下:

package com.lbt.hairdesigner;

import java.util.List;

import android.os.Handler;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.FrameLayout;
import android.widget.LinearLayout;
import android.widget.Toast;

import com.lbt.hairdesigner.net.AsyncBaseRequest;
import com.lbt.hairdesigner.net.DefaultThreadPool;
import com.lbt.hairdesigner.utils.LogUtil;
import com.lbt.hairdesigner.widget.TopNavbar;

/**
 * 功能描述:主界面中各个视图的父类
 * @author android_ls
 */
public abstract class BaseFrameLayout extends FrameLayout {

    /**
     * LOG打印标签
     */
    protected static final String TAG = BaseFrameLayout.class.getSimpleName();

    protected TopNavbar topMenuNavbar;

    public TopNavbar getTopMenuNavbar() {
        return topMenuNavbar;
    }

    /**
     * 获取顶部左侧的menu组件
     * @return
     */
    public LinearLayout getMenuView() {
        return topMenuNavbar.llShowMenu;
    }

    /**
     * 应用主界面
     */
    protected BaseNetworkActivity mActivity;

    /**
     * 当前activity所持有的所有网络请求
     */
    protected List<AsyncBaseRequest> mAsyncRequests;

    /**
     * 当前activity所持有的Handler
     */
    protected Handler mHandler;

    /**
     * 当前activity所持有的线程池对象
     */
    protected DefaultThreadPool mDefaultThreadPool;

    protected LayoutInflater mLayoutInflater;

    /**
     * 当前视图的父容器
     */
    protected LinearLayout viewRoot;

    public BaseFrameLayout(BaseNetworkActivity activity) {
        super(activity);

        mActivity = activity;
        mLayoutInflater = LayoutInflater.from(getContext());

        this.mAsyncRequests = activity.getAsyncRequests();
        this.mDefaultThreadPool = activity.getDefaultThreadPool();
        this.mHandler = activity.getHandler();

        // 向用户展示信息前的准备工作在这个方法里处理
        preliminary();
    }

    /**
     * 向用户展示信息前的准备工作在这个方法里处理
     */
    protected void preliminary() {
        // 初始化组件
        setupViews();

        // 初始化数据
        initialized();
    }

    /**
     * 初始化组件
     */
    protected void setupViews() {
        int layoutId = getLayoutId();
        if (layoutId != 0) {
            viewRoot = (LinearLayout) mLayoutInflater.inflate(layoutId, null);
            addView(viewRoot);

            topMenuNavbar = (TopNavbar) viewRoot.findViewById(R.id.rl_top_menu_navbar);
            topMenuNavbar.ivRefresh.setVisibility(View.GONE);
            topMenuNavbar.ivRightLine.setVisibility(View.GONE);
            topMenuNavbar.tvRightOperationName.setVisibility(View.GONE);
            topMenuNavbar.ivDownListIcon.setVisibility(View.GONE);
        }

    }

    /**
     * 布局文件ID
     * @return
     */
    protected abstract int getLayoutId();

    /**
     * 初始化数据
     */
    protected abstract void initialized();

    /**
     * Debug输出Log信息
     * @param tag
     * @param msg
     */
    protected void debugLog(String msg) {
        LogUtil.d(TAG, msg);
    }

    /**
     * Error输出Log信息
     * @param msg
     */
    protected void errorLog(String msg) {
        LogUtil.e(TAG, msg);
    }

    /**
     * Info输出Log信息
     * @param msg
     */
    protected void showLog(String msg) {
        LogUtil.i(TAG, msg);
    }

    /**
     * 长时间显示Toast提示(来自String)
     * @param message
     */
    protected void showToast(String message) {
        Toast.makeText(mActivity, message, Toast.LENGTH_LONG).show();
    }

    /**
     * 长时间显示Toast提示(来自res)
     * @param resId
     */
    protected void showToast(int resId) {
        Toast.makeText(mActivity, mActivity.getString(resId), Toast.LENGTH_LONG).show();
    }

    /**
     * 短暂显示Toast提示(来自res)
     * @param resId
     */
    protected void showShortToast(int resId) {
        Toast.makeText(mActivity, mActivity.getString(resId), Toast.LENGTH_SHORT).show();
    }

    /**
     * 短暂显示Toast提示(来自String)
     * @param text
     */
    protected void showShortToast(String text) {
        Toast.makeText(mActivity, text, Toast.LENGTH_SHORT).show();
    }

}

PhotoFrameLayout类源码如下:

package com.lbt.hairdesigner;

import java.io.File;
import java.util.UUID;

import android.content.Intent;
import android.net.Uri;
import android.provider.MediaStore;
import android.view.View;
import android.view.animation.Animation;
import android.view.animation.Animation.AnimationListener;
import android.view.animation.TranslateAnimation;
import android.widget.Button;
import android.widget.LinearLayout;

import com.lbt.hairdesigner.utils.Constant;

/**
 * 功能描述:内置底部滑出拍照菜单的视图父类
 * @author android_ls
 */
public abstract class PhotoFrameLayout extends BaseFrameLayout {

    /**
     * 底部弹出菜单
     */
    protected LinearLayout llPopupMenu;

    /**
     * 底部弹出菜单照相机
     */
    private Button btnPopupMenuCamera;

    /**
     * 底部弹出菜单我的相册
     */
    private Button btnPopupMenuPhoto;

    /**
     * 底部弹出菜单取消按钮
     */
    private Button btnPopupMenuCancel;

    /**
     * 存放拍照上传的照片路径
     */
    public String mUploadPhotoPath;

    public PhotoFrameLayout(BaseNetworkActivity activity) {
        super(activity);
    }

    /**
     * 初始化组件
     */
    protected void setupViews() {
        super.setupViews();

        // 底部的弹出菜单
        llPopupMenu = (LinearLayout) this.findViewById(R.id.ll_popup_menu);
        btnPopupMenuCamera = (Button) this.findViewById(R.id.btn_popup_menu_camera);
        btnPopupMenuPhoto = (Button) this.findViewById(R.id.btn_popup_menu_photo);
        btnPopupMenuCancel = (Button) this.findViewById(R.id.btn_popup_menu_cancel);

        popupMenu();

    }

    /**
     * 底部的弹出菜单事件处理
     */
    private void popupMenu() {
        // 点击照相机按钮事件处理
        btnPopupMenuCamera.setOnClickListener(new View.OnClickListener() {

            public void onClick(View v) {
                llPopupMenu.setVisibility(View.GONE);

                String rootDir = Constant.getRootDir(mActivity);
                File dir = new File(rootDir + File.separator + Constant.IMAGE_CAMERA_UPLOAD_PATH);
                if (!dir.exists()) {
                    dir.mkdirs();
                }

                mUploadPhotoPath = rootDir + "/" + Constant.IMAGE_CAMERA_UPLOAD_PATH + "/" + UUID.randomUUID().toString();
                File file = new File(mUploadPhotoPath);

                Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
                intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(file));
                mActivity.startActivityForResult(intent, Constant.REQUEST_CAMERA_CODE);
            }
        });

        // 点击相册按钮事件处理
        btnPopupMenuPhoto.setOnClickListener(new View.OnClickListener() {

            public void onClick(View v) {
                llPopupMenu.setVisibility(View.GONE);

                Intent getImage = new Intent(Intent.ACTION_GET_CONTENT);
                getImage.addCategory(Intent.CATEGORY_OPENABLE);
                getImage.setType("image/*");
                mActivity.startActivityForResult(getImage, Constant.REQUEST_GALLERY_CODE);
            }
        });

        // 点击取消按钮事件处理
        btnPopupMenuCancel.setOnClickListener(new View.OnClickListener() {

            public void onClick(View v) {

                TranslateAnimation animation = new TranslateAnimation(0f, 0f, 1f, 400.0f);
                animation.setDuration(200);
                animation.setAnimationListener(new AnimationListener() {

                    @Override
                    public void onAnimationStart(Animation animation) {
                        // TODO Auto-generated method stub

                    }

                    @Override
                    public void onAnimationRepeat(Animation animation) {
                        // TODO Auto-generated method stub

                    }

                    @Override
                    public void onAnimationEnd(Animation animation) {
                        llPopupMenu.setVisibility(View.GONE);
                    }
                });

                llPopupMenu.startAnimation(animation);

            }
        });

    }
}

三、基于应用框架的应用:

1、先看看效果图吧,如下:

2、具体实现层,个别类的源码

HairDesignerMainActivity类源码如下:

package com.lbt.hairdesigner.main;

import android.content.Context;
import android.content.SharedPreferences;
import android.graphics.Bitmap;
import android.os.Bundle;
import android.view.View;
import android.view.ViewGroup.LayoutParams;

import com.lbt.hairdesigner.BaseApplication;
import com.lbt.hairdesigner.PhotoNetworkActivity;
import com.lbt.hairdesigner.account.AccountManagerLayout;
import com.lbt.hairdesigner.friend.FriendsLayout;
import com.lbt.hairdesigner.leftpanel.LeftPanelLayout;
import com.lbt.hairdesigner.leftpanel.LeftPanelLayout.onChangeViewListener;
import com.lbt.hairdesigner.ma.MyAppointmentLayout;
import com.lbt.hairdesigner.message.MessageLayout;
import com.lbt.hairdesigner.personal.PersonalInformationLayout;
import com.lbt.hairdesigner.ph.PersonalHomepageLayout;
import com.lbt.hairdesigner.pm.PasswordManagerLayout;
import com.lbt.hairdesigner.site.MySiteLayout;
import com.lbt.hairdesigner.widget.ScrollerContainer;
import com.lbt.hairdesigner.widget.ScrollerContainer.OnUgcListener;

/**
 * 功能描述:应用主界面
 * @author android_ls
 *
 */
public class HairDesignerMainActivity extends PhotoNetworkActivity implements View.OnClickListener, onChangeViewListener, OnUgcListener {

    /**
     * LOG打印标签
     */
    private static final String TAG = HairDesignerMainActivity.class.getSimpleName();

    /**
     * 滚动(滑动)容器
     */
    private ScrollerContainer mSlideContainer;

    /**
     * 菜单界面
     */
    private LeftPanelLayout mDesktop;

    /**
     * 我的主页
     */
    private PersonalHomepageLayout mPersonalHomepage;

    /**
     * 消息视图
     */
    private MessageLayout mMessageLayout;

    /**
     * 好友
     */
    private FriendsLayout mFriendsLayout;

    /**
     * 我的预约
     */
    private MyAppointmentLayout mMyAppointmentLayout;

    /**
     * 我的日程
     */
    private MyCalendarLayout mMyCalendarLayout;

    /**
     * 个人信息
     */
    private PersonalInformationLayout mPersonalInformationLayout;

    /**
     * 密码管理
     */
    private PasswordManagerLayout mPasswordManagerLayout;

    /**
     * 账户管理
     */
    private AccountManagerLayout mAccountManagerLayout;

    /**
     * 我的场地
     */
    private MySiteLayout mMySiteLayout;

    /**
     * 同步SNS
     */
    private SynSNSLayout mSynSNSLayout;

    /**
     * 当前显示的View的编号
     */
    private int mPosition;

    /**
     * 退出时间
     */
    private long mExitTime;

    /**
     * 退出间隔
     */
    private static final int EXIT_INTERVAL_TIME = 2000;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

    }

    @Override
    protected int getLayoutId() {
        return 0;
    }

    @Override
    protected void setupViews() {
        mSlideContainer = new ScrollerContainer(mContext);
        mSlideContainer.setOnUgcListener(this);

        mDesktop = new LeftPanelLayout(this);
        mDesktop.setOnChangeViewListener(this);

        mPersonalHomepage = new PersonalHomepageLayout(this);
        mPersonalHomepage.getMenuView().setOnClickListener(this);

        mMessageLayout = new MessageLayout(this);
        mMessageLayout.getMenuView().setOnClickListener(this);

        mFriendsLayout = new FriendsLayout(this);
        mFriendsLayout.getMenuView().setOnClickListener(this);

        mMyAppointmentLayout = new MyAppointmentLayout(this);
        mMyAppointmentLayout.getMenuView().setOnClickListener(this);

        mMyCalendarLayout = new MyCalendarLayout(this);
        mMyCalendarLayout.getMenuView().setOnClickListener(this);

        mPersonalInformationLayout = new PersonalInformationLayout(this);
        mPersonalInformationLayout.getMenuView().setOnClickListener(this);

        mPasswordManagerLayout = new PasswordManagerLayout(this);
        mPasswordManagerLayout.getMenuView().setOnClickListener(this);

        mAccountManagerLayout = new AccountManagerLayout(this);
        mAccountManagerLayout.getMenuView().setOnClickListener(this);

        mMySiteLayout = new MySiteLayout(this);
        mMySiteLayout.getMenuView().setOnClickListener(this);

        mSynSNSLayout = new SynSNSLayout(this);
        mSynSNSLayout.getMenuView().setOnClickListener(this);

        LayoutParams layoutParams = new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT);
        mSlideContainer.addView(mDesktop, 0, layoutParams);
        mSlideContainer.addView(mPersonalHomepage, 1, layoutParams);

        setContentView(mSlideContainer);

    }

    @Override
    protected void initialized() {

    }

    @Override
    protected String getPhotoPath() {
        return mPersonalInformationLayout.mUploadPhotoPath;
    }

    @Override
    protected void onPhotoResult(Bitmap bitmap) {
        mPersonalInformationLayout.onActivityResult(bitmap);
    }

    @Override
    public void onClick(View v) {
        mSlideContainer.open();
    }

    @Override
    public void onChangeView(int position) {
        mPosition = position;

        switch (position) {
        case 0:
            mSlideContainer.replace(mPersonalHomepage);
            break;
        case 1:
            mSlideContainer.replace(mMessageLayout);

            mMessageLayout.getFriendMessage();
            break;
        case 2:
            mSlideContainer.replace(mFriendsLayout);

            mFriendsLayout.getFriends();
            break;
        case 3:
            mSlideContainer.replace(mMyAppointmentLayout);
            break;
        case 4:
            mSlideContainer.replace(mMyCalendarLayout);
            break;
        case 5:
            mSlideContainer.replace(mPersonalInformationLayout);
            break;
        case 6:
            mSlideContainer.replace(mPasswordManagerLayout);
            break;
        case 7:
            mSlideContainer.replace(mAccountManagerLayout);
            break;
        case 8:
            mSlideContainer.replace(mMySiteLayout);
            break;
        case 9:
            mSlideContainer.replace(mSynSNSLayout);
            break;
        default:
            break;
        }

    }

    @Override
    public void dismissUGC() {
        switch (mPosition) {
        case 0:
            mPersonalHomepage.dismissUgc();
            break;
        case 2:
            mFriendsLayout.dismissUgc();
            break;
        case 3:
            mMyAppointmentLayout.dismissUgc();
            break;
        case 5:
            mPersonalInformationLayout.dismissUgc();
            break;
        case 6:
            mPasswordManagerLayout.dismissUgc();
            break;
        case 7:
            mAccountManagerLayout.dismissUgc();
            break;
        case 8:
            mMySiteLayout.dismissUgc();
            break;
        case 9:
            mSynSNSLayout.dismissUgc();
            break;
        default:
            break;
        }
    }

    @Override
    public void showUGC() {
        switch (mPosition) {
        case 0:
            mPersonalHomepage.showUgc();
            break;
        case 2:
            mFriendsLayout.showUgc();
            break;
        case 3:
            mMyAppointmentLayout.showUgc();
            break;
        case 5:
            mPersonalInformationLayout.showUgc();
            break;
        case 6:
            mPasswordManagerLayout.showUgc();
            break;
        case 7:
            mAccountManagerLayout.showUgc();
            break;
        case 8:
            mMySiteLayout.showUgc();
            break;
        case 9:
            mSynSNSLayout.showUgc();
            break;
        default:
            break;
        }
    }

    /**
     * 重写系统返回键事件的处理
     */
    public void onBackPressed() {
        if (mSlideContainer.isPanelInvisible()) {
            // 如果界面的path菜单没有关闭时,关闭path菜单
            if (mDesktop.getUgcIsShowing()) {
                mDesktop.closeUgc();
                return;
            }

            // 界面的path菜单处于关闭状态,关闭左侧面板
            mSlideContainer.close();
        } else {
            switch (mPosition) {
            case 0:
                if (mPersonalHomepage.getUgcIsShowing()) {
                    mPersonalHomepage.closeUgc();
                } else {
                    exit();
                }
                break;
            case 2:
                if (mFriendsLayout.getUgcIsShowing()) {
                    mFriendsLayout.closeUgc();
                } else {
                    exit();
                }
                break;
            case 3:
                if (mMyAppointmentLayout.getUgcIsShowing()) {
                    mMyAppointmentLayout.closeUgc();
                } else {
                    exit();
                }
                break;
            case 5:
                if (mPersonalInformationLayout.getUgcIsShowing()) {
                    mPersonalInformationLayout.closeUgc();
                } else {
                    exit();
                }
                break;
            case 6:
                if (mPasswordManagerLayout.getUgcIsShowing()) {
                    mPasswordManagerLayout.closeUgc();
                } else {
                    exit();
                }
                break;
            case 7:
                if (mAccountManagerLayout.getUgcIsShowing()) {
                    mAccountManagerLayout.closeUgc();
                } else {
                    exit();
                }
                break;
            case 8:
                if (mMySiteLayout.getUgcIsShowing()) {
                    mMySiteLayout.closeUgc();
                } else {
                    exit();
                }
                break;
            case 9:
                if (mSynSNSLayout.getUgcIsShowing()) {
                    mSynSNSLayout.closeUgc();
                } else {
                    exit();
                }
                break;
            default:
                exit();
                break;
            }
        }
    }

    @Override
    protected void onRestart() {
        super.onRestart();

        SharedPreferences sharedPreferences = this.getSharedPreferences("pagehome", Context.MODE_PRIVATE);
        String flage = sharedPreferences.getString("flage", null);
        if ("register".equals(flage)) {
            // mSlideContainer.close();
            mSlideContainer.replace(mPersonalHomepage);
        } else if ("login".equals(flage) || "login_qq".equals(flage) || "login_sina".equals(flage) || "login_tencent".equals(flage)) {
            // mSlideContainer.close();
            mSlideContainer.replace(mPersonalHomepage);
        }

        sharedPreferences.edit().putString("flage", "").commit();
    }

    /**
     * 判断两次返回时间间隔,小于两秒则退出程序
     */
    private void exit() {
        if ((System.currentTimeMillis() - mExitTime) > EXIT_INTERVAL_TIME) {
            showShortToast("再按一次退出应用");
            mExitTime = System.currentTimeMillis();
        } else {
            ((BaseApplication) this.getApplication()).onTerminate();
        }
    }

}

LeftPanelLayout类源码如下:

package com.lbt.hairdesigner.leftpanel;

import java.util.ArrayList;
import java.util.List;

import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.view.View;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.RelativeLayout;
import android.widget.TextView;

import com.lbt.hairdesigner.BaseNetworkActivity;
import com.lbt.hairdesigner.R;
import com.lbt.hairdesigner.UGCFrameLayout;
import com.lbt.hairdesigner.main.SettingActivity;
import com.lbt.hairdesigner.utils.BitmapUtil;

/**
 * 左侧面板视图
 * @author android_ls
 */
public class LeftPanelLayout extends UGCFrameLayout {

    private RelativeLayout mTopLayout;

    private ImageView mAvatar;

    private TextView mName;

    private TextView mSig;

    private ListView mDisplay;

    private ImageView mSetUp;

    /**
     * 桌面适配器
     */
    private LeftPanelAdapter mAdapter;

    /**
     * ExpandableListView组件的数据源
     */
    private List<LeftPanelListItem> mListItems;

    /**
     * 接口对象,用来修改显示的View
     */
    private onChangeViewListener mOnChangeViewListener;

    /**
     * 当前选中项的位置索引
     */
    private int mPosition;

    public LeftPanelLayout(BaseNetworkActivity activity) {
        super(activity);
    }

    @Override
    protected void setupViews() {
        int layoutId = getLayoutId();
        if (layoutId != 0) {
            viewRoot = (LinearLayout) mLayoutInflater.inflate(layoutId, null);
            addView(viewRoot);
        }

        // 初始化path动画组件
        setupUGC();

        mTopLayout = (RelativeLayout) viewRoot.findViewById(R.id.desktop_top_layout);
        mAvatar = (ImageView) viewRoot.findViewById(R.id.desktop_avatar);
        mName = (TextView) viewRoot.findViewById(R.id.desktop_name);
        mSig = (TextView) viewRoot.findViewById(R.id.desktop_sig);

        mDisplay = (ListView) viewRoot.findViewById(R.id.desktop_display);
        mSetUp = (ImageView) viewRoot.findViewById(R.id.desktop_set_up);

        mTopLayout.setOnClickListener(this);
        mSetUp.setOnClickListener(this);

        initialized();

    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
        case R.id.desktop_top_layout:
            if (mOnChangeViewListener != null) {
                mOnChangeViewListener.onChangeView(0);
            }
            break;
        case R.id.desktop_set_up:
            // 选项按钮监听
            mActivity.startActivity(SettingActivity.class);
            break;
        default:
            super.onClick(v);
            break;
        }

    }

    @Override
    protected void initialized() {
        mName.setText("王念茜");
        mSig.setText("每个人来到世上,都是匆匆过客...");

        // 设置用户图像
        Bitmap bitmap = BitmapFactory.decodeResource(mActivity.getResources(), R.drawable.user_big_icon);
        mAvatar.setImageBitmap(BitmapUtil.drawRoundBitmap(bitmap, 8));

        String[] names = this.getResources().getStringArray(R.array.left_panel_names);

        int[] icons = {
                R.drawable.left_panel_personal_homepage_icon_selector,
                R.drawable.left_panel_news_icon_selector,
                R.drawable.left_panel_friends_icon_selector,
                R.drawable.left_panel_appointment_icon_selector,
                R.drawable.left_panel_my_calendar_icon_selector,
                R.drawable.left_panel_personal_details_icon_selector,
                R.drawable.left_panel_password_management_icon_selector,
                R.drawable.left_panel_account_management_icon_selector,
                R.drawable.left_panel_site_icon_selector,
                R.drawable.left_panel_sns_icon_selector };

        mListItems = new ArrayList<LeftPanelListItem>();
        for (int i = 0; i < names.length; i++) {
            LeftPanelListItem listItem = new LeftPanelListItem();
            listItem.setId(i);
            listItem.setName(names[i]);
            listItem.setDrawableId(icons[i]);

            // 默认选中第一项
            if (i == 0) {
                listItem.setSelected(true);
            }

            mListItems.add(listItem);
        }

        mAdapter = new LeftPanelAdapter(mActivity, mListItems);
        mDisplay.setAdapter(mAdapter);

        mDisplay.setOnItemClickListener(new OnItemClickListener() {

            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                if (mOnChangeViewListener == null) {
                    return;
                }

                // 去掉上一次选中的项
                mListItems.get(mPosition).setSelected(false);
                mPosition = position;

                // 选中当前选择的项
                mListItems.get(position).setSelected(true);
                mAdapter.notifyDataSetChanged();

                mOnChangeViewListener.onChangeView(position);
            }
        });

    }

    /**
     * 界面修改方法
     *
     * @param onChangeViewListener
     */
    public void setOnChangeViewListener(onChangeViewListener onChangeViewListener) {
        mOnChangeViewListener = onChangeViewListener;
    }

    /**
     * 切换显示界面的接口
     */
    public interface onChangeViewListener {
        public abstract void onChangeView(int position);
    }

    @Override
    protected int getLayoutId() {
        return R.layout.left_panel;
    }

}

PersonalHomepageLayout类源码如下:

package com.lbt.hairdesigner.ph;

import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.util.TypedValue;
import android.view.View;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.RatingBar;
import android.widget.RelativeLayout;
import android.widget.TextView;

import com.lbt.hairdesigner.BaseNetworkActivity;
import com.lbt.hairdesigner.R;
import com.lbt.hairdesigner.UGCFrameLayout;
import com.lbt.hairdesigner.entity.CommentInfo;
import com.lbt.hairdesigner.entity.PersonalHomeInfo;
import com.lbt.hairdesigner.main.ClientHomepageActivity;
import com.lbt.hairdesigner.main.MyCalendarActivity;
import com.lbt.hairdesigner.personal.ChangePersonalInfoActivity;
import com.lbt.hairdesigner.utils.BitmapUtil;
import com.lbt.hairdesigner.utils.Constant;

/**
 * 功能描述:我的主页
 * @author android_ls
 */
public class PersonalHomepageLayout extends UGCFrameLayout {

    /**
     * LOG打印标签
     */
    private static final String TAG = PersonalHomepageLayout.class.getSimpleName();

    /**用户图像*/
    private ImageView ivUserImage;

    private TextView tv_username;

    private ImageView iv_sex_icon;

    private RatingBar ratingbar;

    private TextView tv_price;

    private TextView tv_haoping;

    private TextView tv_yifuwu;

    private LinearLayout ll_yonghudianping_arrow;

    private TextView tv_dianping_count;

    private ImageView iv_dianping_user_icon;

    private TextView tv_dianping_nickname;

    private TextView tv_dianping_content;

    private TextView tv_dianping_time;

    private RelativeLayout rl_xijianchui;

    private RelativeLayout rl_tangfa;

    private RelativeLayout rl_ranfa;

    private RelativeLayout rl_huli;

    private TextView tv_xijianchui_price;

    private TextView tv_tangfa_price;

    private TextView tv_ranfa_price;

    private TextView tv_huli_price;

    private RelativeLayout rl_yuyue_shijian;

    private RelativeLayout rl_address;

    private RelativeLayout rl_haopinglv;

    private RelativeLayout rl_yifuwu;

    private TextView tv_address;

    private TextView tv_fujin_shangquan;

    private TextView tv_fujianxinxi;

    private LinearLayout ll_signature_arrow;

    private TextView tv_personalized_signature;

    private LinearLayout ll_happy_baby_show;

    private LinearLayout ll_happy_baby_show_arrow;

    private LinearLayout ll_coupon_list_arrow;

    private RelativeLayout rl_yonghu_dianping;

    private RelativeLayout rl_personal_jiamubiao;

    private RelativeLayout rl_signature;

    private RelativeLayout rl_happy_baby_show;

    private RelativeLayout rl_youhuixinxi;

    public PersonalHomepageLayout(BaseNetworkActivity activity) {
        super(activity);
    }

    @Override
    protected void setupViews() {
        super.setupViews();

        topMenuNavbar.tvTitle.setText("我的主页");

        tv_username = (TextView) viewRoot.findViewById(R.id.tv_username);
        ivUserImage = (ImageView) viewRoot.findViewById(R.id.iv_big_icon);
        iv_sex_icon = (ImageView) viewRoot.findViewById(R.id.iv_sex_icon);
        ratingbar = (RatingBar) viewRoot.findViewById(R.id.ratingbar);
        tv_price = (TextView) viewRoot.findViewById(R.id.tv_price);
        tv_haoping = (TextView) viewRoot.findViewById(R.id.tv_haoping);
        tv_yifuwu = (TextView) viewRoot.findViewById(R.id.tv_yifuwu);

        ll_yonghudianping_arrow = (LinearLayout) viewRoot.findViewById(R.id.ll_yonghudianping_arrow);
        ll_yonghudianping_arrow.setOnClickListener(this);

        tv_dianping_count = (TextView) viewRoot.findViewById(R.id.tv_dianping_count);
        iv_dianping_user_icon = (ImageView) viewRoot.findViewById(R.id.iv_dianping_user_icon);
        tv_dianping_nickname = (TextView) viewRoot.findViewById(R.id.tv_dianping_nickname);
        tv_dianping_content = (TextView) viewRoot.findViewById(R.id.tv_dianping_content);
        tv_dianping_time = (TextView) viewRoot.findViewById(R.id.tv_dianping_time);

        rl_xijianchui = (RelativeLayout) viewRoot.findViewById(R.id.rl_xijianchui);
        rl_tangfa = (RelativeLayout) viewRoot.findViewById(R.id.rl_tangfa);
        rl_ranfa = (RelativeLayout) viewRoot.findViewById(R.id.rl_ranfa);
        rl_huli = (RelativeLayout) viewRoot.findViewById(R.id.rl_huli);

        iv_dianping_user_icon.setOnClickListener(this);
        rl_xijianchui.setOnClickListener(this);
        rl_tangfa.setOnClickListener(this);
        rl_ranfa.setOnClickListener(this);
        rl_huli.setOnClickListener(this);

        rl_haopinglv = (RelativeLayout) viewRoot.findViewById(R.id.rl_haopinglv);
        rl_haopinglv.setOnClickListener(this);

        rl_yifuwu = (RelativeLayout) viewRoot.findViewById(R.id.rl_yifuwu);
        rl_yifuwu.setOnClickListener(this);

        tv_xijianchui_price = (TextView) viewRoot.findViewById(R.id.tv_xijianchui_price);
        tv_tangfa_price = (TextView) viewRoot.findViewById(R.id.tv_tangfa_price);
        tv_ranfa_price = (TextView) viewRoot.findViewById(R.id.tv_ranfa_price);
        tv_huli_price = (TextView) viewRoot.findViewById(R.id.tv_huli_price);

        rl_yuyue_shijian = (RelativeLayout) viewRoot.findViewById(R.id.rl_yuyue_shijian);
        rl_yuyue_shijian.setOnClickListener(this);

        rl_address = (RelativeLayout) viewRoot.findViewById(R.id.rl_address);
        rl_address.setOnClickListener(this);

        tv_address = (TextView) viewRoot.findViewById(R.id.tv_address);
        tv_fujin_shangquan = (TextView) viewRoot.findViewById(R.id.tv_fujin_shangquan);
        tv_fujianxinxi = (TextView) viewRoot.findViewById(R.id.tv_fujianxinxi);

        ll_signature_arrow = (LinearLayout) viewRoot.findViewById(R.id.ll_signature_arrow);
        ll_signature_arrow.setOnClickListener(this);

        tv_personalized_signature = (TextView) viewRoot.findViewById(R.id.tv_personalized_signature);
        ll_happy_baby_show = (LinearLayout) viewRoot.findViewById(R.id.ll_happy_baby_show);

        ll_happy_baby_show_arrow = (LinearLayout) viewRoot.findViewById(R.id.ll_happy_baby_show_arrow);
        ll_happy_baby_show_arrow.setOnClickListener(this);

        ll_coupon_list_arrow = (LinearLayout) viewRoot.findViewById(R.id.ll_coupon_list_arrow);
        ll_coupon_list_arrow.setOnClickListener(this);

        rl_yonghu_dianping = (RelativeLayout) viewRoot.findViewById(R.id.rl_yonghu_dianping);
        rl_yonghu_dianping.setOnClickListener(this);

        rl_personal_jiamubiao = (RelativeLayout) viewRoot.findViewById(R.id.rl_personal_jiamubiao);
        rl_personal_jiamubiao.setOnClickListener(this);

        rl_signature = (RelativeLayout) viewRoot.findViewById(R.id.rl_signature);
        rl_signature.setOnClickListener(this);

        rl_happy_baby_show = (RelativeLayout) viewRoot.findViewById(R.id.rl_happy_baby_show);
        rl_happy_baby_show.setOnClickListener(this);

        rl_youhuixinxi = (RelativeLayout) viewRoot.findViewById(R.id.rl_youhuixinxi);
        rl_youhuixinxi.setOnClickListener(this);

    }

    @Override
    public void onClick(View v) {
        Bundle bundle = new Bundle();

        switch (v.getId()) {

        case R.id.rl_yonghu_dianping:
        case R.id.ll_yonghudianping_arrow:
            // 用户点评
            mActivity.startActivity(UserCommentListActivity.class);
            break;
        case R.id.rl_personal_jiamubiao:
        case R.id.rl_xijianchui:
            mActivity.startActivity(PriceListActivity.class);
            break;
        case R.id.rl_tangfa:
            mActivity.startActivity(PriceListActivity.class);
            break;
        case R.id.rl_ranfa:
            mActivity.startActivity(PriceListActivity.class);
            break;
        case R.id.rl_huli:
            mActivity.startActivity(PriceListActivity.class);
            break;
        case R.id.rl_yuyue_shijian:
            bundle.putInt("flage", Constant.PERSONAL_HOMEPAGE_MY_CALENDAR_CODE);
            mActivity.startActivity(MyCalendarActivity.class, bundle);
            break;
        case R.id.rl_address:
            mActivity.startActivity(ShopListActivity.class);
            break;
        case R.id.ll_signature_arrow:
        case R.id.rl_signature:
            bundle.putInt("flage", Constant.CHANGE_PERSOANL_SIGNATURE_CODE);
            bundle.putString("signature", tv_personalized_signature.getText().toString());
            mActivity.startActivity(ChangePersonalInfoActivity.class, bundle);
            break;
        case R.id.ll_happy_baby_show_arrow:
        case R.id.rl_happy_baby_show:
            mActivity.startActivity(WorksShowActivity.class);
            break;
        case R.id.rl_haopinglv:
            bundle.putInt("flage", Constant.REVIEW_HAOPINGLV_CODE);
            mActivity.startActivity(ReviewActivity.class, bundle);
            break;
        case R.id.rl_yifuwu:
            bundle.putInt("flage", Constant.REVIEW_YIFUWU_CODE);
            mActivity.startActivity(ReviewActivity.class, bundle);
            break;
        case R.id.ll_coupon_list_arrow:
        case R.id.rl_youhuixinxi:
            mActivity.startActivity(CouponListActivity.class);
            break;
        case R.id.iv_dianping_user_icon:
            // 点评用户的图像单击事件处理
            mActivity.startActivity(ClientHomepageActivity.class);
            break;
        default:
            super.onClick(v);
            break;
        }
    }

    @Override
    protected int getLayoutId() {
        return R.layout.personal_homepage;
    }

    @Override
    protected void initialized() {
        // 构造测试数据
        PersonalHomeInfo personalHome = new PersonalHomeInfo();
        personalHome.setUid(1004);
        personalHome.setName("王念西");
        // personalBaseInfo.setHeadurl("");
        // personalBaseInfo.setTinyurl("");
        personalHome.setMainurl("");
        personalHome.setSex(1);
        personalHome.setStar(4f);
        personalHome.setPrice(200);
        personalHome.setGoodReputation(0.5);
        personalHome.setYifuwu(50);
        personalHome.setCommentCount(126);

        CommentInfo commentInfo = new CommentInfo();
        commentInfo.setCid(102);
        commentInfo.setUid(23);
        commentInfo.setNickname("Vicy1985");
        commentInfo.setIconPath("");
        commentInfo.setContent("很时尚,不错,这个发型我喜欢,好评,下次还会找你剪头发。");
        commentInfo.setTime("2013-05-03 09:38");

        personalHome.setCommentInfo(commentInfo);

        // 用户基本信息字段赋值
        tv_username.setText(personalHome.getName());

        Bitmap bitmap = BitmapFactory.decodeResource(mActivity.getResources(), R.drawable.user_big_icon);
        ivUserImage.setImageBitmap(BitmapUtil.drawRoundBitmap(bitmap, 8));

        if (personalHome.getSex() == 1) {
            iv_sex_icon.setImageResource(R.drawable.sex_man);
        } else {
            iv_sex_icon.setImageResource(R.drawable.jishi_female);
        }

        ratingbar.setRating(personalHome.getStar());
        tv_price.setText("均价:" + (int) personalHome.getPrice() + "元");

        tv_haoping.setText((int) (personalHome.getGoodReputation() * 100) + "%");
        tv_yifuwu.setText(personalHome.getYifuwu() + "");

        // 用户点评字段赋值
        tv_dianping_count.setText("共" + personalHome.getCommentCount() + "条");

        CommentInfo comment = personalHome.getCommentInfo();
        tv_dianping_nickname.setText(comment.getNickname());
        tv_dianping_content.setText(comment.getContent());
        tv_dianping_time.setText(comment.getTime());

        Bitmap bitmap1 = BitmapFactory.decodeResource(mActivity.getResources(), R.drawable.user_icon);
        iv_dianping_user_icon.setImageBitmap(BitmapUtil.drawRoundBitmap(bitmap1, 8));

        // 价目表字段赋值
        tv_xijianchui_price.setText("小于100");
        tv_tangfa_price.setText("600-1000");
        tv_ranfa_price.setText("600-1000");
        tv_huli_price.setText("600-1000");

        // 场地字段赋值
        tv_address.setText("地址:上海市长宁区安顺路1026号");
        tv_fujin_shangquan.setText("附近商圈:古北");
        tv_fujianxinxi.setText("免费停车、免费无线上网");

        // 个性签名字段赋值
        tv_personalized_signature.setText("我一直在发行业五年,现在一个艺术家工作的可爱的无与伦比的头发工作室,位于旧金山的SOMA区...");

        int[] images = {
                R.drawable.f1, R.drawable.f2, R.drawable.f3,
                R.drawable.f4, R.drawable.f5, R.drawable.f6,
                R.drawable.f7, R.drawable.f8,R.drawable.f9,
                R.drawable.f10, R.drawable.f13, R.drawable.f12,
                R.drawable.f14, R.drawable.f15, R.drawable.f16,
                R.drawable.f17, R.drawable.f18, R.drawable.f19 };

        for (int i = 0; i < images.length; i++) {
            // 显示最近头像
            ImageView imageView = new ImageView(mActivity);
            int widthAndHeight = pxTodip(60);
            LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(widthAndHeight, widthAndHeight);
            params.rightMargin = pxTodip(10);
            imageView.setLayoutParams(params);
            // imageView.setPadding(0, pxTodip(5), 0, pxTodip(5));
            // imageView.setBackgroundResource(R.drawable.select_friend_avatar_frame);

            Bitmap bitmap2 = BitmapFactory.decodeResource(mActivity.getResources(), images[i]);
            imageView.setImageBitmap(BitmapUtil.drawRoundBitmap(bitmap2, 8));
            ll_happy_baby_show.addView(imageView);
            ll_happy_baby_show.invalidate();
            imageView.setOnClickListener(new OnClickListener() {

                public void onClick(View v) {

                }
            });
        }

    }

    private int pxTodip(float valuepx) {
        return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, valuepx, mActivity.getResources().getDisplayMetrics());
    }

}

四、写在最后面的话:

希望每个做Android应用开发的人,都有属于自己的专属应用框架。

====================================================

常用工具类总结

分类: 心得笔记2013-09-07 21:04 970人阅读 评论(0) 收藏 举报

Android

项目中常会遇到的工具类 总结留存

首先Activity的抽象类 BaseActivity

[java] view plaincopy

  1. /**
  2. * Activity 基類
  3. * @author KrisLight
  4. *
  5. */
  6. public abstract class BaseActivity extends Activity {
  7. private static final String TAG = BaseActivity.class.getSimpleName();
  8. /**
  9. * 消息類型默認Default
  10. */
  11. public static int MSGTYPE_DEFAULT = 0;
  12. /**
  13. * 消息類型為Info
  14. */
  15. public static int MSGTYPE_INFO = 1;
  16. /**
  17. * 消息類型為Warning
  18. */
  19. public static int MSGTYPE_WARNING = 2;
  20. /**
  21. * 消息類型為Error
  22. */
  23. public static int MSGTYPE_ERROR = 3;
  24. @Override
  25. protected void onCreate(Bundle savedInstanceState) {
  26. super.onCreate(savedInstanceState);
  27. }
  28. /**初始化**/
  29. protected abstract void init();
  30. /** 初始化監聽器**/
  31. protected abstract void initListener();
  32. /**  得到字符串資源 **/
  33. public String getResStr(int id)
  34. {
  35. return this.getResources().getString(id);
  36. }
  37. /** 短暂显示Toast提示(来自res) **/
  38. protected void showShortToast(int resId) {
  39. Toast.makeText(this, getString(resId), Toast.LENGTH_SHORT).show();
  40. }
  41. /** 短暂显示Toast提示(来自String) **/
  42. protected void showShortToast(String text) {
  43. Toast.makeText(this, text, Toast.LENGTH_SHORT).show();
  44. }
  45. /** 长时间显示Toast提示(来自res) **/
  46. protected void showLongToast(int resId) {
  47. Toast.makeText(this, getString(resId), Toast.LENGTH_LONG).show();
  48. }
  49. /** 长时间显示Toast提示(来自String) **/
  50. protected void showLongToast(String text) {
  51. Toast.makeText(this, text, Toast.LENGTH_LONG).show();
  52. }
  53. /** Debug输出Log日志 **/
  54. protected void showLogDebug(String tag, String msg) {
  55. Log.d(tag, msg);
  56. }
  57. /** Error输出Log日志 **/
  58. protected void showLogError(String tag, String msg) {
  59. Log.e(tag, msg);
  60. }
  61. /** 通过Class跳转界面 **/
  62. protected void startActivity(Class<?> cls) {
  63. startActivity(cls, null);
  64. }
  65. /** 含有Bundle通过Class跳转界面 **/
  66. protected void startActivity(Class<?> cls, Bundle bundle) {
  67. Intent intent = new Intent();
  68. intent.setClass(this, cls);
  69. if (bundle != null) {
  70. intent.putExtras(bundle);
  71. }
  72. if(intent.resolveActivity(getPackageManager()) != null){
  73. startActivity(intent);
  74. }else{
  75. showLogError(TAG, "there is no activity can handle this intent: "+intent.getAction().toString());
  76. }
  77. overridePendingTransition(R.anim.push_left_in, R.anim.push_left_out);
  78. }
  79. /** 通过Action跳转界面 **/
  80. protected void startActivity(String action) {
  81. Intent intent = new Intent();
  82. intent.setAction(action);
  83. if(intent.resolveActivity(getPackageManager()) != null){
  84. startActivity(intent);
  85. }else{
  86. showLogError(TAG, "there is no activity can handle this intent: "+intent.getAction().toString());
  87. }
  88. }
  89. /**含有Date通过Action跳转界面**/
  90. protected void startActivity(String action,Uri data) {
  91. Intent intent = new Intent();
  92. intent.setAction(action);
  93. intent.setData(data);
  94. if(intent.resolveActivity(getPackageManager()) != null){
  95. startActivity(intent);
  96. }else{
  97. showLogError(TAG, "there is no activity can handle this intent: "+intent.getAction().toString());
  98. }
  99. }
  100. /** 含有Bundle通过Action跳转界面 **/
  101. protected void startActivity(String action, Bundle bundle) {
  102. Intent intent = new Intent();
  103. intent.setAction(action);
  104. if (bundle != null) {
  105. intent.putExtras(bundle);
  106. }
  107. if(intent.resolveActivity(getPackageManager()) != null){
  108. startActivity(intent);
  109. }else{
  110. showLogError(TAG, "there is no activity can handle this intent: "+intent.getAction().toString());
  111. }
  112. overridePendingTransition(R.anim.push_left_in, R.anim.push_left_out);
  113. }
  114. /** 含有标题、内容、两个按钮的对话框 **/
  115. protected void showAlertDialog(String title, String message,
  116. String positiveText,
  117. DialogInterface.OnClickListener onPositiveClickListener,
  118. String negativeText,
  119. DialogInterface.OnClickListener onNegativeClickListener) {
  120. AlertDialog alertDialog = new AlertDialog.Builder(this).setTitle(title)
  121. .setMessage(message)
  122. .setPositiveButton(positiveText, onPositiveClickListener)
  123. .setNegativeButton(negativeText, onNegativeClickListener).create();
  124. alertDialog.show();
  125. }
  126. /** 含有标题、内容、图标、两个按钮的对话框 **/
  127. protected void showAlertDialog(String title, String message,
  128. int icon, String positiveText,
  129. DialogInterface.OnClickListener onPositiveClickListener,
  130. String negativeText,
  131. DialogInterface.OnClickListener onNegativeClickListener) {
  132. AlertDialog alertDialog = new AlertDialog.Builder(this).setTitle(title)
  133. .setMessage(message).setIcon(icon)
  134. .setPositiveButton(positiveText, onPositiveClickListener)
  135. .setNegativeButton(negativeText, onNegativeClickListener).create();
  136. alertDialog.show();
  137. }
  138. /**
  139. *
  140. * @Function: com.light.mycal.base.BaseActivity
  141. * @Description:根據不同的信息類型彈出不同等級的對話框
  142. *
  143. * @param i  資源id
  144. * @param iMsgType 信息類型
  145. *
  146. * @version:v1.0
  147. * @author:KrisLight
  148. * @date:2013/9/4 下午4:56:39
  149. *
  150. * Modification History:
  151. * Date         Author      Version     Description
  152. * -----------------------------------------------------------------
  153. * 2013/9/4    KrisLight      v1.0.0         create
  154. */
  155. public void ShowMsgResStr(int i, int iMsgType)
  156. {
  157. String sTitle = getResStr(R.string.app_name);
  158. int iconId = 0;
  159. if (iMsgType == MSGTYPE_INFO)
  160. {
  161. sTitle = getResStr(R.string.msgTypeInfo);
  162. iconId = R.drawable.msgicon_info;
  163. }
  164. if (iMsgType == MSGTYPE_WARNING)
  165. {
  166. sTitle = getResStr(R.string.msgTypeWarning);
  167. iconId = R.drawable.msgicon_warning;
  168. }
  169. if (iMsgType == MSGTYPE_ERROR)
  170. {
  171. sTitle = getResStr(R.string.msgTypeError);
  172. iconId = R.drawable.msgicon_error;
  173. }
  174. AlertDialog.Builder dlg = new AlertDialog.Builder(this);
  175. dlg.setMessage(getResStr(i));
  176. dlg.setPositiveButton(getResStr(R.string.msgBoxButtonOk), null);
  177. dlg.setTitle(sTitle);
  178. dlg.setIcon(iconId);
  179. dlg.create();
  180. dlg.show();
  181. }
  182. /** 带有右进右出动画的退出 **/
  183. public void finish() {
  184. super.finish();
  185. overridePendingTransition(R.anim.push_right_in, R.anim.push_right_out);
  186. }
  187. /** 默认退出 **/
  188. protected void defaultFinish() {
  189. super.finish();
  190. }
  191. }

配置文件工具Prefs

[java] view plaincopy

  1. public class Prefs {
  2. /** Friend+‘s Preference file name */
  3. public static final String PREF_FILE = "friends_plus_pref";
  4. /** Preference key[authToken] */
  5. public static final String KEY_AUTH_TOKEN = "auth_token";
  6. /** Preference key[clientId] */
  7. public static final String KEY_CLIENT_ID = "client_id";
  8. /** Preference key[login_email] */
  9. public static final String KEY_LOGIN_EMAIL = "login_email";
  10. /** Preference key[login_IMId] */
  11. public static final String KEY_LOGIN_IMID = "login_imid";
  12. /** Preference key[login_name] */
  13. public static final String KEY_LOGIN_NAME = "login_name";
  14. /** Preference key[last_update_contact_list] */
  15. public static final String KEY_LAST_UPDATE_CONTACT_LIST = "last_update_contact_list";
  16. public static final String KEY_REGISTRATION_STEP = "registration_step";
  17. public static final String REGISTRATION_STEP_AUTHENTICATE = "authenticate";
  18. public static final String KEY_REGISTRATION_AUTHEN_CODE = "authen_code";
  19. /**
  20. * get the app‘s preference data
  21. *
  22. * @param context
  23. * @param prefKey preference key
  24. * @return
  25. */
  26. public static String getPreference(Context context, String prefKey) {
  27. return getPreference(context, prefKey, "");
  28. }
  29. /**
  30. * get the app‘s preference data
  31. *
  32. * @param context
  33. * @param prefKey preference key
  34. * @param defVal default value
  35. * @return
  36. */
  37. public static String getPreference(Context context, String prefKey, String defVal) {
  38. if (TextUtils.isEmpty(prefKey))
  39. return null;
  40. SharedPreferences prefs =
  41. context.getSharedPreferences(PREF_FILE, Context.MODE_PRIVATE);
  42. return prefs.getString(prefKey, defVal);
  43. }
  44. /**
  45. * write data to app‘s preference
  46. *
  47. * @param context
  48. * @param prefKey
  49. * @param prefValue
  50. */
  51. public static void savePreference(Context context, String prefKey, String prefValue) {
  52. if (TextUtils.isEmpty(prefKey))
  53. return;
  54. SharedPreferences.Editor editor =
  55. context.getSharedPreferences(PREF_FILE, Context.MODE_PRIVATE).edit();
  56. editor.putString(prefKey, prefValue).commit();
  57. }
  58. /**
  59. * remove preference value from app‘s preference file
  60. * @param context
  61. * @param prefKey
  62. */
  63. public static void removePreference(Context context, String prefKey){
  64. if (TextUtils.isEmpty(prefKey))
  65. return;
  66. SharedPreferences.Editor editor =
  67. context.getSharedPreferences(PREF_FILE, Context.MODE_PRIVATE).edit();
  68. editor.remove(prefKey).commit();
  69. }
  70. }

DBHelper类

[java] view plaincopy

  1. /**
  2. * DB工具類
  3. * @author KrisLight
  4. *
  5. */
  6. public class DatabaseOpenHelper extends SQLiteOpenHelper
  7. {
  8. private static final String TAG = DatabaseOpenHelper.class.getSimpleName();
  9. /** 數據庫操作結果 **/
  10. public enum Result
  11. {
  12. /** 成功 **/
  13. Success,
  14. /**未知錯誤**/
  15. errUnknown,
  16. /**無法插入新數據**/
  17. errCantInsertNewData,
  18. /**無法更新數據**/
  19. errCantUpdateData,
  20. /**無法創建Table**/
  21. errCantCreateTable,
  22. /**無法訪問數據庫**/
  23. errNoDbAccess,
  24. /**無法從表中獲取數據**/
  25. errCantGetDataFromTable,
  26. /**無法查到數據**/
  27. errCantFindData,
  28. /**無法得到數據**/
  29. errCantGetData,
  30. /**無法刪除數據**/
  31. errCantDeleteData,
  32. /**表不存在**/
  33. errTableNotExists,
  34. /**不能為該字段指定值**/
  35. errCantSetValuesForDataRow,
  36. /**不能從該字段得到值**/
  37. errCantGetValuesFromDataRow,
  38. };
  39. /** 表名 **/
  40. public static final String TABLE_NAME = "appointments";
  41. /** 臨時表名 **/
  42. public static final String TEMP_TABLE_NAME = "tempDb";
  43. /** 數據庫名 **/
  44. private static final String DB_NAME = "MyCal.db";
  45. private SQLiteDatabase db = null;
  46. /** 版本号 **/
  47. private static final int DB_VERSION = 1;
  48. /**創建Table的結果**/
  49. private Result resultDbTablesCreated = Result.errUnknown;
  50. public DatabaseOpenHelper(Context context, String name, CursorFactory factory,
  51. int version) {
  52. super(context, DB_NAME, factory, DB_VERSION);
  53. }
  54. @Override
  55. public void onCreate(SQLiteDatabase sqLiteDatabase) {
  56. DataRow nDataRow = new NoteDataRow();
  57. String create_sql = getSqlTableDefinition(nDataRow.GetTableName(), nDataRow.GetTableDef());
  58. Log.d(TAG, "create_sql: ---------------------"+create_sql+ "------------");
  59. try{
  60. sqLiteDatabase.execSQL(create_sql);
  61. resultDbTablesCreated = DatabaseOpenHelper.Result.Success;
  62. }catch (Exception e) {
  63. resultDbTablesCreated = DatabaseOpenHelper.Result.errCantCreateTable;
  64. }
  65. }
  66. /**
  67. * 得到創建表的SQL語句
  68. * @param sTableName 表名
  69. * @param vecTableDef 表的字段數組
  70. * @return
  71. */
  72. public String getSqlTableDefinition(String sTableName, DataField[] vecTableDef)
  73. {
  74. String def = "CREATE TABLE " + sTableName + " (";
  75. for (int i = 0; i < vecTableDef.length; i++)
  76. {
  77. def += vecTableDef[i].GetColumnDefinition();
  78. if (i < (vecTableDef.length - 1))
  79. //中間逗號分隔
  80. def += ", ";
  81. }
  82. def += ")";
  83. return def;
  84. }
  85. /* (non-Javadoc)
  86. * @see android.database.sqlite.SQLiteOpenHelper#onUpgrade(android.database.sqlite.SQLiteDatabase, int, int)
  87. */
  88. @Override
  89. public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
  90. switch (newVersion) {
  91. case 2:
  92. /** only add column on old table**/
  93. //          String add_column_sql = getSqlTableAddColumn(TABLE_NAME,newColumn);
  94. //          Log.d(TAG, "add_column_sql:--------------"+add_column_sql+"----------");
  95. //          db.execSQL(add_column_sql);
  96. //          break;
  97. case 3:
  98. //原來的字段集合
  99. List<String> columns = getColumns(db, TABLE_NAME);
  100. String rename_sql = getSqlTableRename(TABLE_NAME);
  101. Log.d(TAG, "rename_sql:--------------"+rename_sql+"----------");
  102. //重命名
  103. db.execSQL(rename_sql);
  104. //創建新表
  105. onCreate(db);
  106. //舊字段和新的字段求交集
  107. columns.retainAll(getColumns(db, TABLE_NAME));
  108. String cols = Utils.join(columns, ",");
  109. //將舊的數據插入到新表
  110. db.execSQL(String.format( "INSERT INTO %s (%s) SELECT %s from temp_%s", TABLE_NAME, cols, cols, TABLE_NAME));
  111. String drop_sql = getSqlTableDrop(TEMP_TABLE_NAME);
  112. Log.d(TAG, "drop_sql:--------------"+drop_sql+"----------");
  113. db.execSQL(drop_sql);
  114. break;
  115. default:
  116. String ds = getSqlTableDrop(TABLE_NAME);
  117. Log.d(TAG, "drop_sql:--------------"+ds+"----------");
  118. break;
  119. }
  120. }
  121. /**
  122. *  得到重命名SQL
  123. */
  124. private String getSqlTableRename(String tableName){
  125. StringBuffer sb = new StringBuffer();
  126. sb.append("ALTER TABLE ");
  127. sb.append(tableName);
  128. sb.append(" RENAME TO temp_");
  129. sb.append(tableName);
  130. return sb.toString();
  131. }
  132. /**
  133. *  得到刪除表SQL
  134. */
  135. private String getSqlTableDrop(String tableName){
  136. StringBuffer sb = new StringBuffer();
  137. sb.append("DROP TABLE IF EXISTS ");
  138. sb.append(tableName);
  139. return sb.toString();
  140. }
  141. /**
  142. *  得到新增字段的表SQL
  143. */
  144. private String getSqlTableAddColumn(String tableName,String columnName){
  145. StringBuffer sb = new StringBuffer();
  146. sb.append("ALTER TABLE ");
  147. sb.append(tableName);
  148. sb.append(" ADD COLUMN ");
  149. sb.append(columnName);
  150. return sb.toString();
  151. }
  152. /**
  153. *  得到這個Table中的所有字段組成的List集合
  154. */
  155. public static List<String> getColumns(SQLiteDatabase db, String tableName) {
  156. List<String> ar = null;
  157. Cursor c = null;
  158. try {
  159. //查一條數據得到所有字段
  160. c = db.rawQuery("select * from " + tableName + " limit 1", null);
  161. if (c != null) {
  162. ar = new ArrayList<String>(Arrays.asList(c.getColumnNames()));
  163. }
  164. } catch (Exception e) {
  165. e.printStackTrace();
  166. } finally {
  167. if (c != null)
  168. c.close();
  169. }
  170. return ar;
  171. }
  172. /**
  173. *  得到數據庫的名字
  174. *
  175. */
  176. public final String getName()
  177. {
  178. return DB_NAME;
  179. }
  180. /** 得到錯誤信息描述 **/
  181. public static int getErrDesc(Result result)
  182. {
  183. int msgId = R.string.errUnknown;
  184. if (result == Result.errCantInsertNewData)
  185. msgId = R.string.errCantInsertNewData;
  186. if (result == Result.errCantUpdateData)
  187. msgId = R.string.errCantUpdateData;
  188. if (result == Result.errCantCreateTable)
  189. msgId = R.string.errCantCreateTable;
  190. if (result == Result.errNoDbAccess)
  191. msgId = R.string.errNoDbAccess;
  192. if (result == Result.errCantGetDataFromTable)
  193. msgId = R.string.errCantGetDataFromTable;
  194. if (result == Result.errCantFindData)
  195. msgId = R.string.errCantFindData;
  196. if (result == Result.errCantGetData)
  197. msgId = R.string.errCantGetData;
  198. if (result == Result.errCantDeleteData)
  199. msgId = R.string.errCantDeleteData;
  200. if (result == Result.errTableNotExists)
  201. msgId = R.string.errTableNotExists;
  202. if (result == Result.errCantSetValuesForDataRow)
  203. msgId = R.string.errCantSetValuesForDataRow;
  204. if (result == Result.errCantGetValuesFromDataRow)
  205. msgId = R.string.errCantGetValuesFromDataRow;
  206. return msgId;
  207. }
  208. /**關閉DB**/
  209. public void close()
  210. {
  211. if (isOpened())
  212. db.close();
  213. }
  214. /**判斷DB是否打開**/
  215. public boolean isOpened()
  216. {
  217. if (db != null)
  218. return true;
  219. return false;
  220. }
  221. /**得到DB寫操作類 **/
  222. public SQLiteDatabase getWriteSQLiteDb()
  223. {
  224. return getWritableDatabase();
  225. }
  226. /**得到DB讀操作類 **/
  227. public SQLiteDatabase getReadSQLiteDb()
  228. {
  229. return getReadableDatabase();
  230. }
  231. /**查詢Table是否存在**/
  232. public boolean isTableExists(String sTableName)
  233. {
  234. boolean bResult = false;
  235. if (isOpened())
  236. {
  237. String sql = "select name from sqlite_master where type = ‘table‘ and name = ‘%s‘";
  238. sql = String.format(sql, sTableName);
  239. Cursor cr = db.rawQuery(sql, null);
  240. if (cr.getCount() > 0)
  241. bResult = true;
  242. cr.close();
  243. }
  244. return bResult;
  245. }
  246. /** 建表是否成功 **/
  247. public boolean TablesCreated()
  248. {
  249. return resultDbTablesCreated == Result.Success;
  250. }
  251. /** 判斷DB是否準備好了**/
  252. public synchronized boolean DatabaseReady()
  253. {
  254. return (isOpened() && TablesCreated());
  255. }
  256. /** 返回創建表的結果 是成功還是失敗 **/
  257. public Result TablesCreationResult()
  258. {
  259. return resultDbTablesCreated;
  260. }
  261. }

表中字段类DataField

[java] view plaincopy

  1. /**
  2. *  表中的字段類
  3. * @author KrisLight
  4. */
  5. public class DataField
  6. {
  7. //types
  8. /** Type枚举 如:INT,TEXT,BOOL**/
  9. public static enum Type { INT, TEXT, BOOL };
  10. //fields
  11. /** Calendar實例 **/
  12. private Calendar dateOut = Calendar.getInstance();
  13. //fields
  14. /** 對應的數據類型 **/
  15. private DataRow dataRow = null;
  16. /** 對應字段的值 **/
  17. private ContentValues values = null;
  18. //fields
  19. /**字段索引**/
  20. private int index = 0;
  21. /** ContentValues存放鍵值對的鍵值 **/
  22. private String sName = "";
  23. /** 字段类型 从Type枚举中取一个类型的值 默認為Int **/
  24. private Type FieldType = Type.INT;
  25. /**是否可以為空**/
  26. private boolean bCanBeNull = true;
  27. /**是否是主鍵**/
  28. private boolean bPrimaryKey = false;
  29. //methods
  30. /**
  31. * 构造方法
  32. * @param index 索引
  33. * @param sName 字段名
  34. * @param FieldType 字段类型
  35. * @param bCanBeNull 是否为空
  36. * @param bPrimaryKey 是否为主键
  37. */
  38. public DataField(int index, String sName, Type FieldType, boolean bCanBeNull, boolean bPrimaryKey)
  39. {
  40. this.index = index;
  41. this.sName = sName;
  42. this.FieldType = FieldType;
  43. this.bCanBeNull = bCanBeNull;
  44. this.bPrimaryKey = bPrimaryKey;
  45. }
  46. /**
  47. * 得到每一個字段描述 形如: "name int PRIMARY KEY Not Null"
  48. * @return
  49. */
  50. public String GetColumnDefinition()
  51. {
  52. String s = sName + " " + GetSqlType(FieldType);
  53. if (bPrimaryKey)
  54. s += " PRIMARY KEY";
  55. if (!bCanBeNull)
  56. s += " NOT NULL";
  57. return s;
  58. }
  59. public Type GetType()
  60. {
  61. return FieldType;
  62. }
  63. public int GetIndex()
  64. {
  65. return index;
  66. }
  67. /** 根據SqlType返回真實的類型字段 注意BOOL對應的是Integer 其他類型的用Text **/
  68. public String GetSqlType(Type value)
  69. {
  70. switch (value)
  71. {
  72. case INT: return "INTEGER";
  73. case TEXT: return "TEXT";
  74. case BOOL: return "INTEGER";
  75. }
  76. return "TEXT";
  77. }
  78. /** 设置这个字段对应的数据类型 **/
  79. public void SetParentRow(DataRow dataRow)
  80. {
  81. this.dataRow = dataRow;
  82. this.values = this.dataRow.GetContentValues();
  83. }
  84. /** 得到字段的名字 **/
  85. public String GetName()
  86. {
  87. return sName;
  88. }
  89. //getters
  90. /** 字符串类型的字段的值 **/
  91. public String asString()
  92. {
  93. return values.getAsString(sName);
  94. }
  95. /** Long类型的字段的值 **/
  96. public long asLong()
  97. {
  98. return values.getAsLong(sName);
  99. }
  100. /** Boolean类型的字段的值 **/
  101. public boolean asBoolean()
  102. {
  103. return (values.getAsLong(sName) == 1);
  104. }
  105. /** 判断是否为Null **/
  106. public boolean isNull()
  107. {
  108. return (values.get(sName) == null);
  109. }
  110. /** 将Long类型的日期类型转换成标准的日期时间 **/
  111. public Calendar asCalendar()
  112. {
  113. dateOut.setTimeInMillis(values.getAsLong(sName));
  114. return dateOut;
  115. }
  116. //setters
  117. /** 设置字符串值 **/
  118. public void set(String value)
  119. {
  120. values.put(sName, value);
  121. }
  122. /** 设置整型值 **/
  123. public void set(long value)
  124. {
  125. values.put(sName, value);
  126. }
  127. /** 设置布尔值 **/
  128. public void set(boolean value)
  129. {
  130. int i = (value)?1:0;
  131. values.put(sName, i);
  132. }
  133. /** 设置日期值 **/
  134. public void set(Calendar value)
  135. {
  136. values.put(sName, value.getTimeInMillis());
  137. }
  138. /** 设置Null值 **/
  139. public void setNull()
  140. {
  141. values.put(sName, (String)null);
  142. }
  143. }

数据原型类DataRow

[java] view plaincopy

  1. /**
  2. * 抽象的数据类型类,
  3. * 所有的数据原型都要继承这个类
  4. * @author KrisLight
  5. *
  6. */
  7. public abstract class DataRow
  8. {
  9. /** 这个类型对应表中的字段集合 **/
  10. private DataField[] vecTableDef = null;
  11. /** 这个类型对应表中的字段的值 用ContentValues形式存放 **/
  12. private ContentValues values = new ContentValues();
  13. /** 構造方法 **/
  14. public DataRow(){}
  15. /**
  16. * 設置字段集合并綁定
  17. * @param vecTableDef 字段集合
  18. */
  19. public void SetTableDefinition(DataField[] vecTableDef)
  20. {
  21. this.vecTableDef = vecTableDef;
  22. UpdateDataFieldsParentRow(this);
  23. }
  24. /** 將數據類型綁定其對應的所有字段 **/
  25. public void UpdateDataFieldsParentRow(DataRow row)
  26. {
  27. for (int i = 0; i < vecTableDef.length; i++)
  28. vecTableDef[i].SetParentRow(row);
  29. }
  30. /** 拷貝另一個DataRow中的所有字段 **/
  31. public void CopyTableDefinition(DataRow data)
  32. {
  33. SetTableDefinition(data.vecTableDef);
  34. }
  35. /** 得到表中的所有字段 **/
  36. public DataField[] GetTableDef()
  37. {
  38. return vecTableDef;
  39. }
  40. /** 驗證方法 **/
  41. public boolean Validate()
  42. {
  43. return false;
  44. }
  45. /** 清空ContentValues **/
  46. public void ClearContentValues()
  47. {
  48. values.clear();
  49. }
  50. /** 得到ContentValues **/
  51. public ContentValues GetContentValues()
  52. {
  53. return values;
  54. }
  55. /** 設置ContentValues **/
  56. public void SetContentValues(ContentValues values)
  57. {
  58. this.values = values;
  59. UpdateDataFieldsParentRow(this);
  60. }
  61. /** 拷貝ContentValues **/
  62. public boolean CopyContentValues(ContentValues values)
  63. {
  64. this.values = values;
  65. UpdateDataFieldsParentRow(this);
  66. try
  67. {
  68. GetValuesFromDataRow();
  69. return true;
  70. } catch (Exception e) {
  71. }
  72. return false;
  73. }
  74. /** 根據索引取出字段 **/
  75. public DataField Value(int idx)
  76. {
  77. return vecTableDef[idx];
  78. }
  79. /** 得到索引位置的字段名 **/
  80. public String fieldName(int idx)
  81. {
  82. return vecTableDef[idx].GetName();
  83. }
  84. /** 查詢結果 遍歷Cursor結果集給對應的字段賦值 **/
  85. public boolean GetValuesFromCursor(Cursor cr)
  86. {
  87. if ((cr != null) && (cr.getPosition() != -1))
  88. {
  89. //遍歷
  90. for (int idx = 0; idx < vecTableDef.length; idx++)
  91. {
  92. DataField field = Value(idx);
  93. //check if null value
  94. if (cr.isNull(idx))
  95. {
  96. //如果查出的值為空 ,設置為空
  97. field.setNull();
  98. } else {
  99. //根據其對應的類型取值
  100. final DataField.Type t = field.GetType();
  101. //parse value by type
  102. if (t == DataField.Type.INT)
  103. field.set(cr.getLong(idx));
  104. if (t == DataField.Type.TEXT)
  105. field.set(cr.getString(idx));
  106. if (t == DataField.Type.BOOL)
  107. field.set((cr.getInt(idx) == 1)?true:false);
  108. }
  109. }
  110. return true;
  111. }
  112. return false;
  113. }
  114. //sets fields values data (ContentValues values contener) from parent object fields
  115. /** 為字段賦值 **/
  116. public abstract void SetValuesForDataRow();
  117. //gets data from fields values (ContentValues values contener) to parent object fields
  118. /** 得到這個數據類型對應的所有的字段的值 **/
  119. public abstract void GetValuesFromDataRow();
  120. /** 得到表名 **/
  121. public abstract String GetTableName();
  122. }

Table类

[java] view plaincopy

  1. /**
  2. * 數據庫中的表類 包含了该表对应的数据类型以及对表的增删改查操作方法
  3. * @author KrisLight
  4. */
  5. public class DataTable
  6. {
  7. /** 這個表綁定的數據類型 **/
  8. private DataRow dataRow = null;
  9. /** DB輔助類 **/
  10. private DatabaseOpenHelper helper;
  11. /**
  12. * 更據DataRow來決定是哪一個Table
  13. * @param dataRow
  14. */
  15. public DataTable(DataRow dataRow,DatabaseOpenHelper helper)
  16. {
  17. this.dataRow = dataRow;
  18. this.helper = helper;
  19. }
  20. /** 得到表名 **/
  21. public String getTableName()
  22. {
  23. return dataRow.GetTableName();
  24. }
  25. //DataRow getter()
  26. public DataRow getDataRow()
  27. {
  28. return dataRow;
  29. }
  30. /** 基本的插入操作 **/
  31. public long insertValues()
  32. {
  33. long lRowId = helper.getWritableDatabase().insert(getTableName(), null, dataRow.GetContentValues());
  34. return lRowId;
  35. }
  36. /** 基本的根據ID更新操作 **/
  37. public long updateValues(long lRowId)
  38. {
  39. String sWhere = String.format("_ID = %d", lRowId);
  40. long lRowsUpdated = helper.getWritableDatabase().update(getTableName(), dataRow.GetContentValues(), sWhere, null);
  41. return lRowsUpdated;
  42. }
  43. /** 基本的根據ID刪除操作 **/
  44. public long deleteDataRow(long lRowId)
  45. {
  46. String sWhere = String.format("_ID = %d", lRowId);
  47. long lRowsUpdated = helper.getWritableDatabase().delete(getTableName(), sWhere, null);
  48. return lRowsUpdated;
  49. }
  50. /** 基本的根據Id查詢表中的所有字段值 **/
  51. public Cursor locateDataRow(long lRowId)
  52. {
  53. List<String> columnNames = getColumn();
  54. String cols = Utils.join(columnNames, ",");
  55. final String s = "select %s from %s where _ID = %d";
  56. String sql = String.format(s, cols, getTableName(), lRowId);
  57. Cursor cr = helper.getReadableDatabase().rawQuery(sql, null);
  58. //if cursor valid, set first data row as current
  59. if ((cr != null) && (cr.getCount() > 0))
  60. cr.moveToFirst();
  61. return cr;
  62. }
  63. /** 基本的根據類型和REF_ID查詢鬧鈴提醒功能表的所有字段數據 **/
  64. public Cursor locateAlarmDataRow(int iType, long lRefID)
  65. {
  66. List<String> columnNames = getColumn();
  67. String cols = Utils.join(columnNames, ",");
  68. final String s = "select %s from %s where Type = %d and RefID = %d";
  69. String sql = String.format(s, cols, getTableName(), iType, lRefID);
  70. Cursor cr = helper.getReadableDatabase().rawQuery(sql, null);
  71. if ((cr != null) && (cr.getCount() > 0))
  72. cr.moveToFirst();
  73. return cr;
  74. }
  75. /**
  76. * 封装的saveOrUpdate操作
  77. * @param bInsertMode  是否是插入模式 為true的話是插入新的數據 為false則直接更新舊數據
  78. * @param lEditRowId   ID
  79. * @return
  80. */
  81. public DatabaseOpenHelper.Result updateData(boolean bInsertMode, long lEditRowId)
  82. {
  83. DatabaseOpenHelper.Result result = DatabaseOpenHelper.Result.errUnknown;
  84. if (helper.isOpened())
  85. {
  86. try
  87. {
  88. //為字段賦值
  89. dataRow.SetValuesForDataRow();
  90. } catch (Exception e) {
  91. //異常就拋出錯誤信息 不能為數據類型的字段賦值
  92. return DatabaseOpenHelper.Result.errCantSetValuesForDataRow;
  93. }
  94. //select update mode
  95. if (bInsertMode)
  96. {
  97. //insert new data row
  98. long lRowId = insertValues();
  99. if (lRowId > 0)
  100. {
  101. //插入成功
  102. result = DatabaseOpenHelper.Result.Success;
  103. } else {
  104. //插入失敗
  105. result = DatabaseOpenHelper.Result.errCantInsertNewData;
  106. }
  107. } else {
  108. //update existing data row
  109. long lRowsUpdated = updateValues(lEditRowId);
  110. if (lRowsUpdated == 1)
  111. {
  112. //更新成功
  113. result = DatabaseOpenHelper.Result.Success;
  114. } else {
  115. //更新失敗
  116. result = DatabaseOpenHelper.Result.errCantUpdateData;
  117. }
  118. }
  119. } else {
  120. result = DatabaseOpenHelper.Result.errNoDbAccess;
  121. }
  122. return result;
  123. }
  124. /** 封装的根據Id刪除 **/
  125. public DatabaseOpenHelper.Result deleteData(long iRowId)
  126. {
  127. DatabaseOpenHelper.Result result = DatabaseOpenHelper.Result.errUnknown;
  128. if (helper.isOpened())
  129. {
  130. if (helper.isTableExists(getTableName()))
  131. {
  132. long lRowsDeleted = deleteDataRow(iRowId);
  133. if (lRowsDeleted == 1)
  134. {
  135. result = DatabaseOpenHelper.Result.Success;
  136. } else {
  137. result = DatabaseOpenHelper.Result.errCantDeleteData;
  138. }
  139. } else {
  140. result = DatabaseOpenHelper.Result.errTableNotExists;
  141. }
  142. } else {
  143. result = DatabaseOpenHelper.Result.errNoDbAccess;
  144. }
  145. return result;
  146. }
  147. /** 封装的根據ID查詢數據 **/
  148. public DatabaseOpenHelper.Result getRowDataForEdit(long lRowId)
  149. {
  150. DatabaseOpenHelper.Result result = DatabaseOpenHelper.Result.errUnknown;
  151. //get requested data row
  152. Cursor cr = locateDataRow(lRowId);
  153. if (cr == null)
  154. {
  155. //如果返回為空 結果為errCantGetData
  156. result = DatabaseOpenHelper.Result.errCantGetData;
  157. } else {
  158. if (cr.getCount() > 0)
  159. {
  160. if (dataRow.GetValuesFromCursor(cr))
  161. {
  162. try
  163. {
  164. dataRow.GetValuesFromDataRow();
  165. } catch (Exception e) {
  166. return DatabaseOpenHelper.Result.errCantGetValuesFromDataRow;
  167. }
  168. result = DatabaseOpenHelper.Result.Success;
  169. } else {
  170. //無法從表中取出数据
  171. result = DatabaseOpenHelper.Result.errCantGetDataFromTable;
  172. }
  173. //关闭光标
  174. cr.close();
  175. } else {
  176. //无法找到数据
  177. result = DatabaseOpenHelper.Result.errCantFindData;
  178. }
  179. }
  180. return result;
  181. }
  182. /** 得到這個表中的所有字段 **/
  183. public List<String> getColumn() {
  184. List<String> ar = new ArrayList<String>();
  185. try {
  186. DataField[] fields = dataRow.GetTableDef();
  187. for(DataField f : fields){
  188. ar.add(f.GetName());
  189. }
  190. } catch (Exception e) {
  191. e.printStackTrace();
  192. }
  193. return ar;
  194. }
  195. }

安装程序类Installating

[java] view plaincopy

  1. public class Installation {
  2. private static String sID = null;
  3. private static final String INSTALLATION = "INSTALLATION";
  4. public synchronized static String id(Context context) {
  5. if (sID == null) {
  6. File installation = new File(context.getFilesDir(), INSTALLATION);
  7. try {
  8. if (!installation.exists()){
  9. writeInstallationFile(installation, context);
  10. }
  11. sID = readInstallationFile(installation);
  12. } catch (Exception e) {
  13. //throw new RuntimeException(e);
  14. }
  15. }
  16. return sID;
  17. }
  18. private static String readInstallationFile(File installation) throws IOException {
  19. RandomAccessFile f = new RandomAccessFile(installation, "r");
  20. byte[] bytes = new byte[(int) f.length()];
  21. f.readFully(bytes);
  22. f.close();
  23. return new String(bytes);
  24. }
  25. private static void writeInstallationFile(File installation, Context context) throws IOException {
  26. FileOutputStream out = new FileOutputStream(installation);
  27. String id = "";
  28. try{
  29. id = Settings.Secure.getString(context.getContentResolver(),
  30. Settings.Secure.ANDROID_ID);
  31. id+=id;
  32. }catch(Exception e){
  33. id = UUID.randomUUID().toString();
  34. }
  35. out.write(id.getBytes());
  36. out.close();
  37. }
  38. }

获取资源类SearchResource

[java] view plaincopy

  1. public class SearchResource {
  2. public static int getDrawableResId(Context cnt, String name) throws NotFoundException {
  3. int resid = 0;
  4. resid = cnt.getResources().getIdentifier(name, "drawable", cnt.getPackageName());
  5. if (resid == 0)
  6. resid = cnt.getResources().getIdentifier( "transparent_background", "drawable", cnt.getPackageName());
  7. return resid;
  8. }
  9. public static int getStringResId(Context cnt, String name) throws NotFoundException {
  10. int resid = 0;
  11. resid = cnt.getResources().getIdentifier(name, "string", cnt.getPackageName());
  12. if (resid == 0)
  13. resid = cnt.getResources().getIdentifier("empty_string", "string", cnt.getPackageName());
  14. return resid;
  15. }
  16. public static int getLayoutResId(Context cnt, String name) throws NotFoundException {
  17. int resid = 0;
  18. resid = cnt.getResources().getIdentifier(name, "layout", cnt.getPackageName());
  19. if (resid == 0)
  20. resid = cnt.getResources().getIdentifier("empty_layout","layout", cnt.getPackageName());
  21. return resid;
  22. }
  23. public static int getItemResId(Context cnt, String name) throws NotFoundException {
  24. int resid = cnt.getResources().getIdentifier(name, "id", cnt.getPackageName());
  25. return resid;
  26. }
  27. public static int getAnimResId(Context cnt, String name) throws NotFoundException {
  28. int resid = cnt.getResources().getIdentifier(name, "anim", cnt.getPackageName());
  29. return resid;
  30. }
  31. public static int getAttrResId(Context cnt, String attrName) throws NotFoundException {
  32. int resid = cnt.getResources().getIdentifier(attrName, "attr", cnt.getPackageName());
  33. return resid;
  34. }
  35. public static int getStyleResId(Context cnt, String attrName) throws NotFoundException {
  36. int resid = cnt.getResources().getIdentifier(attrName, "style", cnt.getPackageName());
  37. return resid;
  38. }
  39. public static int getMenuResId(Context cnt, String name) throws NotFoundException {
  40. int resid = cnt.getResources().getIdentifier(name, "menu", cnt.getPackageName());
  41. return resid;
  42. }
  43. public static int[] getStyleableArray(Context cnt, String name) {
  44. return null;
  45. }
  46. }

发送短信类SendMessage

[java] view plaincopy

  1. public class SendMessage {
  2. private static final String TAG = "SendMessage";
  3. private Context m_contect;
  4. private ArrayList<HashMap<String, Object>> m_ContactList;
  5. private ArrayList<HashMap<String, Object>> m_ContactListbuffer;
  6. private String m_strMessageContent;
  7. private int m_intMessageSendCount=0;
  8. private int m_intMessageSendTotalParts;
  9. private int m_intMessageSendParts;
  10. public static final String SENT = "com.commez.psmd.SMS_SENT";
  11. public static final String DELIVERED = "com.commez.psmd.SMS_DELIVERED";
  12. private ArrayList<String> m_phoneList;
  13. private ListView m_ltvDialogContactList;
  14. private CustomDialogAdapter m_DialogAdapter;
  15. private Dialog dialog;
  16. private boolean m_isSendCancel;
  17. private static Handler m_handler = new Handler();
  18. private BroadcastReceiver m_bcrSend;
  19. private BroadcastReceiver m_bcrDelivred;
  20. public SendMessage(Context context, ArrayList<HashMap<String, Object>> contactList,  String messageContent){
  21. this.m_contect = context;
  22. this.m_strMessageContent = messageContent;
  23. m_ContactListbuffer = new ArrayList<HashMap<String,Object>>(contactList);
  24. m_isSendCancel = false;
  25. fillPhoneNumber();
  26. }
  27. public void startSendMessage(){
  28. showSendingListDialog();
  29. registerBroadCastReceivers();
  30. m_intMessageSendCount = 0;
  31. sendSMS(m_phoneList.get(m_intMessageSendCount).toString(), m_strMessageContent);
  32. }
  33. private void fillPhoneNumber(){
  34. if(m_ContactListbuffer!=null){
  35. m_ContactList = new ArrayList<HashMap<String,Object>>();
  36. HashMap<String , Object> temp;
  37. for(int j=0; j<m_ContactListbuffer.size(); j++){
  38. temp=new HashMap<String, Object>();
  39. if(m_ContactListbuffer.get(j).get("name")!=null)
  40. temp.put("name", m_ContactListbuffer.get(j).get("name").toString());
  41. if(m_ContactListbuffer.get(j).get("number")!=null)
  42. temp.put("number", m_ContactListbuffer.get(j).get("number").toString());
  43. if(m_ContactListbuffer.get(j).get("contentid")!=null)
  44. temp.put("contentid", m_ContactListbuffer.get(j).get("contentid").toString());
  45. if(j==m_intMessageSendCount)
  46. temp.put("sendstatus", "sending");
  47. else
  48. temp.put("sendstatus", "unsend");
  49. m_ContactList.add(temp);
  50. }
  51. m_phoneList = new ArrayList<String>();
  52. for(int i=0; i<m_ContactList.size(); i++){
  53. m_phoneList.add(m_ContactList.get(i).get("number").toString());
  54. }
  55. }
  56. }
  57. private void sendNextMessage(){
  58. if(thereAreSMSToSend()){
  59. //m_phoneList.
  60. //m_DialogAdapter.notifyDataSetChanged();
  61. /*if(m_ContactList!=null)
  62. m_ContactList.clear();
  63. HashMap<String , Object> temp;
  64. for(int j=0; j<m_ContactListbuffer.size(); j++){
  65. temp=new HashMap<String, Object>();
  66. if(m_ContactListbuffer.get(j).get("name")!=null)
  67. temp.put("name", m_ContactListbuffer.get(j).get("name").toString());
  68. if(m_ContactListbuffer.get(j).get("number")!=null)
  69. temp.put("number", m_ContactListbuffer.get(j).get("number").toString());
  70. if(m_ContactListbuffer.get(j).get("contentid")!=null)
  71. temp.put("contentid", m_ContactListbuffer.get(j).get("contentid").toString());
  72. if(j<m_intMessageSendCount)
  73. temp.put("sendstatus", "sent");
  74. else if(j==m_intMessageSendCount)
  75. temp.put("sendstatus", "sending");
  76. else
  77. temp.put("sendstatus", "unsend");
  78. m_ContactList.add(j,temp);
  79. }*/
  80. HashMap<String , Object> temp =new HashMap<String, Object>();
  81. if(m_ContactListbuffer.get(m_intMessageSendCount).get("name")!=null)
  82. temp.put("name", m_ContactListbuffer.get(m_intMessageSendCount).get("name").toString());
  83. if(m_ContactListbuffer.get(m_intMessageSendCount).get("number")!=null)
  84. temp.put("number", m_ContactListbuffer.get(m_intMessageSendCount).get("number").toString());
  85. if(m_ContactListbuffer.get(m_intMessageSendCount).get("contentid")!=null)
  86. temp.put("contentid", m_ContactListbuffer.get(m_intMessageSendCount).get("contentid").toString());
  87. temp.put("sendstatus", "sending");
  88. m_ContactList.set(m_intMessageSendCount,temp);
  89. sendSMS(m_phoneList.get(m_intMessageSendCount).toString(), m_strMessageContent);
  90. m_DialogAdapter.notifyDataSetChanged();
  91. }else{
  92. Toast.makeText(m_contect, "All SMS have been sent",Toast.LENGTH_SHORT).show();
  93. dialog.dismiss();
  94. unRegisterBroadCastReceivers();
  95. }
  96. }
  97. private void unRegisterBroadCastReceivers() {
  98. m_contect.unregisterReceiver(m_bcrSend);
  99. m_contect.unregisterReceiver(m_bcrDelivred);
  100. }
  101. private boolean thereAreSMSToSend(){
  102. return m_intMessageSendCount < m_phoneList.size();
  103. }
  104. private void sendSMS(String strPhoneNumber, String message){
  105. SmsManager sms = SmsManager.getDefault();
  106. ArrayList<String> parts = sms.divideMessage(message);
  107. m_intMessageSendTotalParts = parts.size();
  108. ArrayList<PendingIntent> deliveryIntents = new ArrayList<PendingIntent>();
  109. ArrayList<PendingIntent> sentIntents = new ArrayList<PendingIntent>();
  110. PendingIntent sentPI = PendingIntent.getBroadcast(m_contect, 0, new Intent(SENT), 0);
  111. PendingIntent deliveredPI = PendingIntent.getBroadcast(m_contect, 0, new Intent(DELIVERED), 0);
  112. for(int j=0; j<m_intMessageSendTotalParts; j++){
  113. sentIntents.add(sentPI);
  114. deliveryIntents.add(deliveredPI);
  115. }
  116. m_intMessageSendParts = 0;
  117. /**************************************************************/
  118. /*  SystemClock.sleep(50);
  119. m_intMessageSendParts++;
  120. if(m_intMessageSendParts == m_intMessageSendTotalParts){
  121. m_intMessageSendCount++;
  122. sendNextMessage();
  123. m_DialogAdapter.notifyDataSetChanged();
  124. }
  125. /******************************************************************/
  126. //  sms.sendMultipartTextMessage(strPhoneNumber, null, parts, sentIntents, deliveryIntents);
  127. //m_handler.removeCallbacks(updatTimer);
  128. //m_handler.postDelayed(updatTimer, 3000);
  129. }
  130. private Runnable updatTimer = new Runnable() {
  131. public void run() {
  132. if(m_intMessageSendCount<m_ContactList.size()){
  133. HashMap<String , Object> temp =new HashMap<String, Object>();
  134. if(m_ContactListbuffer.get(m_intMessageSendCount).get("name")!=null)
  135. temp.put("name", m_ContactListbuffer.get(m_intMessageSendCount).get("name").toString());
  136. if(m_ContactListbuffer.get(m_intMessageSendCount).get("number")!=null)
  137. temp.put("number", m_ContactListbuffer.get(m_intMessageSendCount).get("number").toString());
  138. if(m_ContactListbuffer.get(m_intMessageSendCount).get("contentid")!=null)
  139. temp.put("contentid", m_ContactListbuffer.get(m_intMessageSendCount).get("contentid").toString());
  140. temp.put("sendstatus", "sent");
  141. m_ContactList.set(m_intMessageSendCount,temp);
  142. m_intMessageSendCount++;
  143. sendNextMessage();
  144. }
  145. }
  146. };
  147. private void registerBroadCastReceivers() {
  148. IntentFilter intentFilter = new IntentFilter(SENT);
  149. m_bcrSend = new BroadcastReceiver() {
  150. @Override
  151. public void onReceive(Context arg0, Intent arg1) {
  152. switch(getResultCode()){
  153. case Activity.RESULT_OK:
  154. m_intMessageSendParts++;
  155. if(m_intMessageSendParts == m_intMessageSendTotalParts && !m_isSendCancel){
  156. HashMap<String , Object> temp =new HashMap<String, Object>();
  157. if(m_ContactListbuffer.get(m_intMessageSendCount).get("name")!=null)
  158. temp.put("name", m_ContactListbuffer.get(m_intMessageSendCount).get("name").toString());
  159. if(m_ContactListbuffer.get(m_intMessageSendCount).get("number")!=null)
  160. temp.put("number", m_ContactListbuffer.get(m_intMessageSendCount).get("number").toString());
  161. if(m_ContactListbuffer.get(m_intMessageSendCount).get("contentid")!=null)
  162. temp.put("contentid", m_ContactListbuffer.get(m_intMessageSendCount).get("contentid").toString());
  163. temp.put("sendstatus", "sent");
  164. m_ContactList.set(m_intMessageSendCount,temp);
  165. m_intMessageSendCount++;
  166. sendNextMessage();
  167. }
  168. //Toast.makeText(m_contect, "SMS sent",Toast.LENGTH_SHORT).show();
  169. break;
  170. case SmsManager.RESULT_ERROR_GENERIC_FAILURE:
  171. Toast.makeText(m_contect, "Generic failure",Toast.LENGTH_SHORT).show();
  172. break;
  173. case SmsManager.RESULT_ERROR_NO_SERVICE:
  174. Toast.makeText(m_contect, "No service",Toast.LENGTH_SHORT).show();
  175. break;
  176. case SmsManager.RESULT_ERROR_NULL_PDU:
  177. Toast.makeText(m_contect, "No PDU",Toast.LENGTH_SHORT).show();
  178. break;
  179. case SmsManager.RESULT_ERROR_RADIO_OFF:
  180. Toast.makeText(m_contect, "Radio off",Toast.LENGTH_SHORT).show();
  181. break;
  182. }
  183. }
  184. };
  185. m_contect.registerReceiver(m_bcrSend, intentFilter);
  186. IntentFilter intentFilter1 = new IntentFilter(DELIVERED);
  187. m_bcrDelivred = new BroadcastReceiver() {
  188. @Override
  189. public void onReceive(Context arg0, Intent arg1) {
  190. switch(getResultCode()){
  191. case Activity.RESULT_OK:
  192. break;
  193. case Activity.RESULT_CANCELED:
  194. break;
  195. }
  196. }
  197. };
  198. m_contect.registerReceiver(m_bcrDelivred, intentFilter1);
  199. /*m_contect.registerReceiver(new BroadcastReceiver(){
  200. @Override
  201. public void onReceive(Context arg0, Intent arg1) {
  202. switch(getResultCode()){
  203. case Activity.RESULT_OK:
  204. m_intMessageSendParts++;
  205. if(m_intMessageSendParts == m_intMessageSendTotalParts && !m_isSendCancel){
  206. HashMap<String , Object> temp =new HashMap<String, Object>();
  207. if(m_ContactListbuffer.get(m_intMessageSendCount).get("name")!=null)
  208. temp.put("name", m_ContactListbuffer.get(m_intMessageSendCount).get("name").toString());
  209. if(m_ContactListbuffer.get(m_intMessageSendCount).get("number")!=null)
  210. temp.put("number", m_ContactListbuffer.get(m_intMessageSendCount).get("number").toString());
  211. if(m_ContactListbuffer.get(m_intMessageSendCount).get("contentid")!=null)
  212. temp.put("contentid", m_ContactListbuffer.get(m_intMessageSendCount).get("contentid").toString());
  213. temp.put("sendstatus", "sent");
  214. m_ContactList.set(m_intMessageSendCount,temp);
  215. m_intMessageSendCount++;
  216. sendNextMessage();
  217. }
  218. //Toast.makeText(m_contect, "SMS sent",Toast.LENGTH_SHORT).show();
  219. break;
  220. case SmsManager.RESULT_ERROR_GENERIC_FAILURE:
  221. Toast.makeText(m_contect, "Generic failure",Toast.LENGTH_SHORT).show();
  222. break;
  223. case SmsManager.RESULT_ERROR_NO_SERVICE:
  224. Toast.makeText(m_contect, "No service",Toast.LENGTH_SHORT).show();
  225. break;
  226. case SmsManager.RESULT_ERROR_NULL_PDU:
  227. Toast.makeText(m_contect, "No PDU",Toast.LENGTH_SHORT).show();
  228. break;
  229. case SmsManager.RESULT_ERROR_RADIO_OFF:
  230. Toast.makeText(m_contect, "Radio off",Toast.LENGTH_SHORT).show();
  231. break;
  232. }
  233. }
  234. }, new IntentFilter(SENT));
  235. m_contect.registerReceiver(new BroadcastReceiver(){
  236. @Override
  237. public void onReceive(Context arg0, Intent arg1) {
  238. switch(getResultCode()){
  239. case Activity.RESULT_OK:
  240. break;
  241. case Activity.RESULT_CANCELED:
  242. break;
  243. }
  244. }
  245. }, new IntentFilter(DELIVERED));
  246. */
  247. }
  248. private void showSendingListDialog() {
  249. LayoutInflater factory = LayoutInflater.from(m_contect);
  250. View dialogView = factory.inflate(R.layout.sms_send_list, null);
  251. m_ltvDialogContactList = (ListView) dialogView.findViewById(R.id.lv_sendlist);
  252. setDialogAdapter();
  253. TextView dialogContent = (TextView) dialogView.findViewById(R.id.dialog_sendlist_content);
  254. dialogContent.setText(R.string.dtl_SendList);
  255. Button rightButton = (Button) dialogView.findViewById(R.id.dialog_sendlist_rightbtn);
  256. rightButton.setText(R.string.dmg_SendBackground);
  257. Button leftButton = (Button) dialogView.findViewById(R.id.dialog_sendlist_leftbtn);
  258. leftButton.setText(R.string.dmg_SendCancel);
  259. rightButton.setOnClickListener(new OnClickListener() {
  260. @Override
  261. public void onClick(View v) {
  262. dialog.dismiss();
  263. }
  264. });
  265. leftButton.setOnClickListener(new OnClickListener() {
  266. @Override
  267. public void onClick(View v) {
  268. dialog.dismiss();
  269. }
  270. });
  271. dialog = new Dialog(m_contect);
  272. dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
  273. dialog.setCancelable(false);
  274. dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
  275. dialog.getWindow().setBackgroundDrawable(new ColorDrawable(0));
  276. dialog.setContentView(dialogView);
  277. dialog.show();
  278. /*dialog = new AlertDialog.Builder(m_contect).setTitle(R.string.dtl_SendList)
  279. .setView(dialogView)
  280. .setPositiveButton(R.string.dmg_SendCancel, new DialogInterface.OnClickListener() {
  281. @Override
  282. public void onClick(DialogInterface dialog, int which) {
  283. m_isSendCancel = true;
  284. unRegisterBroadCastReceivers();
  285. }})
  286. .setNegativeButton(R.string.dmg_SendBackground, new DialogInterface.OnClickListener() {
  287. @Override
  288. public void onClick(DialogInterface dialog, int which) {
  289. }}).create();
  290. dialog.show();*/
  291. }
  292. private void setDialogAdapter() {
  293. m_DialogAdapter = new CustomDialogAdapter(m_contect, R.layout.sms_send_list_item, m_ContactList);
  294. m_ltvDialogContactList.setAdapter(m_DialogAdapter);
  295. }
  296. private class CustomDialogAdapter extends ArrayAdapter<HashMap<String, Object>> {
  297. public CustomDialogAdapter(Context context, int textViewResourceId, ArrayList<HashMap<String, Object>> Strings) {
  298. super(context, textViewResourceId, Strings);
  299. }
  300. private class ViewHolder{
  301. TextView txvContact;
  302. TextView txvSendStatus;
  303. ProgressBar prgbSend;
  304. }
  305. ViewHolder viewHolder;
  306. @Override
  307. public View getView(final int position, View convertView, ViewGroup parent) {
  308. if(convertView==null){
  309. LayoutInflater inflater = (LayoutInflater) m_contect.getSystemService( Context.LAYOUT_INFLATER_SERVICE );
  310. convertView = inflater.inflate(R.layout.sms_send_list_item, null);
  311. viewHolder=new ViewHolder();
  312. viewHolder.txvContact=(TextView) convertView.findViewById(R.id.txvSendlistitem_name);
  313. viewHolder.txvSendStatus=(TextView) convertView.findViewById(R.id.txvSendlistitem_status);
  314. viewHolder.prgbSend=(ProgressBar) convertView.findViewById(R.id.pb_sending);
  315. convertView.setTag(viewHolder);
  316. }
  317. viewHolder=(ViewHolder) convertView.getTag();
  318. viewHolder.txvContact.setText(m_ContactList.get(position).get("number").toString());
  319. String isSend = m_ContactList.get(position).get("sendstatus").toString();
  320. if(isSend=="sent"){
  321. viewHolder.prgbSend.setVisibility(View.GONE);
  322. viewHolder.txvSendStatus.setVisibility(View.VISIBLE);
  323. viewHolder.txvSendStatus.setText(R.string.dmg_Sent);
  324. }else if(isSend=="sending"){
  325. viewHolder.prgbSend.setVisibility(View.VISIBLE);
  326. viewHolder.txvSendStatus.setVisibility(View.GONE);
  327. }else if(isSend=="unsend"){
  328. viewHolder.prgbSend.setVisibility(View.GONE);
  329. viewHolder.txvSendStatus.setVisibility(View.VISIBLE);
  330. viewHolder.txvSendStatus.setText(R.string.dmg_SendWait);
  331. }
  332. return convertView;
  333. }
  334. }
  335. /*public static void sendMessage(Context context, String strAddress, String strMessage){
  336. try {
  337. Uri smsUri = Uri.parse("tel:123456");
  338. Intent intent = new Intent(Intent.ACTION_VIEW, smsUri);
  339. intent.putExtra("sms_body", "");
  340. intent.setType("vnd.android-dir/mms-sms");
  341. intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
  342. context.startActivity(intent);
  343. } catch (ActivityNotFoundException e) {
  344. Log.e(TAG, "Send SMS failed", e);
  345. }
  346. }*/
  347. }

时间字符串处理类1:

[java] view plaincopy

  1. public class C_DateUtils {
  2. private static final String TAG = C_DateUtils.class.getSimpleName();
  3. /**
  4. * check date is today
  5. * @param date
  6. * @return
  7. */
  8. public static boolean isToday(Date date){
  9. return isSameDate(new Date(), date);
  10. }
  11. /**
  12. * check Date is same day
  13. * @param baseDate
  14. * @param thenDate
  15. * @return
  16. */
  17. public static boolean isSameDate(Date baseDate, Date thenDate){
  18. Time time = new Time();
  19. time.set(thenDate.getTime());
  20. int thenYear = time.year;
  21. int thenMonth = time.month;
  22. int thenMonthDay = time.monthDay;
  23. time.set(baseDate.getTime());
  24. return (thenYear == time.year)
  25. && (thenMonth == time.month)
  26. && (thenMonthDay == time.monthDay);
  27. }
  28. /**
  29. * caculate day counts between startDate and endDate
  30. * @param startDate
  31. * @param endDate
  32. * @return
  33. */
  34. public static int diffDays(Date startDate, Date endDate){
  35. return (int)((endDate.getTime() - startDate.getTime()) / DateUtils.DAY_IN_MILLIS);
  36. }
  37. /**
  38. * caculate week counts between startDate and endDate
  39. * @param startDate
  40. * @param endDate
  41. * @return
  42. */
  43. public static int diffWeeks(Date startDate, Date endDate){
  44. return (int)((endDate.getTime() - startDate.getTime()) / DateUtils.WEEK_IN_MILLIS);
  45. }
  46. /**
  47. * caculate month counts between startDate and endDate
  48. * @param startDate
  49. * @param endDate
  50. * @return
  51. */
  52. public static int diffMonths(Date startDate, Date endDate){
  53. Time startTime = new Time();
  54. startTime.set(startDate.getTime());
  55. Time endTime = new Time();
  56. endTime.set(endDate.getTime());
  57. int diffYears = endTime.year - startTime.year;
  58. return diffYears * 12 + endTime.month - startTime.month;
  59. }
  60. /**
  61. * caculate year counts between startDate and endDate
  62. * @param startDate
  63. * @param endDate
  64. * @return
  65. */
  66. public static int diffYears(Date startDate, Date endDate){
  67. Time startTime = new Time();
  68. startTime.set(startDate.getTime());
  69. Time endTime = new Time();
  70. endTime.set(endDate.getTime());
  71. int diffYears = endTime.year - startTime.year;
  72. return diffYears;
  73. }
  74. /**
  75. * return date is Saturday or Sunday
  76. * @param date
  77. * @return
  78. */
  79. public static boolean isWeekend(Date date){
  80. Time time = new Time();
  81. time.set(date.getTime());
  82. return (time.weekDay == Time.SATURDAY || time.weekDay == Time.SUNDAY);
  83. }
  84. }

时间字符串处理类2:

[java] view plaincopy

  1. /**
  2. * 工具類
  3. * @author KrisLight
  4. *
  5. */
  6. public class Utils
  7. {
  8. /**
  9. * 透明度動畫變化持續時間
  10. */
  11. public static int ANIM_ALPHA_DURATION = 100;
  12. /**
  13. * 平移動畫持續時間
  14. */
  15. public static int ANIM_TRANSLATE_DURATION = 30;
  16. /**
  17. *  周別格式   EEEE
  18. */
  19. private SimpleDateFormat dateFormatWeekDay = new SimpleDateFormat("EEEE");
  20. /**
  21. *  月份格式    MMMM
  22. */
  23. private SimpleDateFormat dateFormatMonth = new SimpleDateFormat("MMMM");
  24. /**
  25. *  包括年,月,日,周的日期格式   EEEE, d MMMM yyyy
  26. */
  27. private SimpleDateFormat dateFormatLong = new SimpleDateFormat("EEEE, d MMMM yyyy");
  28. /**
  29. *  包括年,月,日的日期格式   dd-MM-yyyy
  30. */
  31. private SimpleDateFormat dateFormatShort = new SimpleDateFormat("dd-MM-yyyy");
  32. /**
  33. * Sql中的日期格式   dd-MM-yyyy kk:mm.ss
  34. */
  35. private SimpleDateFormat dateFormatSql = new SimpleDateFormat("dd-MM-yyyy kk:mm.ss");
  36. //UTILS
  37. public Utils()
  38. {
  39. }
  40. /**
  41. * 得到周別的日期字符串
  42. */
  43. public String GetWeekDay(Calendar date)
  44. {
  45. return dateFormatWeekDay.format(date.getTime());
  46. }
  47. /**
  48. * 得到月的日期字符串
  49. */
  50. public String GetMonth(Calendar date)
  51. {
  52. return dateFormatMonth.format(date.getTime());
  53. }
  54. /**
  55. * 得到包括年,月,日,周的日期格式字符串
  56. */
  57. public String GetLongDate(Calendar date)
  58. {
  59. return dateFormatLong.format(date.getTime());
  60. }
  61. /**
  62. * 得到包括年,月,日的日期格式字符串
  63. */
  64. public String GetShortDate(Calendar date)
  65. {
  66. return dateFormatShort.format(date.getTime());
  67. }
  68. /**
  69. *
  70. * @Function: pl.magot.vetch.ancal.Utils.GetLongTime
  71. * @Description: 得到時和分
  72. *
  73. * @param date 日期
  74. * @param b24HourMode  是否24小時制: true 是  false 否
  75. * @return  由小時和分鐘組成的字符串 如: 12:20
  76. *
  77. * @version:v1.0
  78. * @author:KrisLight
  79. * @date:2013/9/4 下午4:51:27
  80. *
  81. * Modification History:
  82. * Date         Author      Version     Description
  83. * -----------------------------------------------------------------
  84. * 2013/9/4    KrisLight      v1.0.0         create
  85. */
  86. public String GetLongTime(Calendar date, boolean b24HourMode)
  87. {
  88. String s = "";
  89. if (b24HourMode)
  90. {
  91. //k: 24 小时制的小时     M: 小时中的分钟
  92. s = String.format("%tk:%tM", date, date);
  93. } else {
  94. //l: 12 小时制的小时     M: 小时中的分钟
  95. if (date.get(Calendar.AM_PM) == 0) //AM
  96. s = String.format("%tl:%tM am", date, date, date.get(Calendar.AM_PM));
  97. if (date.get(Calendar.AM_PM) == 1) //PM
  98. s = String.format("%tl:%tM pm", date, date, date.get(Calendar.AM_PM));
  99. }
  100. return s;
  101. }
  102. /**
  103. *
  104. * @Function: pl.magot.vetch.ancal.Utils.SqlStrToDate
  105. * @Description: 將用Sql語句查出來的日期字符串轉換成對應的日期Date
  106. *
  107. * @param s  sql format: "dd-MM-yyyy kk:mm.ss"
  108. * @param dateOut 轉換成功的日期
  109. * @param dateFail 轉換失敗默認的日期
  110. * @return
  111. *
  112. * @version:v1.0
  113. * @author:KrisLight
  114. * @date:2013/9/4 下午5:07:40
  115. *
  116. * Modification History:
  117. * Date         Author      Version     Description
  118. * -----------------------------------------------------------------
  119. * 2013/9/4    KrisLight      v1.0.0         create
  120. */
  121. public static Calendar SqlStrToDate(String s, Calendar dateOut, Calendar dateFail)
  122. {
  123. if (s.length() == 19)
  124. {
  125. int dd = Integer.parseInt(s.substring(0, 2));
  126. int MM = Integer.parseInt(s.substring(3, 5));
  127. int yyyy = Integer.parseInt(s.substring(6, 10));
  128. int kk = Integer.parseInt(s.substring(11, 13));
  129. int mm = Integer.parseInt(s.substring(14, 16));
  130. int ss = Integer.parseInt(s.substring(17, 19));
  131. // set(int year, int month, int day, int hourOfDay, int minute, int second) 這裡月從0開始  1月對應的是0
  132. dateOut.set(yyyy, MM - 1, dd, kk, mm, ss);
  133. return dateOut;
  134. }
  135. return dateFail;
  136. }
  137. /**
  138. *
  139. * @Function: pl.magot.vetch.ancal.Utils.DateToSqlStr
  140. * @Description:將日期轉換成SQL中需要的日期格式
  141. *
  142. * @param date
  143. * @return
  144. *
  145. * @version:v1.0
  146. * @author:KrisLight
  147. * @date:2013/9/4 下午5:11:29
  148. *
  149. * Modification History:
  150. * Date         Author      Version     Description
  151. * -----------------------------------------------------------------
  152. * 2013/9/4    KrisLight      v1.0.0         create
  153. */
  154. public String DateToSqlStr(Calendar date)
  155. {
  156. return dateFormatSql.format(date.getTime());
  157. }
  158. /**
  159. *  將時間轉換成秒
  160. */
  161. public static int GetTimeAsSeconds(Calendar date)
  162. {
  163. return (date.get(Calendar.HOUR_OF_DAY) * 3600) +
  164. date.get(Calendar.MINUTE) * 60;
  165. }
  166. /**
  167. *  清除日期
  168. */
  169. public static void ClearCalendarTime(Calendar cal)
  170. {
  171. cal.clear(Calendar.MILLISECOND);
  172. cal.clear(Calendar.SECOND);
  173. cal.clear(Calendar.MINUTE);
  174. cal.clear(Calendar.HOUR_OF_DAY);
  175. }
  176. /**
  177. *  判斷日期是否相等
  178. */
  179. public static boolean YearDaysEqual(Calendar calDate, Calendar calDateTo)
  180. {
  181. if (calDate.get(Calendar.YEAR) == calDateTo.get(Calendar.YEAR))
  182. if (calDate.get(Calendar.MONTH) == calDateTo.get(Calendar.MONTH))
  183. if (calDate.get(Calendar.DAY_OF_MONTH) == calDateTo.get(Calendar.DAY_OF_MONTH))
  184. return true;
  185. return false;
  186. }
  187. /**
  188. *  判斷前一個日期是否大於后一個
  189. */
  190. public static boolean YearDaysGreater(Calendar calDate, Calendar calDateTo)
  191. {
  192. if (calDate.get(Calendar.YEAR) >= calDateTo.get(Calendar.YEAR))
  193. if (calDate.get(Calendar.MONTH) >= calDateTo.get(Calendar.MONTH))
  194. if (calDate.get(Calendar.DAY_OF_MONTH) >= calDateTo.get(Calendar.DAY_OF_MONTH))
  195. return true;
  196. return false;
  197. }
  198. /**
  199. * 判斷前一個時間是否等於或晚於後面一個時間
  200. * 用於設置鬧鐘的時候與當前時間判斷
  201. * 設置的鬧鈴時間必須晚於當前時間
  202. */
  203. public static boolean IsTimeOverdued(Calendar calDate, Calendar calDueDate)
  204. {
  205. if ((calDueDate.compareTo(calDate) == 0) || (calDueDate.compareTo(calDate) == 1))
  206. return true;
  207. return false;
  208. }
  209. //compare time: for calendar view display
  210. public static boolean IsInTimeRange(Calendar calDateStart, Calendar calDate, int iDurationInMinutes)
  211. {
  212. if (calDate.get(Calendar.HOUR_OF_DAY) == calDateStart.get(Calendar.HOUR_OF_DAY))
  213. if (calDate.get(Calendar.MINUTE) >= calDateStart.get(Calendar.MINUTE))
  214. if (calDate.get(Calendar.MINUTE) <= (calDateStart.get(Calendar.MINUTE) + iDurationInMinutes))
  215. return true;
  216. return false;
  217. }
  218. /**
  219. *  將時間轉換成long類型  形如: 200712122359
  220. */
  221. public static long GetDateTimeKey(Calendar calDate)
  222. {
  223. long lYear = calDate.get(Calendar.YEAR) * 100000000;
  224. long lMonth = calDate.get(Calendar.MONTH) * 1000000;
  225. long lDay = calDate.get(Calendar.DAY_OF_MONTH) * 10000;
  226. long lHour = calDate.get(Calendar.HOUR_OF_DAY) * 100;
  227. long lMinute = calDate.get(Calendar.MINUTE);
  228. return lYear + lMonth + lDay + lHour + lMinute;
  229. }
  230. /**
  231. *  首字母大寫
  232. */
  233. public static String CapitalizeFirstLetter(String sText)
  234. {
  235. return sText.substring(0,1).toUpperCase() + sText.substring(1, sText.length()).toLowerCase();
  236. }
  237. /**
  238. *  得到App版本
  239. */
  240. public static String getAppVersionName(Context ctx)
  241. {
  242. try
  243. {
  244. PackageInfo pi = ctx.getPackageManager().getPackageInfo("pl.magot.vetch.ancal", 0);
  245. return pi.versionName;
  246. } catch (NameNotFoundException e) {
  247. }
  248. return "";
  249. }
  250. /**
  251. *
  252. * @Function: com.light.mycal.util.Utils.join
  253. * @Description: 集合中的元素以指定分隔符隔開
  254. *
  255. * @param list   集合List
  256. * @param delim  分隔符
  257. * @return  用分隔符隔開的集合元素字符串
  258. *
  259. * @version: v1.0
  260. * @author: KrisLight
  261. * @date: 2013/9/5 上午10:20:51
  262. *
  263. * Modification History:
  264. * Date         Author      Version     Description
  265. * -----------------------------------------------------------------
  266. * 2013/9/5    KrisLight      v1.0.0         create
  267. */
  268. public static String join(List<String> list, String delim) {
  269. StringBuilder buf = new StringBuilder();
  270. int num = list.size();
  271. for (int i = 0; i < num; i++) {
  272. if (i != 0){
  273. buf.append(delim);
  274. }
  275. buf.append((String) list.get(i));
  276. }
  277. return buf.toString();
  278. }
  279. /**
  280. *  開始alpha動畫
  281. */
  282. public static void startAlphaAnimIn(View view)
  283. {
  284. AlphaAnimation anim = new AlphaAnimation(0.5F, 1);
  285. anim.setDuration(ANIM_ALPHA_DURATION);
  286. anim.startNow();
  287. view.startAnimation(anim);
  288. }
  289. /**
  290. *  開始translate動畫
  291. */
  292. public static void startTranslateAnimIn(View view)
  293. {
  294. TranslateAnimation anim = new TranslateAnimation(0, 0, - view.getHeight(), 0);
  295. anim.setDuration(ANIM_TRANSLATE_DURATION);
  296. anim.startNow();
  297. view.startAnimation(anim);
  298. }
  299. }

图像处理类

1.图像缓存

[java] view plaincopy

  1. public class BitmapCache {
  2. private static final
  3. String TAG = "ImageCache";
  4. private static final int
  5. DEFAULT_MEM_CACHE_SIZE = 1024 * 1024 * 8; // 8MB
  6. private static final int DEFAULT_DISK_CACHE_SIZE = 1024 *
  7. 1024 * 20; // 20MB
  8. // Compression settings when
  9. writing images to disk cache
  10. private static final
  11. CompressFormat DEFAULT_COMPRESS_FORMAT =
  12. CompressFormat.JPEG;
  13. private static final int
  14. DEFAULT_COMPRESS_QUALITY = 70;
  15. private static final
  16. int DISK_CACHE_INDEX = 0;
  17. // Constants to easily
  18. toggle various caches
  19. private static final boolean
  20. DEFAULT_MEM_CACHE_ENABLED = true;
  21. private static final
  22. boolean DEFAULT_DISK_CACHE_ENABLED = true;
  23. private
  24. static final boolean DEFAULT_CLEAR_DISK_CACHE_ON_START =
  25. false;
  26. private static final boolean
  27. DEFAULT_INIT_DISK_CACHE_ON_CREATE = false;
  28. private
  29. LruDiskCache mDiskLruCache;
  30. private
  31. LruMemoryCache<String, Bitmap> mMemoryCache;
  32. private
  33. ImageCacheParams mCacheParams;
  34. private final Object
  35. mDiskCacheLock = new Object();
  36. private boolean
  37. mDiskCacheStarting = true;
  38. /**
  39. * Creating a new
  40. ImageCache object using the specified parameters.
  41. *
  42. * @param cacheParams The cache parameters to use to
  43. initialize the cache
  44. */
  45. public BitmapCache
  46. (ImageCacheParams cacheParams) {
  47. init
  48. (cacheParams);
  49. }
  50. /**
  51. * Initialize the cache,
  52. providing all parameters.
  53. *
  54. * @param cacheParams
  55. The cache parameters to initialize the cache
  56. */
  57. private void init(ImageCacheParams cacheParams) {
  58. mCacheParams = cacheParams;
  59. // Set up memory cache
  60. if (mCacheParams.memoryCacheEnabled) {
  61. mMemoryCache = new LruMemoryCache<String, Bitmap>
  62. (mCacheParams.memCacheSize) {
  63. /**
  64. * Measure item size in bytes rather than units
  65. which is more practical
  66. * for a bitmap
  67. cache
  68. */
  69. @Override
  70. protected int sizeOf(String key, Bitmap bitmap) {
  71. return BitmapCommonUtils.getBitmapSize
  72. (bitmap);
  73. }
  74. };
  75. }
  76. // By default the disk cache is not initialized here as
  77. it should be initialized
  78. // on a separate thread
  79. due to disk access.
  80. if
  81. (cacheParams.initDiskCacheOnCreate) {
  82. // Set
  83. up disk cache
  84. initDiskCache();
  85. }
  86. }
  87. /**
  88. * Initializes the disk cache.  Note that this
  89. includes disk access so this should not be
  90. * executed
  91. on the main/UI thread. By default an ImageCache does not
  92. initialize the disk
  93. * cache when it is created,
  94. instead you should call initDiskCache() to initialize it
  95. on a
  96. * background thread.
  97. */
  98. public void
  99. initDiskCache() {
  100. // Set up disk cache
  101. synchronized (mDiskCacheLock) {
  102. if
  103. (mDiskLruCache == null || mDiskLruCache.isClosed()) {
  104. File diskCacheDir = mCacheParams.diskCacheDir;
  105. if (mCacheParams.diskCacheEnabled &&
  106. diskCacheDir != null) {
  107. if (!
  108. diskCacheDir.exists()) {
  109. diskCacheDir.mkdirs();
  110. }
  111. if (BitmapCommonUtils.getUsableSpace(diskCacheDir) >
  112. mCacheParams.diskCacheSize) {
  113. try
  114. {
  115. mDiskLruCache =
  116. LruDiskCache.open(diskCacheDir, 1, 1,
  117. mCacheParams.diskCacheSize);
  118. }
  119. catch (final IOException e) {
  120. mCacheParams.diskCacheDir = null;
  121. Log.e(TAG, "initDiskCache - " + e);
  122. }
  123. }
  124. }
  125. }
  126. mDiskCacheStarting = false;
  127. mDiskCacheLock.notifyAll();
  128. }
  129. }
  130. /**
  131. *
  132. Adds a bitmap to both memory and disk cache.
  133. * @param
  134. data Unique identifier for the bitmap to store
  135. *
  136. @param bitmap The bitmap to store
  137. */
  138. public void
  139. addBitmapToCache(String data, Bitmap bitmap) {
  140. if
  141. (data == null || bitmap == null) {
  142. return;
  143. }
  144. // Add to memory cache
  145. if
  146. (mMemoryCache != null && mMemoryCache.get(data) == null)
  147. {
  148. mMemoryCache.put(data, bitmap);
  149. }
  150. synchronized (mDiskCacheLock) {
  151. if
  152. (mDiskLruCache != null && mDiskLruCache.getDirectory()!=
  153. null ) {
  154. if(!
  155. mDiskLruCache.getDirectory().exists())
  156. mDiskLruCache.getDirectory().mkdirs();
  157. final String key =
  158. FileNameGenerator.generator(data);
  159. OutputStream out = null;
  160. try {
  161. LruDiskCache.Snapshot snapshot =
  162. mDiskLruCache.get(key);
  163. if (snapshot
  164. == null) {
  165. final
  166. LruDiskCache.Editor editor = mDiskLruCache.edit(key);
  167. if (editor != null) {
  168. out = editor.newOutputStream(DISK_CACHE_INDEX);
  169. bitmap.compress(
  170. mCacheParams.compressFormat,
  171. mCacheParams.compressQuality, out);
  172. editor.commit();
  173. out.close();
  174. }
  175. } else {
  176. snapshot.getInputStream
  177. (DISK_CACHE_INDEX).close();
  178. }
  179. } catch (final IOException e) {
  180. Log.e(TAG, "addBitmapToCache - " + e);
  181. }
  182. catch (Exception e) {
  183. Log.e(TAG,
  184. "addBitmapToCache - " + e);
  185. } finally {
  186. try {
  187. if (out !=
  188. null) {
  189. out.close();
  190. }
  191. } catch (IOException e)
  192. {}
  193. }
  194. }
  195. }
  196. }
  197. /**
  198. * Get from memory cache.
  199. *
  200. * @param data Unique
  201. identifier for which item to get
  202. * @return The bitmap
  203. if found in cache, null otherwise
  204. */
  205. public Bitmap
  206. getBitmapFromMemCache(String data) {
  207. if
  208. (mMemoryCache != null) {
  209. final Bitmap
  210. memBitmap = mMemoryCache.get(data);
  211. if
  212. (memBitmap != null) {
  213. return memBitmap;
  214. }
  215. }
  216. return null;
  217. }
  218. /**
  219. *
  220. @param data
  221. * @return
  222. */
  223. public Bitmap
  224. getBitmapFromDiskCache(String data) {
  225. final
  226. String key = FileNameGenerator.generator(data);
  227. synchronized (mDiskCacheLock) {
  228. while
  229. (mDiskCacheStarting) {
  230. try {
  231. mDiskCacheLock.wait();
  232. } catch
  233. (InterruptedException e) {}
  234. }
  235. if
  236. (mDiskLruCache != null) {
  237. InputStream
  238. inputStream = null;
  239. try {
  240. final LruDiskCache.Snapshot snapshot =
  241. mDiskLruCache.get(key);
  242. if (snapshot
  243. != null) {
  244. inputStream =
  245. snapshot.getInputStream(DISK_CACHE_INDEX);
  246. if (inputStream != null) {
  247. final Bitmap bitmap = BitmapFactory.decodeStream
  248. (inputStream);
  249. return bitmap;
  250. }
  251. }
  252. } catch (final IOException e) {
  253. Log.e(TAG, "getBitmapFromDiskCache - " + e);
  254. } finally {
  255. try {
  256. if (inputStream != null) {
  257. inputStream.close();
  258. }
  259. } catch (IOException e) {}
  260. }
  261. }
  262. return null;
  263. }
  264. }
  265. /**
  266. *
  267. Clears both the memory and disk cache associated with
  268. this ImageCache object. Note that
  269. * this includes
  270. disk access so this should not be executed on the main/UI
  271. thread.
  272. */
  273. public void clearCache() {
  274. clearMemoryCache();
  275. synchronized (mDiskCacheLock)
  276. {
  277. mDiskCacheStarting = true;
  278. if
  279. (mDiskLruCache != null && !mDiskLruCache.isClosed()) {
  280. try {
  281. mDiskLruCache.delete();
  282. } catch
  283. (IOException e) {
  284. Log.e(TAG,
  285. "clearCache - " + e);
  286. }
  287. mDiskLruCache = null;
  288. initDiskCache();
  289. }
  290. }
  291. }
  292. public void
  293. clearMemoryCache(){
  294. if (mMemoryCache != null) {
  295. mMemoryCache.evictAll();
  296. }
  297. }
  298. /**
  299. *
  300. Flushes the disk cache associated with this ImageCache
  301. object. Note that this includes
  302. * disk access so this
  303. should not be executed on the main/UI thread.
  304. */
  305. public void flush() {
  306. synchronized
  307. (mDiskCacheLock) {
  308. if (mDiskLruCache != null)
  309. {
  310. try {
  311. mDiskLruCache.flush();
  312. } catch
  313. (IOException e) {
  314. Log.e(TAG, "flush -
  315. " + e);
  316. }
  317. }
  318. }
  319. }
  320. /**
  321. * Closes the disk cache associated with this
  322. ImageCache object. Note that this includes
  323. * disk
  324. access so this should not be executed on the main/UI
  325. thread.
  326. */
  327. public void close() {
  328. synchronized (mDiskCacheLock) {
  329. if
  330. (mDiskLruCache != null) {
  331. try {
  332. if (!mDiskLruCache.isClosed()) {
  333. mDiskLruCache.close();
  334. mDiskLruCache = null;
  335. }
  336. } catch (IOException e) {
  337. Log.e(TAG,
  338. "close - " + e);
  339. }
  340. }
  341. }
  342. }
  343. /**
  344. * A holder class that contains cache
  345. parameters.
  346. */
  347. public static class
  348. ImageCacheParams {
  349. public int memCacheSize =
  350. DEFAULT_MEM_CACHE_SIZE;
  351. public int diskCacheSize =
  352. DEFAULT_DISK_CACHE_SIZE;
  353. public File diskCacheDir;
  354. public CompressFormat compressFormat =
  355. DEFAULT_COMPRESS_FORMAT;
  356. public int
  357. compressQuality = DEFAULT_COMPRESS_QUALITY;
  358. public
  359. boolean memoryCacheEnabled = DEFAULT_MEM_CACHE_ENABLED;
  360. public boolean diskCacheEnabled =
  361. DEFAULT_DISK_CACHE_ENABLED;
  362. public boolean
  363. clearDiskCacheOnStart =
  364. DEFAULT_CLEAR_DISK_CACHE_ON_START;
  365. public boolean
  366. initDiskCacheOnCreate =
  367. DEFAULT_INIT_DISK_CACHE_ON_CREATE;
  368. public
  369. ImageCacheParams(File diskCacheDir) {
  370. this.diskCacheDir = diskCacheDir;
  371. }
  372. public ImageCacheParams(String diskCacheDir) {
  373. this.diskCacheDir = new File(diskCacheDir);
  374. }
  375. /**
  376. * @param context棿
  377. */
  378. public
  379. void setMemCacheSizePercent(Context context, float
  380. percent) {
  381. if (percent < 0.05f || percent >
  382. 0.8f) {
  383. throw new
  384. IllegalArgumentException("setMemCacheSizePercent -
  385. percent must be "
  386. + "between 0.05
  387. and 0.8 (inclusive)");
  388. }
  389. memCacheSize = Math.round(percent * getMemoryClass
  390. (context) * 1024 * 1024);
  391. }
  392. public void setMemCacheSize(int memCacheSize) {
  393. this.memCacheSize = memCacheSize;
  394. }
  395. public void setDiskCacheSize(int diskCacheSize) {
  396. this.diskCacheSize = diskCacheSize;
  397. }
  398. private static int getMemoryClass(Context
  399. context) {
  400. return ((ActivityManager)
  401. context.getSystemService(
  402. Context.ACTIVITY_SERVICE)).getMemoryClass();
  403. }
  404. }
  405. }

图像处理类

[java] view plaincopy

  1. public class BitmapCommonUtils {
  2. private static final String TAG = "BitmapCommonUtils";
  3. /**
  4. * @param context
  5. * @return
  6. */
  7. public static File getDiskCacheDir(Context context, String uniqueName) {
  8. final String cachePath = Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState()) ?
  9. getExternalCacheDir(context).getPath() : context.getCacheDir().getPath();
  10. return new File(cachePath + File.separator + uniqueName);
  11. }
  12. /**
  13. * @param bitmap
  14. * @return
  15. */
  16. public static int getBitmapSize(Bitmap bitmap) {
  17. return bitmap.getRowBytes() * bitmap.getHeight();
  18. }
  19. /**
  20. * @param context
  21. * @return
  22. */
  23. public static File getExternalCacheDir(Context context) {
  24. final String cacheDir = "/Android/data/" + context.getPackageName() + "/cache/";
  25. return new File(Environment.getExternalStorageDirectory().getPath() + cacheDir);
  26. }
  27. /**
  28. * @param path
  29. * @return
  30. */
  31. public static long getUsableSpace(File path) {
  32. try{
  33. final StatFs stats = new StatFs(path.getPath());
  34. return (long) stats.getBlockSize() * (long) stats.getAvailableBlocks();
  35. }catch (Exception e) {
  36. e.printStackTrace();
  37. return -1;
  38. }
  39. }
  40. }

图像Decoder类

[java] view plaincopy

  1. public class BitmapDecoder {
  2. private static final String TAG = "BitmapDecoder";
  3. private BitmapDecoder(){}
  4. public static Bitmap decodeSampledBitmapFromResource(Resources res, int resId,int reqWidth, int reqHeight) {
  5. final BitmapFactory.Options options = new BitmapFactory.Options();
  6. options.inJustDecodeBounds = true;
  7. options.inPurgeable = true;
  8. BitmapFactory.decodeResource(res, resId, options);
  9. options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);
  10. options.inJustDecodeBounds = false;
  11. try {
  12. return BitmapFactory.decodeResource(res, resId, options);
  13. } catch (OutOfMemoryError e) {
  14. e.printStackTrace();
  15. return null;
  16. }
  17. }
  18. public static Bitmap decodeSampledBitmapFromFile(String filename,int reqWidth, int reqHeight) {
  19. final BitmapFactory.Options options = new BitmapFactory.Options();
  20. options.inJustDecodeBounds = true;
  21. options.inPurgeable = true;
  22. BitmapFactory.decodeFile(filename, options);
  23. options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);
  24. options.inJustDecodeBounds = false;
  25. try {
  26. return BitmapFactory.decodeFile(filename, options);
  27. } catch (OutOfMemoryError e) {
  28. e.printStackTrace();
  29. return null;
  30. }
  31. }
  32. public static Bitmap decodeSampledBitmapFromDescriptor(FileDescriptor fileDescriptor, int reqWidth, int reqHeight) {
  33. final BitmapFactory.Options options = new BitmapFactory.Options();
  34. options.inJustDecodeBounds = true;
  35. options.inPurgeable = true;
  36. BitmapFactory.decodeFileDescriptor(fileDescriptor, null, options);
  37. options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);
  38. options.inJustDecodeBounds = false;
  39. try {
  40. return BitmapFactory.decodeFileDescriptor(fileDescriptor, null, options);
  41. } catch (OutOfMemoryError e) {
  42. // Log.e(TAG, "decodeSampledBitmapFromDescriptor");
  43. e.printStackTrace();
  44. return null;
  45. }
  46. }
  47. public static int calculateInSampleSize(BitmapFactory.Options options,int reqWidth, int reqHeight) {
  48. final int height = options.outHeight;
  49. final int width = options.outWidth;
  50. int inSampleSize = 1;
  51. if (height > reqHeight || width > reqWidth) {
  52. if (width > height) {
  53. inSampleSize = Math.round((float) height / (float) reqHeight);
  54. } else {
  55. inSampleSize = Math.round((float) width / (float) reqWidth);
  56. }
  57. final float totalPixels = width * height;
  58. final float totalReqPixelsCap = reqWidth * reqHeight * 2;
  59. while (totalPixels / (inSampleSize * inSampleSize) > totalReqPixelsCap) {
  60. inSampleSize++;
  61. }
  62. }
  63. return inSampleSize;
  64. }
  65. }

图像显示配置类

[java] view plaincopy

  1. public class BitmapDisplayConfig {
  2. private int bitmapWidth;
  3. private int bitmapHeight;
  4. private Animation animation;
  5. private int animationType;
  6. private Bitmap loadingBitmap;
  7. private Bitmap loadfailBitmap;
  8. public int getBitmapWidth() {
  9. return bitmapWidth;
  10. }
  11. public void setBitmapWidth(int bitmapWidth) {
  12. this.bitmapWidth = bitmapWidth;
  13. }
  14. public int getBitmapHeight() {
  15. return bitmapHeight;
  16. }
  17. public void setBitmapHeight(int bitmapHeight) {
  18. this.bitmapHeight = bitmapHeight;
  19. }
  20. public Animation getAnimation() {
  21. return animation;
  22. }
  23. public void setAnimation(Animation animation) {
  24. this.animation = animation;
  25. }
  26. public int getAnimationType() {
  27. return animationType;
  28. }
  29. public void setAnimationType(int animationType) {
  30. this.animationType = animationType;
  31. }
  32. public Bitmap getLoadingBitmap() {
  33. return loadingBitmap;
  34. }
  35. public void setLoadingBitmap(Bitmap loadingBitmap) {
  36. this.loadingBitmap = loadingBitmap;
  37. }
  38. public Bitmap getLoadfailBitmap() {
  39. return loadfailBitmap;
  40. }
  41. public void setLoadfailBitmap(Bitmap loadfailBitmap) {
  42. this.loadfailBitmap = loadfailBitmap;
  43. }
  44. public class AnimationType{
  45. public static final int userDefined = 0;
  46. public static final int fadeIn = 1;
  47. }
  48. }

图像流读取类

[java] view plaincopy

  1. public class BitmapProcess {
  2. private static final String TAG = "BitmapProcess";
  3. private boolean mHttpDiskCacheStarting = true;
  4. private int cacheSize;
  5. private static final int DEFAULT_CACHE_SIZE = 20 * 1024 * 1024; // 20MB
  6. private LruDiskCache mOriginalDiskCache;
  7. private final Object mHttpDiskCacheLock = new Object();
  8. private static final int DISK_CACHE_INDEX = 0;
  9. private File mOriginalCacheDir;
  10. private Downloader downloader;
  11. private boolean neverCalculate = false;
  12. public BitmapProcess(Downloader downloader,String filePath,int cacheSize) {
  13. this.mOriginalCacheDir = new File(filePath+"/original");
  14. this.downloader = downloader;
  15. if(cacheSize<=0)
  16. cacheSize = DEFAULT_CACHE_SIZE;
  17. this.cacheSize = cacheSize;
  18. }
  19. public void configCalculateBitmap(boolean neverCalculate){
  20. this.neverCalculate = neverCalculate;
  21. }
  22. public Bitmap processBitmap(String data, BitmapDisplayConfig config) {
  23. final String key = FileNameGenerator.generator(data);
  24. FileDescriptor fileDescriptor = null;
  25. FileInputStream fileInputStream = null;
  26. LruDiskCache.Snapshot snapshot;
  27. synchronized (mHttpDiskCacheLock) {
  28. // Wait for disk cache to initialize
  29. while (mHttpDiskCacheStarting) {
  30. try {
  31. mHttpDiskCacheLock.wait();
  32. } catch (InterruptedException e) {
  33. }
  34. }
  35. if (mOriginalDiskCache != null) {
  36. try {
  37. snapshot = mOriginalDiskCache.get(key);
  38. if (snapshot == null) {
  39. LruDiskCache.Editor editor = mOriginalDiskCache.edit(key);
  40. if (editor != null) {
  41. if (downloader.downloadToLocalStreamByUrl(data,editor.newOutputStream(DISK_CACHE_INDEX))) {
  42. editor.commit();
  43. } else {
  44. editor.abort();
  45. }
  46. }
  47. snapshot = mOriginalDiskCache.get(key);
  48. }
  49. if (snapshot != null) {
  50. fileInputStream = (FileInputStream) snapshot.getInputStream(DISK_CACHE_INDEX);
  51. fileDescriptor = fileInputStream.getFD();
  52. }
  53. } catch (IOException e) {
  54. Log.e(TAG, "processBitmap - " + e);
  55. } catch (IllegalStateException e) {
  56. Log.e(TAG, "processBitmap - " + e);
  57. } finally {
  58. if (fileDescriptor == null && fileInputStream != null) {
  59. try {
  60. fileInputStream.close();
  61. } catch (IOException e) {
  62. }
  63. }
  64. }
  65. }
  66. }
  67. Bitmap bitmap = null;
  68. if (fileDescriptor != null) {
  69. if(neverCalculate)
  70. bitmap = BitmapFactory.decodeFileDescriptor(fileDescriptor);
  71. else
  72. bitmap = BitmapDecoder.decodeSampledBitmapFromDescriptor(fileDescriptor, config.getBitmapWidth(),config.getBitmapHeight());
  73. }
  74. if (fileInputStream != null) {
  75. try {
  76. fileInputStream.close();
  77. } catch (IOException e) {
  78. }
  79. }
  80. return bitmap;
  81. }
  82. public void initHttpDiskCache() {
  83. if (!mOriginalCacheDir.exists()) {
  84. mOriginalCacheDir.mkdirs();
  85. }
  86. synchronized (mHttpDiskCacheLock) {
  87. if (BitmapCommonUtils.getUsableSpace(mOriginalCacheDir) > cacheSize) {
  88. try {
  89. mOriginalDiskCache = LruDiskCache.open(mOriginalCacheDir, 1, 1,cacheSize);
  90. } catch (IOException e) {
  91. mOriginalDiskCache = null;
  92. }
  93. }
  94. mHttpDiskCacheStarting = false;
  95. mHttpDiskCacheLock.notifyAll();
  96. }
  97. }
  98. public void clearCacheInternal() {
  99. synchronized (mHttpDiskCacheLock) {
  100. if (mOriginalDiskCache != null && !mOriginalDiskCache.isClosed()) {
  101. try {
  102. mOriginalDiskCache.delete();
  103. } catch (IOException e) {
  104. Log.e(TAG, "clearCacheInternal - " + e);
  105. }
  106. mOriginalDiskCache = null;
  107. mHttpDiskCacheStarting = true;
  108. initHttpDiskCache();
  109. }
  110. }
  111. }
  112. public void flushCacheInternal() {
  113. synchronized (mHttpDiskCacheLock) {
  114. if (mOriginalDiskCache != null) {
  115. try {
  116. mOriginalDiskCache.flush();
  117. } catch (IOException e) {
  118. Log.e(TAG, "flush - " + e);
  119. }
  120. }
  121. }
  122. }
  123. public void closeCacheInternal() {
  124. synchronized (mHttpDiskCacheLock) {
  125. if (mOriginalDiskCache != null) {
  126. try {
  127. if (!mOriginalDiskCache.isClosed()) {
  128. mOriginalDiskCache.close();
  129. mOriginalDiskCache = null;
  130. }
  131. } catch (IOException e) {
  132. Log.e(TAG, "closeCacheInternal - " + e);
  133. }
  134. }
  135. }
  136. }
  137. }

下载类

[java] view plaincopy

  1. public interface Downloader  {
  2. public boolean downloadToLocalStreamByUrl(String urlString, OutputStream outputStream);
  3. }

[java] view plaincopy

  1. public class SimpleHttpDownloader implements Downloader{
  2. private static final String TAG = "BitmapDownloader";
  3. private static final int IO_BUFFER_SIZE = 8 * 1024; //8k
  4. public boolean downloadToLocalStreamByUrl(String urlString, OutputStream outputStream) {
  5. HttpURLConnection urlConnection = null;
  6. BufferedOutputStream out = null;
  7. FlushedInputStream in = null;
  8. try {
  9. final URL url = new URL(urlString);
  10. urlConnection = (HttpURLConnection) url.openConnection();
  11. in = new FlushedInputStream(new BufferedInputStream(urlConnection.getInputStream(), IO_BUFFER_SIZE));
  12. out = new BufferedOutputStream(outputStream, IO_BUFFER_SIZE);
  13. int b;
  14. while ((b = in.read()) != -1) {
  15. out.write(b);
  16. }
  17. return true;
  18. } catch (final IOException e) {
  19. Log.e(TAG, "Error in downloadBitmap - "+urlString +" : " + e);
  20. } finally {
  21. if (urlConnection != null) {
  22. urlConnection.disconnect();
  23. }
  24. try {
  25. if (out != null) {
  26. out.close();
  27. }
  28. if (in != null) {
  29. in.close();
  30. }
  31. } catch (final IOException e) {}
  32. }
  33. return false;
  34. }
  35. public class FlushedInputStream extends FilterInputStream {
  36. public FlushedInputStream(InputStream inputStream) {
  37. super(inputStream);
  38. }
  39. @Override
  40. public long skip(long n) throws IOException {
  41. long totalBytesSkipped = 0L;
  42. while (totalBytesSkipped < n) {
  43. long bytesSkipped = in.skip(n - totalBytesSkipped);
  44. if (bytesSkipped == 0L) {
  45. int by_te = read();
  46. if (by_te < 0) {
  47. break; // we reached EOF
  48. } else {
  49. bytesSkipped = 1; // we read one byte
  50. }
  51. }
  52. totalBytesSkipped += bytesSkipped;
  53. }
  54. return totalBytesSkipped;
  55. }
  56. }
  57. }
时间: 2024-11-03 21:17:59

【转载】Android应用框架及常用工具类总结的相关文章

Android Studio快速创建常用工具类的插件Utils

现如今Android开发,开发工具Android Studio已成为主流,而为Android Studio打造的插件也越来越多,今天为大家介绍一个快速创建常用工具类的插件Utils.其实Android中有关工具类的库有很多,但我们开发中一般只会用到某个库的一个或几个类,所以这时候Utils就有了很大的优势了,它直接创建自己所需要的工具类,而且每个工具类是相互解耦的.下面,我们就来一起看看它的集成及使用. 首先,我们看一下集成方式 下载jar包导入1.下载最新jar包Utils.jar-v1.32

Android快速开发系列 常用工具类

1.日志工具类L.java package com.way.common.util; import android.util.Log; /** * Log统一管理类 * * @author way * */ public class L { public static boolean isDebug = true;// 是否需要打印bug,可以在application的onCreate函数里面初始化 private static final String TAG = "way"; //

Android 疯狂造轮子 常用工具类 直接拿来用!

转载请注明出处:http://blog.csdn.net/smartbetter/article/details/52709446 1.NetUtils(网络相关) public class NetUtils { private NetUtils() { throw new UnsupportedOperationException("cannot be instantiated"); } /** * 判断网络是否连接 */ public static boolean isConnec

java常用工具类(java技术交流群57388149)

package com.itjh.javaUtil; import java.util.ArrayList; import java.util.List; /** * * String工具类. <br> * * @author 宋立君 * @date 2014年06月24日 */ public class StringUtil { private static final int INDEX_NOT_FOUND = -1; private static final String EMPTY =

Android 常用工具类之SPUtil,可以修改默认sp文件的路径

参考: 1. 利用Java反射机制改变SharedPreferences存储路径    Singleton1900 2. Android快速开发系列 10个常用工具类 Hongyang import android.app.Activity; import android.content.Context; import android.content.ContextWrapper; import android.content.SharedPreferences; import java.io.

Android常用工具类(收藏)

Android常用工具类 主要介绍总结的Android开发中常用的工具类,大部分同样适用于Java. 目前包括(HttpUtils.DownloadManagerPro.ShellUtils.PackageUtils.PreferencesUtils.JSONUtils.FileUtils.ResourceUtils.StringUtils.ParcelUtils.RandomUtils.ArrayUtils.ImageUtils.ListUtils.MapUtils.ObjectUtils.S

Android|Java 开发常用工具类

如题 该文章展示的是我开发过程中使用的部分常用工具类方法,不定期更新. 欢迎各位大牛批评指教,如有发现错误,欢迎留言指教,如有更好的实现方式,也欢迎留言交流学习,谢谢. 一.手机号 座机号.邮箱格式匹配工具类 package com.kevin.test.utils; /** * 字符串格式匹配工具类 匹配手机号.座机号.邮箱等 * * @author blj * */ public class FormatCheckUtils { /** * 判断是否符合邮箱格式 */ public stat

[精品] 收集的27个java开发常用工具类.基本满足开发需求

原文:[精品] 收集的27个java开发常用工具类.基本满足开发需求 源代码下载地址:http://www.zuidaima.com/share/1596028005993472.htm 最近从网上收集的java开发常用的工具类,分享给大家.基本满足开发需求.推荐给热爱最代码以及java的牛牛们.   每个类都有注释的,欢迎大家可以下载使用. 字符编码:CharTools, base64:Base64 *.java Md5加密:  MD5*.java 上传:*Uploader* 生成缩略图类:T

iOS开发常用工具类

iOS开发常用工具类(提高开发的工作效率) 前言 作为一个开发者应该学会去整理收集开发常用的工具类,这些复用的工具可以在项目开发中给你很大程度提高你的工作效率.难道你不想早点完成工作,然后出去撩妹.陪女朋友或者回家陪老婆孩子吗?反正我想早点回家??. 一.常用的宏定义 善于利用宏在开发中过程中会减少很多工作量比如定义开发过程中的常用尺寸,这样在后续开发中不用为了改一个相同尺寸而满世界的去找这个尺寸在哪用到了.宏定义用的很广泛,例如屏幕的宽高,网络请求的baseUrl等等下面是自己整理的一些示例: