2015-05-12 25 views
5

Mam aplikację latarki z widżetem. Widżet służy do włączania i wyłączania latarki i nie wyświetla głównej aktywności ani niczego. Jednak po kilku godzinach widżet nic nie robi. Mam na myśli, jeśli klikniesz, nic się nie dzieje. Mam dwie klasy klasy, aby osiągnąć to Provider i Receiver.Widżet Android przestaje działać po pewnym czasie?

Provider:

public class WidgetProvider extends AppWidgetProvider { 
 

 
    @ 
 
    Override 
 
    public void onUpdate(Context context, AppWidgetManager appWidgetManager, 
 
    int[] appWidgetIds) { 
 

 
    Intent receiver = new Intent(context, FlashlightWidgetReceiver.class); 
 
    receiver.setAction("COM_FLASHLIGHT"); 
 
    receiver.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, appWidgetIds); 
 
    PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, receiver, 0); 
 

 
    RemoteViews views = new RemoteViews(context.getPackageName(), 
 
     R.layout.appwidget_layout); 
 
    views.setOnClickPendingIntent(R.id.imageButton, pendingIntent); 
 

 
    appWidgetManager.updateAppWidget(appWidgetIds, views); 
 

 
    } 
 
}

Receiver:

public class FlashlightWidgetReceiver extends BroadcastReceiver { 
 
    private static boolean isLightOn = false; 
 
    private static Camera camera; 
 
    MediaPlayer mp;@ 
 
    Override 
 
    public void onReceive(Context context, Intent intent) { 
 
    RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.appwidget_layout); 
 

 
    if (isLightOn) { 
 
     views.setImageViewResource(R.id.imageButton, R.drawable.btn_switch_off); 
 
     mp = MediaPlayer.create(context, R.raw.light_switch_off); 
 
    } else { 
 
     views.setImageViewResource(R.id.imageButton, R.drawable.btn_switch_on); 
 
     mp = MediaPlayer.create(context, R.raw.light_switch_on); 
 
    } 
 
    mp.setOnCompletionListener(new MediaPlayer.OnCompletionListener() { 
 

 
     @ 
 
     Override 
 
     public void onCompletion(MediaPlayer mp) { 
 
     // TODO Auto-generated method stub 
 
     mp.release(); 
 
     } 
 
    }); 
 
    mp.start(); 
 
    AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context); 
 
    appWidgetManager.updateAppWidget(new ComponentName(context, WidgetProvider.class), 
 
     views); 
 

 
    if (isLightOn) { 
 
     if (camera != null) { 
 
     camera.stopPreview(); 
 
     camera.release(); 
 
     camera = null; 
 
     isLightOn = false; 
 
     } 
 

 
    } else { 
 
     camera = Camera.open(); 
 

 
     if (camera == null) { 
 
     Toast.makeText(context, "No Camera!", Toast.LENGTH_SHORT).show(); 
 
     } else { 
 
     Camera.Parameters param = camera.getParameters(); 
 
     param.setFlashMode(Camera.Parameters.FLASH_MODE_TORCH); 
 
     try { 
 
      camera.setParameters(param); 
 
      camera.startPreview(); 
 
      isLightOn = true; 
 
     } catch (Exception e) { 
 
      Toast.makeText(context, "No Flash!", Toast.LENGTH_SHORT).show(); 
 
     } 
 
     } 
 
    } 
 
    } 
 
}

Setup:

<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android" 
 
    android:minWidth="40dp" 
 
    android:minHeight="40dp" 
 
    android:maxWidth="40dp" 
 
    android:maxHeight="40dp" 
 
    android:updatePeriodMillis="86400000" 
 
    android:initialLayout="@layout/appwidget_layout" 
 
    android:resizeMode="horizontal|vertical"> 
 
</appwidget-provider>

Aktualizacja: Zmniejszenie interwał aktualizacji sprawia widget odświeżyć częściej więc jeśli jest zatrzymany to działa ponownie po 30 minut, a to może zamrażać ponownie kiedyś.

Aktualizacja 2: Zmiana daty powoduje natychmiastowe zawieszenie widgetu do czasu jego odświeżenia.

Update 3: Zmiana daty jakoś restartuje wyrzutnię i gdy wyrzutnia zostaje wznowiona widget zamarza w ciągu 30 minut.

Odpowiedz

1

Alright guys, I w końcu czas, aby rozwiązać ten problem raz na zawsze :)

Stworzyłem więcej metod dla dostawcy zamiast robić wszystko, co w onUpdate, jedna ważna metoda potrzebne:

public static PendingIntent buildButtonPendingIntent(Context context) { 
 
     Intent intent = new Intent(); 
 
     intent.setAction("COM_FLASHLIGHT"); 
 
     return PendingIntent.getBroadcast(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT); 
 
    }

I ta metoda jest wywoływana przez odbiornik kiedy widżet jest kliknięty za pomocą poniższego kodu:

private void turnFlash(Context context) { 
 
    RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.appwidget_layout); 
 
    views.setOnClickPendingIntent(R.id.imageButton,  WidgetProvider.buildButtonPendingIntent(context)); 
 
}

to wszystko, nie więcej czkawka!

+0

Dlaczego ta zmiana rozwiązuje problem? – Alireza

+1

Odświeża odbiornik dla widżetu. –

+0

Cześć Mohamed, Wiem, że post od 2 lat, ale jeśli możesz podać mi kod po zmianach, lub przynajmniej powiedz mi, gdzie dzwonisz turnFlash? Będę wdzięczny tak bardzo. Próbuję utworzyć widget aplikacji, ale nadal nie do końca rozumiem, jak to działa, więc mam nadzieję, że mi pomożesz – Tefa

5

Spójrz na ten post, myślę, że ten problem jest wyjaśnione tutaj the dark side of app widgets

+0

Ładne informacje dziękuję! –

+0

Dzięki, ale post mówi o niektórych błędach systemu operacyjnego, większość zawieszeń, których doświadczamy, pochodzi z samej aplikacji i można ich uniknąć. – Alireza

Powiązane problemy