2013-06-30 14 views
7

위젯을 업데이트하려면 AlarmManager을 사용하고 있습니다. 홈 화면에 위젯이 없으면 중지하고 싶습니다. 하지만 홈 화면에 위젯이 없는지 감지하는 데 문제가 있습니다. 나는이 방법을 사용하여 AppWidgetIds를 얻으려고 할 때마다로appWidgetId를 사용하여 홈 화면에 위젯이 있는지 확인하십시오.

: 사실 홈 화면에는 위젯이없는 동안

AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context); 

int[] appWidgetIDs = appWidgetManager 
    .getAppWidgetIds(new ComponentName(context, Widget.class)); 

나는 appWidgetIDs의 길이를 얻는다. 왜?

따라서 홈 화면에 위젯 ID가 있는지 감지하는 방법이 있는지 알고 싶습니다.

감사합니다.

답변

16

축하합니다. 팬텀 앱 위젯을 보았습니다. Android issue tracker에 문서화되어있는 것으로 보입니다. 일반적으로 appwidget의 구성 활동이 취소 될 때 발생하지만, 구성 활동의 부적절한 구현을 통해 발생하는 것 같습니다. 개발자들은 액티비티 결과를 RESULT_CANCELED으로 설정할 때 appwidget ID를 추가로 무시합니다.

public class AppWidgetConfigActivity extends Activity { 

    private int appWidgetId; 
    private Intent resultValue; 

    protected void onCreate(bundle saved) { 
     super.onCreate(saved); 

     // get the appwidget id from the intent 
     Intent intent = getIntent(); 
     appWidgetId = intent.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, 
       AppWidgetManager.INVALID_APPWIDGET_ID); 

     // make the result intent and set the result to canceled 
     resultValue = new Intent(); 
     resultValue.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId); 
     setResult(RESULT_CANCELED, resultValue); 

     // if we weren't started properly, finish here 
     if (appwidgetId == AppWidgetManager.INVALID_APPWIDGET_ID) { 
      finish(); 
     } 

     /* ... */ 
    } 

    /* ... */ 

    private void finishConfigure() { 
     /* finish configuring appwidget ... */ 
     setResult(RESULT_OK, resultValue); 
    } 
} 

지금까지 내가 당신의 자신의 부기를하지 않고 팬텀 appwidget의 존재를 감지 할 수있는 방법을 알고 :

적절한 구현이이처럼 (! 심지어 구글의 ApiDemos에 샘플 응용 프로그램은이 일을 무시) . 구성 활동이 취소되지 않았다는 것을 나타내는 SharedPreferences 값을 저장하고 다른 코드에서이 값을 쿼리하는 것이 좋습니다. 이 정보를 사용하여 팬텀 위젯을 "삭제"할 수도 있습니다. 당신의 appwidget 구성 활동에 :

private void finishConfigure() { 
    /* finish configuring appwidget ... */ 
    setResult(RESULT_OK, resultValue); 

    String key = String.format("appwidget%d_configured", appwidgetId); 
    SharedPreferences prefs = getSharedPreferences("widget_prefs", 0); 
    prefs.edit().putBoolean(key, true).commit; 
} 

그런 다음 당신은 당신이 적어도 하나의 비 팬텀과 같이 appwidget이 있는지 확인 할 수 있습니다

AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context); 
AppWidgetHost appWidgetHost = new AppWidgetHost(context, 1); // for removing phantoms 
SharedPreferences prefs = getSharedPreferences("widget_prefs", 0); 
boolean hasWidget = false; 

int[] appWidgetIDs = appWidgetManager.getAppWidgetIds(new ComponentName(context, Widget.class)); 
for (int i = 0; i < appWidgetIDs.length; i++) { 
    int id = appWidgetIDs[i]; 
    String key = String.format("appwidget%d_configured", id); 
    if (prefs.getBoolean(key, false)) { 
     hasWidget = true; 
    } else { 
     // delete the phantom appwidget 
     appWidgetHost.deleteAppWidgetId(id); 
    } 
} 

if (hasWidget) { 
    // proceed 
} else { 
    // turn off alarms 
} 
+0

이 답변이 더 많은 칭찬을받을 자격이! 나는 안드로이드 스튜디오에서 얻은 샘플 "hello world"appwidget 코드가 제대로하지 못하기 때문에 많은 사람들이이 문제를 겪게 될 것이라고 확신한다. 사람들이 시작됩니다. 액티비티 결과를 RESULT_CANCELED로 설정할 때 appwidget ID를 추가로 포함하라는 조언을 통해 나는 더 이상 팬텀 위젯을 생성하지 않는 것 같습니다. 감사! – drmrbrewer

+0

팬텀 위젯을 삭제하는 코드는 어떤 이유로 든 나타나야합니다. 어디에 넣을 것을 권장합니까? onUpdate()는 위젯이 설정되기 전에 설정 활동이 처음 열릴 때 호출되는 것으로 보이기 때문에 위젯이 태어나 기 전에 죽이기를 원하지 않습니다! – drmrbrewer

+0

매우 유용하고 잘 쓰여진 답변입니다. 감사. – dazed