代码之家  ›  专栏  ›  技术社区  ›  Leif Andersen

Android中的可点击小工具

  •  60
  • Leif Andersen  · 技术社区  · 14 年前

    开发人员文档似乎使我在这里失败了。我可以创建一个静态的小部件而不需要思考,我甚至可以创建一个类似于模拟时钟小部件的小部件来自我更新,但是,在我的一生中,我不知道如何创建一个小部件来响应用户单击它。下面是开发人员文档给出的关于小部件活动应该包含哪些内容的最佳代码示例(唯一的其他提示是API演示,它只创建静态小部件):

    public class ExampleAppWidgetProvider extends AppWidgetProvider {
        public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
            final int N = appWidgetIds.length;
    
            // Perform this loop procedure for each App Widget that belongs to this provider
            for (int i=0; i<N; i++) {
                int appWidgetId = appWidgetIds[i];
    
                // Create an Intent to launch ExampleActivity
                Intent intent = new Intent(context, ExampleActivity.class);
                PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, 0);
    
                // Get the layout for the App Widget and attach an on-click listener to the button
                RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.appwidget_provider_layout);
                views.setOnClickPendingIntent(R.id.button, pendingIntent);
    
                // Tell the AppWidgetManager to perform an update on the current App Widget
                appWidgetManager.updateAppWidget(appWidgetId, views);
            }
        }
    }
    

    来自: The Android Developer Documentation's Widget Page

    因此,当单击小部件时,似乎会调用挂起的意图,这是基于意图的(我不太确定意图和挂起的意图之间的区别),而意图是针对ExampleActivity类的。所以我把我的示例活动类变成了一个简单的活动,当它被创建时,会创建一个MediaPlayer对象,并启动它(它永远不会释放该对象,所以它最终会崩溃,代码如下:

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        MediaPlayer mp = MediaPlayer.create(getApplicationContext(), R.raw.sound);
        mp.start();
    }
    

    但是,当我将小部件添加到主屏幕并单击它时,实际上,当我将更新计时器设置为几百毫秒(在AppWidget提供程序XML文件中)时,没有播放任何内容。此外,我设置了断点,发现它不仅从未到达活动,而且我设置的断点也不会被触发。(我仍然不明白为什么会这样),但是,logcat似乎表明正在运行活动类文件。

    那么,我能做些什么来让AppWidget响应单击吗?因为onclickEndingIntent()方法是我找到的最接近onclick类型的方法。

    非常感谢你。

    2 回复  |  直到 6 年前
        1
  •  125
  •   h0ussni genericuser    11 年前

    首先,添加一个带有常量的静态变量。

    public static String YOUR_AWESOME_ACTION = "YourAwesomeAction";
    

    然后,在将意图添加到待定意图之前,需要将该操作添加到意图中:

    Intent intent = new Intent(context, widget.class);
    intent.setAction(YOUR_AWESOME_ACTION);
    

    (其中widget.class是AppWidgetProvider的类,即当前类)

    然后需要使用getbroadcast创建挂起的内容

    PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, intent, 0);
    

    为小部件中的可单击视图设置onclickEndingingIntent

    remoteView.setOnClickPendingIntent(R.id.widgetFrameLayout, pendingIntent);
    

    接下来,重写同一类中的onReceive方法:

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

    然后通过查询onReceive方法中为您的操作返回的意图来响应您的按钮按下:

    if (intent.getAction().equals(YOUR_AWESOME_ACTION)) {
       //do some really cool stuff here
    }
    

    就这样吧!

        2
  •  1
  •   Mike    6 年前

    离开 更新 方法,复制粘贴逻辑到 更新应用程序小部件 .

    static void updateAppWidget(Context context, AppWidgetManager appWidgetManager,
                                int appWidgetId) {
    
        // Create an Intent to launch ExampleActivity when clicked
        Intent intent = new Intent(context, ExampleActivity.class);
        PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, 0);
        // Construct the RemoteViews object
        RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.appwidget_provider_layout);
        // Widgets allow click handlers to only launch pending intents
        views.setOnClickPendingIntent(R.id.button, pendingIntent);
        // Instruct the widget manager to update the widget
        appWidgetManager.updateAppWidget(appWidgetId, views);
    }
    
    @Override
    public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
        // There may be multiple widgets active, so update all of them
        for (int appWidgetId : appWidgetIds) {
            updateAppWidget(context, appWidgetManager, appWidgetId);
        }
    }
    

    PS。 处理意图 只是一个意图的“盒子”,它允许 其他应用 以便在应用程序中访问和运行该意图。