【问题标题】:Android widget fails to start activity when clicked first time第一次单击时,Android小部件无法启动活动
【发布时间】:2014-05-22 16:59:55
【问题描述】:

我有一个 android 小部件,它实际上是一个启动活动的按钮。使用此代码该小部件可以正常工作,但有一个小错误:

当我将小部件添加到主屏幕时,第一次单击它不会做任何事情,第二次它会起作用。然后它从第一次单击开始正常工作。重启手机时也会出现同样的情况。有人可以帮我解决这个问题吗??

MyWidgetIntentReceiver.java

public class MyWidgetIntentReceiver extends BroadcastReceiver {


@Override
public void onReceive(Context context, Intent intent) {
    if (intent.getAction().equals("Start")) {
        onUpdate(context);
    }
}


private void onUpdate(Context context) {
    RemoteViews remoteViews = new RemoteViews(context.getPackageName(),
            R.layout.widget_demo);

    Intent configIntent = new Intent(context, WidgetFlash.class);
    configIntent.putExtra("widget", 1);
    configIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

    PendingIntent configPendingIntent = PendingIntent.getActivity(context,
            0, configIntent, 0);

    remoteViews.setOnClickPendingIntent(R.id.widget_button,
            configPendingIntent);

    MyWidgetProvider.pushWidgetUpdate(context.getApplicationContext(),
            remoteViews);
} }


MyWidgetProvider.java :

    public class MyWidgetProvider extends AppWidgetProvider {

@Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager,
        int[] appWidgetIds) {

    RemoteViews remoteViews = new RemoteViews(context.getPackageName(), R.layout.widget_demo);
    remoteViews.setOnClickPendingIntent(R.id.widget_button, buildButtonPendingIntent(context));

    pushWidgetUpdate(context, remoteViews);
}

public static PendingIntent buildButtonPendingIntent(Context context) {
    Intent intent = new Intent();
    intent.setAction("Start");
    return PendingIntent.getBroadcast(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
}

public static void pushWidgetUpdate(Context context, RemoteViews remoteViews) {
    ComponentName myWidget = new ComponentName(context, MyWidgetProvider.class);
    AppWidgetManager manager = AppWidgetManager.getInstance(context);
    manager.updateAppWidget(myWidget, remoteViews);     
}}



清单中的小部件:

   <receiver android:name="com.hybernect.flashlight.MyWidgetProvider" >
        <intent-filter>
            <action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
        </intent-filter>

        <meta-data
            android:name="android.appwidget.provider"
            android:resource="@xml/demo_widget_provider" />
    </receiver>
    <receiver
        android:name="com.hybernect.flashlight.MyWidgetIntentReceiver"
        android:label="widgetBroadcastReceiver" >
        <intent-filter>
            <action android:name="Start" />
        </intent-filter>

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


【问题讨论】:

  • 当你第一次说它不起作用时,你应该在第一次点击它时查看logcat。您可能会在其中看到一些有用/信息丰富的内容。
  • logcat 在第一次点击时不显示任何内容 :(
  • 你在过滤logcat吗?如果是这样,请不要。你会错过一些重要的事情。
  • 请发布您的清单
  • 您是否为您的小部件定义了配置活动?

标签: android android-widget android-pendingintent


【解决方案1】:

在我看来,您可能对 Android 小部件非常陌生,并且缺少一些您需要了解的基础知识。我的建议是找到更多教程,而不是您完成的教程,以比较处理小部件的不同方式。

我编写了一个简单的小部件作为演示教程 - 它包含小部件所需的所有样板代码,仅此而已:

我以这样一种方式编写它,以便任何人都可以轻松删除“wifi”相关代码,并使其适应他们自己的小部件需求。它可能非常适合您查看,并且添加一个按钮相对简单。


您在MyWidgetIntentReceiverMyWidgetProvider 中混合了不同的onUpdate() 方法。下面我将尝试解释您在原始问题中提供的代码有什么问题。


当您将小部件添加到主屏幕时,会调用MyWidgetProvider.onUpdate(),而后者又会调用buildPendingIntent()

public static PendingIntent buildButtonPendingIntent(Context context) {
    Intent intent = new Intent();
    intent.setAction("Start");
    return PendingIntent.getBroadcast(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
}

这将创建一个PendingIntent,当单击按钮时,它将发送一个动作设置为“开始”的广播。

这就是发生的事情。单击该按钮,您发送带有“开始”的广播,您的MyWidgetIntentReceiver 会收到该广播。

我不明白你为什么选择这样做,因为你宁愿从这个类开始活动。


当您的MyWidgetIntentReceiver.onReceive() 方法运行时,它会调用自己的onUpdate() 方法。

(注意:这是一种不好的做法;尽量在BroadcastReceiver 中做的更少)

这个新的onUpdate() 方法设置点击动作来启动活动:

Intent configIntent = new Intent(context, WidgetFlash.class);
configIntent.putExtra("widget", 1);
configIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

PendingIntent configPendingIntent = PendingIntent.getActivity(context,
        0, configIntent, 0);

remoteViews.setOnClickPendingIntent(R.id.widget_button,
        configPendingIntent);

因此,当您第二次单击该按钮时,WidgetFlash 活动将启动。


总结一下:

  • 您的第一个更新调用PendingIntent.getBroadcast(),它将“开始”发送给接收者
  • 您的第二次更新调用PendingIntent.getActivity(),这将启动WidgetFlash

我不明白此代码中需要您的MyWidgetIntentReceiver

【讨论】:

  • 现在根本不工作了?我将 MyWidgetIntentReceiver 中的 onUpdate 更改为您发布的新方法,并且该按钮现在不执行任何操作
  • 我没有发布任何新方法。这是您的所有原始代码。告诉我,你为什么决定使用MyWidgetIntentReceiver?看起来你的基础知识都错了。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-10-16
  • 2013-07-02
  • 2015-08-21
  • 1970-01-01
相关资源
最近更新 更多