手机卫士开发第八天
2014-07-29 08:26
211 查看
手机卫士第八天知识点
进程管理器的开发
一、获取可用内存和总内存的信息public class SysInfoProvider { public static long getAvailableMemory(Context context) { ActivityManager am = (ActivityManager) context .getSystemService(Context.ACTIVITY_SERVICE); MemoryInfo outInfo = new MemoryInfo(); am.getMemoryInfo(outInfo); return outInfo.availMem; } public static long getTotalMemory(Context context) { /** * 第一种方式(API 16+) */ // ActivityManager am = (ActivityManager) context // .getSystemService(Context.ACTIVITY_SERVICE); // MemoryInfo outInfo = new MemoryInfo(); // am.getMemoryInfo(outInfo); /** * 第二种方式 */ long totalMem = 0l; try { BufferedReader reader = new BufferedReader(new FileReader(new File( "/proc/meminfo"))); String info = reader.readLine(); StringBuilder builder = new StringBuilder(20); for (char c : info.toCharArray()) { if (c >= '0' && c <= '9') { builder.append(c); } } totalMem = Long.parseLong(builder.toString()); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } return totalMem * 1024; } }
二、使用ActivityManager和PackageInfo类得到正在运行的进程的信息
public class ProcessInfoManager { public static List<ProcessInfo> listProcessInfos(Context context) { PackageManager pm = context.getPackageManager(); ActivityManager am = (ActivityManager) context .getSystemService(Context.ACTIVITY_SERVICE); List<RunningAppProcessInfo> runningAppProcessInfos = am .getRunningAppProcesses(); ProcessInfo processInfo = null; List<ProcessInfo> infos = new ArrayList<ProcessInfo>(); for (RunningAppProcessInfo runningInfo : runningAppProcessInfos) { processInfo = new ProcessInfo(); // 得到包名或者是进程名 String packageName = runningInfo.processName; // 得到进程的内存信息 MemoryInfo memInfo = (am .getProcessMemoryInfo(new int[] { runningInfo.pid }))[0]; processInfo.setMemSize(memInfo.getTotalPrivateDirty() * 1024); ApplicationInfo appInfo = null; try { appInfo = pm.getApplicationInfo(packageName, 0); processInfo.setIcon(appInfo.loadIcon(pm)); processInfo.setName(appInfo.loadLabel(pm).toString()); processInfo.setPackageName(packageName); processInfo .setUserApp((appInfo.flags & ApplicationInfo.FLAG_SYSTEM) == 0); } catch (NameNotFoundException e) { // e.printStackTrace(); processInfo.setIcon(context.getResources().getDrawable( R.drawable.ic_app_default)); processInfo.setName(packageName); processInfo.setPackageName(packageName); processInfo.setUserApp(false); } infos.add(processInfo); } return infos; } }
三、为了提高ListView的效率所以复用了convertView。这样的化Item里面的CheckedBox如果不加验证会出现错误。一般情况下是在业务Bean里面增加字段来记录它自己的选中状态。
四、Weight的使用,控件的属性中width=”0dp”那么weight代表的就是宽度的比例。如果height=”0dp”那么weight代表就是高度的优先级。
布局代码如下:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:background="@color/background_color" android:orientation="vertical" > <!-- 该Activity是程序开始的一个软件管理界面 --> <TextView style="@style/titile_context_app" android:text="进程管理" /> <RelativeLayout android:layout_width="fill_parent" android:layout_height="30dp" > <TextView android:id="@+id/tv_count_process" android:layout_width="wrap_content" android:layout_height="fill_parent" android:layout_alignParentLeft="true" android:gravity="center" android:text="进程总数:60" android:textSize="14sp" /> <TextView android:id="@+id/tv_ava_total_space" android:layout_width="wrap_content" android:layout_height="fill_parent" android:layout_alignParentRight="true" android:gravity="center" android:text="剩余/总内存:98/500MB" android:textSize="14sp" /> </RelativeLayout> <TextView android:id="@+id/tv_groupinfo" android:layout_width="fill_parent" android:layout_height="wrap_content" android:background="@android:color/black" android:text="用户进程:9个" android:textColor="@android:color/white" android:textSize="16sp" /> <FrameLayout android:layout_width="fill_parent" android:layout_height="fill_parent" > <LinearLayout android:id="@+id/ll_loading_in_taskmanager" android:layout_width="fill_parent" android:layout_height="fill_parent" android:background="#aaffffff" android:gravity="center" android:orientation="vertical" android:visibility="visible" > <ProgressBar android:layout_width="wrap_content" android:layout_height="wrap_content" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="正在玩命加载中..." /> </LinearLayout> <LinearLayout android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical" > <ListView android:id="@+id/lv_list_all_process" android:layout_width="fill_parent" android:layout_height="0dip" android:layout_weight="1000" > </ListView> <LinearLayout android:layout_width="fill_parent" android:layout_height="wrap_content" android:orientation="horizontal" > <Button android:layout_width="0dip" android:layout_height="wrap_content" android:layout_weight="1" android:onClick="cleanUp" android:text="清理" /> <Button android:layout_width="0dip" android:layout_height="wrap_content" android:layout_weight="1" android:onClick="checkAll" android:text="全选" /> <Button android:layout_width="0dip" android:layout_height="wrap_content" android:layout_weight="1" android:onClick="checkOppo" android:text="反选" /> <Button android:layout_width="0dip" android:layout_height="wrap_content" android:layout_weight="1" android:onClick="showSetting" android:text="设置" /> </LinearLayout> </LinearLayout> </FrameLayout> </LinearLayout>
效果如下:
五、选择显示系统进程只需要更改适配器代码里面的getCount方法即可。
class MyDapter extends BaseAdapter { @Override public int getCount() { if (sp.getBoolean("isShowSysProcess", true)) { return sysProcessInfos.size() + userProcessInfos.size() + 1; } return userProcessInfos.size(); } @Override public View getView(int position, View convertView, ViewGroup parent) { ViewHolder holder = null; if (position == userProcessInfos.size()) { TextView tv = new TextView(TaskManagerActivity.this); tv.setBackgroundColor(Color.BLACK); tv.setTextColor(Color.WHITE); tv.setTextSize(16); tv.setText("系统应用:共" + sysProcessInfos.size() + "个"); return tv; } else { if (convertView != null && convertView instanceof RelativeLayout) { holder = (ViewHolder) convertView.getTag(); } else { holder = new ViewHolder(); convertView = inflater.inflate( R.layout.processinfo_item_show, null); holder.cb_process_check = (CheckBox) convertView .findViewById(R.id.cb_process_check); holder.iv_process_icon = (ImageView) convertView .findViewById(R.id.iv_process_icon); holder.tv_process_memsize = (TextView) convertView .findViewById(R.id.tv_process_memsize); holder.tv_process_name = (TextView) convertView .findViewById(R.id.tv_process_name); convertView.setTag(holder); } if (position < userProcessInfos.size()) { ProcessInfo info = userProcessInfos.get(position); holder.cb_process_check.setChecked(info.isChecked()); holder.iv_process_icon.setImageDrawable(userProcessInfos .get(position).getIcon()); holder.tv_process_memsize.setText(Formatter.formatFileSize( TaskManagerActivity.this, info.getMemSize())); holder.tv_process_name.setText(info.getName()); } else { ProcessInfo info = sysProcessInfos.get(position - userProcessInfos.size() - 1); holder.cb_process_check.setChecked(info.isChecked()); holder.iv_process_icon.setImageDrawable(info.getIcon()); holder.tv_process_memsize.setText(Formatter.formatFileSize( TaskManagerActivity.this, info.getMemSize())); holder.tv_process_name.setText(info.getName()); } return convertView; } } @Override public Object getItem(int position) { // TODO Auto-generated method stub return null; } @Override public long getItemId(int position) { // TODO Auto-generated method stub return 0; } class ViewHolder { ImageView iv_process_icon; TextView tv_process_name; TextView tv_process_memsize; CheckBox cb_process_check; } }
六、锁屏清理进程。注意点锁屏广播是一个特殊的广播,只能在代码里面声明广播接收者不能再清单文件中声明广播接收者。
public class AutoCleanService extends Service { private MyLockReceiver lockReceiver; private ActivityManager am; @Override public IBinder onBind(Intent intent) { // TODO Auto-generated method stub return null; } @Override public void onCreate() { am = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE); lockReceiver = new MyLockReceiver(); registerReceiver(lockReceiver, new IntentFilter( Intent.ACTION_SCREEN_OFF)); Toast.makeText(this, "自动清理服务已经开启", 0).show(); super.onCreate(); } @Override public void onDestroy() { unregisterReceiver(lockReceiver); lockReceiver = null; Toast.makeText(this, "自动清理服务已经销毁", 0).show(); super.onDestroy(); } class MyLockReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { List<RunningAppProcessInfo> infos = am.getRunningAppProcesses(); for (RunningAppProcessInfo info : infos) { // 不能自杀呀 if (!context.getPackageName().equals(info.processName)) { am.killBackgroundProcesses(info.processName); } } Toast.makeText(context, "旺旺卫士已经为您清理了进程", 0).show(); } } }
Widget控件的开发
一、新建一个AppWidgetProvider扩展类类,MyAppWidgetProviderpackage com.example.phoneguard.receiver; import com.example.phoneguard.service.AutoCleanService; import com.example.phoneguard.service.UpdateWidgetService; import android.appwidget.AppWidgetManager; import android.appwidget.AppWidgetProvider; import android.content.Context; import android.content.Intent; import android.util.Log; public class MyAppWidgetProvider extends AppWidgetProvider { }
二、编写widget控件的界面样式和布局代码
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="wrap_content" android:background="#D8BFD8" android:orientation="vertical" > <RelativeLayout android:layout_width="fill_parent" android:layout_height="fill_parent" > <TextView android:id="@+id/tv_process_count" android:layout_width="200dp" android:layout_height="35dp" android:text="进程总数:共1个" android:textColor="#000000" /> <TextView android:id="@+id/tv_memsize_count" android:layout_width="200dp" android:layout_height="35dp" android:layout_below="@id/tv_process_count" android:text="可用内存:0MB" android:textColor="#000000" /> <Button android:id="@+id/btn_process_cleanup" android:layout_width="90dp" android:layout_height="30dp" android:layout_alignParentRight="true" android:layout_centerVertical="true" android:background="#AFEEEE" android:text="一键清理" /> </RelativeLayout> </LinearLayout>
三、在RES/xml目录下建立元数据,列出该widget的信息
<?xml version="1.0" encoding="UTF-8"?> <appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android" android:initialLayout="@layout/example_appwidget" android:minHeight="72.0dip" android:minWidth="294.0dip" android:updatePeriodMillis="1800000" />
四、在清单文件注册该广播接收者
<receiver android:name=".receiver.MyAppWidgetProvider" > <intent-filter> <action android:name="android.appwidget.action.APPWIDGET_UPDATE" /> </intent-filter> <meta-data android:name="android.appwidget.provider" android:resource="@xml/my_appwidget_info" /> </receiver>
五、新建一个服务,用于更新Widget的UI显示。
package com.example.phoneguard.service; import java.text.Normalizer.Form; import java.util.Timer; import java.util.TimerTask; import com.example.phoneguard.R; import com.example.phoneguard.engine.SysInfoProvider; import com.example.phoneguard.receiver.MyAppWidgetProvider; import android.app.ActivityManager; import android.app.PendingIntent; import android.app.Service; import android.appwidget.AppWidgetManager; import android.content.BroadcastReceiver; import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.os.IBinder; import android.text.format.Formatter; import android.view.View.OnCreateContextMenuListener; import android.widget.RemoteViews; import android.widget.Toast; import android.widget.RemoteViews.RemoteView; public class UpdateWidgetService extends Service { private Timer timer; private TimerTask task; private AppWidgetManager appWidgetManager; private ActivityManager am; private MyLockReceiver lockReceiver; private MyLockOffReceiver lockOffReceiver; @Override public IBinder onBind(Intent intent) { return null; } @Override public void onCreate() { lockOffReceiver = new MyLockOffReceiver(); // 接收设备唤醒的广播 registerReceiver(lockOffReceiver, new IntentFilter( Intent.ACTION_USER_PRESENT)); lockReceiver = new MyLockReceiver(); // 接收设备锁定的广播 registerReceiver(lockReceiver, new IntentFilter( Intent.ACTION_SCREEN_OFF)); updateWidget(5000); } public void updateWidget(long time) { timer = new Timer(); task = new TimerTask() { private ComponentName provider = new ComponentName( getApplicationContext(), MyAppWidgetProvider.class); @Override public void run() { // 设置远程视图 RemoteViews views = new RemoteViews(getPackageName(), R.layout.example_appwidget); am = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE); appWidgetManager = AppWidgetManager .getInstance(getApplicationContext()); views.setTextViewText(R.id.tv_process_count, "进程总数:共" + am.getRunningAppProcesses().size() + "个"); long memsize = SysInfoProvider .getAvailableMemory(getApplicationContext()); views.setTextViewText( R.id.tv_memsize_count, "可用内存:" + Formatter.formatFileSize( getApplicationContext(), memsize)); Intent intent = new Intent(); intent.setAction("com.example.phoneguard.cleanup"); PendingIntent pendingIntent = PendingIntent.getBroadcast( getApplicationContext(), 0, intent, PendingIntent.FLAG_UPDATE_CURRENT); views.setOnClickPendingIntent(R.id.btn_process_cleanup, pendingIntent); // 应用远程视图 appWidgetManager.updateAppWidget(provider, views); System.out.println("更新Widget方法执行下..."); } }; // 启动任务,0从现在开始,time 间隔time毫秒执行下任务方法 timer.schedule(task, 0, time); } @Override public void onDestroy() { Toast.makeText(this, "更新Widget的服务已经销毁...", 0).show(); unregisterReceiver(lockOffReceiver); unregisterReceiver(lockReceiver); lockOffReceiver = null; lockReceiver = null; timer.cancel(); task = null; timer = null; super.onDestroy(); } class MyLockReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { // System.out.println("屏幕已经锁定,停止更新widget"); timer.cancel(); task = null; timer = null; } } class MyLockOffReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { // System.out.println("屏幕已经解锁,开始更新widget..."); updateWidget(5000); } } }
六、MyAppWidgetProvider中控制上诉上面那个服务的生命周期
package com.example.phoneguard.receiver; import com.example.phoneguard.service.AutoCleanService; import com.example.phoneguard.service.UpdateWidgetService; import android.appwidget.AppWidgetManager; import android.appwidget.AppWidgetProvider; import android.content.Context; import android.content.Intent; import android.util.Log; public class MyAppWidgetProvider extends AppWidgetProvider { private static final String TAG = "MyAppWidgetProvider"; private Intent itt; @Override public void onReceive(Context context, Intent intent) { System.out.println("onReceive"); // 广播接收者收到了广播 itt = new Intent(context, UpdateWidgetService.class); context.startService(itt); super.onReceive(context, intent); } @Override public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) { System.out.println("onUpdate"); // 广播接收者更新了 super.onUpdate(context, appWidgetManager, appWidgetIds); } @Override public void onEnabled(Context context) { System.out.println("onEnabled"); // 启用更新Widget的服务 itt = new Intent(context, UpdateWidgetService.class); context.startService(itt); super.onEnabled(context); } @Override public void onDisabled(Context context) { System.out.println("onDisabled"); // 禁用更新Widget的服务 context.stopService(itt); super.onDisabled(context); } }
相关文章推荐
- 手机卫士 第二天主界面的开发
- 开发手机卫士第二天,自定义style,对话框
- Android项目实战--手机卫士开发系列教程
- 安卓开发小练手之手机卫士开发(1)——Splash界面
- 手机卫士开发_setting界面和自动更新的设置
- Android - 手机卫士开发(MobileSafe)(二)
- 安卓手机卫士开发学习第一天--Splash界面
- 手机卫士 第四天高级工具开发
- 安卓开发小练手之手机卫士开发(4)——手机防盗设置界面
- 手机卫士开发学习1
- 安卓开发小练手之手机卫士开发(3)——手机防盗界面的开启
- 手机卫士开发第二天
- Android项目实战--手机卫士开发系列教程
- 安卓开发小练手之手机卫士开发(2)——主界面
- 手机卫士 第八天
- 用S60操作系统SDK开发NOKIA手机应用程序(5)-范例HelloWorld分析
- 用S60操作系统SDK开发NOKIA手机应用程序-学习笔记(2)
- 手机软件开发学习准备指南
- 用S60操作系统SDK开发NOKIA手机应用程序(4)- 界面层框架及一些特性
- 开发moto手机的网址