2013-06-30 26 views
7

kullanarak ana ekranda bir pencere öğesi olup olmadığını kontrol edin AlarmManager kullanıyorum. Ve ana ekranda widget yok ise onu durdurmak istiyorum. Ancak, ana ekranda herhangi bir widget olup olmadığını tespit etmekle ilgili bir sorunla karşılaşıyorum. Bu şekilde kullanarak AppWidgetIds elde etmeye çalışmak zaman olduğu gibiWidget'ları güncellemek için appWidgetId

: aslında ana ekrandaki hiçbir Widget varken

AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context); 

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

Ben appWidgetIDs uzunluğu olsun. Neden?

Bu nedenle, bir widget kimliğinin ana ekranda var olduğunu algılamanın bir yolu olup olmadığını bilmek istiyorum.

Teşekkür ederiz.

cevap

16

Tebrikler, phantom appwidgets ile karşılaştınız. Android issue tracker'da belgelenmiş gibi görünüyor. Genellikle, bir appwidget yapılandırma faaliyeti iptal edildiğinde gerçekleşir, ancak yapılandırma etkinliğinin hatalı bir şekilde uygulanmasıyla olduğu anlaşılmaktadır; Geliştiriciler, etkinlik sonucunu RESULT_CANCELED olarak ayarlarken, appwidget kimliğini ek olarak eklemeyi ihmal eder.

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); 
    } 
} 

Şimdiye kadar ben kendi muhasebe yapmadan bir fantom appwidget varlığını tespit için hiçbir yol biliyorum:

doğru bir şekilde çalışmak böyledir (! Hatta Google'ın ApiDemos örnek uygulama bunu ihmal) . Yapılandırma etkinliğinin iptal edilmediğini ve ardından bu değeri diğer kodunuzda sorguladığını belirten bir SharedPreferences değeri depolamanızı öneririm. Ayrıca, bu bilgiyi, birine rastlarsanız bir hayali parçacığı "silmek" için de kullanabilirsiniz. senin appwidget yapılandırma etkinliği:

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; 
} 

O zaman en azından bir sigara fantom şöyle appwidget sahip olduğunu kontrol edebilirsiniz:

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

Bu cevap çok daha fazla övgü hak ediyor! Ben Android Studio'dan aldığınız örnek "merhaba dünya" appwidget kodu düzgün yapmaz çünkü bu kadar çok insanın bu sorunu yaşıyor olacağına inanıyorum (ve burası çok) insanlar başlayacak. Etkinlik sonucunu "RESULT_CANCELED" olarak ayarlarken ek olarak appwidget kimliğini eklemeye ilişkin tavsiyenizle artık herhangi bir fantom öğesi oluşturmuyorum. Teşekkürler! – drmrbrewer

+0

Phantom widget'larını silme koduna gelince * bunlar * her ne sebeple olursa olsun, nereye koymanızı önerirsiniz? OnUpdate() 'de değil çünkü bu, bir yapılandırma etkinliğinin ilk açıldığında, yani pencere öğesi yapılandırılmadan önce çağrılmış gibi görünüyor - doğmadan önce widget'ı öldürmek istemiyorum! – drmrbrewer

+0

Çok yardımcı ve iyi yazılmış bir cevap. Teşekkürler. – dazed