[安卓]手机管家(十八)一键 锁屏清理线程以及widget
2015-06-25 17:46
537 查看
有些broadcastReceiver不能在manifest里静态注册(不用运行起来就能收到)
锁屏是不能静态注册的,非常频繁的锁屏,动态注册,绑到service里最好,这样生命周期长
receiver
在service里注册
可以再setting里写一个控制按钮,这里让他在splash里启动,不能忘了service的声明
在日常使用中,可以再锁屏的时候把进程清一遍,其实很实用
widgets相当于桌面的功能快捷方式
桌面其实也是一个程序,相当于在一个程序上实现另一个程序的功能
需要一个类继承AppWidgetProvider,但是要声明称一个receiver,实际上他是一个receiver
和之前获得管理员权限类似,这个类里面什么也不做
声明一下,需要在values下新建一个xml文件夹,其中需有一个xml文件
这个xml文件里面,制定了我们要做出来的widget的相关属相参数,他还要一个layout来显示widget的外观
layout 这里面不支持复杂控件,比如edittext,若加上,在拖到桌面时提示有问题
widget生命周期,是一个receiver
第一次新建时,call到几个函数
onEnAble
onUpdate
第二次拖到别的桌面
onupdate onReceive
第三次 还是和第二次一样
可以想到 onEnabled只在第一次建立的时候调用
删除第三个 ondelete onreceive
删除第二个 ondelete onreceive
删除第一个 ondelete ondisable
最后一次会调用disable
启用widget会有广播,onreceive里面会看广播里附带了什么信息,如果是update,他会先调用update,可以看源码
来实现手机管家的widget项目
新建widget类
然后去manifest注册
xml写法
新建layout
完成交互,类里的方法
首先是onenable,拖到到桌面会调到他,只有第一次创建时会用到
onupdate,我们要让widget的图标上的内容内很快更新,默认是至少半小时,可以去弄一个service
让widget启动时启动这个service,放到onenable里
然后在service的onstart里更新widget,这样相当于是在第一次创建桌面的widget时更新了widget,并且要让他更新快点,用到timer,更新的代码应该在timer里
当最后一个widget没有了的时候销毁这个service,在ProcessManagerWidget里的ondisable里
处理点击事件
pending,在点击时页面不跳转,只发出一个自定义的广播,然后有一个接收者
这样子就可以随时清理线程了,而不用等半小时更新一次
锁屏是不能静态注册的,非常频繁的锁屏,动态注册,绑到service里最好,这样生命周期长
receiver
public class LockScreenReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { // TODO Auto-generated method stub System.out.println("LockScreenReceiver.onReceive()"); }
在service里注册
public class ListenLockScreenService extends Service { private LockScreenReceiver lockScreenReceiver; @Override public IBinder onBind(Intent intent) { // TODO Auto-generated method stub return null; } @Override public int onStartCommand(Intent intent, int flags, int startId) { // TODO Auto-generated method stub lockScreenReceiver = new LockScreenReceiver(); IntentFilter filter = new IntentFilter("android.intent.action.SCREEN_OFF"); registerReceiver(lockScreenReceiver, filter); return super.onStartCommand(intent, flags, startId); } @Override public void onDestroy() { // TODO Auto-generated method stub if (lockScreenReceiver!=null) { unregisterReceiver(lockScreenReceiver); lockScreenReceiver=null; } super.onDestroy(); } }
可以再setting里写一个控制按钮,这里让他在splash里启动,不能忘了service的声明
Intent service = new Intent(this,ListenLockScreenService.class); startService(service); } Handler myHandler = new Handler(){
在日常使用中,可以再锁屏的时候把进程清一遍,其实很实用
ublic class LockScreenReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { // TODO Auto-generated method stub System.out.println("LockScreenReceiver.onReceive()"); //kill所有的后台进程 ActivityManager ams = (ActivityManager) context.getSystemService(context.ACTIVITY_SERVICE); List<RunningAppProcessInfo> list = ams.getRunningAppProcesses(); for (RunningAppProcessInfo runningAppProcessInfo : list) { ams.killBackgroundProcesses(runningAppProcessInfo.processName); } } }
widgets相当于桌面的功能快捷方式
桌面其实也是一个程序,相当于在一个程序上实现另一个程序的功能
需要一个类继承AppWidgetProvider,但是要声明称一个receiver,实际上他是一个receiver
和之前获得管理员权限类似,这个类里面什么也不做
public class MyAppWidgetProvider extends AppWidgetProvider { }
声明一下,需要在values下新建一个xml文件夹,其中需有一个xml文件
<receiver android:name="com.example.myappwidget.MyAppWidgetProvider" > <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文件里面,制定了我们要做出来的widget的相关属相参数,他还要一个layout来显示widget的外观
<?xml version="1.0" encoding="utf-8"?> <appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android" android:minWidth="300dp" android:minHeight="40dp" android:updatePeriodMillis="0" android:previewImage="@drawable/ic_launcher" android:initialLayout="@layout/example_appwidget" android:resizeMode="horizontal|vertical" android:widgetCategory="home_screen|keyguard"> </appwidget-provider>
layout 这里面不支持复杂控件,比如edittext,若加上,在拖到桌面时提示有问题
<?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:orientation="vertical" > <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="hello widget"/> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="widget"/> </LinearLayout>
widget生命周期,是一个receiver
第一次新建时,call到几个函数
onEnAble
onUpdate
第二次拖到别的桌面
onupdate onReceive
第三次 还是和第二次一样
可以想到 onEnabled只在第一次建立的时候调用
删除第三个 ondelete onreceive
删除第二个 ondelete onreceive
删除第一个 ondelete ondisable
最后一次会调用disable
启用widget会有广播,onreceive里面会看广播里附带了什么信息,如果是update,他会先调用update,可以看源码
来实现手机管家的widget项目
新建widget类
public class ProcessManagerWidget extends AppWidgetProvider { }
然后去manifest注册
<receiver android:name="com.rjl.mobilephonemanager.widget.ProcessManagerWidget" > <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写法
<?xml version="1.0" encoding="utf-8"?> <appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android" android:minWidth="300dp" android:minHeight="40dp" android:updatePeriodMillis="0" android:previewImage="@drawable/ic_launcher" android:initialLayout="@layout/processmanager_appwidget" android:resizeMode="horizontal|vertical" android:widgetCategory="home_screen|keyguard"> </appwidget-provider>
新建layout
<?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="@drawable/widget_bg_portrait" android:orientation="horizontal" > <LinearLayout android:layout_width="0.0dip" android:layout_height="fill_parent" android:layout_marginLeft="5.0dip" android:layout_weight="1.0" android:background="@drawable/widget_bg_portrait_child" android:gravity="center_vertical" android:orientation="vertical" android:paddingBottom="3.0dip" android:paddingTop="3.0dip" > <TextView android:id="@+id/tv_processwidget_count" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginLeft="10.0dip" android:textSize="16sp" android:text="正在运行的软件:6个"/> <ImageView android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_marginBottom="1.0dip" android:layout_marginTop="1.0dip" android:background="@drawable/widget_bg_portrait_child_divider" /> <TextView android:text="可用内存:433.37M" android:id="@+id/tv_processwidget_memory" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginLeft="10.0dip" android:textSize="16sp"/> </LinearLayout> <LinearLayout android:layout_width="wrap_content" android:layout_height="wrap_content" android:gravity="center_horizontal" android:orientation="vertical" > <LinearLayout android:layout_width="wrap_content" android:layout_height="wrap_content" android:gravity="center_vertical" > <ImageView android:layout_width="20.0dip" android:layout_height="20.0dip" android:src="@drawable/ic_launcher" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="手机管家" android:textColor="#FF0000" /> </LinearLayout> <Button android:id="@+id/btn_clear" android:layout_width="90.0dip" android:layout_height="wrap_content" android:layout_centerVertical="true" android:layout_marginTop="5.0dip" android:background="@drawable/call_locate_green" android:text="一键清理" android:textColor="#000000" /> </LinearLayout> </LinearLayout>
完成交互,类里的方法
首先是onenable,拖到到桌面会调到他,只有第一次创建时会用到
onupdate,我们要让widget的图标上的内容内很快更新,默认是至少半小时,可以去弄一个service
@Override public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) { //1.不是service而是provider AppWidgetManager widgetManager = AppWidgetManager.getInstance(context); //3.updateAppWidget的第一个参数应该是component的name ComponentName provider = new ComponentName(context, ProcessManagerWidget.class); //4.updateAppWidget的第二个参数 RemoteViews views = new RemoteViews("com.rjl.mobilephonemanager",R.layout.processmanager_appwidget); //5.通过view找到控件 views.setTextViewText(R.id.tv_processwidget_count, "10个进程"); views.setTextViewText(R.id.tv_processwidget_memory, "400MB RAM"); //2.更新桌面控件 widgetManager.updateAppWidget(provider, views); super.onUpdate(context, appWidgetManager, appWidgetIds); }service manifest里声明
ublic class WidgetUpdateService extends Service { @Override public IBinder onBind(Intent intent) { // TODO Auto-generated method stub return null; } @Override public void onCreate() { // TODO Auto-generated method stub super.onCreate(); } @Override public void onDestroy() { // TODO Auto-generated method stub super.onDestroy(); } }
<service android:name="com.rjl.mobilephonemanager.service.WidgetUpdateService"></service>
让widget启动时启动这个service,放到onenable里
@Override public void onEnabled(Context context) { Intent service = new Intent(context, WidgetUpdateService.class); context.startService(service); super.onEnabled(context); }
然后在service的onstart里更新widget,这样相当于是在第一次创建桌面的widget时更新了widget,并且要让他更新快点,用到timer,更新的代码应该在timer里
@Override public int onStartCommand(Intent intent, int flags, int startId) { timer = new Timer(); timer.schedule(new TimerTask() { @Override public void run() { //1.不是service而是provider widgetManager = AppWidgetManager.getInstance(WidgetUpdateService.this); //6.动态获取进程数,ram也可以获取 int count =GetProcessInfoUtils.getAllProcess(WidgetUpdateService.this); long ram = GetProcessInfoUtils.getAvailRam(WidgetUpdateService.this); //3.updateAppWidget的第一个参数应该是component的name ComponentName provider = new ComponentName(WidgetUpdateService.this, ProcessManagerWidget.class); //4.updateAppWidget的第二个参数 views = new RemoteViews("com.rjl.mobilephonemanager",R.layout.processmanager_appwidget); //5.通过view找到控件 views.setTextViewText(R.id.tv_processwidget_count, count+"个进程"); views.setTextViewText(R.id.tv_processwidget_memory, ram/1024+"MB RAM"); //2.更新桌面控件 widgetManager.updateAppWidget(provider, views); } }, 1000, 3000); //3s更新一次 return super.onStartCommand(intent, flags, startId); }
当最后一个widget没有了的时候销毁这个service,在ProcessManagerWidget里的ondisable里
@Override public void onDisabled(Context context) { // 销毁service Intent service = new Intent(context, WidgetUpdateService.class); context.stopService(service); super.onDisabled(context); }
处理点击事件
pending,在点击时页面不跳转,只发出一个自定义的广播,然后有一个接收者
@Override public int onStartCommand(Intent intent, int flags, int startId) { //注册下面的广播接收者,自定义的action IntentFilter fileFilter = new IntentFilter("com.rjl.widget.update"); registerReceiver(new MyWidgetBroadcastReceiver(), fileFilter); //1.不是service而是provider widgetManager = AppWidgetManager.getInstance(WidgetUpdateService.this); //3.updateAppWidget的第一个参数应该是component的name provider = new ComponentName(WidgetUpdateService.this, ProcessManagerWidget.class); //4.updateAppWidget的第二个参数 views = new RemoteViews("com.rjl.mobilephonemanager",R.layout.processmanager_appwidget); timer = new Timer(); timer.schedule(new TimerTask() { @Override public void run() { //6.动态获取进程数,ram也可以获取 int count =GetProcessInfoUtils.getAllProcess(WidgetUpdateService.this); long ram = GetProcessInfoUtils.getAvailRam(WidgetUpdateService.this); //5.通过view找到控件 views.setTextViewText(R.id.tv_processwidget_count, count+"个进程"); views.setTextViewText(R.id.tv_processwidget_memory, ram/1024+"MB RAM"); //2.更新桌面控件 widgetManager.updateAppWidget(provider, views); } }, 1000, 3000); //3s更新一次 Intent myintent = new Intent("com.rjl.widget.update"); //widget的广播机制,经常需要pending,也就是说不是立即执行,需要去点击后助兴 //点击后还在当前页面,只发出一个广播,所以是getBroadcast,然后需要一个广播接收者 PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 100, myintent, PendingIntent.FLAG_UPDATE_CURRENT); views.setOnClickPendingIntent(R.id.btn_clear, pendingIntent); return super.onStartCommand(intent, flags, startId); } class MyWidgetBroadcastReceiver extends BroadcastReceiver{ @Override public void onReceive(Context context, Intent intent) { //此处应该去将后台应用杀掉,然后在更新count显示的数字 views.setTextViewText(R.id.tv_processwidget_count, "当前时间"+ System.currentTimeMillis()); widgetManager.updateAppWidget(provider, views); } }
这样子就可以随时清理线程了,而不用等半小时更新一次
相关文章推荐
- 当前我国经济体制改革形势
- Linux系统上Samba服务器的配置教程
- sql中distinct多列
- 高性能 CSS3 动画
- iOS 9: UIStackView入门
- 插入与改写
- 性能超美国10倍的中国射电天文望远镜
- Prism框架(三)——基于模块的应用程序开发
- Python 学习笔记12
- js判断checkbox状态,处理表单提交事件
- 新gre考试用什么复习资料?
- as3.0加载本地或网络上的图片
- 在Windows上访问Linux下的Samba服务器的方法
- Java 调用 C# DLL
- Samba:您没有权限访问的问题
- java 以及 vs 的快捷键
- 那些成功学和鸡汤文没有告诉你的
- From MSI to WiX, Part 2 - ARP support, by Alex Shevchuk
- 我国国民经济宏观景气周期初探
- 回答自己的提问