回答
您需要自行存储该信息。我通常使用应用程序首选项,但可以使用任何东西。通常,小部件使用服务进行通信,因此您的代码可能在服务中执行,但使用首选项可以让应用程序的任何部分都可以访问它。
在扩展AppWidgetProvider的widget类中,当widget被放在主屏幕上时,onEnabled被调用,onDeleted被移除时(通常)被调用。当所有副本被删除时,onDisabled被调用。
因此,在您微件提供者的代码:
@Override
public void onEnabled(Context context) {
super.onEnabled(context);
setWidgetActive(true);
context.startService(new Intent(appContext, WidgetUpdateService.class));
}
@Override
public void onDisabled(Context context) {
Context appContext = context.getApplicationContext();
setWidgetActive(false);
context.stopService(new Intent(appContext, WidgetUpdateService.class));
super.onDisabled(context);
}
private void setWidgetActive(boolean active){
Context appContext = context.getApplicationContext();
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(appContext);
SharedPreferences.Editor edit = prefs.edit();
edit.putBoolean(Constants.WIDGET_ACTIVE, active);
edit.commit();
}
其他地方的代码,你会检查是否该控件是活动的:
public boolean isWidgetActive(Context context){
Context appContext = context.getApplicationContext();
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
return prefs.getBoolean(Constants.WIDGET_ACTIVE, false);
}
我知道这是个老问题,但今天看到这个,我看到@ larsona1接受的答案有几个问题:
- 如果用户清除了t他分享了偏好 - 还有小部件,但应用程序不知道它。
- 如果用户后悔在“添加小部件”和按“ok”之前 - onEnabled将被调用,并且即使没有小部件也将在主屏幕中注册小部件,并且以后无法将其删除。 (这可能是ADT主页启动器中的一个错误)。
我找到了第一个问题的解决方案。 根本不需要共享首选项,因为它无论如何都不可靠。它必须在运行时检查。
// in some class you define a static variable, say in S.java
static boolean sWidgetMayExist = true;
在您的控件提供者:
// MyAppWidgetProvider.java
// to respond to runtime changes, when widgets are added and removed
@Override
public void onEnabled(Context context) {
super.onEnabled(context);
S.sWidgetMayExist = true;
}
@Override
public void onDisabled(Context context) {
super.onDisabled(context);
S.sWidgetMayExist = true;
}
而且,在你的服务代码补充一点:
AppWidgetManager manager = null;
RemoteViews views = null;
ComponentName widgetComponent = null;
// ..and in your update thread
if (!S.sWidgetMayExist) { return; }
if (manager == null || widgetComponent == null) {
widgetComponent = new ComponentName(c,
MyAppWidgetProvider.class);
manager = AppWidgetManager.getInstance(c);
}
if (manager.getAppWidgetIds(widgetComponent) == null) {
S.sWidgetMayExist = false;
}
根据此页[1] 2的问题似乎是,固定与Android 2.1及更高版本的bug。我使用Android 4.1.2测试了它,并正确调用了onDelete和onDisabled方法。 [1] https://groups.google.com/forum/?fromgroups=#!topic/android-developers/4agiDfaGvDw – friday 2013-01-18 11:41:15
见Waza_Be的回答,似乎工作,并需要更少的代码。 – 2014-09-26 16:13:07
@ WilliamT.Mallard我的回答比Waza年纪大6个月。所以我在回答时没有检查它。但现在回顾一下,我不确定它是否涵盖了我所指的边缘案例。 – auval 2014-09-26 19:46:31
只是说,但...
int ids[] = AppWidgetManager.getInstance(this).getAppWidgetIds(new ComponentName(this,MyAppWidgetProvider.class));
Toast.makeText(this, "Number of widgets: "+ids.length, Toast.LENGTH_LONG).show();
@ Waza_Be是正确的,正在查看“AppWidgetIds”列表来了解t他的活动窗口小部件(安装在主屏幕上)的数量是了解此信息的正确方法。
但是,请记住,你应该不必自己看这个。
检查小部件的最佳实践Android官方文档: https://developer.android.com/guide/topics/appwidgets/index.html#AppWidgetProvider
正确的做法是只覆盖了的onUpdate()方法,并通过“活动”窗口小部件列表迭代:
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);
}
}
}
而且作为自己的微件提供覆盖的AppWidgetProvider,你会不会进入的onUpdate()方法,如果你没有在主屏幕上活动控件!
见的Android的AppWidgetProvider的的onReceive()代码检查已经为你 “appWidgetIds.length> 0”:
public void onReceive(Context context, Intent intent) {
// Protect against rogue update broadcasts (not really a security issue,
// just filter bad broacasts out so subclasses are less likely to crash).
String action = intent.getAction();
if (AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)) {
Bundle extras = intent.getExtras();
if (extras != null) {
int[] appWidgetIds = extras.getIntArray(AppWidgetManager.EXTRA_APPWIDGET_IDS);
if (appWidgetIds != null && appWidgetIds.length > 0) {
this.onUpdate(context, AppWidgetManager.getInstance(context), appWidgetIds);
}
}
}
(...)
}
- 1. 在小屏幕上查看Android字体
- 2. 检查屏幕大小不工作
- 3. mono for android。主屏幕上的小工具
- 4. 小工具在主屏幕中拉伸。
- 5. 在Android中检测屏幕大小
- 6. Android - 在屏幕上拖放片段
- 7. Android上的缩放小部件(dp,px,屏幕大小)
- 8. 放大和缩小android屏幕
- 9. 需要在Android上处理大屏幕和小屏幕的工作示例
- 10. 适合屏幕所有小工具
- 11. 从按钮打开小工具屏幕
- 12. addEventListener()不能在小屏幕上工作
- 13. 从主屏幕删除小工具,不用拖放
- 14. 小屏幕上
- 15. 如何检查/测试小工具在Android咖啡上解雇
- 16. 在主屏幕上显示加载屏幕小部件Android
- 17. 正常屏幕上的宽屏检查
- 18. 如何检测小工具是否开/关屏幕?
- 19. iOS今日小工具扩展 - 检测屏幕是否锁定
- 20. 检查控制是否在屏幕上
- 21. 检查元素在屏幕上
- 22. 如何检查小部件主屏幕
- 23. Android工具栏填满整个屏幕
- 24. 在Android上查看PC屏幕
- 25. FileObserver不能在Android 6上工作,替代在Android上检测屏幕截图
- 26. 工具栏滚动屏幕上的屏幕
- 27. 使在小屏幕上
- 28. 检查屏幕窄
- 29. Android将图像拖放到屏幕上?
- 30. 屏幕上的工具提示
你好,做了你看看我的答案吗?我认为这可能会有所帮助.. ;-) – 2013-06-19 10:29:31