自定义显示APP的桌面程序
原创文章,转载请注明出处!
手机上往往有许多APP,全部显示非常多非常麻烦,因而作者有针对性地写了一个程序,对APP进行管理。
效果图

由上图可以看到,通过对APP图标的管理,成功隐藏了九个不需要的图标。实现方式是怎样的呢?
一、隐藏图标数据库
我们把需要隐藏的图标放在Sqlite数据库中,这样在显示的时候,就可以排除这些图标。
import java.util.Locale; import android.content.ContentValues; import android.content.Context; import android.database.Cursor; import android.database.sqlite.SQLiteDatabase; import android.util.Log; public class AppsDatabase { private String DB_NAME = "setting.db3"; private String TB_NAME = "PKG_NAME"; private static SQLiteDatabase appsDB; public AppsDatabase(Context context) { // 用户数据库 appsDB = context.openOrCreateDatabase(DB_NAME, SQLiteDatabase.CREATE_IF_NECESSARY, null); appsDB.setLocale(Locale.getDefault()); appsDB.setLockingEnabled(true); appsDB.setVersion(1); String CrTable = "CREATE TABLE IF NOT EXISTS " + TB_NAME + " (pkgName CHAR(50) PRIMARY KEY)"; appsDB.execSQL(CrTable); } // 将App设置成可见或者不可见 public int setVisible(String pkgName) { int retVal = -1; try { String seekArray[] = { "pkgName" }; Cursor c = appsDB.query(TB_NAME, seekArray, "pkgName=?", new String[] { pkgName }, null, null, null); if (c.getCount() > 0) { appsDB.delete(TB_NAME, "pkgName=?", new String[] { pkgName }); retVal = 0; } else { ContentValues values = new ContentValues(); values.put(c.getColumnName(0), pkgName); appsDB.insert(TB_NAME, null, values); values.clear(); retVal = 1; } } catch (Exception e) { System.out.println(e.getMessage()); } return retVal; } // App是否可见 public boolean isVisible(String pkgName) { Boolean retVal = true; try { String seekArray[] = { "pkgName" }; Cursor c = appsDB.query(TB_NAME, seekArray, "pkgName=?", new String[] { pkgName }, null, null, null); if (c.getCount() > 0) retVal = false; c.close(); } catch (Exception e) { System.out.println(e.getMessage()); Log.e("sh", e.getMessage()); } return retVal; } public void close() { appsDB.close(); } }
二、创建图标管理Activity
设计思路:该Activity下有两种模式,一种是正常模式,点击图标即进入APP。另一种是管理模式,点击图标进行显示或者隐藏。
1、图标Adapter
这里的图标是一个自创的控件,包括一个ImageView和一个TextView,也就是APP图形和APP名称。另外这里还有一个功能,就是可以增加一个“取消”的样式,是通过图层叠加实现的。
// 应用程序列表适配器 public class AppsAdapter extends BaseAdapter { LayoutInflater infater = null; public AppsAdapter(Context context) { infater = (LayoutInflater) context .getSystemService(Context.LAYOUT_INFLATER_SERVICE); } public View getView(int position, View convertView, ViewGroup parent) { View view = null; ViewHolder holder = null; if (convertView == null || convertView.getTag() == null) { view = infater.inflate(R.layout.app_icon, null); holder = new ViewHolder(view); view.setTag(holder); } else { view = convertView; holder = (ViewHolder) convertView.getTag(); } ResolveInfo info; info = apps.get(position); // 合成图片 String pkName = info.activityInfo.packageName; Drawable ld = null; if (modify && !ad.isVisible(pkName)) ld = (Drawable) drawableMixer(info.activityInfo .loadIcon(getPackageManager())); else ld = info.activityInfo.loadIcon(getPackageManager()); holder.appIcon.setImageDrawable(ld); holder.tvAppLabel.setText(info.activityInfo .loadLabel(getPackageManager())); return view; } public final int getCount() { return apps.size(); } public final Object getItem(int position) { return apps.get(position); } public final long getItemId(int position) { return position; } // 图标层叠,用于添加注脚 private LayerDrawable drawableMixer(Drawable d1) { Bitmap bitmap1 = ((BitmapDrawable) d1).getBitmap(); Bitmap bitmap2 = ((BitmapDrawable) getResources().getDrawable( R.drawable.temp1)).getBitmap(); Drawable[] array = new Drawable[2]; array[0] = new BitmapDrawable(bitmap1); array[1] = new BitmapDrawable(bitmap2); LayerDrawable ld = new LayerDrawable(array); // 其中第一个参数为层的索引号,后面的四个参数分别为left、top、right和bottom ld.setLayerInset(0, 0, 0, 0, 0); ld.setLayerInset(1, 0, 0, 0, 0); return ld; } // 图标显示 class ViewHolder { ImageView appIcon; TextView tvAppLabel; public ViewHolder(View view) { this.appIcon = (ImageView) view.findViewById(R.id.imgApp); this.tvAppLabel = (TextView) view.findViewById(R.id.tvLabel); } } }
2、刷新APP列表部分
// 读取应用程序列表 private void loadApps() { int max = totalApps.size(); if (mApps.size() > 0) mApps.clear(); for (int i = 0; i < max; i++) { ResolveInfo info = totalApps.get(i); String pkgName = info.activityInfo.packageName; if (!modify) { if (ad.isVisible(pkgName)) { mApps.add(info); } } } if (modify) apps = totalApps; else apps = mApps; }
其中List<ResolveInfo> totalApps = getPackageManager().queryIntentActivities(mainIntent, 0);
获取所有的APP列表,然后逐一和隐藏APP数据库进行比对,如果可见,则将APP图标添加到GridView中去。
3、正常模式和管理模式切换
@Override public boolean onCreateOptionsMenu(Menu menu) { getMenuInflater().inflate(R.menu.my_desktop, menu); if (modify) { this.setTitle("管理状态"); menu.getItem(0).setTitle("保存并退出"); } else { this.setTitle("应用状态"); menu.getItem(0).setTitle("应用程序管理"); } return true; } @Override public boolean onMenuItemSelected(int featureId, MenuItem item) { if (modify) { item.setTitle("应用程序管理"); } else { item.setTitle("保存并退出"); } modify = !modify; loadApps(); mGrid.setAdapter(aa); return true; }
通过按menu键实现,点击之后,改变标识变量modify。
4、点击效果
private OnItemClickListener listener = new OnItemClickListener() { @Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { ResolveInfo info = apps.get(position); // 该应用的包名 String pkg = info.activityInfo.packageName; // 应用的主activity类 String cls = info.activityInfo.name; if (modify) { ad.setVisible(pkg); loadApps(); mGrid.setAdapter(aa); } else { ComponentName componet = new ComponentName(pkg, cls); Intent intent = new Intent(); intent.setComponent(componet); startActivity(intent); } } };
可以看到,如果modify为true,则进行修改,点击后改变图标的状态。如果为false,则直接进入APP。
浙公网安备 33010602011771号