三:软件管理
1.程序管理器:
将程序分为系统程序和应用程序来区分,通过点击可以卸载程序,启动程序,查看程序的详细信息
其实就是获取手机上的所以应用程序的信息,然后以listview的方式展示到界面上去,主要是通过packagermanager对象来获取信息
2.反编译:
   通过apktool.bat工具来反编译.apk文件,命令:apktool d .apk,反编译出来一个文件夹,可以看到程序的资源内容,反编译会把id前的+给漏掉
3.listview的优化:
 其实是利用了getview方法里的contentview这个参数,使用的时候先检查这个历史的
 Contentview是否存在,如果存在则复用,如果不存在在根据布局文件进行创建,就是将
Item的布局文件通过inflater填充成一个view对象
还有一点涉及到优化:
// convertView 历史的缓存的view对象
       public View getView(int position, View convertView, ViewGroup parent) {
           View view;
           ViewHolder holder = null;
           if (convertView == null) {// 如果没有历史缓存的view对象 就利用布局文件生成一个view对象
              view = View.inflate(getApplicationContext(),
                     R.layout.applationinstall_item, null);
              holder = new ViewHolder();
              Logger.i(TAG, "GETvIEW----" + position + "创建新的view对象");
              holder.tv_name = (TextView) view.findViewById(R.id.tv_appname);
              holder.tv_version = (TextView) view
                     .findViewById(R.id.tv_appversion);
              holder.iv_icon = (ImageView) view.findViewById(R.id.iv_appicon);
              view.setTag(holder);
           } else {
              view = convertView;
              holder = (ViewHolder) view.getTag();
              Logger.i(TAG, "GETvIEW----" + position + "使用历史的view对象");
           }
           AppInfo appinfo = adapterappinfos.get(position);
           holder.tv_name.setText(appinfo.getAppname());
           holder.tv_version.setText(appinfo.getVersion());
           holder.iv_icon.setImageDrawable(appinfo.getAppicon());
           return view;
       }
 
    }
 
    static class ViewHolder {
       TextView tv_name;
       TextView tv_version;
       ImageView iv_icon;
    }
 
如果Listview要显示的图片很大,数据很大,可以通过分页显示,异步加载的方式来进行

 

4.区分系统程序和用户程序
可以参考setting的源代码
/**
     *
     * @param info ApplicationInfo
     * @return 当前应用程序是否是用户的应用
     */
    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;
}
1. 如果正在加载数据不能够进行界面的切换,这是一个隐含的bug
if (loading)// 如果正在加载数据 不能进行界面的切换
return;
6.程序管理器的分享和启动
7.反编译源代码:
通过dex2jar.bat来反编译classes.dex,反编译出来的jar文件通过jd-gui.exe来查看源代码
8.listview上的点击事件的处理
   lv_appmanger.setOnItemClickListener(new OnItemClickListener() {
 
           public void onItemClick(AdapterView<?> parent, View view,
                  int position, long id) {
               dismissPopwindow();
9.popupWindow
   popupWindow = new PopupWindow(popupview, getWindowManager()
                     .getDefaultDisplay().getWidth() - DensityUtil.dip2px(getApplicationContext(), 80), bottom - top + DensityUtil.dip2px(getApplicationContext(), 20));
 
Popupwindow可以看成是一个轻量级的activity,popupwindow一定要设置一个背景图片
否则可能会出现问题
11.popupwindow上的卸载,运行,分享
case R.id.ll_app_share:
               Logger.i(TAG, "分享" + packname);
               Intent shareintent = new Intent("android.intent.action.SEND");
               shareintent.setType("text/plain");
               shareintent.putExtra("android.intent.extra.SUBJECT", "f分享");
               StringBuilder localStringBuilder = new StringBuilder("Hi!推荐您使用软件:");
               localStringBuilder.append("程序叫 "+packname);
               shareintent.putExtra("android.intent.extra.TEXT", localStringBuilder.toString());
               startActivity(shareintent);
               dismissPopwindow();
           break;
 
       case R.id.ll_app_start:
           Logger.i(TAG, "开启" + packname);
           try {
              PackageInfo packinfo = packageManager.getPackageInfo(packname,
                     PackageManager.GET_ACTIVITIES);
              ActivityInfo[] activityinfos = packinfo.activities;
              if (activityinfos != null && activityinfos.length > 0) {
                  ActivityInfo activityinfo = packinfo.activities[0];
                  String activityname = activityinfo.name;
                  Intent intent = new Intent();
                  intent.setClassName(packname, activityname);
                  startActivity(intent);
              }else {
                  Toast.makeText(this, "无法启动改应用", 0).show();
              }
           } catch (NameNotFoundException e) {
              e.printStackTrace();
              Toast.makeText(this, "无法启动改应用", 0).show();
           }
           dismissPopwindow();
           break;
 
       case R.id.ll_app_uninstall:
           Logger.i(TAG, "卸载" + packname);
           //判断当前程序是否是系统的apk
           AppInfo appinfo = (AppInfo) v.getTag();
           if(appinfo.isUserapp()){
              //激活系统的组件进行卸载应用的操作
              Intent intent = new Intent();
              intent.setAction(Intent.ACTION_DELETE);
              intent.setData(Uri.parse("package:"+packname));
              //startActivity(intent);
              startActivityForResult(intent, 0);
           }else{//系统应用
              //TODO:弹出土司,提示用户系统应用不能被卸载
              Toast.makeText(getApplicationContext(), "系统应用不能被卸载", 0).show();
           }
           dismissPopwindow();
           break;
 
       }
分享功能在模拟器和真机上是不一样的,在真机上可以选择通过哪个程序进行分享,会有一个弹出列表
 
12.程序锁
   实现原理是采用了后台的一个服务,程序锁其实就是一个看门狗,它不停的监视手机里的进程的运行状态,如果它发现要启动的进程是要锁定的进程,则弹出来一个界面,让用户去输入密码,获取当前应用程序的状态需要通过activitymanager来实现,他是一个系统服务,通过getsystemservice(ACTIVITY_SERVICE)来获取
PackageManager pm;// 包管理服务 程序管理器
private ActivityManager am; // 活动的管理服务 任务管理器
监视任务栈,获取栈顶的activity,然后得到程序的包名
点击Listview条目后将程序的包名持久化到数据库中
13.服务的两种开启方式:
/**
     * start开启一个后台运行的服务,
     * 服务跟调用者没有任何的关系.
     * 一旦服务开启就会长期的在后台运行,
     * 直到显示的调用stopService的时候 服务才会停止
     * @param view
     */
/**
     * bind绑定开启一个服务,
     * 服务的生命周期跟调用者进行了关联
     * 一旦调用者ondestroy的方法,
     * 绑定的服务也会停止运行
*
     * 可以利用ServiceConntion的实例,去调用服务里面的方法
     * @param view
     */
*注意:
 *1... start方式开启服务- bind的方式绑定服务- 接触绑定服务(服务不会被停止掉)- stopservice
 *
 *2... start方式开启服务--bind的方式绑定服务- stopservice停止服务(服务是停不掉的)-unbindservice接触绑定服务(服务会被直接停止掉)
 *
14.绑定服务,调用服务里面的方法
   通过serviceconntion的实例去调用服务里面的方法
15. lv_applock.setOnItemClickListener(new OnItemClickListener() {
 
           public void onItemClick(AdapterView<?> parent, View view,
                  int position, long id) {
 
AdapterView<?> parent:代表当前的listview
View view:代表每一个被点击的条目
16.getview的优化:
查询数据库的操作:
 /*
            * if (dao.find(info.getPackname())) {
            * holder.iv_lock.setImageResource(R.drawable.lock); } else {
            * holder.iv_lock.setImageResource(R.drawable.unlock); }
            */
查询内存的操作:(效率高)
if (lockpacknames.contains(info.getPackname())) {
              holder.iv_lock.setImageResource(R.drawable.lock);
           } else {
              holder.iv_lock.setImageResource(R.drawable.unlock);
           }
17.service ,broadcastreceiver里没有任务栈,开启activity需要增加
entryPwdIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK );//在没有任务栈的组件里面激活activity 一定要指定FLAG_ACTIVITY_NEW_TASK 参数