Android 使用資料庫操作應用加鎖、未加鎖,列表展示效果
阿新 • • 發佈:2018-12-31
效果圖:
要求:1.獲取應用並展示,上下滑動帶動畫
2.未加鎖中點選"鎖"圖示動畫刪除該條目,並新增至 程式鎖 資料庫(存放已加鎖應用)
3.已加鎖中點選"鎖"圖示動畫刪除該條目,並將當前應用從 程式鎖 中刪除
上程式碼:
首先編寫頁面:
activity_main.xml
MainActivity.java<?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>
獲取應用資料:AppUtils.javapublic 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(); } }
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;
}
程式碼中註釋的已經很詳細,請參看