簡體   English   中英

Android-Widget:從Appwidgetprovider的onUpdate調用BroadcastReceiver onReceive

[英]Android-Widget : Calling BroadcastReceiver onReceive from onUpdate of Appwidgetprovider

我正在制作一個手電筒小部件,它將打開/關閉手電筒,並且我也嘗試在單擊小部件按鈕時切換小部件按鈕的圖標,為此,我有Appwidgetprovider,其onUpdate將使用RemoteViews並調用BroadcastReceiver。

在BroadcastReceiver中,onReceive函數將執行小部件的手電筒切換和圖標切換。 我面臨的問題是onReceive函數沒有被調用,並且小部件沒有任何動作。

下面是代碼:

AppWidgetProvider類:

public class WidgetActivity extends AppWidgetProvider {
    public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
        Intent receiver = new Intent(context, WidgetActivity.class);
        receiver.setAction("COM_FLASHLIGHT");
        receiver.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, appWidgetIds);
        PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, receiver, 0);

        RemoteViews views = new RemoteViews(context.getPackageName(),
                R.layout.widget_flash_layout);
        views.setOnClickPendingIntent(R.id.imageButton1, pendingIntent);

        appWidgetManager.updateAppWidget(appWidgetIds, views);

    }
}

BroadcastReceiver類:

public class WidgetService extends BroadcastReceiver {
    private static boolean isLightOn = false;
    private static Camera camera;

    @Override
    public void onReceive(Context context, Intent intent) {
        // TODO Auto-generated method stub

        RemoteViews views = new RemoteViews(context.getPackageName(),
                R.layout.widget_flash_layout);

        if (isLightOn) {
            views.setImageViewResource(R.id.imageButton1,
                    R.drawable.light_off_widget);
        } else {
            views.setImageViewResource(R.id.imageButton1,
                    R.drawable.light_on_widget);
        }

        AppWidgetManager appWidgetManager = AppWidgetManager
                .getInstance(context);
        appWidgetManager.updateAppWidget(new ComponentName(context,
                WidgetActivity.class), views);

        if (isLightOn) {
            if (camera != null) {
                camera.stopPreview();
                camera.release();
                camera = null;
                isLightOn = false;
            }

        } else {
            // Open the default i.e. the first rear facing camera.
            camera = Camera.open();

            if (camera == null) {
                Toast.makeText(context, "no camera", Toast.LENGTH_SHORT).show();
            } else {
                // Set the torch flash mode
                Parameters param = camera.getParameters();
                param.setFlashMode(Camera.Parameters.FLASH_MODE_TORCH);
                try {
                    camera.setParameters(param);
                    camera.startPreview();
                    isLightOn = true;
                } catch (Exception e) {
                    Toast.makeText(context, "no flash", Toast.LENGTH_SHORT)
                            .show();
                }
            }
        }
    }
}

表現:

<receiver android:name="com.widget.WidgetActivity">
    <intent-filter>
              <action
                 android:name="android.appwidget.action.APPWIDGET_UPDATE" />
    </intent-filter>
    <meta-data
              android:name="android.appwidget.provider"
              android:resource="@xml/flash_widget" />
</receiver>

<receiver android:name="com.widget.WidgetService">

    <action android:name="COM_FLASHLIGHT"></action>

</receiver>

在清單中,我沒有<intent-filter>包裝窗口小部件服務的<action>標記,因為它顯示警告說“導出的接收者不需要權限”。

onReceive function is not being called and no action happening with the widget

您的意圖component class應該是Broadcast Receiver class ,而不是WidgetProvider

改變這個

 Intent receiver = new Intent(context, WidgetActivity.class);

Intent receiver = new Intent(context, WidgetService.class);

當您使用PendingIntent.getBroadcast它預期Intent to be broadcast 因此,當您單擊widget的按鈕時,將調用Broadcast Receiver onResume

您實際上不需要在此處為receiver設置任何Action

但是,如果您想使用自定義Intent ,則可以像這樣設置Intent action

 Intent receiver = new Intent("COM_FLASHLIGHT");

並且manifest的接收者應向intent-filter注冊以處理自定義操作。

 <receiver android:name=".services.WidgetService">
     <intent-filter>
        <action android:name="COM_FLASHLIGHT"></action>
     </intent-filter>
 </receiver>

因此,在調用BroadCast Receiver onReceive ,您可以像這樣檢查特定的操作

public class WidgetService extends BroadcastReceiver {

  @Override
  public void onReceive(Context context, Intent intent) {
    if(intent.getAction().equalsIgnoreCase("COM_FLASHLIGHT")){
          // do your stuff for this action.
    }
}

當您在RemoteView有多個動作時,通常會定義自定義Actions

在此處輸入圖片說明 如果您閱讀文檔,則在觸發notifyDataSetChanged()時會調用RemoteViewsService中的onDataSetChanged

因此,如果您想通過onReceive()方法更新WidgetService,則可以從AppWidgetManager調用notifyAppWidgetViewDataChanged()方法

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

    int[] ids = intent.getIntArrayExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS);
    AppWidgetManager.getInstance(context)
            .notifyAppWidgetViewDataChanged(ids, R.id.stack_view_movies);
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM