Java android中的可点击小部件
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2748590/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Clickable widgets in android
提问by Leif Andersen
The developer documentation has seemed to have failed me here. I can create a static widget without thinking, I can even create a widget like the analogue clock widget that will update itself, however, I can not for the life of me figure out how to create a widget that reacts to when a user clicks on it. Here is the best code sample that the developer documentation gives to what a widget activity should contain (the only other hint being the API demos, which only creates a static widget):
开发人员文档在这里似乎让我失望。我可以不假思索地创建一个静态小部件,我什至可以创建一个像模拟时钟小部件这样会自动更新的小部件,但是,我一生都无法弄清楚如何创建一个对用户点击时做出反应的小部件它。以下是开发人员文档给出的关于小部件活动应包含的内容的最佳代码示例(唯一的其他提示是 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);
}
}
}
from: The Android Developer Documentation's Widget Page
So, it looks like pending intent is called when the widget is clicked, which is based off of an intent (I'm not quite sure what the difference between an intent and a pending intent is), and the intent is for the ExampleActivity class. So I made my sample activity class a simple activity that when created, would create a mediaplayer object, and start it (it wouldn't ever release the object, so it would eventually crash, here is it's code:
因此,当单击小部件时,它看起来像是调用了挂起的意图,这是基于意图的(我不太确定意图和挂起的意图之间的区别是什么),并且该意图是针对 ExampleActivity 类的. 所以我让我的示例活动类成为一个简单的活动,在创建时会创建一个媒体播放器对象并启动它(它永远不会释放该对象,所以它最终会崩溃,这是它的代码:
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
MediaPlayer mp = MediaPlayer.create(getApplicationContext(), R.raw.sound);
mp.start();
}
However, when I added the widget to the home screen, and clicked on it, nothing played, in fact, nothing played when I set the update timer to just a few hundred milliseconds (in the appwidget provider xml file). Furthermore, I set break points and found out that not only was it never reaching the activity, but no break points I set would ever get triggered. (I still haven't figured out why that is), however, logcat seemed to indicate that the activity class file was being run.
但是,当我将小部件添加到主屏幕并单击它时,没有任何播放,实际上,当我将更新计时器设置为几百毫秒(在 appwidget 提供程序 xml 文件中)时,没有任何播放。此外,我设置了断点并发现它不仅永远不会到达活动,而且我设置的断点也不会被触发。(我仍然没有弄清楚为什么会这样),但是,logcat 似乎表明活动类文件正在运行。
So, is there anything I can do to get an appwidget to respond to a click? As the onClickPendingIntent() method is the closest I have found to a onClick type of method.
那么,我能做些什么来让应用小部件响应点击吗?由于 onClickPendingIntent() 方法是我发现的最接近 onClick 类型的方法。
Thank you very much.
非常感谢。
采纳答案by strange quark
First, add a static variable with a constant.
首先,添加一个带有常量的静态变量。
public static String YOUR_AWESOME_ACTION = "YourAwesomeAction";
Then you need to add the action to the intent before you add the intent to the pending intent:
然后您需要在将意图添加到待处理意图之前将操作添加到意图中:
Intent intent = new Intent(context, widget.class);
intent.setAction(YOUR_AWESOME_ACTION);
(Where widget.class is the class of your AppWidgetProvider, your current class)
(其中widget.class 是您的AppWidgetProvider 的类,即您当前的类)
You then need to create a PendingIntent with getBroadcast
然后你需要使用 getBroadcast 创建一个 PendingIntent
PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, intent, 0);
Set the onClickPendingIntent for the clickable view in your widget
为小部件中的可点击视图设置 onClickPendingIntent
remoteView.setOnClickPendingIntent(R.id.widgetFrameLayout, pendingIntent);
Next, override the onReceive method in the same class:
接下来,覆盖同一个类中的 onReceive 方法:
@Override
public void onReceive(Context context, Intent intent) {
super.onReceive(context, intent);
And then respond to your button presses by querying the intent returned for your action within the onReceive method:
然后通过在 onReceive 方法中查询为您的操作返回的意图来响应您的按钮按下:
if (intent.getAction().equals(YOUR_AWESOME_ACTION)) {
//do some really cool stuff here
}
And that should do it!
那应该这样做!
回答by Mike
Leave the onUpdatemethod as it was and copy-paste the logic to updateAppWidget.
保持onUpdate方法不变,并将逻辑复制粘贴到updateAppWidget。
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. PendingIntentis just "box" for an Intent, that allows other applicationsto have access and run that Intent in your application.
附注。PendingIntent只是 Intent 的“盒子”,它允许其他应用程序访问并在您的应用程序中运行该 Intent。