回答
您需要自行存儲該信息。我通常使用應用程序首選項,但可以使用任何東西。通常,小部件使用服務進行通信,因此您的代碼可能在服務中執行,但使用首選項可以讓應用程序的任何部分都可以訪問它。
在擴展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. mono for android。主屏幕上的小工具
- 3. 需要在Android上處理大屏幕和小屏幕的工作示例
- 4. addEventListener()不能在小屏幕上工作
- 5. 從按鈕打開小工具屏幕
- 6. 正常屏幕上的寬屏檢查
- 7. 如何檢測小工具是否開/關屏幕?
- 8. 檢查元素在屏幕上
- 9. 檢查控制是否在屏幕上
- 10. Android工具欄填滿整個屏幕
- 11. 在Android上查看PC屏幕
- 12. FileObserver不能在Android 6上工作,替代在Android上檢測屏幕截圖
- 13. 工具欄滾動屏幕上的屏幕
- 14. 檢查屏幕窄
- 15. 如何檢查Android設備是HDPI屏幕還是MDPI屏幕?
- 16. 在小屏幕上摺疊div,在大屏幕上展開-javascript
- 17. onReceive of Android主屏幕小工具在重新創建小工具時不起作用
- 18. Android屏幕尺寸縮放
- 19. Android在屏幕上打開
- 20. 在屏幕上android動畫
- 21. 防止在不同屏幕大小的不同屏幕上播放動畫(具有相同的動畫效果)
- 22. Android小工具:顯示小部件添加到屏幕前的配置活動
- 23. Android屏幕取向大小
- 24. Android主屏幕小部件
- 25. iOS今日小工具擴展:檢測是否在鎖定屏幕中打開
- 26. Android屏幕按下檢測
- 27. 應用程序崩潰時,在Android的小屏幕和大屏幕上運行
- 28. 在小屏幕上查看HTML表格時強制「縮小」
- 29. 在較小屏幕上查看時適當縮小面板
- 30. 在Android的全屏幕播放視頻
你好,做了你看看我的答案嗎?我認爲這可能會有所幫助.. ;-) – 2013-06-19 10:29:31