我尝试创建一个带有2个可点击按钮的小部件,这些按钮使用AppWidgetProvider中的onUpdate方法将其处理程序连接到它们。但是,广播消息没有被接收。有人有任何想法吗?
MainActivity:
public class MainActivity extends ActionBarActivity implements View.OnClickListener {
private static final String TAG = "MainActivity";
private IRThread irThread;
private Handler handler;
private boolean onOff = false;
private static HashMap<Integer, Integer> codeLookup = new HashMap<>();
static {
codeLookup.put(R.id.up_button, AuraGlowCodes.BRIGHTNESS_UP);
codeLookup.put(R.id.down_button, AuraGlowCodes.BRIGHTNESS_DOWN);
codeLookup.put(R.id.green_button, AuraGlowCodes.COLOR_GREEN);
codeLookup.put(R.id.red_button, AuraGlowCodes.COLOR_RED);
codeLookup.put(R.id.blue_button, AuraGlowCodes.COLOR_BLUE);
codeLookup.put(R.id.red_button_2, AuraGlowCodes.COLOR_RED_2);
codeLookup.put(R.id.blue_button_2, AuraGlowCodes.COLOR_BLUE_2);
codeLookup.put(R.id.green_button_2, AuraGlowCodes.COLOR_GREEN_2);
codeLookup.put(R.id.red_button_3, AuraGlowCodes.COLOR_RED_3);
codeLookup.put(R.id.blue_button_3, AuraGlowCodes.COLOR_BLUE_3);
codeLookup.put(R.id.green_button_3, AuraGlowCodes.COLOR_GREEN_3);
codeLookup.put(R.id.red_button_4, AuraGlowCodes.COLOR_RED_4);
codeLookup.put(R.id.blue_button_4, AuraGlowCodes.COLOR_BLUE_4);
codeLookup.put(R.id.green_button_4, AuraGlowCodes.COLOR_GREEN_4);
codeLookup.put(R.id.flash_button, AuraGlowCodes.PATTERN_FLASH);
codeLookup.put(R.id.fade_button, AuraGlowCodes.PATTERN_FADE);
codeLookup.put(R.id.smooth_button, AuraGlowCodes.PATTERN_SMOOTH);
codeLookup.put(R.id.strobe_button, AuraGlowCodes.PATTERN_STROBE);
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
irThread = new IRThread(getApplicationContext());
handler = irThread.getHandler();
findViewById(R.id.onOff_button).setOnClickListener(this);
findViewById(R.id.up_button).setOnClickListener(this);
findViewById(R.id.down_button).setOnClickListener(this);
findViewById(R.id.red_button).setOnClickListener(this);
findViewById(R.id.green_button).setOnClickListener(this);
findViewById(R.id.blue_button).setOnClickListener(this);
findViewById(R.id.red_button_2).setOnClickListener(this);
findViewById(R.id.green_button_2).setOnClickListener(this);
findViewById(R.id.blue_button_2).setOnClickListener(this);
findViewById(R.id.red_button_3).setOnClickListener(this);
findViewById(R.id.green_button_3).setOnClickListener(this);
findViewById(R.id.blue_button_3).setOnClickListener(this);
findViewById(R.id.red_button_4).setOnClickListener(this);
findViewById(R.id.green_button_4).setOnClickListener(this);
findViewById(R.id.blue_button_4).setOnClickListener(this);
findViewById(R.id.flash_button).setOnClickListener(this);
findViewById(R.id.fade_button).setOnClickListener(this);
findViewById(R.id.strobe_button).setOnClickListener(this);
findViewById(R.id.smooth_button).setOnClickListener(this);
Intent intent = new Intent(this, WidgetProvider.class);
intent.setAction(AppWidgetManager.ACTION_APPWIDGET_UPDATE);
sendBroadcast(intent);
Log.e("[HERE]", "SENT BROADCAST");
}
@Override
public void onClick(View v) {
int val = 0;
switch (v.getId()){
case R.id.onOff_button:
if (onOff){
val = AuraGlowCodes.TURN_OFF;
} else {
val = AuraGlowCodes.TURN_ON;
}
onOff=!onOff;
break;
default:
val = codeLookup.get(v.getId());
break;
}
Log.wtf("[fuck]", Integer.toHexString(val));
int[] pattern = NECFactory
.createCommand()
.addInteger(val, (byte)32)
.getPattern(5);
Message msg = handler.obtainMessage(IRThread.MSG_NAME, pattern);
handler.sendMessage(msg);
}
}
AndroidManifest:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="io.github.dadude941.auraglowremote">
<uses-permission android:name="android.permission.TRANSMIT_IR" />
<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme">
<activity
android:name=".ui.MainActivity"
android:label="@string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<receiver android:name="io.github.dadude941.auraglowremote.ui.WidgetProvider" >
<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>
</application>
</manifest>
WidgetProvider.java:
package io.github.dadude941.auraglowremote.ui;
import android.app.PendingIntent;
import android.appwidget.AppWidgetManager;
import android.appwidget.AppWidgetProvider;
import android.content.Context;
import android.content.Intent;
import android.util.Log;
import android.view.View;
import android.widget.RemoteViews;
import io.github.dadude941.auraglowremote.R;
/**
* Created by Miguel Boland on 06/03/2015.
*/
public class WidgetProvider extends AppWidgetProvider {
public final static String WIDGET_ON_BUTTON = "MY_PACKAGE_NAME.WIDGET_BUTTON";
public final static String WIDGET_OFF_BUTTON = "MY_PACKAGE_NAME.WIDGET_BUTTON2";
@Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds){
Log.e("[onUpdate]", "UPDATING");
Intent intent = new Intent(WIDGET_ON_BUTTON);
PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
RemoteViews remoteViews = new RemoteViews(context.getPackageName(), R.layout.widget);
remoteViews.setOnClickPendingIntent(R.id.on_button, pendingIntent);
Intent intent2 = new Intent(WIDGET_OFF_BUTTON);
PendingIntent pendingIntent2 = PendingIntent.getBroadcast(context, 0, intent2, PendingIntent.FLAG_UPDATE_CURRENT);
remoteViews.setOnClickPendingIntent(R.id.off_button, pendingIntent2);
}
@Override
public void onReceive(Context context, Intent intent){
switch(intent.getAction()){
case WIDGET_ON_BUTTON:
Log.e("[onReceive]", "ON BUTTON");
break;
case WIDGET_OFF_BUTTON:
Log.e("[onReceive]", "OFF BUTTON");
break;
}
}
}
答案 0 :(得分:0)
首先不要发送广播意图ACTION_APPWIDGET_UPDATE
。这是Android自己发送的,因此您无需发送它。 Android会在设备启动时发送此消息,并根据您的小部件的配置定期发送。
此外,您通过实施onReceive()
和onUpdate()
来破坏您的小部件代码。 AppWidgetProvider
类只是一个便利类,可以为您进行一些处理。它扩展BroadcastReceiver
并覆盖onReceive()
方法。触发接收器并调用onReceive()
时,它会从Intent
中提取ACTION和其他参数,然后调用onUpdate()
,onDeleted()
,onEnabled()
之一或onDisabled()
。由于您已在onReceive()
课程中覆盖了WidgetProvider
,因此您的实施将被调用。由于您的onReceive()
方法无法调用super.onReceive()
,onReceive()
的{{1}}方法永远不会被调用,这就是为什么它永远不会调用AppWidgetProvider
。< / p>
可能的解决方案:
1)在onUpdate()
中,如果ACTION不是您感兴趣的,请务必致电WidgetProvider.onReceive()
,让超级班有机会做到这一点。
2)创建一个单独的类来处理您要发送的广播Intents(即:super.onReceive()
和WIDGET_ON_BUTTON
)并且不要使用您的WIDGET_OFF_BUTTON
类来处理这些。它只是让事情混乱。