Android学习笔记_63_手机安全卫士知识点归纳(3)分享 程序锁 服务 进程管理 widget

  1、分享:

Intent shareIntent = new Intent();  
shareIntent.setAction(Intent.ACTION_SEND);  
shareIntent.setType("text/plain");  
shareIntent.putExtra(Intent.EXTRA_SUBJECT, "分享");  
shareIntent.putExtra(Intent.EXTRA_TEXT,"推荐你使用一个程序" + item.getAppName());  
startActivity(shareIntent);  

  2、程序锁功能 : 

    1. 用户要开启的这个应用是哪一个应用.
      寻找系统里面是不是这样的广播事件,如果这样直接注册一个广播接收者。不过有的应用不行,所以排除 。 我们发现每个应用程序打开的时间ActivityManager都会暴露出来一段Log.
    2. 判断这个应用的包名 程序名 是否是要锁定的应用名字一致 。ActvityManager里面有个方法可以得到最近应用,与长按Home键盘得到的东西是一致的。特别好用的。
可以得到当前正在运行的 任务栈里面的信息。

ActivityManager manager = (ActivityManager) getSystemService(ACTIVITY_SERVICE);  
List<RunningTaskInfo>  infos = manager.getRunningTasks(2);  
for (RunningTaskInfo info : infos) {  
    System.out.println("tt  "+info.topActivity.getPackageName());  
}  

  3、服务:

想要调用同一个进程里面服务里的方法,要绑定这个服务。  想要跨进程访问,就用AIDL。  
  
之所以绑定服务能够调用服务里面的方法,主要是因为  在onBinder方法里面能够返回一个IBinder对象。  
  
先自己做试验,常规的。  如果是绑定,同生共死的,如果你退出activity会  出错。  
先开启,后绑定方式。 一个服务也只能被解除绑定一次,多次会出异常。 服务总结:   
1、startService()开启的服务会长期运行在后台与服务调用者无关, 调用者结束,服务不会结束,不能调用服务里面的方法。   2、bindService()服务和调用者绑定在一起,如果调用者挂掉了,服务 也会终止,调用者可以访问服务里面的方法。 如果我们既要服务长期在后台运行,又要去调用服务里面的方法。 那么,1、startService()保证服务长期在后台运行,2、bindService() 把服务绑定,调用服务里面的方法。 那么这种如何结束服务呢,首先解绑服务,然后再stop服务这样就结束了。 在单独使用绑定服务的时间,如果调用者关了,但是服务没有停止 ,这样 会报出异常,如果你该服务你已经解除绑定过了,再次解绑还会出错。 针对第一种调用者关了,那么应该在调用者的activity里面重写onDestory() 方法,并且在里面调用 unbind()方法,这样当调用者退出时间,它也会自动 退出。

  3、看门狗逻辑:

看门狗服务第一创建出的时间,应该去找任务栈中的应用是否在  锁定状态(访问数据库知道)  太厉害了,让一个服务一直反复监听执行,原来是用循环。  
  
服务里面激活任务栈:  
在安卓中数据通信就两点,  
一是跟后台持久化的东西,  
二是前台各个控件之间通信。  
掌握到这两点即可。  
  
结束当前activity,finish()、  后台开启一个服务,弄一个死循环,一直在获取当前运行的  
activity是不是在锁定表中,如果是果断弹出相应的输入密码界面。  
  
stopService(iservic) 会调用服务中的ondestory()方法。  
  
其实这个看门狗非常简单,就是在发现被锁定的程序运行时间,赶紧自己  
弹出一个输入密码的activity去在当前任务栈中新加一个,但是,如果  
用户按后退的时间就挂了,会回去要打开的程序中,所以屏蔽后退按钮。  
  
1. 用户输入密码正确. 通知看门狗 临时的停止对这个程序的保护   
就需要调用服务里面的方法 。  
  
2. 更新完毕数据库之后 通知看门狗 更新lockapp集合里面的内容  

  4、进程管理:

为什么需要进程管理,因为它不自动去关闭后台进程。它是一个多任务的,  
你退出后,留下一个空进程,不过这些做,在你再次打开的时间就比较快了  
这些多个应用切换的时间就比较快了。  
  
activity的Tittle管理(customertitle)。  
setText()不以设置为int类型,必须转化成字符串,因为  
这是一个重载的方法,如果你传过去一个int类型,它会认为  
你传过去的是一个资源的引用,所以你要把它转化成字符串  
它会用另外一个重载方法去处理它。  
  
ActivityManger太强大了,能得到任务栈,进程,内存等。。  
  
获取总内存信息是没有API可以得到的。我们已经得到的剩余内存,可以通过加上已用的算出总内存。  
  
安卓中重要的类:Build  
  
自定义activityTitle:  
super.onCreate(savedInstanceState);  
//1.隐藏掉系统的title 然后自己的layout的布局 上面做出来一个类似title效果  
//2.请求系统的服务,让系统的title 使用我们定义的样式  
boolean flag = requestWindowFeature(Window.FEATURE_CUSTOM_TITLE);  
  
//请求系统使用自定义的title, 这一句代码一定要写到setcontentView之前  
setContentView(R.layout.task_manager);  
  
if (flag) {  
    getWindow().setFeatureInt(Window.FEATURE_CUSTOM_TITLE, R.layout.task_manager_title);  
}  
  
tv_task_count = (TextView) this.findViewById(R.id.tv_task_count);  
tv_avail_memory = (TextView) this.findViewById(R.id.tv_avail_memory);  
  
思考所有布局的根本方法,先不要想什么细节,而是直接把大块给划分好。先把块一分好,确定大块的布局即可。  
不会说谁会覆盖谁,如果是这样,你就想的太多了。因为可以设置它。  
  
如果ListView控件过多,定义一个静态类,专门去存储它。  
  
对ListView进行分组。复杂的ListView再复杂的就是在getView里面做的复杂的业务逻辑。  
public class TaskManagerActivity extends Activity{  
    private TextView tv_task_count;  
    private TextView tv_avail_memory;  
    private ActivityManager am;//它很强大,可以得到任务栈,内存,进程等。  
    private List<RunningAppProcessInfo> runingappinfos;//所以正在运行的进程信息  
      
    private ListView lv_task_manager;//用来装内容 的  
    private LinearLayout ll_task_manager_loading;//模态图标  
    private TaskInfoProvider taskInfoprovider;//  
      
    private List<TaskInfo> listtaskinfos;//所有任务信息列表   
    private List<TaskInfo> usertaskinfos;//用户信息列表  
    private List<TaskInfo> systemtaskinfos;//系统信息列表  
      
    private TaskInfoAdapter adapter;  
      
    private long totalused = 0;// 所有程序占用的内存信息 kb  
      
    private Handler handler = new Handler(){  
        @Override  
        public void handleMessage(android.os.Message msg) {  
            ll_task_manager_loading.setVisibility(View.INVISIBLE);  
            long totalmemoryinfo = totalused*1024 + getAvailMemoryInfo();//占用的内存加上可用的内存等于总内存  
            String strtotalmemory = TextFormater.getDataSize(totalmemoryinfo);  
            String text = tv_avail_memory.getText().toString() + "总内存:"+ strtotalmemory;  
            tv_avail_memory.setText(text);  
            adapter = new TaskInfoAdapter();  
            lv_task_manager.setAdapter(adapter);  
              
        };  
          
    };  
      
    @Override  
    protected void onCreate(Bundle savedInstanceState) {  
          
        super.onCreate(savedInstanceState);  
        //1.隐藏掉系统的title 然后自己的layout的布局 上面做出来一个类似title效果  
        //2.请求系统的服务,让系统的title 使用我们定义的样式  
        boolean flag = requestWindowFeature(Window.FEATURE_CUSTOM_TITLE);  
          
        //请求系统使用自定义的title, 这一句代码一定要写到setcontentView之前  
        setContentView(R.layout.task_manager);  
          
        if (flag) {  
            getWindow().setFeatureInt(Window.FEATURE_CUSTOM_TITLE, R.layout.task_manager_title);  
        }  
          
        //获取am进程服务  
        am = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);  
          
        tv_task_count = (TextView) this.findViewById(R.id.tv_task_count);  
        tv_avail_memory = (TextView) this.findViewById(R.id.tv_avail_memory);  
        lv_task_manager = (ListView) this.findViewById(R.id.lv_task_manager);  
        ll_task_manager_loading = (LinearLayout) this.findViewById(R.id.ll_task_manager_loading);  
        taskInfoprovider = new TaskInfoProvider(this);  
          
          
        //填充listview的数据  
        fillData();  
          
    }  
    //填充listview的数据  
    private void fillData() {  
        //设置title的数据  
        setTitleData();  
          
        //先让其处于可见状态   
        ll_task_manager_loading.setVisibility(View.VISIBLE);  
        //起一个线程,找到所有的任务信息  
        new Thread(){  
            @Override  
            public void run() {  
                listtaskinfos = taskInfoprovider.getAllTasks(runingappinfos);  
                  
                totalused = 0; // 所有程序占用的内存信息 kb  
                for(TaskInfo taskInfo : listtaskinfos){  
                    totalused += taskInfo.getMemorysize();  
                }  
                // 通知界面更新数据  
                handler.sendEmptyMessage(0);  
            };  
        }.start();  
          
    }  
  
    /** 
     * 设置title的数据 
     */  
    private void setTitleData() {  
        tv_task_count.setText("进程数目: " + getProcessCount());  
        tv_avail_memory.setText("剩余内存"  
                + TextFormater.getDataSize(getAvailMemoryInfo()));  
    }  
    /** 
     * 获取当前正在运行的进程的数目 
     * @return 
     */  
    private int getProcessCount(){  
        runingappinfos = am.getRunningAppProcesses();  
        return runingappinfos.size();  
    }  
    /** 
     * 获取当前系统的剩余的可用内存信息 byte long 
     */  
    private long getAvailMemoryInfo(){  
        MemoryInfo outInfo = new ActivityManager.MemoryInfo();  
        am.getMemoryInfo(outInfo);  
        return outInfo.availMem;  
    }  
    /** 
     *  
     * @author chen 
     * 无论 多么复杂的业务逻辑都是通过在getView里面复杂的业务判断出来的。 
     */  
    private class TaskInfoAdapter extends BaseAdapter{  
        /** 
         * 在构造方法里面完成了用户列表和系统程序列表的区分 
         */  
        public TaskInfoAdapter() {  
            usertaskinfos = new ArrayList<TaskInfo>();  
            systemtaskinfos = new ArrayList<TaskInfo>();  
              
            for(TaskInfo taskInfo : listtaskinfos){  
                if (taskInfo.isSystemapp()) {  
                    systemtaskinfos.add(taskInfo);  
                }else {  
                    usertaskinfos.add(taskInfo);  
                }  
            }  
        }  
          
          
          
        @Override  
        public int getCount() {  
            return listtaskinfos.size() + 2;//因为显示出来的  
        }  
  
        @Override  
        public Object getItem(int position) {  
            if (position == 0) {  
                return 0;  
            }else if (position <= usertaskinfos.size()) {  
                return usertaskinfos.get(position - 1);  
            }else if (position == usertaskinfos.size()+1) {  
                return position;  
            }else if (position <= listtaskinfos.size()+2) {  
                return systemtaskinfos.get(position-usertaskinfos.size() -2);  
            }else {  
                return position;  
            }  
        }  
  
        @Override  
        public long getItemId(int position) {  
            if (position == 0) {  
                return -1;//这只是一个标识,标识这里面显示的TextView,  
            }else if (position <= usertaskinfos.size()) {  
                return position - 1;  
            }else if (position == usertaskinfos.size()+1) {  
                return -1;  
            }else if (position <= listtaskinfos.size()+2) {  
                return position-usertaskinfos.size() -2;  
            }else {  
                return -1;  
            }  
        }  
  
        @Override  
        public View getView(int position, View convertView, ViewGroup parent) {  
            // 把这些条目信息 做一下分类 系统进程和用户进程区分出来  
            if (position == 0) {  
                TextView tv_userapp = new TextView(TaskManagerActivity.this);  
                tv_userapp.setTextSize(22);  
                tv_userapp.setText("用户进程 "+usertaskinfos.size()+"个");  
                return tv_userapp;  
            }else if (position <= usertaskinfos.size()) {  
                int currentpositon = position - 1;  
                TaskInfo taskInfo = usertaskinfos.get(currentpositon);  
                View view = View.inflate(TaskManagerActivity.this, R.layout.task_manager_item, null);  
                  
                ViewHolder holder = new ViewHolder();  
                holder.iv = (ImageView) view.findViewById(R.id.iv_app_icon);  
                holder.tv_name = (TextView) view.findViewById(R.id.tv_app_name);  
                holder.tv_memory_size = (TextView) view  
                        .findViewById(R.id.tv_app_memory_size);  
                holder.cb_task_checked = (CheckBox) view  
                        .findViewById(R.id.cb_task_checked);  
                String packname = taskInfo.getPackname();  
                System.out.println("包名:"+packname);  
                System.out.println("appname " + taskInfo.getAppname());  
                //如果是以下三个程序 是不可以被清理的  
                if ("360safe".equals(taskInfo.getAppname())) {  
                    holder.cb_task_checked.setVisibility(View.INVISIBLE);  
  
                } else {  
                    holder.cb_task_checked.setVisibility(View.VISIBLE);  
                }  
                holder.iv.setImageDrawable(taskInfo.getAppicon());  
                holder.tv_name.setText(taskInfo.getAppname());  
                holder.tv_memory_size.setText("内存占用: "  
                        + TextFormater.getKBDataSize(taskInfo.getMemorysize()));  
                holder.cb_task_checked.setChecked(taskInfo.isIschecked());  
                return view;  
            }else if (position == usertaskinfos.size()+1) {  
                TextView tv_systemapp = new TextView(TaskManagerActivity.this);  
                tv_systemapp.setText("系统进程 " + systemtaskinfos.size() + "个");  
                tv_systemapp.setTextSize(22);  
                return tv_systemapp;  
            }else if (position <= listtaskinfos.size() + 2) {  
                int systemposition = position - usertaskinfos.size() - 2;  
                TaskInfo taskInfo = systemtaskinfos.get(systemposition);  
                View view = View.inflate(TaskManagerActivity.this, R.layout.task_manager_item, null);  
                ViewHolder holder = new ViewHolder();  
                holder.iv = (ImageView) view.findViewById(R.id.iv_app_icon);  
                holder.tv_name = (TextView) view.findViewById(R.id.tv_app_name);  
                holder.tv_memory_size = (TextView) view  
                        .findViewById(R.id.tv_app_memory_size);  
                holder.cb_task_checked = (CheckBox) view  
                        .findViewById(R.id.cb_task_checked);  
                String packname = taskInfo.getPackname();  
                //如果是以下三个程序 是不可以被清理的  
                if ("cn.itcast.mobilesafe".equals(packname)  
                        || "system".equals(packname)  
                        || "android.process.media".equals(packname)) {  
                    holder.cb_task_checked.setVisibility(View.INVISIBLE);  
  
                } else {  
                    holder.cb_task_checked.setVisibility(View.VISIBLE);  
                }  
                holder.iv.setImageDrawable(taskInfo.getAppicon());  
                holder.tv_name.setText(taskInfo.getAppname());  
                holder.tv_memory_size.setText("内存占用: "  
                        + TextFormater.getKBDataSize(taskInfo.getMemorysize()));  
                holder.cb_task_checked.setChecked(taskInfo.isIschecked());  
                return view;  
            }else {  
                // 肯定不会执行  
                return null;  
            }  
        }  
          
    }  
    /** 
     * @author chen 
     * 用于ListView优化。 
     */  
    static class ViewHolder {  
        public ImageView iv;  
        public TextView tv_name;  
        public TextView tv_memory_size;  
        public CheckBox cb_task_checked;  
    }  
}  

CheckBox的二个属性应该都写成false,交给程序员来控制。
android:focusable="false"
android:clickable="false"

  4、安全权限获取:

//利用反射获取权限,因为安卓没有提供这个API,但是我们知道它一定要手机中,所以我们在运行时间获取,利用反射。  
 try {  
        Class clazz = getClass().getClassLoader().loadClass("android.widget.AppSecurityPermissions");  
      
        Constructor constructor = clazz.getConstructor(new Class[]{Context.class,String.class});  
          
        Object object = constructor.newInstance(new Object[]{this,packName});  
          
        Method method = clazz.getDeclaredMethod("getPermissionsView", new Class[]{});  
  
        View view = (View) method.invoke(object, new Object[]{});  
          
        sv_app_detail.addView(view);  
      
    } catch (Exception e) {  
        e.printStackTrace();  
    }  
//完结后我们把全局上下文的内容清空,提高效率。  
myApplication.taskInfo = null;   

  5、Widget开发;

<receiver android:name="ExampleAppWidgetProvider" >  
    <intent-filter>  
        <action android:name="android.appwidget.action.APPWIDGET_UPDATE" />  
    </intent-filter>  
    <meta-data android:name="android.appwidget.provider"  
               android:resource="@xml/example_appwidget_info" />  
</receiver>  
?xml version="1.0" encoding="utf-8"?>  
<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"  
    android:minWidth="294dp"  
    android:minHeight="72dp"  
    android:updatePeriodMillis="1800000"  
    android:initialLayout="@layout/main"  
>  
</appwidget-provider>  
  
/** 
 * 根据配置文件 每隔固定的时间 更新一下界面  
 * 最小值 半个小时 1800000毫秒 
 * onRecevie - > onUpdate 
 *  
 *  
 * 注意 widget这个组件不是在我们的应用程序里面 
 * 显示在桌面的应用程序  
 * 不同的桌面 他们的widget的创建和销毁对应的 回调的事件可能会有不同 
 * android luncher / htc sence / 米ui / 360桌面/awt /qq桌面/.... 
 *  
 * 
 */  
public class MyWidget extends AppWidgetProvider {  
  
    @Override  
    public void onReceive(Context context, Intent intent) {  
        super.onReceive(context, intent);  
        System.out.println("onReceive");  
    }  
  
    @Override  
    public void onUpdate(Context context, AppWidgetManager appWidgetManager,  
            int[] appWidgetIds) {  
        System.out.println("onUpdate");  
        super.onUpdate(context, appWidgetManager, appWidgetIds);  
    }  
  
    @Override  
    public void onDeleted(Context context, int[] appWidgetIds) {  
        System.out.println("onDeleted");  
        super.onDeleted(context, appWidgetIds);  
        //当某一个widget被删除的时候 会执行ondelete方法  
    }  
  
    @Override  
    public void onEnabled(Context context) {  
        System.out.println("onEnabled");  
          
        // widget第一次创建的时候 执行的方法   
        //可以做 初始化widget数据的操作,开启以后后台   
        super.onEnabled(context);  
    }  
  
    @Override  
    public void onDisabled(Context context) {  
        super.onDisabled(context);  
        System.out.println("onDisabled");  
        // 当所有的widget都被删除的时候 执行 ondisable();  
        // 停止我们开启的服务  
        // 删除垃圾文件 临时文件  
    }  
  
}  
/*虽然说onupdate 和 onreceiver这两个方法在不同的  平台上略有不同,不过相同的是onEnabled会在第一次  
创建的时间执行,它只执行一次,以后只会执行onupdate  和onreceiver方法,当这个widget删除的时间才执行ondeled  
方法,当所有桌面小控件都删除的时间才执行ondisabled.  
方法,当所有桌面小控件都删除的时间才执行  
  */
public class ProcessWidget extends AppWidgetProvider  extends BroadcastReceiver{};  
所以它本质上是一个广播接收者  
  
做这个东西,记清楚一件事,就是它永远是在这里面去调用后台的服务的,这是最基本的思路,  
因为它所有的各种东西是在生命周期里面调用的.这是一条主线.  
/** 
 * 它在不同的生命周期里面只需要调用不同的方法即可。 
 * @author chen 
 */  
public class ProcessWidget extends AppWidgetProvider {  
     Intent intent ;  
      
    @Override  
    public void onDeleted(Context context, int[] appWidgetIds) {  
        super.onDeleted(context, appWidgetIds);  
        intent = new Intent(context,UpdateWidgetService.class);  
        context.stopService(intent);  
    }  
      
      
    @Override  
    public void onEnabled(Context context) {  
        super.onEnabled(context);  
        intent = new Intent(context,UpdateWidgetService.class);  
        context.startService(intent);  
    }  
}  

 

posted @ 2014-03-07 15:53  若 ♂ 只如初见  阅读(605)  评论(0编辑  收藏  举报