1.定义AppWidgetProvider
package com.sineva.rosapidemo.widget; import android.appwidget.AppWidgetManager; import android.appwidget.AppWidgetProvider; import android.content.Context; import android.content.Intent; import android.net.Uri; import android.os.Bundle; import android.util.Log; import android.widget.RemoteViews; import android.widget.Toast; import com.sineva.rosapidemo.R; import java.util.HashSet; import java.util.Iterator; import java.util.Set; /** * Created by Eligah on 2017/9/29. */ public class RobotControllerWidgetProvider extends AppWidgetProvider { private static final String TAG = "WidgetProvider"; private boolean DEBUG = false; private final Intent EXAMPLE_SERVICE_INTENT = new Intent("android.appwidget.action.SLAM_APP_WIDGET_SERVICE"); private final String ACTION_UPDATE_ALL = "com.sineva.widget.UPDATE_ALL"; private static Set idsSet = new HashSet(); private static final int BUTTON_SHOW = 1; @Override public void onReceive(Context context, Intent intent) { final String action = intent.getAction(); Log.d(TAG, "OnReceive:Action: " + action); if (ACTION_UPDATE_ALL.equals(action)) { updateAllAppWidgets(context, AppWidgetManager.getInstance(context), idsSet); } else if (intent.hasCategory(Intent.CATEGORY_ALTERNATIVE)) { // “按钮点击”广播 Uri data = intent.getData(); int buttonId = Integer.parseInt(data.getSchemeSpecificPart()); if (buttonId == BUTTON_SHOW) { Log.d(TAG, "Button wifi clicked"); Toast.makeText(context, "Button Clicked", Toast.LENGTH_SHORT).show(); } } super.onReceive(context, intent); } @Override public void onEnabled(Context context) { Log.d(TAG, "onEnabled"); EXAMPLE_SERVICE_INTENT.setPackage(context.getPackageName()); context.startService(EXAMPLE_SERVICE_INTENT); super.onEnabled(context); } @Override public void onAppWidgetOptionsChanged(Context context, AppWidgetManager appWidgetManager, int appWidgetId, Bundle newOptions) { Log.d(TAG, "onAppWidgetOptionsChanged"); super.onAppWidgetOptionsChanged(context, appWidgetManager, appWidgetId, newOptions); } @Override public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) { Log.d(TAG, "onUpdate(): appWidgetIds.length=" + appWidgetIds.length); for (int appWidgetId : appWidgetIds) { idsSet.add(Integer.valueOf(appWidgetId)); } prtSet(); } @Override public void onDisabled(Context context) { Log.d(TAG, "onDisabled"); context.stopService(EXAMPLE_SERVICE_INTENT); super.onDisabled(context); } @Override public void onDeleted(Context context, int[] appWidgetIds) { Log.d(TAG, "onDeleted(): appWidgetIds.length=" + appWidgetIds.length); for (int appWidgetId : appWidgetIds) { idsSet.remove(Integer.valueOf(appWidgetId)); } prtSet(); super.onDeleted(context, appWidgetIds); } private void updateAllAppWidgets(Context context, AppWidgetManager appWidgetManager, Set set) { Log.d(TAG, "updateAllAppWidgets(): size=" + set.size()); int appID; Iterator it = set.iterator(); while (it.hasNext()) { appID = ((Integer) it.next()).intValue(); RemoteViews remoteView = new RemoteViews(context.getPackageName(), R.layout.robotcontroller_widget); remoteView.setTextViewText(R.id.tv_battery_v, "25.3V"); //remoteView.setOnClickPendingIntent(R.id.btn_show, getPendingIntent(context,BUTTON_SHOW)); appWidgetManager.updateAppWidget(appID, remoteView); } } /*private PendingIntent getPendingIntent(Context context, int buttonId) { Intent intent = new Intent(); intent.setClass(context, RobotControllerWidgetProvider.class); intent.addCategory(Intent.CATEGORY_ALTERNATIVE); intent.setData(Uri.parse("custom:" + buttonId)); PendingIntent pi = PendingIntent.getBroadcast(context, 0, intent, 0 ); return pi; }*/ private void prtSet() { if (DEBUG) { int index = 0; int size = idsSet.size(); Iterator it = idsSet.iterator(); Log.d(TAG, "total:" + size); while (it.hasNext()) { Log.d(TAG, index + " -- " + ((Integer) it.next()).intValue()); } } } }
2.manifest配置
<receiver android:name=".widget.RobotControllerWidgetProvider"> <intent-filter> <action android:name="android.appwidget.action.APPWIDGET_UPDATE" /> <action android:name="com.sineva.widget.UPDATE_ALL" /> </intent-filter> <meta-data android:name="android.appwidget.provider" android:resource="@xml/robotcontroller_widget_info" /> </receiver> <service android:name=".service.SLAMAppWidgetService"> <intent-filter> <action android:name="android.appwidget.action.SLAM_APP_WIDGET_SERVICE" /> </intent-filter> </service>
3.定义robotcontroller_widget_info(xml包下)
<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android" android:initialLayout="@layout/robotcontroller_widget" android:minHeight="180dp" android:minWidth="180dp" android:resizeMode="horizontal|vertical" android:widgetCategory="home_screen|keyguard"> </appwidget-provider>
4.定义robotcontroller_widget.xml
<?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/gray" android:orientation="vertical"> <Button android:id="@+id/button2" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="Button" /> <Button android:id="@+id/button3" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="Button" /> <TextView android:id="@+id/tv_battery_v" android:layout_width="match_parent" android:layout_height="match_parent" /> </LinearLayout>
5.定义SLAMAppWidgetService
package com.sineva.rosapidemo.service; import android.app.Service; import android.content.Context; import android.content.Intent; import android.os.IBinder; import android.util.Log; /** * Created by Eligah on 2017/9/29. */ public class SLAMAppWidgetService extends Service { private static final String TAG = "SlamAppWidgetService"; private final String ACTION_UPDATE_ALL = "com.sineva.widget.UPDATE_ALL"; private static final int UPDATE_TIME = 5000; private UpdateThread mUpdateThread; private Context mContext; private int count = 0; @Override public void onCreate() { mUpdateThread = new UpdateThread(); mUpdateThread.start(); mContext = this.getApplicationContext(); super.onCreate(); } @Override public void onDestroy() { if (mUpdateThread != null) { mUpdateThread.interrupt(); } super.onDestroy(); } @Override public IBinder onBind(Intent intent) { return null; } @Override public int onStartCommand(Intent intent, int flags, int startId) { Log.d(TAG, "onStartCommand"); super.onStartCommand(intent, flags, startId); return START_STICKY; } private class UpdateThread extends Thread { @Override public void run() { super.run(); try { count = 0; while (true) { Log.d(TAG, "run ... count:" + count); count++; Intent updateIntent = new Intent(ACTION_UPDATE_ALL); mContext.sendBroadcast(updateIntent); Thread.sleep(UPDATE_TIME); } } catch (InterruptedException e) { e.printStackTrace(); } } } }