zoukankan      html  css  js  c++  java
  • 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);  
        }  
    }  
  • 相关阅读:
    Visifire Chart控件设置 柱状图 条的宽窄
    silverlight+wcf 获得web参数
    Maven教程(转载)
    Eclipse插件CheckStyle的安装和使用
    log4net面面观之工作原理
    javabean实体类对象转为Map类型对象的方法(转发)
    ORACLE数据库创建用户名和表空间
    ORACLE 12C PDB 维护基础介绍
    int 与 Integer--话说数组转集合
    Shiro--权限控制
  • 原文地址:https://www.cnblogs.com/lbangel/p/3586580.html
Copyright © 2011-2022 走看看