2013-02-10 48 views
32

我有一个Android小部件,每10分钟从服务器获取数据,并将其显示在屏幕上。
我想添加一个“刷新”按钮到该小部件。
当用户点击那个按钮时,我想运行从服务器获取信息的方法。
向应用程序中的按钮添加事件处理程序非常简单,但我找不到小部件的示例。
我想获得一些帮助,添加一个功能的按钮点击一个小部件。按钮点击事件为Android小部件

+1

这是有用的http://stackoverflow.com/a/8635715/2015318 – StarsSky 2013-02-10 13:14:34

回答

39

我发现了如何做到这一点。
添加操作到AndroidManifest.xml文件中的><receiver><intent-filter>标签:

<action android:name="MY_PACKAGE_NAME.WIDGET_BUTTON" /> 

在软件中添加相匹配的操作名称不变:

public static String WIDGET_BUTTON = "MY_PACKAGE_NAME.WIDGET_BUTTON"; 

onUpdate()方法添加挂起的意图是匹配动作:

Intent intent = new Intent(WIDGET_BUTTON); 
PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT); 
views.setOnClickPendingIntent(R.id.MY_BUTTON_ID, pendingIntent); 

最后,在onRecieve()方法中,检查动作名称:

if (WIDGET_BUTTON.equals(intent.getAction())) { 
//your code here 

    } 
+0

非常感谢! – 2013-10-17 03:56:08

+0

谢谢@Sharon Haim倒! – 2013-12-30 07:35:38

+1

我认为有意思的是您可以(也可能应该)使用明确的意图而不是隐含的意图。这意味着您不必在清单中定义动作,并且应该像这样创建意图:Intent intent = new Intent(context,MyClass.class); – user936580 2014-03-08 09:19:10

9
protected PendingIntent getPendingSelfIntent(Context context, String action) { 
    Intent intent = new Intent(context, getClass()); 
    intent.setAction(action); 
    return PendingIntent.getBroadcast(context, 0, intent, 0); 
} 

views.setOnClickPendingIntent(R.id.Timm, getPendingSelfIntent(context, 
           "ham")); 

也喜欢网址:

How to correctly handle click events on Widget

如果你以不同的方式解决了这个问题,请提供这作为一个答案

+1

我不明白在哪里把这段代码。您在哪里通过点击呼叫该功能? – 2013-02-11 07:45:38

59

下面是一个例子,应该帮助:

package com.automatic.widget; 

import android.app.PendingIntent; 
import android.appwidget.AppWidgetManager; 
import android.appwidget.AppWidgetProvider; 
import android.content.ComponentName; 
import android.content.Context; 
import android.content.Intent; 
import android.widget.RemoteViews; 

public class Widget extends AppWidgetProvider { 

    private static final String SYNC_CLICKED = "automaticWidgetSyncButtonClick"; 

    @Override 
    public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) { 
     RemoteViews remoteViews; 
     ComponentName watchWidget; 

     remoteViews = new RemoteViews(context.getPackageName(), R.layout.widget_layout); 
     watchWidget = new ComponentName(context, Widget.class); 

     remoteViews.setOnClickPendingIntent(R.id.sync_button, getPendingSelfIntent(context, SYNC_CLICKED)); 
     appWidgetManager.updateAppWidget(watchWidget, remoteViews); 
    } 

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

     if (SYNC_CLICKED.equals(intent.getAction())) { 

      AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context); 

      RemoteViews remoteViews; 
      ComponentName watchWidget; 

      remoteViews = new RemoteViews(context.getPackageName(), R.layout.widget_layout); 
      watchWidget = new ComponentName(context, Widget.class); 

      remoteViews.setTextViewText(R.id.sync_button, "TESTING"); 

      appWidgetManager.updateAppWidget(watchWidget, remoteViews); 

     } 
    } 

    protected PendingIntent getPendingSelfIntent(Context context, String action) { 
     Intent intent = new Intent(context, getClass()); 
     intent.setAction(action); 
     return PendingIntent.getBroadcast(context, 0, intent, 0); 
    } 
} 
+2

感谢这么好的例子我已经使用这段代码和我的应用程序正常工作.... Thiks a Lot – 2013-06-09 12:22:31

+0

谢谢一吨,这个答案帮助了我。 =) – 2013-07-06 10:31:14

+1

这段代码工作时没有混淆其他示例 - 这是开发指南信息的一个很好的简明示例 - 谢谢! – headscratch 2013-09-10 18:52:19

7

这里是另一个答案具有以下优点:

  • 它处理应用程序控件实例(一个用户可能有您的屏幕上的各种配置/尺寸的小部件的多个实例)。所有实例的编码是官方文档规定的。请参阅Guide > App Widgets > Using the AppWidgetProvider Class,向下滚动到“ExampleAppWidgetProvider”的代码示例。
  • onReceive中的主要代码实际上调用onUpdate(这样可以减少代码重复)。
  • onUpdate(Context context)中的代码是泛化的,因此它可以放入任何AppWidgetProvider子类中。

代码:

public class MyWidget extends AppWidgetProvider { 

    private static final String ACTION_UPDATE_CLICK = 
       "com.example.myapp.action.UPDATE_CLICK"; 

    private static int mCount = 0; 

    private static String getMessage() { 
     return String.valueOf(mCount++); 
    } 

    private PendingIntent getPendingSelfIntent(Context context, String action) { 
     // An explicit intent directed at the current class (the "self"). 
     Intent intent = new Intent(context, getClass()); 
     intent.setAction(action); 
     return PendingIntent.getBroadcast(context, 0, intent, 0); 
    } 

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

     String message = getMessage(); 

     // Loop for every App Widget instance that belongs to this provider. 
     // Noting, that is, a user might have multiple instances of the same 
     // widget on 
     // their home screen. 
     for (int appWidgetID : appWidgetIds) { 
      RemoteViews remoteViews = new RemoteViews(context.getPackageName(), 
                 R.layout.my_widget); 

      remoteViews.setTextViewText(R.id.textView_output, message); 
      remoteViews.setOnClickPendingIntent(R.id.button_update, 
               getPendingSelfIntent(context, 
                  ACTION_UPDATE_CLICK) 
      ); 

      appWidgetManager.updateAppWidget(appWidgetID, remoteViews); 

     } 
    } 

    /** 
    * A general technique for calling the onUpdate method, 
    * requiring only the context parameter. 
    * 
    * @author John Bentley, based on Android-er code. 
    * @see <a href="http://android-er.blogspot.com 
    * .au/2010/10/update-widget-in-onreceive-method.html"> 
    * Android-er > 2010-10-19 > Update Widget in onReceive() method</a> 
    */ 
    private void onUpdate(Context context) { 
     AppWidgetManager appWidgetManager = AppWidgetManager.getInstance 
       (context); 

     // Uses getClass().getName() rather than MyWidget.class.getName() for 
     // portability into any App Widget Provider Class 
     ComponentName thisAppWidgetComponentName = 
       new ComponentName(context.getPackageName(),getClass().getName() 
     ); 
     int[] appWidgetIds = appWidgetManager.getAppWidgetIds(
       thisAppWidgetComponentName); 
     onUpdate(context, appWidgetManager, appWidgetIds); 
    } 

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

     if (ACTION_UPDATE_CLICK.equals(intent.getAction())) { 
      onUpdate(context); 
     } 
    } 

} 

小部件看起来像这样

Widget update button example. Simple counting.

此基础上@Kels,@SharonHaimPour的getPendingSelfIntent工作和@ ERTI-ChrisEelmaa。

它还建立在Android-er > 2010-10-19 > Update Widget in onReceive() method(不是我)的地方,演示了如何在App Widget实例的基础上从onReceive调用onUpdate。我将该代码作为一般代码并将其包装在callOnUpdate中。