桌面小控件(Widget)--之清理进程

首先,简单的说一下什么是Widget,Widget是在Android系统界面中添加的小部件。那么在android中有一个系统内置服务来专门管理widget,该服务为AppWidgetManager。


建立widget的步骤如下:
1.建立一个工程,然后写一个类继承AppWidgetProvider并重写onEnabled(),onUpdate(),onDisabled()方法
classTimeWidgetProviderextendsAppWigetProvider
{
}
2.AppWigetProvider是一个广播接者。在配置文件中进行配置:
<receiverandroid:name=".receiver.MyWidget">
<intent-filter>
<actionandroid:name="android.appwidget.action.APPWIDGET_UPDATE"/>
</intent-filter>
<meta-dataandroid:name="android.appwidget.provider“
android:resource="@xml/appwidget_info"/>
</receiver>
3.在res文件夹下建一个xml文件夹,放置一个appwidget_info.xml该文件为widget的界面
在桌上第一个添加该widget时系统会发出一个广播,该广播会被我们定义的TimeWidgetProvider所接收,并执行onEnabled()方法,该widget添加后会发出一个广播,该广播的类型为:
android.appwidget.action.APPWIDGET_UPDATE会执行onUpdate()方法,当桌面上同类型的Widget的最后一个被删除时会执行onDisabled()方法.
在onUpate()方法中可以更改widget界面上的内容.

效果图如下:

当我们点击一键清理的时候,就会把手机的一些正在运行的进程结束掉,当然用户系统在没有获得root权限之前是不可以结束掉的。

步骤一

写一个类,继承AppWidgetProvider

package cn.cbd.clean;import android.appwidget.AppWidgetManager;import android.appwidget.AppWidgetProvider;import android.content.Context;import android.content.Intent;public class CleanWidget extends AppWidgetProvider{private Intent service;@Overridepublic void onDeleted(Context context, int[] appWidgetIds){super.onDeleted(context, appWidgetIds);}@Overridepublic void onDisabled(Context context){//停止服务service = new Intent(context, MyService.class);context.stopService(service);super.onDisabled(context);}@Overridepublic void onEnabled(Context context){//开启服务service = new Intent(context, MyService.class);context.startService(service);super.onEnabled(context);}@Overridepublic void onReceive(Context context, Intent intent){super.onReceive(context, intent);}@Overridepublic void onUpdate(Context context, AppWidgetManager appWidgetManager,int[] appWidgetIds){// TODO Auto-generated method stubsuper.onUpdate(context, appWidgetManager, appWidgetIds);}}

AppWidgetProvider也是一个广播接收者,所以我们要在清单文件中对CleanWidget进行配置

<applicationandroid:icon="@drawable/ic_launcher"android:label="@string/app_name" ><receiver android:name=".CleanWidget" ><intent-filter><action android:name="android.appwidget.action.APPWIDGET_UPDATE" /></intent-filter><!-- meta-data  携带数据 传递数据用的 --><meta-dataandroid:name="android.appwidget.provider"android:resource="@xml/example_appwidget_info" /></receiver>

在类CleanWidget中我们可以看到,我们在ouEnabled()方法中开启一个服务,在onDisabled()中关闭这个服务,当我们把小控件拖到桌面上的时候,就会先执行onReceive然后紧接着执行onEnable()方法,当我们把桌面上相同的最后一个控件删除,就会执行onDisabled()方法。

那我们在服务中做哪些事情呢?

package cn.cbd.clean;import java.util.ArrayList;import java.util.List;import java.util.Timer;import java.util.TimerTask;import android.app.ActivityManager;import android.app.PendingIntent;import android.app.Service;import android.app.ActivityManager.RunningAppProcessInfo;import android.appwidget.AppWidgetManager;import android.content.ComponentName;import android.content.Context;import android.content.Intent;import android.os.IBinder;import android.text.format.Formatter;import android.widget.RemoteViews;public class MyService extends Service{private List<String> packageNames;private static final String BUTTON_KILLPROCESS = "cn.cbd.KILLPROCESS";private Timer timer;@Overridepublic void onCreate(){//新建一个计时器,来不断的监听手机正在运行程序的个数是否发生改变timer = new Timer();timer.schedule(new TimerTask(){public void run(){//新建一个String类型集合,来存放正在运行程序的包名(我们结束进程是需要通过应用程序的包名来结束的)。packageNames = new ArrayList<String>();//获取AppWidgetManager控件管理者对象AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(getApplicationContext());ActivityManager am = (ActivityManager) getApplicationContext().getSystemService(Context.ACTIVITY_SERVICE);List<RunningAppProcessInfo> infos = am.getRunningAppProcesses();for (RunningAppProcessInfo info : infos){packageNames.add(info.processName);}//对于本应用来说,桌面的控件属于远程View了,所以我们需要一个RemoteViews对象,来管理我们自定义ViewRemoteViews views = new RemoteViews(getApplicationContext().getPackageName(), R.layout.memorycleanning);//设置控件上的文字内容views.setTextViewText(R.id.tv_runningAppNums, "正在运行程序有"+ (packageNames.size() + "个"));views.setTextViewText(R.id.tv_availableMemory,"剩余内存"+ Formatter.formatFileSize(getApplicationContext(),MemoryUtil.getAvailableMem(getApplicationContext())));//当我们点击一键清理按钮时发送一个自定义广播,类型为cn.cbd.KILLPROCESS 配置文件中也要进行相应的配置Intent intent = new Intent();intent.setAction(BUTTON_KILLPROCESS);PendingIntent pendingIntent = PendingIntent.getBroadcast(getApplicationContext(), 0, intent,PendingIntent.FLAG_UPDATE_CURRENT);//为小控件上的按钮设置点击事件views.setOnClickPendingIntent(R.id.btn_clean, pendingIntent);ComponentName componentName = new ComponentName(getApplicationContext(), CleanWidget.class);//更新AppAidget 也就是更新桌面控件中的内容appWidgetManager.updateAppWidget(componentName, views);}}, 0, 10);super.onCreate();}@Overridepublic IBinder onBind(Intent intent){return null;}@Overridepublic void onDestroy(){super.onDestroy();}}

自定义广播在配置文件中的配置情况

<!-- 广播接收者 自定义了一种广播 --><receiver android:name=".KillProcessBroadcaseReceiver" ><intent-filter><action android:name="cn.cbd.KILLPROCESS" /></intent-filter></receiver>

此时,显然我们要写一个广播接收者,来接收我们这种类型的广播

package cn.cbd.clean;import java.util.ArrayList;import java.util.List;import android.app.ActivityManager;import android.app.ActivityManager.RunningAppProcessInfo;import android.appwidget.AppWidgetManager;import android.content.BroadcastReceiver;import android.content.ComponentName;import android.content.Context;import android.content.Intent;import android.text.format.Formatter;import android.widget.RemoteViews;public class KillProcessBroadcaseReceiver extends BroadcastReceiver{private List<String> packageNames;@Overridepublic void onReceive(Context context, Intent intent){packageNames = new ArrayList<String>();RemoteViews views = new RemoteViews(context.getPackageName(),R.layout.memorycleanning);AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context);ActivityManager am = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);List<RunningAppProcessInfo> infos = am.getRunningAppProcesses();for (RunningAppProcessInfo info : infos){packageNames.add(info.processName);}String action = intent.getAction();if (action.equals("cn.cbd.KILLPROCESS")){for (String packageName : packageNames){am.killBackgroundProcesses(packageName);}ComponentName componentName = new ComponentName(context,CleanWidget.class);views.setTextViewText(R.id.tv_runningAppNums, "正在运行程序有"+ packageNames.size() + "个");views.setTextViewText(R.id.tv_availableMemory,"剩余内存"+ Formatter.formatFileSize(context,MemoryUtil.getAvailableMem(context)));appWidgetManager.updateAppWidget(componentName, views);}}}

在这个广播中,我们会用到一个工具类,就是获取手机RAM剩余内存大小的。这个类是我们自定义的工具类。

package cn.cbd.clean;import android.app.ActivityManager;import android.app.ActivityManager.MemoryInfo;import android.content.Context;/*** 工具类,用来获取手机剩余内存大小* @author Administrator**/public class MemoryUtil{//Formatter.formatFileSize(this,availaleMemory) 格式化public static long getAvailableMem(Context context){ActivityManager am = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);MemoryInfo outInfo= new MemoryInfo();am.getMemoryInfo(outInfo);return outInfo.availMem;}}

到此呢,我们这个清理手机进程的小控件已经完成。现在呢,我整理一下这个小项目的思路:

1.得到一个Widget对象(继承AppWidgetProvider)

2.开启一个服务,来更新控件上数据的变化

3.在服务中定义一个广播,当我们点击“一键清理”按钮时,就会发送一个广播。这时候呢,需要我们写一个广播接收者,来接收我们定义的这种类型的广播。

4.在广播中,我们做杀掉进程的操作。

更多相关文章

  1. 详解如何让Android(安卓)UI设计性能更高效
  2. 基于Android平台下的科学计算器
  3. android 7.0 ,6.0本地多语言切换失效
  4. Android底部菜单栏的实现
  5. android 中定时器的几种用法总结
  6. Android(安卓)中TextView 添加超链接
  7. android内核编译方法 转载
  8. android中MediaPlayer的用法
  9. Android梳理不常用widget篇

随机推荐

  1. Android遇到No external storage availab
  2. Android代码风格(Android属性前缀m的意思)
  3. Android(安卓)AIDL实现两个APP间的跨进程
  4. Android中bindService()启动Service的过
  5. 通信组件之Intent的基本使用
  6. Android(安卓)Studio提示端口号5037被占
  7. 通过GridView仿微信动态添加本地图片
  8. android RecyclerView实现列表定位
  9. Android文件存储和读取方式
  10. Android(安卓)简单实现订单模块类APP的物