好了,之前我们就讲了高级工具里面的短信备份与还原,那么我们高级工具里面的功能就基本上完成的啦,还有一个叫程序锁的功能而已,但我们今天先不做它先,我们先把我们的程序管理这个功能完成先。
先让大家看一下我们程序管理要做成什么样子先
我们程序管理这个功能主要就是上面的第二张图片啦,主要就是有卸载、运行和分享而已
我们今天就先把第一张图片里面的内容完成先,
要完成第一张截图里面的内容,我们首先就要知道,程序管理,那么就是要把我们手机里面的所有应用读取出来,然后才能操作的,所以我们就要新建一个model类用来存放这些应用的信息啦,然后还有有一个类用来读取手机里面所有的应用的
com.xiaobin.security.domain.AppInfo
package com.xiaobin.security.domain; import android.graphics.drawable.Drawable; public class AppInfo { private Drawable icon; private String appName; private String packageName; private boolean isSystemApp; public Drawable getIcon() { return icon; } public void setIcon(Drawable icon) { this.icon = icon; } public String getAppName() { return appName; } public void setAppName(String appName) { this.appName = appName; } public String getPackageName() { return packageName; } public void setPackageName(String packageName) { this.packageName = packageName; } public boolean isSystemApp() { return isSystemApp; } public void setSystemApp(boolean isSystemApp) { this.isSystemApp = isSystemApp; } }
Model类写好之后,我们就要写一个类来读取手机里面的应用啦
com.xiaobin.security.engine.AppInfoProvider
package com.xiaobin.security.engine; import java.util.ArrayList; import java.util.List; import android.content.Context; import android.content.pm.ApplicationInfo; import android.content.pm.PackageInfo; import android.content.pm.PackageManager; import android.graphics.drawable.Drawable; import com.xiaobin.security.domain.AppInfo; public class AppInfoProvider { private PackageManager packageManager; public AppInfoProvider(Context context) { //拿到一个包管理器 packageManager = context.getPackageManager(); } public List<AppInfo> getAllApps() { List<AppInfo> list = new ArrayList<AppInfo>(); AppInfo myAppInfo; //获取到所有安装了的应用程序的信息,包括那些卸载了的,但没有清除数据的应用程序 List<PackageInfo> packageInfos = packageManager.getInstalledPackages(PackageManager.GET_UNINSTALLED_PACKAGES); for(PackageInfo info : packageInfos) { myAppInfo = new AppInfo(); //拿到包名 String packageName = info.packageName; //拿到应用程序的信息 ApplicationInfo appInfo = info.applicationInfo; //拿到应用程序的图标 Drawable icon = appInfo.loadIcon(packageManager); //拿到应用程序的程序名 String appName = appInfo.loadLabel(packageManager).toString(); myAppInfo.setAppName(appName); myAppInfo.setPackageName(packageName); myAppInfo.setIcon(icon); if(filterApp(appInfo)) { myAppInfo.setSystemApp(false); } else { myAppInfo.setSystemApp(true); } list.add(myAppInfo); } return list; } //判断某一个应用程序是不是系统的应用程序,如果是返回true,否则返回false public boolean filterApp(ApplicationInfo info) { //有些系统应用是可以更新的,如果用户自己下载了一个系统的应用来更新了原来的, //它还是系统应用,这个就是判断这种情况的 if((info.flags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0) { return true; } else if((info.flags & ApplicationInfo.FLAG_SYSTEM) == 0)//判断是不是系统应用 { return true; } return false; } }
大家也可以看到啦,主要就是通过PackageManager来拿到ApplicationInfo然后得到应用的包名这些信息的
最后大家可以看到,我们写了一个函数来判定是不是系统自带的应用,因为我们明天要做那些卸载逻辑的时候就要用到了,如果是系统的应用,那么我们是不可以卸载的
好啦,现在所以的应用都被我们拿到啦,那么,我们现在要做的就是展现到界面上啦,那么我们就来处理一下UI
我们是用一个ListView来存放这些应用的信息的
所以就有两个布局文件啦
app_manager_item.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="65dip" android:gravity="center_vertical" android:background="@drawable/item_background_selector" android:orientation="horizontal" > <ImageView android:id="@+id/iv_app_manager_icon" android:layout_width="60dip" android:layout_height="60dip" android:scaleType="fitXY" android:src="@drawable/app" android:contentDescription="@string/hello_world"/> <TextView android:id="@+id/tv_app_manager_name" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="5dip" android:textSize="21sp" android:textColor="#ff000000"/> </LinearLayout>
app_manager.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <LinearLayout android:layout_width="match_parent" android:layout_height="40dip" android:gravity="center_vertical|center_horizontal" android:background="@drawable/title_background" android:orientation="vertical"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:textColor="@android:color/white" android:textSize="22sp" android:text="@string/app_manager"/> </LinearLayout> <FrameLayout android:layout_width="match_parent" android:layout_height="match_parent" android:background="@android:color/white"> <ListView android:id="@+id/lv_app_manager" android:layout_width="match_parent" android:layout_height="match_parent" android:background="@android:color/white" android:cacheColorHint="@android:color/white" android:layout_marginTop="10dip" /> <LinearLayout android:id="@+id/ll_app_manager_progress" android:layout_width="match_parent" android:layout_height="match_parent" android:gravity="center_vertical|center_horizontal" android:orientation="vertical" android:visibility="gone"> <ProgressBar android:layout_width="wrap_content" android:layout_height="wrap_content"/> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/app_manager_load" android:textSize="18sp" android:textColor="#ffbc04e5"/> </LinearLayout> </FrameLayout> </LinearLayout>
因为读取手机里面的应用是一个非常耗时的操作来的,特别是用户手机里面的应用特别多的时候,所以我们就在上面加了一个进度条,让用户知道现在是读取着应用的
所以如果一进去,就是像下面这个样子的了
那么,现在我们就来写一下Activity里面的逻辑啦
com.xiaobin.security.ui.AppManagerActivity
package com.xiaobin.security.ui; import java.util.List; import android.annotation.SuppressLint; import android.app.Activity; import android.os.Bundle; import android.os.Handler; import android.os.Message; import android.view.View; import android.view.ViewGroup; import android.widget.BaseAdapter; import android.widget.ImageView; import android.widget.LinearLayout; import android.widget.ListView; import android.widget.TextView; import com.xiaobin.security.R; import com.xiaobin.security.domain.AppInfo; import com.xiaobin.security.engine.AppInfoProvider; public class AppManagerActivity extends Activity { private static final int GET_ALL_APP_FINISH = 1; private ListView lv_app_manager; private LinearLayout ll_app_manager_progress; private AppInfoProvider provider; private AppManagerAdapter adapter; private List<AppInfo> list; @SuppressLint("HandlerLeak") private Handler handler = new Handler() { public void handleMessage(Message msg) { switch(msg.what) { case GET_ALL_APP_FINISH : //进度条设置为不可见 ll_app_manager_progress.setVisibility(View.GONE); adapter = new AppManagerAdapter(); lv_app_manager.setAdapter(adapter); break; default : break; } }; }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.app_manager); lv_app_manager = (ListView) findViewById(R.id.lv_app_manager); ll_app_manager_progress = (LinearLayout) findViewById(R.id.ll_app_manager_progress); ll_app_manager_progress.setVisibility(View.VISIBLE); //因为搜索手机里面的应用程序有可能是非常耗时的,所以我们开启一个新的线程去进行搜索 //当搜索完成之后,就把一个成功的消息发送给Handler,然后handler把搜索到的数据设置进入listview里面 new Thread() { public void run() { provider = new AppInfoProvider(AppManagerActivity.this); list = provider.getAllApps(); Message msg = new Message(); msg.what = GET_ALL_APP_FINISH; handler.sendMessage(msg); }; }.start(); } //====================================================================== private class AppManagerAdapter extends BaseAdapter { @Override public int getCount() { return list.size(); } @Override public Object getItem(int position) { return list.get(position); } @Override public long getItemId(int position) { return position; } @Override public View getView(int position, View convertView, ViewGroup parent) { AppInfo info = list.get(position); if(convertView == null) { View view = View.inflate(AppManagerActivity.this, R.layout.app_manager_item, null); AppManagerViews views = new AppManagerViews(); views.iv_app_icon = (ImageView) view.findViewById(R.id.iv_app_manager_icon); views.tv_app_name = (TextView) view.findViewById(R.id.tv_app_manager_name); views.iv_app_icon.setImageDrawable(info.getIcon()); views.tv_app_name.setText(info.getAppName()); view.setTag(views); return view; } else { AppManagerViews views = (AppManagerViews) convertView.getTag(); views.iv_app_icon.setImageDrawable(info.getIcon()); views.tv_app_name.setText(info.getAppName()); return convertView; } } } //用来优化listview的类 private class AppManagerViews { ImageView iv_app_icon; TextView tv_app_name; } }
上面的代码也很简单啦,我们之前都写过不少啦,应用可以看明白的了,所以我就不写注释了
到这里为止,我们今天要讲的就完成的啦
现在我们就可以测试一下,看一下我们的程序管理能不能把手机里面的应用读取出来的啦,至于那些卸载这些的逻辑,我们明天再完成它
好啦,今天就到这里,谢谢支持!