[mobilesafe] 07_进程管理——设置

Android 4.0

进程管理——设置

一、显示系统进程1、设置Activity,布局
2、利用SharedPreferences来保存是否显示进程
3、然后在ListView的getCount()方法中,控制显示的个数
4、利用结果码,来更新ListView界面
1、布局 activity_taskmanager_setting.xml
<?xml version="1.0" encoding="utf-8"?>
<!-- 34、任务管理器设置界面Activity的布局 -->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >
    <TextView
        style="@style/wizard_textview_title"
        android:paddingLeft="5dip"
        android:text="@string/task_manage_setting" />
    <!-- 1、是否显示系统进程 -->
    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="center_vertical"
        android:orientation="horizontal" >
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_centerVertical="true"
            android:layout_marginBottom="3dip"
            android:layout_marginLeft="5dip"
            android:layout_marginTop="3dip"
            android:text="@string/show_system_process"
            android:textColor="#000000"
            android:textSize="20sp" />
        <CheckBox
            android:id="@+id/cb_task_setting_checkstatus"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentRight="true"
            android:layout_marginBottom="3dip"
            android:layout_marginRight="5dip"
            android:layout_marginTop="3dip"
            android:textColor="#000000"
            android:textSize="20sp" />
    </RelativeLayout>
    <View
        android:layout_width="match_parent"
        android:layout_height="1dip"
        android:layout_marginLeft="5dip"
        android:layout_marginRight="5dip"
        android:background="#66000000" />
</LinearLayout>
2、 TaskManageSettingActivity.java
package cn.zengfansheng.mobilesafe;
import android.app.Activity;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.os.Bundle;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.CompoundButton.OnCheckedChangeListener;
/**
 * 21、任务管理器设置界面Activity
 * @author hacket
 */
public class TaskManageSettingActivity extends Activity {
    private CheckBox cb_task_setting_checkstatus;// 显示系统进程的checkbox
    private SharedPreferences sp;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        this.setContentView(R.layout.activity_taskmanager_setting);
        sp = this.getSharedPreferences("config"MODE_PRIVATE);
        
        cb_task_setting_checkstatus = (CheckBox) this.findViewById(R.id.cb_task_setting_checkstatus);
        
        //3、下次进入,记住保存的状态
        boolean isShowSystemProc = sp.getBoolean("isShowSystemProc"false);
        cb_task_setting_checkstatus.setChecked(isShowSystemProc);
        
        //1、设置checkbox的选中状态变化事件
        cb_task_setting_checkstatus.setOnCheckedChangeListener(new OnCheckedChangeListener() {
            
            @Override
            public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                //2、将选中的状态保存到SharedPreferences中去                
                Editor edit = sp.edit();
                edit.putBoolean("isShowSystemProc",isChecked);
                edit.commit();
                
                //设置结果码,告诉开启该Activity的intent
                setResult(RESULT_OK);
            }
        });
    }
}
3) TaskManageActivity.java
// 10、获取结果码,来更新ListView中的数据
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    if (resultCode == RESULT_OK) {// 即,显示系统进程的状态发生了变化
        adapter.notifyDataSetChanged();// 通过更新ListView
    }
}
/**
 * 9、设置
 */
public void enterSetting() {
    Intent intent = new Intent(this, TaskManageSettingActivity.class);
    // startActivity(intent);//用这句就没有效果
    startActivityForResult(intent, 0);
}
ListView中,getCount()方法
@Override
public int getCount() {
    boolean isShowSystemProc = sp.getBoolean("isShowSystemProc"false);//显示系统应用是否开启了
    if (isShowSystemProc) {// 开启了显示系统应用
        return userTaskInfos.size() + 1 + sysTaskInfos.size() + 1;
    } else {
        return userTaskInfos.size() + 1;
    }
}
二、锁屏时清理进程-最实用的功能
注意:屏幕锁屏的广播接收者,在清单文件中进行配置,对于很多手机来说,不会生效,这是一个bug。
步骤:
1、布局
2、需要一个服务,绑定一个屏幕锁屏的广播接收者
3、一旦接收到屏幕锁屏的事件,那么就将后台的进程给kill掉
1、布局

<!-- 2、是否锁屏清理后台进程 -->
<RelativeLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:gravity="center_vertical"
    android:orientation="horizontal" >
    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerVertical="true"
        android:layout_marginBottom="3dip"
        android:layout_marginLeft="5dip"
        android:layout_marginTop="3dip"
        android:text="@string/screen_off_clear_background_process"
        android:textColor="#000000"
        android:textSize="20sp" />
    <CheckBox
        android:id="@+id/cb_task_setting_clear_bg_process"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentRight="true"
        android:layout_marginBottom="3dip"
        android:layout_marginRight="5dip"
        android:layout_marginTop="3dip"
        android:textColor="#000000"
        android:textSize="20sp" />
</RelativeLayout>
2、服务,绑定屏幕竖屏广播事件
ScreenOffAutoClearDaemonProcService.java 
package cn.zengfansheng.mobilesafe.service;
 
import java.util.List;
import android.app.ActivityManager;
import android.app.ActivityManager.RunningAppProcessInfo;
import android.app.Service;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.os.IBinder;
import android.util.Log;
/**
* 6、屏幕锁屏时,清理后台进程
* @author hacket
*/

public class ScreenOffAutoClearDaemonProcService extends Service {
    private BroadcastReceiver screenOffReceiver;//屏幕锁屏的广播接收者
    private SharedPreferences sp;
    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }
    /**
     * 1、屏幕锁屏的广播接收者
     * @author hacket
     */

    private class ScreenOffReceiver extends BroadcastReceiver {
        private static final String TAG = "ScreenOffReceiver";
        @Override
        public void onReceive(Context context, Intent intent) {
 
            // 是否锁屏清理后台进程
            boolean isAutoClearBgProcess = sp.getBoolean("isAutoClearBgProcess", false);
            if (isAutoClearBgProcess) {// 如果选中了,那么在锁屏时杀死后台进程
                Log.i(TAG, "锁屏了,清理后台进程~");
                ActivityManager activityManager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
                List<RunningAppProcessInfo> runningAppProcesses = activityManager.getRunningAppProcesses();
                for (RunningAppProcessInfo taskInfoProcessInfo : runningAppProcesses) {
                    String processName = taskInfoProcessInfo.processName;
                    if (processName.equals(getPackageName())) {
                        Log.i(TAG, "这是自己的进程,不清理掉~");
                        continue;
                    }
                    activityManager.killBackgroundProcesses(processName);
                }
            }
        }
    }
    // 服务创建时,注册屏幕锁屏的广播接收者
    @Override
    public void onCreate() {
        super.onCreate();
 
        sp = this.getSharedPreferences("config", MODE_PRIVATE);
 
        // 注册屏幕锁屏的广播接收者
        screenOffReceiver = new ScreenOffReceiver();
        IntentFilter filter = new IntentFilter();
        filter.addAction(Intent.ACTION_SCREEN_OFF);
        registerReceiver(screenOffReceiver, filter);
    }
    // 服务停止时,取消注册屏幕锁屏的广播接收者
    @Override
    public void onDestroy() {
        super.onDestroy();
 
        // 取消注册屏幕锁屏的广播接收者
        if (screenOffReceiver != null) {
            unregisterReceiver(screenOffReceiver);
            screenOffReceiver = null;
        }
    }
}
3、 在屏幕锁屏时,将后台进程杀死
TaskManageSettingActivity.java 
//4、锁屏清理后台进程checkbox的选中状态变化事件
cb_task_setting_clearbgproc.setOnCheckedChangeListener(new OnCheckedChangeListener() {
    
    @Override
    public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
        //5、将是否锁屏清理后台进程的选中的状态保存到SharedPreferences中去    
        Editor edit = sp.edit();
        edit.putBoolean("isAutoClearBgProcess", isChecked);
        edit.commit();
        
        //如果选中了锁屏时清理后台,开启锁屏时清理后台的服务
        Intent service = new Intent(getApplicationContext(), ScreenOffAutoClearDaemonProcService.class);
        if (isChecked) {
            startService(service);
        }else {//未选中,则取消
            stopService(service);
        }
    }
});
注意:对于服务状态的回显
a)不能用简单的SharedPreferences来保存状态
// 6、下次进入,记住保存的状态,对于服务,而不是用SharedPreferences来保存状态,而是要检测是否运行来设置是否选中,见下面onStart()方法
//boolean isAutoClearBgProcess = sp.getBoolean("isAutoClearBgProcess", false);
//cb_task_setting_clearbgproc.setChecked(isAutoClearBgProcess);
b)而应该检测服务是否运行,来设置状态
// 对于服务,而不是用SharedPreferences来保存状态,而是要检测是否运行来设置是否选中
@Override
protected void onStart() {
    super.onStart();
    // 锁屏清理后台进程服务状态
    boolean isServiceOpen = ServiceStatusUtils.isServiceOpen(getApplicationContext(), ScreenOffAutoClearDaemonProcService.class);
    cb_task_setting_clearbgproc.setChecked(isServiceOpen);
}