当前位置:首页 » 安卓系统 » android桌面widget

android桌面widget

发布时间: 2023-05-13 21:44:39

‘壹’ 如何在Android实现桌面清理内存简单Widget小控件

我们经常会看到类似于360、金山手机卫士一类的软件会带一个widget小控件,显示在桌面上,上面会显示现有内存大小,然后会带一个按键卖亮功能来一键清理内存,杀死后台进程的功能,那么这个功能是如何实现的呢,我们今天也来尝试做一个类似的功能的小控件。


效果图:

一、UI部分的编写:

参照Google的文档,首先在建立一个类继承 AppWidgetProvider


import android.appwidget.AppWidgetProvider;


public class MyWidget extends AppWidgetProvider {

}

然后在清单文件中申明它,我们必须注意到,AppWidgetProvider实际上是BroadcastReceiver,所以要注册成一个receiver,然后还有一些其他的东西需要注意:


<receiver android:name="com.alexchen.widget.MyWidget" >

<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>

android.appwidget.action.APPWIDGET_UPDATE


表明这个receiver能够接受一个APPWIDGET_UPDATE的广播,而且在这里,只能加入这一个action。

android.appwidget.provider 表明数据类型时widget提供者提供的数据, example_appwidget_info 表明这个widget的参数配置文件名和位置


那么接下来就需要在res目录下建立一个xml文件夹,并且在其中建立一个 example_appwidget_info.xml 的配置文件,Google的文档中给出了示例有很多参数,实际上关键的参数只有下面的4个:


<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"

android:minWidth="94dp"

android:minHeight="72dp"

android:updatePeriodMillis="86400000"

android:initialLayout="@layout/example_appwidget">

</appwidget-provider>

其中, minWidth 和 minHeight 代表这个widget控件所占据的最小空间,这个空间一般来讲不需要太大,因为太大的话,一个屏幕可能都没办法放下,Google的官汪陪方文档的说法是大于4x4的就可能无法显示。


updatePeriodMillis 代表数据更新的时间,这里86400000毫秒实际上是24小时,可能最开始看到这个参数会想我能否将其设的很小,每一秒刷新很多次?, 实际上对于 updatePeriodMillis 这个参数而言, 即算你设的再小也没用,Google设定widget控件这个参数控制的最短update时间为30分钟,就算将其设置在30分钟以内也会以30分钟的频率来更新数据。


initialLayout 参数代表的是本widget空间的布局文件。


那么下一步就是定义出一个对应的布局文件。我们可以简单的在layout目录下建立一个布局文件example_appwidget.xml


<?xml version="1.0" encoding="utf-8"?>

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"

android:layout_width="200dp"

android:layout_height="80dp"

android:background="@android:color/white"

android:gravity="center_vertical"

android:orientation="vertical" >


<TextView

android:id="@+id/tv_widget"

android:layout_width="fill_parent"

android:layout_height="wrap_content"

android:gravity="center"

android:text="widget控件测试"

android:textColor="@android:color/black"

android:textSize="15sp" />


<Button

android:id="@+id/btn_clear"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:layout_gravity="center_horizontal"

android:text="清理内存"

android:textColor="#ff000000" />


</LinearLayout>

‘贰’ 如何开发android 桌面widget 源代码

参考如下内容:
AppWidgetProvider类
AppWidgetProvider 继承自 BroadcastReceiver,它能接收 widget 相关的广播,例如 widget 的更新、删除、开启和禁用等。
AppWidgetProvider中的广播处理函数如下:
onUpdate()
当 widget 更新时被执行。同样,当用户首次添加 widget 时,onUpdate() 也会被调用,这样 widget 就能进行必要的设置工作(如果需要的话) 。但是,如果定义了 widget 的 configure属性(即android:config,后面会介绍),那么当用户首次添加 widget 时,onUpdate()不会被调用;之后更新 widget 时,onUpdate才会被调用。
onAppWidgetOptionsChanged()
当 widget 被初次添加 或者 当 widget 的大小被改变时,执行onAppWidgetOptionsChanged()。你可以在该函数中,根据 widget 的大小来显示/隐藏某些内容。可以通过 getAppWidgetOptions() 来返回 Bundle 对象以读取 widget 的大小信息,Bundle中包括以下信息:
OPTION_APPWIDGET_MIN_WIDTH – 包含 widget 当前宽度的下限,以dp为单位。
OPTION_APPWIDGET_MIN_HEIGHT – 包含 widget 当前高度的下限,以dp为单位。
OPTION_APPWIDGET_MAX_WIDTH – 包含 widget 当前宽度的上限,以dp为单位。
OPTION_APPWIDGET_MAX_HEIGHT – 包含 widget 当前高度的上限,以dp为单位。
onAppWidgetOptionsChanged() 是 Android 4.1 引入的。
onDeleted(Context, int[])
当 widget 被删除时被触发。
onEnabled(Context)
当第1个 widget 的实例被创建时触发。也就是说,如果用户对同一个 widget 增加了两次(两个实例),那么onEnabled()只会在第一次增加widget时触发。
onDisabled(Context)
当最后1个 widget 的实例被删除时触发。
onReceive(Context, Intent)
接收到任意广播时触发,并且会在上述的方法之前被调用。
总结,AppWidgetProvider 继承于 BroadcastReceiver。实际上,App Widge中的onUpdate()、onEnabled()、onDisabled()等方法都是在 onReceive()中调用的,是onReceive()对特定事情的响应函数。

‘叁’ 安卓桌面小部件Widget的局限性及适用性

一、Widget并不支持所有的控件跟布局,而仅仅只是支持Android布局和控件的一个子集。(当然也不支持自定义View)

1.支持的布局:

2.支持的控件:

二、Widget不支持Animation动画。

1.可以通过Bitmap、layoutAnimation和帧动画实现动画效果:

用这些方式虽然可以实现简单的动效,但是非常容易产生内存溢出问题,导致OOM和闪退。归根结底,Widget的设计是主打轻量化,需要长期放在桌面的Widget如果有大量动效,将会耗费大量系统性能和电量,这与它的设计初衷是相违背的。

2.动画效果和方位传感器测试:

动效:使用 setImageViewBitmap 方法设置简单的旋转动画,动画会在两基吵乎分钟后停止播放。

传感器:在应用进入后台,执行 onStop 方法时,方位传感器会在一分钟后停止监听回调,此时后台Service正常运行,Widget时间正常更新,但是方位传碰正感器不再回调监听。(经测试,开启前台Service才可以正常监听)

总结:非常不建议Widget需要动画或者调用传感器展示,在部分手机上会提示耗电异常,强制杀死程序。

三、进程保活:

进程保活涉及到的问题搏悉非常复杂,且越来越严格。测试了三款APP:

顺历:清除后台任务后Widget时间停止更新。

万年历:正常更新。

中华万年历:正常更新。

总结:顺历未设置保活方案,或保活失败。

万年历与中华万年历监听了系统时区改变广播、时间手动设置广播,在手动设置时间或时区后这两个Widget也同步更新。同时还有一个时间正常流逝的广播,系统每分钟会发送一次,但是这个广播在8.0系统以后不允许静态注册,也就是只能在APP运行的情况下才能监听这个广播。尚不清楚这两个APP如何保活,或是如何在8.0以上系统监听这个广播,达到即便杀死后台,也能每分钟刷新Widget时间的目的。

关键词“轻量化”

1.因为Widget主打轻量化,对动效支持较差,所以Widget界面以静态界面为主。

2.支持的布局和控件非常少,不支持自定义View,界面以简易布局为主。(如图片+文字)

3.实时性要求不高。(如每日一首古诗)

4.与用户简单互动。(如播放器的播放、暂停、下一曲)

‘肆’ androidwidget有用吗

1.身材微:它们一般都很小,在终端上嵌入非常方便,运行快速。
2.形式多:Widget可以以多种形式呈现出来,幻灯秀、视频、地图、新闻、小游戏……
3.功能巨:别看它们小,却服务周到,它可以为你报告新闻、帮你买东西、列出你最喜欢的乐队,还有你最近看的视频。另外,它还是一个殷勤的管家,你不必亲自去Flickr或者天气预报网站,Widget会将信息主动带给你。
4.姿容丽:它们可以称得上玉面飞龙、以色服人。只要你愿意,你可以把它变成任何你想要得样子。它的出现,无异于一枚“桌面炸弹”,狭窄而单调的IE窗口将被更为广阔和绚丽的桌面空间所取代。
5.个性化:Widget更像一个属于我们每个人的魔方,任由用户聚合。你可以根据自己喜好,将多个Widget,随心所欲的去精心组装你的网络世界。通过Widget,可以用户把一切在“网”中的内容打乱重来,并按照用户希望看到的样子重新排列组合一个属于自己的互联网。比如说一个由微件搭建个人空间,可以包括来自新浪的体育新闻,来自论坛的一个板块,来自权威财经网站的一则随时更新的股票信息 ——这些以往需要用户同时分别进入几个网站才能看到的信息,现在由一个个微件将其转变为用户个人空间的一部分,从而可以直接在同一个页面中并存。传统互联网访问方式处于分裂状态的后Web2.0时期,多样性、炫酷且更具个性化的Widget流行,或许能引领一个新的潮流。
6.易制作:制作 Widget 部件并不复杂,只需要熟悉三方面的知识:图像处理、HTML/XML、java,就可以按照开发站点里的教程做出漂亮的部件来。Widget能够流行的一个要点在于开放制作,UGC应用带来爆炸式地增长。
那么,什么是android widget呢?
在Android 1.5 SDK preview中,我们看到了一系列功能和API上的变化变化,包括软键盘、桌面Widget和Live Folder API、视频录制API,蓝牙功能升级等,Google近来对于这些全新功能的解析使得Android开发者blog变得异常活跃。上周,Jeff Sharkey就有一篇对于Android桌面widget和AppWidget框架的简介,以“Word of the day”的一个例子讲述了桌面Widget的运作机制。昨天他又在个人blog上放出了一个天气预报Widget的例子,事实上这已经是一个真正实用的程序了。它每天更新4次天气预报,我们可以添加多个Widget来关注多个城市的天气情况,另外,点击Widget后我们还可以看到今后几天的详细预报。
这让我想起了HTC Source的Nick Gray上周的一篇文章Android Widgets, Unlimited Potential中提到的几类可能会大受欢迎的Android桌面Widget。
Android本身已经自带了时钟、音乐播放器、相框和Google搜索4个Widget程序,不过这并不能阻止大家开发自己更加美观,功能更丰富的版本。另外,微博客、RSS订阅、股市信息、天气预报这些Widget也都有流行的可能。
微博客Widget:Twidroid是Android上迄今为止最棒的Twitter客户端,大家显然都期待着它会推出支持桌面Widget的版本,另外像国内比较受欢迎的饭否、嘀咕、叽歪等应该也会有类似的Widget推出。对于一个微博客类的Widget来说,有两个方面是必不可少的,一是用来发布消息,另一个则是用来浏览。
RSS订阅Widget: 尽管微博客(尤其是Twitter)已经完全盖过来RSS订阅的风头,越来越多的人用Twitter来跟踪站点的更新,不过RSS订阅也并非完全没有了市场,像分类订阅这样的功能还是需要RSS来帮忙,另外站点管理员也未必会在Twitter上发布所有的更新。
股市信息Widget:对于炒股的人来说,大概没有什么能比在手机桌面上放上几个所关注股票的实时股价更有运筹帷幄的感觉了吧。
天气预报Widget:对于我这样成天窝在办公室或者家里的人来说,有一个Widget能够让我了解当前的天气和近1、2天的天气是非常有用的,这大概会大大减少我下了楼又跑回去拿雨伞的几率。如果能加上像TouchFLO 3D中那样的UI效果,当然就更酷了。
这只是我现在想到的一些Widget,得益于Android 1.5为我们提供的Widget API为我们的手机桌面带来的无限的可能,我们的手机桌面无疑将会更有趣。
对国内G1的用户,如果想体验Android 1.5的桌面Widget,可以看看Haykuro的blog,他正在为制作G1可用的Android 1.5 ROM而努力。另外,T-Mobile已经计划在五月向德国的T-Mobile G1用户推送1.5的更新了,所以即使到时候没有官方的G1简体中文1.5 ROM,相信Haykuro的 1.5 ROM for G1也能非常接近官方的成熟度。
Widget应用目前在Android手机上得到了广泛的应用。由于其方便小巧,所以得到了很多的应用,像天气,微博,信息,歌曲,时间等等。
关于android Wpp widget:
应用程序窗口小部件(Widget)是微小的应用程序视图,可以被嵌入到其它应用程序中(比如桌面)并接收周期性的更新。你可以通过一个App Widget provider来发布一个Widget。可以容纳其它App Widget的应用程序组件被称为App Widget宿主。下面的截屏显示了一个音乐App Widget。

‘伍’ Android桌面小部件AppWidget开发

在Android我们经常可以看到各种桌面小部件,比如时钟、天气、音乐播放器等等。我们可以使用AppWidgetProvider来实现小部件的开发。

开发一个桌面小部件的步骤:

在res/layout/下新建一个布局文件,名称和内容自定义,看你想把小工具做成什么样。需要注意的是系统默认的小工具布局中只支持以下这些标签,如果用了列表以外的标签,会导致小工具加载错误:

比如,我们创建了一个名为widget_layout.xml的布局文件:

定义小部件的配置信息需要在res目录下新建一个xml目录,然后在res/xml/目录下创建一个配置文件,配置文件名称随意。新建app_widget_provider_info.xml:

上面的参数意义很明确,initialLayout指小部件的初始化布局,一般与最终布局相同;minHeight和minWidth定义了小部件的最小宽高,与小部件所占网格大小有关;previewImage可以指定在添加小部件时看到的预览图;updatePeriodMillis指定了小部件的自动更新周期,单位为毫秒。

其中minHeight和minWidth的定义可以参考官方文档: https://developer.android.com/guide/practices/ui_guidelines/widget_design.html#design

OK,小部件完成了,运行一下看看效果:

‘陆’ 如何在Android实现桌面清理内存简单Widget小控件

一、UI部分的编写:
参照Google的文档,首先在建立一个类继承 AppWidgetProvider
import android.appwidget.AppWidgetProvider;

public class MyWidget extends AppWidgetProvider {

}

然后在清单文件中申明它,我们必须注意到,AppWidgetProvider实际上是BroadcastReceiver,所以要注册成一个receiver,然后还有一些其他的东西需要注意:
<receiver android:name="com.alexchen.widget.MyWidget" >
<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>

android.appwidget.action.APPWIDGET_UPDATE
表明这个receiver能够接受一个APPWIDGET_UPDATE的广播,而且在这里,只能加入这一个action。
android.appwidget.provider 表明数据类型时widget提供者提供的数据,example_appwidget_info 表明这个widget的参数配置文件名和位置
那么接下来就需要在res目录下建立一个xml文件夹,并且在其中建立一个example_appwidget_info.xml 的配置文件,Google的文档中给出了示例有很多参数,实际上关键的参数只有下面的4个:
<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
android:minWidth="94dp"
android:minHeight="72dp"
android:updatePeriodMillis="86400000"
android:initialLayout="@layout/example_appwidget">
</appwidget-provider>

其中, minWidth 和 minHeight 代表这个widget控件所占据的最小空间,这个空间一般来讲不需要太大,因为太大的话,一个屏基陵幕可能都没办法放下,Google的官方文档的说法是大于4x4的就可能无法显示。
updatePeriodMillis 代表数据更新的时间,这里86400000毫秒实际上是24小时,可能最开始看到这个参数会想我能否将其设的很小,每一秒搏纤戚刷新很多次?, 实际上对于updatePeriodMillis 这个参数而言, 即算你设的再小也没用,Google设定widget控件这个参数控制的最短update时间为30分钟,就算将其设置在30分钟以内也会以30分钟的频率来更新数据。
initialLayout 参数代表的是本widget空间的布局文件。
那么下一步就是定义出一个对应的布局文件。我们可以简单的在layout目录下建立一个布局文件example_appwidget.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="200dp"
android:layout_height="80dp"
android:background="@android:color/white"
android:gravity="竖旅center_vertical"
android:orientation="vertical" >

<TextView
android:id="@+id/tv_widget"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:text="widget控件测试"
android:textColor="@android:color/black"
android:textSize="15sp" />

<Button
android:id="@+id/btn_clear"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:text="清理内存"
android:textColor="#ff000000" />

</LinearLayout>

在Google的文档中有指出,并非所有的布局组件都可以在上面的这个布局中生效,有效的组件或布局为:
FrameLayout
LinearLayout
RelativeLayout
GridLayout
AnalogClock
Button
Chronometer
ImageButton
ImageView
ProgressBar
TextView
ViewFlipper
ListView
GridView
StackView
AdapterViewFlipper
至此,一个简单的widget控件就写好了,我们可以在模拟器上将其拖到桌面上看一看效果:

二、功能逻辑部分的实现
大部分的Widget小控件都会需要在特定情况下更新上面显示的数据,那么这个是如何实现的呢,我们经过上面的代码不难发现实际上这个widget控件并没有一个Activity,所以说这个控件的显示实际上不是本应用来实现的,它实际上是桌面这个应用来显示的,所以我们也不可能直接去更新它上面的数据。
回过头去看看上面我们写的那个receiver,实际上没有实现任何方法。实际上AppWidgetProvider里面有几个比较重要的方法: onReceive、 onUpdate、onDisabled、onEnabled
其中 onReceive 方法跟大多数广播接收者的onReceive方法一样,但是在这里,onReceive方法的调用并不是我们可以决定的, 它依赖于显示该widget控件的Host组件,在这里也就是Android桌面应用,所以我们会发现在不同的手机上,将widget控件拖到桌面上显示的时候onReceive可能调用的次数和先后顺序可能完全不一样,这依赖于Host组件是如何实现的。
所以在这里onReceive方法对于我们刷新widget数据基本没有什么帮助。
而 onUpdate 方法则是由上面所说的 updatePeriodMillis 参数来控制的,经过上面的分析,我们都知道了,它的最小周期为30分钟。所以我们一般将这个参数设为0即可。那么在这个方法里,我们往往会在其中放置一些启动更新数据服务的功能,因为如果后台的更新数据的Service被意外停止了,那么每30分钟还会被重新启用,不至于一直启动不了了:
@Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager,
int[] appWidgetIds) {
super.onUpdate(context, appWidgetManager, appWidgetIds);
// System.out.println("onUpdate");
//每隔一段时间重新启动服务,防止服务中间被终止了之后没法重启
Intent intent = new Intent(context, UpdateWidgetService.class);
context.startService(intent);
}

下面是比较重要的两个方法了:
onDisabled和onEnabled
我们知道,widget 小控件是可 以拖动多个到桌面上的,而 onEnabled 方法会在第一个widget控件拖到桌面上的时候调用一次, onDisabled 会在最后一个widget控件从桌面被删除时调用一次,那么我们需要做的就是在 onEnabled 这个方法中启用一个刷新widget数据的服务,在 onDisabled 方法中使用 stopService 方法来停止这个服务。
@Override
public void onDisabled(Context context) {
super.onDisabled(context);
System.out.println("onDisabled");
//停止数据刷新服务
Intent intent = new Intent(context, UpdateWidgetService.class);
context.stopService(intent);
}

@Override
public void onEnabled(Context context) {
super.onEnabled(context);
System.out.println("onEnabled");
//开启数据刷新服务
Intent intent = new Intent(context, UpdateWidgetService.class);
context.startService(intent);
}

三、刷新数据的服务
那么下面的任务就只剩下 UpdateWidgetService 这个刷新数据的服务(Service)如何实现的问题了。
我们在这里的想法很简单,比如说每隔三秒钟来刷新一下widget中的数据。Android中定时执行任务的方法有很多,我们这里使用 Timer 和 TimerTask 来实现,之后我们需要关心的就是具体如何实现刷新widget中的数据,毕竟这些数据是在桌面应用中显示的。
并且我们需要用到一个API-- AppWidgetManager ,它有一个实例方法AppWidgetManager .updateAppWidget( ComponentName provider, RemoteViews views) 来实现更新widget数据,我们都知道,如果需要调用另外应用的方法,需要使用远程调用的方法来实现,在这里起到在我们的应用和桌面应用之间的桥梁作用的就是这第二个参数:RemoteViews views, 它会将我们设置的数据传送到桌面应用来刷新widget上的数据,我们需要经过下面几步:
1、定义一个RemoteViews的实例:
RemoteViews views = new RemoteViews(getPackageName(),R.layout.process_widget);
2、设置views的内容,也就是刷新其中的数据,这里的方法名会比较奇怪,RemoteViews .setTextViewText( int viewId, CharSequence text)
其中viewId是在我们前面定义的widget布局文件中的子组件的id,也就是我们要刷新内容的对象,这里就是R.id.tv_test,第二个参数是我们要更新的内容
3、定义好第一个参数ComponentName provider 之后,就可以调用AppWidgetManager .updateAppWidget( ComponentName provider, RemoteViews views) 来实现更新数据
if (timer == null && task == null) {
//AppWidgetManager对象,用于更新widget的数据
awm = AppWidgetManager.getInstance(this);
timer = new Timer();
task = new TimerTask() {
@Override
public void run() {
ComponentName provider = new ComponentName(UpdateWidgetService.this, MyWidget.class);
//远程view对象,用于在本应用和桌面应用中起传递数据的桥梁作用
RemoteViews views = new RemoteViews(getPackageName(),R.layout.example_appwidget);
views.setTextViewText(R.id.tv_widget, "想刷新的数据的内容");
awm.updateAppWidget(provider, views);
System.out.println("====刷新了widget====");
}
//设置循环时间
timer.schele(task, 0, 3000);
}

四、定时刷新可用内存和一键清理内存功能实现
要实现这个功能,我们需要再上面定时刷新数据服务中将定时刷新的内容改为当前内存所剩余的量,我们这里写一个工具类方法来实现返回内存剩余量;
另外我们还需要在widget控件的布局文件中添加一个button,并在更新widget数据的服务中,设置这个button的点击事件,但是这里也不像以前的点击事件,同样要应用到RemoteView对象,在这个点击事件中需要发送一个广播,Action为自定义的,我们这里设为: "com.alexchen.mobilesafeexercise.killall" ,之后,我们需要再写一个广播接收者,来接收这个广播,在onReceive方法中执行杀死后台进程的操作。这里也不能直接使用Intent,由于我们这个意图的Action不是由我们自己执行而是由其他应用程序(桌面应用)执行的,所以需要用到 PendingIntent 。
刷新widget数据的服务代码:
package com.alexchen.widget.service;

import java.util.Timer;
import java.util.TimerTask;

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.widget.RemoteViews;

import com.alexchen.widget.MyWidget;
import com.alexchen.widget.R;
import com.alexchen.widget.utils.SystemInfoUtils;

public class UpdateWidgetService extends Service {
private Timer timer;
private TimerTask task;
private AppWidgetManager awm;

@Override
public IBinder onBind(Intent intent) {
return null;
}

@Override
public void onCreate() {
super.onCreate();
startTimer();
}

private void startTimer() {
if (timer == null && task == null) {
awm = AppWidgetManager.getInstance(this);
timer = new Timer();
task = new TimerTask() {

@Override
public void run() {
ComponentName provider = new ComponentName(
UpdateWidgetService.this, MyWidget.class);
RemoteViews views = new RemoteViews(getPackageName(),
R.layout.example_appwidget);
views.setTextViewText(R.id.tv_widget, "dd");
views.setTextViewText(R.id.tv_widget,
"可用内存:"+ Formatter.formatFileSize(getApplicationContext(),
SystemInfoUtils.getAvailableMem(getApplicationContext())));
// 自定义一个广播,杀死后台进程的事件
Intent intent = new Intent();
intent.setAction("com.alexchen.mobilesafeexercise.killall");

// 描述一个动作,这个动作是由另外一个应用程序执行的
PendingIntent pendingIntent = PendingIntent.getBroadcast(
getApplicationContext(), 0, intent,
PendingIntent.FLAG_UPDATE_CURRENT);
views.setOnClickPendingIntent(R.id.btn_clear, pendingIntent);
awm.updateAppWidget(provider, views);
System.out.println("====刷新了widget====");
}
};
timer.schele(task, 0, 3000);
}
}
@Override
public void onDestroy() {
super.onDestroy();
stopTimer();
unregisterReceiver(offReceiver);
unregisterReceiver(onReceiver);
}

private void stopTimer() {
if (timer != null && task != null) {
timer.cancel();
task.cancel();
task = null;
timer = null;
}
}
}

按键清理内存的广播接收者:
package com.alexchen.widget.receiver;

import java.util.List;

import android.app.ActivityManager;
import android.app.ActivityManager.RunningAppProcessInfo;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;

public class KillAllReceiver extends BroadcastReceiver {

@Override
public void onReceive(Context context, Intent intent) {
System.out.println("自定义的广播消息接收到了...开始清理内存...");
ActivityManager am = (ActivityManager) context
.getSystemService(Context.ACTIVITY_SERVICE);
List<RunningAppProcessInfo> runningAppProcesses = am
.getRunningAppProcesses();
for (RunningAppProcessInfo info : runningAppProcesses) {
am.killBackgroundProcesses(info.processName);
}
}
}

获取可用内存的工具类方法:
/**
* 获取手机可用的剩余内存
*
* @param context
* 上下文
* @return
*/
public static long getAvailableMem(Context context) {
ActivityManager am = (ActivityManager) context
.getSystemService(Context.ACTIVITY_SERVICE);
MemoryInfo outInfo = new MemoryInfo();
am.getMemoryInfo(outInfo);
return outInfo.availMem;
}

热点内容
内置存储卡可以拆吗 发布:2025-05-18 04:16:35 浏览:336
编译原理课时设置 发布:2025-05-18 04:13:28 浏览:378
linux中进入ip地址服务器 发布:2025-05-18 04:11:21 浏览:612
java用什么软件写 发布:2025-05-18 03:56:19 浏览:32
linux配置vim编译c 发布:2025-05-18 03:55:07 浏览:107
砸百鬼脚本 发布:2025-05-18 03:53:34 浏览:944
安卓手机如何拍视频和苹果一样 发布:2025-05-18 03:40:47 浏览:741
为什么安卓手机连不上苹果7热点 发布:2025-05-18 03:40:13 浏览:803
网卡访问 发布:2025-05-18 03:35:04 浏览:511
接收和发送服务器地址 发布:2025-05-18 03:33:48 浏览:372