您的位置:首页 > 移动开发

widget的进一步使用,利用AppWidgetProvider实现桌面的时钟挂件

2016-10-17 10:08 831 查看
1、通过上面介绍widget的基本应用外面知道,系统最多30分钟才更新挂件的内容,为了实时更新时钟我们必须自己发送广播来实现挂件内容的更新,其方法就是覆写父类AppWidgetProvider的onReceive()方法,并在注册的广播接收的intent-fliter里添加接受自己的广播。

2、用过查看Mainfest文件知道广播接受原始只注册了android.appwidget.action.APPWIDGET_UPDATE,但是可以接收android.appwidget.action.APPWIDGET_ENABLED,android.appwidget.action.APPWIDGET_DISENABLED,猜想AppWidgetProvider里的接受者在系统里已经注册了接收这些广播,而我写的类继承它,因此也可以接收。

3、当我去掉注册的android.appwidget.action.APPWIDGET_UPDATE只保留我自己添加的更新时间的广播时候却收不到android.appwidget.action.APPWIDGET_UPDATE等一些广播了并且在widget里找不到我定义的挂件了。猜想在系统定义了相应的规则,必须注册了的广播中含有android.appwidget.action.APPWIDGET_UPDATE,且注册的类必须继承了AppWidgetProvider才会在系统里注册一个挂件,并且继承的类可以收到AppWidgetProvider接受的广播。

4、 当我们在存储widgetId时候数据不加static时候发现每次接收到信号时候widgetIds这个集合的size都为0,表明每次接受到广播后就重新创建了NewAppWidge这个类对象。因此在广播类中重要的数据得用static变量。

5 广播机制:广播在mainfest里注册后,当接受到相应的广播后就会创建相应注册在receiver的类,然后由这些类的onreceiver来处理,处理后当系统内存不足的时候就会回收这个对象,然后下次收到的时候就会再次重新创建对象。

下面给出实现的demo:

widget类:

package com.example.user.appwidget;

import android.app.PendingIntent;
import android.appwidget.AppWidgetManager;
import android.appwidget.AppWidgetProvider;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.widget.RemoteViews;
import android.widget.TextView;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.Comparator;

/**
* Implementation of App Widget functionality.
*/
public class NewAppWidget extends AppWidgetProvider {

private final  static  String Action_UpDateTime ="android.appwidget.action.APPWIDGET_UPDATE";
private final  static  String Action_Enable ="android.appwidget.action.APPWIDGET_ENABLED";
private  static  ArrayList<Integer> widgetIds = new ArrayList<>();

private static boolean  HasUpdateThread = false;
Thread upWidget= null;

@Override
public void onReceive(Context context, Intent intent) {

int size = widgetIds.size();
int [] widgetIdArray =  new int [size];
for(int i = 0 ; i < size ; i++)
{
widgetIdArray[i] = widgetIds.get(i);
}

onUpdate(context , AppWidgetManager.getInstance(context) , widgetIdArray );

System.out.println("收到了广播" + intent.getAction());

super.onReceive(context, intent);
}

static void updateAppWidget(Context context, AppWidgetManager appWidgetManager,
int appWidgetId) {
Calendar c = Calendar.getInstance();
int hour = c.get(Calendar.HOUR_OF_DAY);
int minute = c.get(Calendar.MINUTE);
int seconds = c.get(Calendar.SECOND);
CharSequence widgetText = "Time:" + hour + ":" + minute + ":" + seconds;//context.getString(R.string.appwidget_text);
// Construct the RemoteViews object
RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.new_app_widget);
views.setTextViewText(R.id.appwidget_text, widgetText);

// Instruct the widget manager to update the widget
appWidgetManager.updateAppWidget(appWidgetId, views);
}

// 到达指定更新时间(new_app_widget_info.xml中指定的,大于30分钟才有效,小于30分钟会30分钟执行一次)
// 或者向桌面添加Widget时候执行
@Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
// There may be multiple widgets active, so update all of them
for (int appWidgetId : appWidgetIds)
{
updateAppWidget(context, appWidgetManager, appWidgetId);
if(!widgetIds.contains((Integer)appWidgetId))
{
System.out.println("不含有挂件"+appWidgetId);
widgetIds.add((Integer) appWidgetId);
}
else
System.out.println("含有挂件"+appWidgetId);
}
if (!HasUpdateThread)
{
System.out.println("创建了一个进程");HasUpdateThread =true;
upWidget = new UpDateWiget(context);
upWidget.start();

}
}

//当第一个widget创建时候执行
@Override
public void onEnabled(Context context) {
// Enter relevant functionality for when the first widget is created
//        System.out.println("1111111111111111111111111111111111111111111111");

}

//当最后一个widget实例被删除时执行
@Override
public void onDisabled(Context context) {
// Enter relevant functionality for when the last widget is disabled
}

class UpDateWiget extends Thread {
//        public int widgetId;
public Context context;

public UpDateWiget(Context context) {
//            this.widgetId = widgetId;
this.context = context;
}

@Override
public void run() {
while (true) {
Intent intent = new Intent("android.appwidget.action.APPWIDGET_UPDATETIME");
//                intent.putExtra("wigetId", widgetId);
try {
sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("发送了一条广播");
context.sendBroadcast(intent);
}
}
}

}


  挂件的布局文件:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#09C"
android:padding="@dimen/widget_margin">

<TextView
android:id="@+id/appwidget_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:layout_margin="8dp"
android:background="#09C"
android:contentDescription="@string/appwidget_text"
android:text="ca"
android:textColor="#ffffff"
android:textSize="20dp"
android:textStyle="bold|italic" />

</RelativeLayout>


  mainfset里注册的广播:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.user.appwidget">

<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />

<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>

<receiver android:name=".NewAppWidget">
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
<action android:name="android.appwidget.action.APPWIDGET_UPDATETIME"/>
</intent-filter>

<meta-data
android:name="android.appwidget.provider"
android:resource="@xml/new_app_widget_info" />
</receiver>

</application>

</manifest>


  
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: