自定义显示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。

posted on 2013-06-18 00:05  金狼古十四  阅读(288)  评论(0)    收藏  举报