1. 程式人生 > >Android 使用資料庫操作應用加鎖、未加鎖,列表展示效果

Android 使用資料庫操作應用加鎖、未加鎖,列表展示效果

效果圖:

要求:1.獲取應用並展示,上下滑動帶動畫

2.未加鎖中點選"鎖"圖示動畫刪除該條目,並新增至 程式鎖 資料庫(存放已加鎖應用)

3.已加鎖中點選"鎖"圖示動畫刪除該條目,並將當前應用從  程式鎖  中刪除

上程式碼:

首先編寫頁面:

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context="pl.zyqj.zz.programlock.MainActivity">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="#6600ff00"
        android:gravity="center"
        android:padding="8dp" >

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:id="@+id/tv_unlock"
            android:background="@drawable/tab_left_pressed"
            android:gravity="center"
            android:text="未加鎖"
            android:textColor="#ffffff" />

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:background="@drawable/tab_right_default"
            android:gravity="center"
            android:text="已加鎖"
            android:id="@+id/tv_locked"
            android:textColor="#ffffff" />
    </LinearLayout>

    <LinearLayout
        android:id="@+id/ll_content"
        android:orientation="vertical"
        android:layout_width="match_parent"
        android:layout_height="match_parent" >



    </LinearLayout>
</LinearLayout>
MainActivity.java
public class MainActivity extends FragmentActivity implements View.OnClickListener {

    private TextView tvUnLock;
    private TextView tvLocked;
    private UnLockFragment unlockFragment;
    private LockedFragment lockedFragment;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        tvUnLock = (TextView) findViewById(R.id.tv_unlock);
        tvLocked = (TextView) findViewById(R.id.tv_locked);

        tvUnLock.setOnClickListener(this);
        tvLocked.setOnClickListener(this);

        unlockFragment = new UnLockFragment();
        lockedFragment = new LockedFragment();

        // 獲得fragment管理器
        FragmentManager fragmentManager = getSupportFragmentManager();
        // 開啟事務
        FragmentTransaction beginTransaction = fragmentManager.beginTransaction();
        // 使用 fragment 替換  指定的佈局中所有的子view
        beginTransaction.replace(R.id.ll_content, unlockFragment);
        // 提交
        beginTransaction.commit();

    }

    /**
     * fragment 的使用步驟:
     * 一:先在佈局檔案中,為fragment指定一個顯示的區域
     * 二:讓activiy改為繼承自 FragmentActivity
     * 三:顯示fragment
     // 獲得fragment管理器
     FragmentManager fragmentManager = getSupportFragmentManager();
     // 開啟事務
     FragmentTransaction beginTransaction = fragmentManager.beginTransaction();
     // 使用 fragment 替換  指定的佈局中所有的子view
     beginTransaction.replace(R.id.ll_content, unlockFragment);
     // 提交
     beginTransaction.commit();
     *
     * 	注意事件:如果關聯了v4包的原始碼,記著把v4包加入到apk安裝包中
     */

    @Override
    public void onClick(View v) {

        // 獲得fragment管理器
        FragmentManager fragmentManager = getSupportFragmentManager();
        // 開啟事務
        FragmentTransaction beginTransaction = fragmentManager.beginTransaction();

        switch (v.getId()) {
            case R.id.tv_unlock:
                // 使用 fragment 替換  指定的佈局中所有的子view
                beginTransaction.replace(R.id.ll_content, unlockFragment);

                tvUnLock.setBackgroundResource(R.drawable.tab_left_pressed);
                tvLocked.setBackgroundResource(R.drawable.tab_right_default);

                break;
            case R.id.tv_locked:
                // 使用 fragment 替換  指定的佈局中所有的子view
                beginTransaction.replace(R.id.ll_content, lockedFragment);

                tvUnLock.setBackgroundResource(R.drawable.tab_left_default);
                tvLocked.setBackgroundResource(R.drawable.tab_right_pressed);
                break;
        }

        // 提交
        beginTransaction.commit();
    }
}
獲取應用資料:AppUtils.java
public class AppUtils {

	/**
	 * 獲得手機中安裝的所有的應用的資訊
	 * @param ctx
	 * @return
	 */
	public static List<AppInfoBean> getAllAppInfo(Context ctx){
		List<AppInfoBean> allAppInfo = new ArrayList<AppInfoBean>();
		
		// 包管理器,管理手機 中所有的APK 安裝包
		PackageManager pm = ctx.getPackageManager();    //   pm  project manager 專案經理
		
		List<PackageInfo> installedPackages = pm.getInstalledPackages(0);
		for (PackageInfo packageInfo : installedPackages) {
			
			// PackageInfo 包含AndroidManifest清單檔案中,所有的資訊
			// ApplicationInfo 包含 AndroidManifest清單檔案中 , application中的所有的資訊
			ApplicationInfo applicationInfo = packageInfo.applicationInfo;
			
			AppInfoBean appBean = new AppInfoBean();
			allAppInfo.add(appBean); // 新增至集合
			
			// 設定包名
			appBean.packageName = packageInfo.packageName;
			
			// 獲得應用名稱
			appBean.appName = applicationInfo.loadLabel(pm).toString();
			// 應用圖示
			appBean.appIcon = applicationInfo.loadIcon(pm);
			
//			applicationInfo.dataDir; // /data/data/包名 路徑
			String apkPath = applicationInfo.sourceDir; // 該應用apk 的路徑
//			System.out.println(appBean.appName+ " : "+apkPath);
			
			// 為apkPath 賦值
			appBean.apkPath = apkPath;
			
			File apkFile = new File(apkPath);
			appBean.appSize = apkFile.length();
			
			// 根據路徑判斷是否是系統應用
			if(apkPath.startsWith("/data")){ // 使用者應用
				appBean.isSys = false;
				System.out.println(appBean.appName+" 根據 路徑 值判斷,是使用者應用");
			}else{
				// 系統應用
				appBean.isSys = true;
				System.out.println(appBean.appName+" 根據 路徑 值判斷,是系統應用");
			}
			
			// 根據flag 值來判斷是否是系統應用
			// 如果不等於0,說明批配成功,那麼當前應用,擁有該 FLAG 值標註的屬性
			if((applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM)!=0 ){ 
				System.out.println(appBean.appName+" 根據 flag 值判斷,是系統應用");
			}else{
				System.out.println(appBean.appName+" 根據 flag 值判斷,是使用者應用");
			}
			
			if((applicationInfo.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE)!=0){ //  
				appBean.isInSd = true;
			}else{
				appBean.isInSd = false;
			}
		}
		
		SystemClock.sleep(500); // 休眠2秒,模擬耗時的情況
		
		return allAppInfo;
	}

未加鎖,已加鎖 中做操作

UnLockFragment.java

public class UnLockFragment extends Fragment {

    private TextView tvDesc;
    private ListView listView;
    private AppLockDao lockDao;
    private boolean isAnim;
    /**
     * 未加鎖的應用集合
     */
    private List<AppInfoBean> unlockAppList;
    private ProgressDialog proDlg;
    private MyAdapter adapter;

    @Override
    /**
     * Fragment 就是對一個view 和這個 view 的所有邏輯處理 封裝在一個類中
     * 建立一個view
     */
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {

        lockDao = AppLockDao.getInsantce(getActivity());
        View view = inflater.inflate(R.layout.fragment_unlock, null);
        tvDesc = (TextView) view.findViewById(R.id.tv_desc);
        listView = (ListView) view.findViewById(R.id.listView);

        proDlg = new ProgressDialog(getActivity());
        proDlg.setMessage("玩命載入中...");

        fillData();
        initListener();

        return view;
    }

    private void initListener() {
        listView.setOnScrollListener(new OnScrollListener() {
            @Override
            public void onScrollStateChanged(AbsListView view, int scrollState) {

                if (scrollState == OnScrollListener.SCROLL_STATE_TOUCH_SCROLL
                        || scrollState == OnScrollListener.SCROLL_STATE_FLING) {
                    isAnim = true;
                } else {
                    isAnim = false;
                }
            }

            @Override
            public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
            }
        });
    }

    private void fillData() {

        proDlg.show();
        new Thread() {
            public void run() {
                unlockAppList = new ArrayList<AppInfoBean>();
                //獲取應用
                List<AppInfoBean> allAppInfo = AppUtils.getAllAppInfo(getActivity());

                for (AppInfoBean app : allAppInfo) {
                    if (lockDao.isLockApp(app.packageName)) {//查詢資料庫中是否包名此包名的應用
                        // 是需要鎖定的  包含:說明是鎖定的程式
                    } else {
                        // 沒有鎖定的  不包含:不需要鎖定的程式
                        unlockAppList.add(app);
                    }
                }
                handler.sendEmptyMessage(88);
            }

            ;
        }.start();
    }

    private Handler handler = new Handler() {
        public void handleMessage(android.os.Message msg) {
            proDlg.dismiss();
            // 顯示listView
            adapter = new MyAdapter();
            listView.setAdapter(adapter);

        }

        ;
    };

    private class ViewHolder {

        public TextView tvName;
        public ImageView ivIcon;
        public ImageView ivUnLock;

    }

    private class MyAdapter extends BaseAdapter {
        @Override
        public int getCount() {
            tvDesc.setText("未加鎖應用:" + unlockAppList.size() + "個");
            return unlockAppList.size();
        }

        @Override
        public Object getItem(int position) {
            return null;
        }

        @Override
        public long getItemId(int position) {
            return 0;
        }

        @Override
        public View getView(final int position, View convertView, ViewGroup parent) {
            View view;
            ViewHolder vh;

            if (convertView == null) {
                view = View.inflate(getActivity(), R.layout.list_item_unlock_fragment, null);
                vh = new ViewHolder();
                //  找到子view , 並打包
                vh.tvName = (TextView) view.findViewById(R.id.tv_name_list_item);
                vh.ivIcon = (ImageView) view.findViewById(R.id.iv_icon_list_item);
                vh.ivUnLock = (ImageView) view.findViewById(R.id.iv_unlock_fragment);

                // 揹包
                view.setTag(vh);

            } else {
                view = convertView;
                vh = (ViewHolder) view.getTag();
            }

            AppInfoBean app = unlockAppList.get(position);

            vh.ivIcon.setBackgroundDrawable(app.appIcon);
            vh.tvName.setText(app.appName);


            vh.ivUnLock.setOnClickListener(new OnClickListener() {
                @Override
                public void onClick(View v) {
                    // 當前條目做平移動畫
                    // X方向從0到100% ,Y方向保持不變
                    TranslateAnimation ta = new TranslateAnimation(
                            Animation.RELATIVE_TO_SELF, 0, Animation.RELATIVE_TO_SELF, 1,
                            Animation.RELATIVE_TO_SELF, 0, Animation.RELATIVE_TO_SELF, 0);
                    ta.setDuration(500);
//					ta.setFillAfter(true); // 動畫完成後,保持完成的狀態
                    View itemView = (View) v.getParent(); // v.getParent() 獲得V的父view
                    itemView.startAnimation(ta); // 向系統釋出做動畫的命令

                    /**
                     * 新增動畫的監聽,當動畫執行完之後,再刪除並重新整理條目,否則條目會複用混論,同時 //ta.setFillAfter(true); // 動畫完成後,保持完成的狀態
                     */
                    ta.setAnimationListener(new AnimationListener() {
                        @Override
                        public void onAnimationStart(Animation animation) {
                        }
                        @Override
                        public void onAnimationRepeat(Animation animation) {
                        }
                        @Override
                        public void onAnimationEnd(Animation animation) {
                            // 將當前應用新增至程式鎖 資料庫
                            lockDao.addAppLock(unlockAppList.get(position).packageName);

                            // 從未加鎖列表中刪除該條目
                            unlockAppList.remove(position);
                            notifyDataSetChanged(); //  重新整理列表

                        }
                    });
                }
            });


            if (isAnim) {
                // 課外題,讓listView 僅在上下滑動時,執行條目動畫
                TranslateAnimation ta = new TranslateAnimation(
                        Animation.RELATIVE_TO_SELF, -1, Animation.RELATIVE_TO_SELF, 0,
                        Animation.RELATIVE_TO_SELF, 0, Animation.RELATIVE_TO_SELF, 0);
                ta.setDuration(500);
                view.startAnimation(ta);

            }
            return view; // 如果返回 null ,發報異常,並且,異常中,只有系統程式碼,沒有我們的程式碼
        }
    }


}
LockedFragment.java
public class LockedFragment extends Fragment {

    private TextView tvDesc;
    private ListView listView;
    private AppLockDao lockDao;
    /**
     * 已加鎖的應用集合
     */
    private List<AppInfoBean> lockedAppList;
    private ProgressDialog proDlg;
    private MyAdapter adapter;

    @Override
    /**
     * Fragment 就是對一個view 和這個 view 的所有邏輯處理 封裝在一個類中
     * 建立一個view
     */
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {

        lockDao = AppLockDao.getInsantce(getActivity());

        View view = inflater.inflate(R.layout.fragment_locked, null);
        tvDesc = (TextView) view.findViewById(R.id.tv_desc);
        listView = (ListView) view.findViewById(R.id.listView);

        proDlg = new ProgressDialog(getActivity());
        proDlg.setMessage("玩命載入中...");

        fillData();

        return view;
    }

    private void fillData() {
        proDlg.show();

        new Thread() {
            public void run() {
                lockedAppList = new ArrayList<AppInfoBean>();

                List<AppInfoBean> allAppInfo = AppUtils.getAllAppInfo(getActivity());

                for (AppInfoBean app : allAppInfo) {
                    if (lockDao.isLockApp(app.packageName)) {
                        // 是需要鎖定的
                        lockedAppList.add(app);

                    } else {
                        // 沒有鎖定的
                    }
                }
                handler.sendEmptyMessage(88);
            };
        }.start();
    }

    private Handler handler = new Handler() {
        public void handleMessage(android.os.Message msg) {
            proDlg.dismiss();
            // 顯示listView
            adapter = new MyAdapter();
            listView.setAdapter(adapter);

        }

        ;
    };

    private class ViewHolder {
        public TextView tvName;
        public ImageView ivIcon;
        public ImageView ivLocked;

    }

    private class MyAdapter extends BaseAdapter {
        @Override
        public int getCount() {
            tvDesc.setText("已加鎖應用:" + lockedAppList.size() + "個");
            return lockedAppList.size();
        }

        @Override
        public Object getItem(int position) {
            return null;
        }

        @Override
        public long getItemId(int position) {
            return 0;
        }

        @Override
        public View getView(final int position, View convertView, ViewGroup parent) {
            View view;
            ViewHolder vh;

            if (convertView == null) {
                view = View.inflate(getActivity(), R.layout.list_item_locked_fragment, null);
                vh = new ViewHolder();
                //  找到子view , 並打包
                vh.tvName = (TextView) view.findViewById(R.id.tv_name_list_item);
                vh.ivIcon = (ImageView) view.findViewById(R.id.iv_icon_list_item);
                vh.ivLocked = (ImageView) view.findViewById(R.id.iv_locked_fragment);

                // 揹包
                view.setTag(vh);

            } else {
                view = convertView;
                vh = (ViewHolder) view.getTag();
            }

            AppInfoBean app = lockedAppList.get(position);

            vh.ivIcon.setBackgroundDrawable(app.appIcon);
            vh.tvName.setText(app.appName);

            vh.ivLocked.setOnClickListener(new OnClickListener() {

                @Override
                public void onClick(View v) {
                    // 當前條目做平移動畫
                    // X方向從0到100% ,Y方向保持不變
                    TranslateAnimation ta = new TranslateAnimation(
                            Animation.RELATIVE_TO_SELF, 0, Animation.RELATIVE_TO_SELF, -1,
                            Animation.RELATIVE_TO_SELF, 0, Animation.RELATIVE_TO_SELF, 0);
                    ta.setDuration(500);
//					ta.setFillAfter(true); // 動畫完成後,保持完成的狀態
                    View itemView = (View) v.getParent(); // v.getParent() 獲得V的父view
                    itemView.startAnimation(ta); // 向系統釋出做動畫的命令

                    ta.setAnimationListener(new AnimationListener() {
                        @Override
                        public void onAnimationStart(Animation animation) {
                        }
                        @Override
                        public void onAnimationRepeat(Animation animation) {
                        }
                        @Override
                        public void onAnimationEnd(Animation animation) {
                            // 將當前應用從程式鎖中刪除
                            lockDao.deleteAppLock(lockedAppList.get(position).packageName);

                            // 從未加鎖列表中刪除該條目
                            lockedAppList.remove(position);
                            notifyDataSetChanged(); //  重新整理列表
                        }
                    });
                }
            });

            // 課外題,讓listView 僅在上下滑動時,執行條目動畫
            TranslateAnimation ta = new TranslateAnimation(
                    Animation.RELATIVE_TO_SELF, -1, Animation.RELATIVE_TO_SELF, 0,
                    Animation.RELATIVE_TO_SELF, 0, Animation.RELATIVE_TO_SELF, 0);
            ta.setDuration(500);
//			view.startAnimation(ta);

            return view; // 如果返回 null ,發報異常,並且,異常中,只有系統程式碼,沒有我們的程式碼
        }
    }

}
展示資料庫:

AppLockDbHelper.java

/**
 * 程式鎖資料庫
 */
public class AppLockDbHelper extends SQLiteOpenHelper{

	public AppLockDbHelper(Context context, String name, int version) {
		super(context, name, null, version);
	}

	@Override
	public void onCreate(SQLiteDatabase db) {
		
		// 建立程式鎖 表,儲存所有的需要被鎖定的應用的(包名) 作為唯一標識
		db.execSQL("create table applock(_id integer primary key autoincrement, package_name varchar(40));");
	}

	@Override
	public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
		
	}

}
AppLockDao.java
/**
 * 操作的工具類  單例的
 */
public class AppLockDao {

	private Context ctx;

	private AppLockDao(Context ctx){
		this.ctx = ctx;
		dbHelper = new AppLockDbHelper(ctx, "app_lock.db", 1);
	}
	
	private static AppLockDao instance;
	
	public static synchronized AppLockDao getInsantce(Context ctx){
		if(instance == null){
			instance = new AppLockDao(ctx);
		}
		return instance;
	}
	
	private AppLockDbHelper dbHelper;
	
	private String table_app_lock = "applock";

	/**
	 * 定義一個指向程式鎖資料庫的URI 
	 */
//	private Uri uri = Uri.parse("content://zz.itcast.cn.applock");
	
	//////// 
	
	/**
	 * 新增程式鎖  已加鎖
	 * @param packageName
	 */
	public void addAppLock(String packageName){
		
		SQLiteDatabase db = dbHelper.getWritableDatabase();
		
		ContentValues values = new ContentValues();
		values.put("package_name", packageName);
		db.insert(table_app_lock, null, values);
		
	}
	
	/**
	 * 刪除程式鎖
	 * @param packageName
	 */
	public void deleteAppLock(String packageName){
		
		SQLiteDatabase db = dbHelper.getWritableDatabase();
		db.delete(table_app_lock, " package_name = ? ", new String[]{packageName});
		
	}
	
	/**
	 * 判斷指定包名的應用是否需要被鎖定 查
	 * @param packageName
	 * @return
	 */
	public boolean isLockApp(String packageName){
		SQLiteDatabase db = dbHelper.getReadableDatabase();
		
		Cursor cursor = db.query(table_app_lock, null," package_name = ? ", new String[]{packageName}, null, null, null);
		boolean isAppLock = false;
		
		if(cursor.moveToNext()){ // 如果查到內容,移動成功
			isAppLock = true;
		}
		cursor.close();
		return isAppLock;
	}
	
	/**
	 * 獲得所有需要被鎖定的應用
	 * @return
	 */
	public List<String> getAllAppLock(){
		ArrayList<String> appLocks = new ArrayList<String>();
		
		SQLiteDatabase db = dbHelper.getReadableDatabase();
		Cursor cursor = db.query(table_app_lock, null, null, null, null, null, null);
		// cursor 預設指向第一行的上一行
		while(cursor.moveToNext()){
			String packageName = cursor.getString(1); // 總共二列,包名那列,下標為1
			appLocks.add(packageName);
		}
		cursor.close();
		return appLocks;
	}

}
AppInfoBean.java
public class AppInfoBean {
	
	/**
	 * 應用的包名
	 */
	public String packageName;
	
	public String appName;
	
	public Drawable appIcon;
	
	/**
	 * 應用的大小,即APK安裝包的大小
	 */
	public long appSize;
	
	/**
	 * 判斷是否是安裝在SD卡中
	 */
	public boolean isInSd;
	
	/**
	 * 判斷是否是系統應用
	 */
	public boolean isSys;
	
	/**
	 * APK檔案的路徑
	 */
	public String apkPath;
	
}

程式碼中註釋的已經很詳細,請參看