2013-07-07 10 views
5

Chcę uruchomić usługę od wewnątrz widget, wiem, że mogę to zrobić za pomocą PendingIntent jakStart/Stop Service z Widget

PendingIntent intent = PendingIntent.getService(context, 0, new Intent(context, MyService.class), Intent.FLAG_ACTIVITY_NEW_TASK); 
remoteViews.setOnClickPendingIntent(R.id.buttonWidgetStartService, intent); 

ale problemem jest to, że już na tym stosowane PendingIntent w innym celu. Więc starałem uruchamiania usługi przy użyciu

context.startService(new Intent(context, MyService.class)); 

a tu dostaję NullPointerException.

Oto mój kod:

public class WiNetWidget extends AppWidgetProvider { 

    public static String TOGGLE_WINET = "ToggleWiNetService"; 
    private static boolean serviceRunning = false; 
    private static Intent serviceIntent; 
    @Override 
    public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) { 
     final int N = appWidgetIds.length; 
     serviceIntent = new Intent(context, WiNetService.class); 

     for (int i=0; i<N; i++) { 
      int appWidgetId = appWidgetIds[i]; 
      RemoteViews remoteViews = new RemoteViews(context.getPackageName(), R.layout.widget_winet); 

      remoteViews.setViewVisibility(R.id.buttonWidgetLoading, View.INVISIBLE); 
      remoteViews.setViewVisibility(R.id.buttonWidgetStartService, View.VISIBLE); 

      Intent newIntent = new Intent(context, WiNetWidget.class); 
      newIntent.setAction(TOGGLE_WINET); 
      PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, newIntent, 0); 
      remoteViews.setOnClickPendingIntent(R.id.buttonWidgetStartService, pendingIntent); 
      remoteViews.setOnClickPendingIntent(R.id.buttonWidgetStopService, pendingIntent); 

      appWidgetManager.updateAppWidget(appWidgetId, remoteViews); 
      Log.i(TOGGLE_WINET, "updated"); 
     } 
    } 

    @Override 
    public void onReceive(Context context, Intent intent) { 
     if(intent.getAction().equals(TOGGLE_WINET)) { 
      RemoteViews remoteViews = new RemoteViews(context.getPackageName(), R.layout.widget_winet); 
      if(serviceRunning) { 
       context.stopService(serviceIntent); 
       remoteViews.setViewVisibility(R.id.buttonWidgetStartService, View.VISIBLE); 
       remoteViews.setViewVisibility(R.id.buttonWidgetStopService, View.INVISIBLE); 
       Toast.makeText(context, "serviceStopped", Toast.LENGTH_SHORT).show(); 
      } else { 
       context.startService(serviceIntent); 
       remoteViews.setViewVisibility(R.id.buttonWidgetStopService, View.VISIBLE); 
       remoteViews.setViewVisibility(R.id.buttonWidgetStartService, View.INVISIBLE); 
       Toast.makeText(context, "serviceStarted", Toast.LENGTH_SHORT).show(); 
      } 
      serviceRunning=!serviceRunning; 
      ComponentName componentName = new ComponentName(context, WiNetWidget.class); 
      AppWidgetManager.getInstance(context).updateAppWidget(componentName, remoteViews); 
     } 
     super.onReceive(context, intent); 
    } 
} 

Uwaga: Jeśli usunąć wiersze zawierające startService i stopService, wszystko odbywa się płynnie.

Z góry dziękuję !! :)

+0

Czy to działa, jeśli użyjesz 'context.startService (new Intent (context, MyService.class));' zamiast zmiennej 'serviceIntent'? –

+0

@Neil Townsend: Dziękuję, proszę pana, zadziałało. Wielkie dzięki!! Czy możesz wyjaśnić, dlaczego to nie działa wcześniej? Dzięki jeszcze raz. :) –

+0

Zobacz poniżej, aby uzyskać pełniejszą odpowiedź. –

Odpowiedz

2

Problem polegał na tym, że jednorazowo utworzono jednorazowy kod Intent, ale używaj go kilka razy. Lepiej stworzyć świeżym Intent każdym razem, gdy chcesz uruchomić lub zatrzymać Service następująco:

@Override 
public void onReceive(Context context, Intent intent) { 
    if(intent.getAction().equals(TOGGLE_WINET)) { 
     RemoteViews remoteViews = new RemoteViews(context.getPackageName(), R.layout.widget_winet); 

     // Create a fresh intent 
     Intent serviceIntent = new Intent(context, WiNetService.class); 

     if(serviceRunning) { 
      context.stopService(serviceIntent); 
      remoteViews.setViewVisibility(R.id.buttonWidgetStartService, View.VISIBLE); 
      remoteViews.setViewVisibility(R.id.buttonWidgetStopService, View.INVISIBLE); 
      Toast.makeText(context, "serviceStopped", Toast.LENGTH_SHORT).show(); 
     } else { 
      context.startService(serviceIntent); 
      remoteViews.setViewVisibility(R.id.buttonWidgetStopService, View.VISIBLE); 
      remoteViews.setViewVisibility(R.id.buttonWidgetStartService, View.INVISIBLE); 
      Toast.makeText(context, "serviceStarted", Toast.LENGTH_SHORT).show(); 
     } 
     serviceRunning=!serviceRunning; 
     ComponentName componentName = new ComponentName(context, WiNetWidget.class); 
     AppWidgetManager.getInstance(context).updateAppWidget(componentName, remoteViews); 
    } 
    super.onReceive(context, intent); 
} 
-1
Intent newIntent = new Intent(context, WiNetWidget.class); 
if(newIntent){ 
    //that means your service is already running 
    // stop your service here 
    context.stopService(newIntent); 
}else{ 
    //Its not running 
    //Start your service here 
    context.startService(newIntent); 
} 

spróbować. Dzięki

+0

proszę wyjaśnić, w jaki sposób różni się on od istniejącej odpowiedzi i co dodaje do istniejącego pytania, aby rozwiązać problem. –

+0

To jest krótki letni okres tego, co jest wymagane – Fazal