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);  

    }  

}  

 

你可能感兴趣的:(Android学习)