Beispiel: Kommunikation zwischen Aktivität und Dienst über Messaging

584

Ich konnte keine Beispiele dafür finden, wie Nachrichten zwischen einer Aktivität und einem Dienst gesendet werden können, und ich habe viel zu viele Stunden damit verbracht, dies herauszufinden. Hier ist ein Beispielprojekt, auf das andere verweisen können.

In diesem Beispiel können Sie einen Dienst direkt starten oder stoppen und ihn separat vom Dienst binden / trennen. Wenn der Dienst ausgeführt wird, erhöht er eine Zahl mit 10 Hz. Wenn die Aktivität an gebunden ist Service, wird der aktuelle Wert angezeigt. Daten werden als Ganzzahl und als Zeichenfolge übertragen, sodass Sie auf zwei verschiedene Arten sehen können, wie dies funktioniert. In der Aktivität gibt es auch Schaltflächen zum Senden von Nachrichten an den Dienst (ändert den Inkrementierungswert).

Bildschirmfoto:

Screenshot des Android Service Messaging-Beispiels

AndroidManifest.xml:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
      package="com.exampleservice"
      android:versionCode="1"
      android:versionName="1.0">
    <application android:icon="@drawable/icon" android:label="@string/app_name">
        <activity android:name=".MainActivity"
                  android:label="@string/app_name">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    <service android:name=".MyService"></service>
    </application>
    <uses-sdk android:minSdkVersion="8" />
</manifest>

res \ values ​​\ strings.xml:

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string name="app_name">ExampleService</string>
    <string name="service_started">Example Service started</string>
    <string name="service_label">Example Service Label</string>
</resources>

res \ layout \ main.xml:

<RelativeLayout
    android:id="@+id/RelativeLayout01"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content" >

    <Button
        android:id="@+id/btnStart"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Start Service" >
    </Button>

    <Button
        android:id="@+id/btnStop"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentRight="true"
        android:text="Stop Service" >
    </Button>
</RelativeLayout>

<RelativeLayout
    android:id="@+id/RelativeLayout02"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content" >

    <Button
        android:id="@+id/btnBind"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Bind to Service" >
    </Button>

    <Button
        android:id="@+id/btnUnbind"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentRight="true"
        android:text="Unbind from Service" >
    </Button>
</RelativeLayout>

<TextView
    android:id="@+id/textStatus"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:text="Status Goes Here"
    android:textSize="24sp" />

<TextView
    android:id="@+id/textIntValue"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:text="Integer Value Goes Here"
    android:textSize="24sp" />

<TextView
    android:id="@+id/textStrValue"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:text="String Value Goes Here"
    android:textSize="24sp" />

<RelativeLayout
    android:id="@+id/RelativeLayout03"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content" >

    <Button
        android:id="@+id/btnUpby1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Increment by 1" >
    </Button>

    <Button
        android:id="@+id/btnUpby10"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentRight="true"
        android:text="Increment by 10" >
    </Button>
</RelativeLayout>

src \ com.exampleservice \ MainActivity.java:

package com.exampleservice;

import android.app.Activity;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.os.Messenger;
import android.os.RemoteException;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;

public class MainActivity extends Activity {
    Button btnStart, btnStop, btnBind, btnUnbind, btnUpby1, btnUpby10;
    TextView textStatus, textIntValue, textStrValue;
    Messenger mService = null;
    boolean mIsBound;
    final Messenger mMessenger = new Messenger(new IncomingHandler());

    class IncomingHandler extends Handler {
        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
            case MyService.MSG_SET_INT_VALUE:
                textIntValue.setText("Int Message: " + msg.arg1);
                break;
            case MyService.MSG_SET_STRING_VALUE:
                String str1 = msg.getData().getString("str1");
                textStrValue.setText("Str Message: " + str1);
                break;
            default:
                super.handleMessage(msg);
            }
        }
    }
    private ServiceConnection mConnection = new ServiceConnection() {
        public void onServiceConnected(ComponentName className, IBinder service) {
            mService = new Messenger(service);
            textStatus.setText("Attached.");
            try {
                Message msg = Message.obtain(null, MyService.MSG_REGISTER_CLIENT);
                msg.replyTo = mMessenger;
                mService.send(msg);
            }
            catch (RemoteException e) {
                // In this case the service has crashed before we could even do anything with it
            }
        }

        public void onServiceDisconnected(ComponentName className) {
            // This is called when the connection with the service has been unexpectedly disconnected - process crashed.
            mService = null;
            textStatus.setText("Disconnected.");
        }
    };

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        btnStart = (Button)findViewById(R.id.btnStart);
        btnStop = (Button)findViewById(R.id.btnStop);
        btnBind = (Button)findViewById(R.id.btnBind);
        btnUnbind = (Button)findViewById(R.id.btnUnbind);
        textStatus = (TextView)findViewById(R.id.textStatus);
        textIntValue = (TextView)findViewById(R.id.textIntValue);
        textStrValue = (TextView)findViewById(R.id.textStrValue);
        btnUpby1 = (Button)findViewById(R.id.btnUpby1);
        btnUpby10 = (Button)findViewById(R.id.btnUpby10);

        btnStart.setOnClickListener(btnStartListener);
        btnStop.setOnClickListener(btnStopListener);
        btnBind.setOnClickListener(btnBindListener);
        btnUnbind.setOnClickListener(btnUnbindListener);
        btnUpby1.setOnClickListener(btnUpby1Listener);
        btnUpby10.setOnClickListener(btnUpby10Listener);

        restoreMe(savedInstanceState);

        CheckIfServiceIsRunning();
    }

    @Override
    protected void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        outState.putString("textStatus", textStatus.getText().toString());
        outState.putString("textIntValue", textIntValue.getText().toString());
        outState.putString("textStrValue", textStrValue.getText().toString());
    }
    private void restoreMe(Bundle state) {
        if (state!=null) {
            textStatus.setText(state.getString("textStatus"));
            textIntValue.setText(state.getString("textIntValue"));
            textStrValue.setText(state.getString("textStrValue"));
        }
    }
    private void CheckIfServiceIsRunning() {
        //If the service is running when the activity starts, we want to automatically bind to it.
        if (MyService.isRunning()) {
            doBindService();
        }
    }

    private OnClickListener btnStartListener = new OnClickListener() {
        public void onClick(View v){
            startService(new Intent(MainActivity.this, MyService.class));
        }
    };
    private OnClickListener btnStopListener = new OnClickListener() {
        public void onClick(View v){
            doUnbindService();
            stopService(new Intent(MainActivity.this, MyService.class));
        }
    };
    private OnClickListener btnBindListener = new OnClickListener() {
        public void onClick(View v){
            doBindService();
        }
    };
    private OnClickListener btnUnbindListener = new OnClickListener() {
        public void onClick(View v){
            doUnbindService();
        }
    };
    private OnClickListener btnUpby1Listener = new OnClickListener() {
        public void onClick(View v){
            sendMessageToService(1);
        }
    };
    private OnClickListener btnUpby10Listener = new OnClickListener() {
        public void onClick(View v){
            sendMessageToService(10);
        }
    };
    private void sendMessageToService(int intvaluetosend) {
        if (mIsBound) {
            if (mService != null) {
                try {
                    Message msg = Message.obtain(null, MyService.MSG_SET_INT_VALUE, intvaluetosend, 0);
                    msg.replyTo = mMessenger;
                    mService.send(msg);
                }
                catch (RemoteException e) {
                }
            }
        }
    }


    void doBindService() {
        bindService(new Intent(this, MyService.class), mConnection, Context.BIND_AUTO_CREATE);
        mIsBound = true;
        textStatus.setText("Binding.");
    }
    void doUnbindService() {
        if (mIsBound) {
            // If we have received the service, and hence registered with it, then now is the time to unregister.
            if (mService != null) {
                try {
                    Message msg = Message.obtain(null, MyService.MSG_UNREGISTER_CLIENT);
                    msg.replyTo = mMessenger;
                    mService.send(msg);
                }
                catch (RemoteException e) {
                    // There is nothing special we need to do if the service has crashed.
                }
            }
            // Detach our existing connection.
            unbindService(mConnection);
            mIsBound = false;
            textStatus.setText("Unbinding.");
        }
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        try {
            doUnbindService();
        }
        catch (Throwable t) {
            Log.e("MainActivity", "Failed to unbind from the service", t);
        }
    }
}

src \ com.exampleservice \ MyService.java:

package com.exampleservice;

import java.util.ArrayList;
import java.util.Timer;
import java.util.TimerTask;

import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.os.Messenger;
import android.os.RemoteException;
import android.util.Log;

public class MyService extends Service {
    private NotificationManager nm;
    private Timer timer = new Timer();
    private int counter = 0, incrementby = 1;
    private static boolean isRunning = false;

    ArrayList<Messenger> mClients = new ArrayList<Messenger>(); // Keeps track of all current registered clients.
    int mValue = 0; // Holds last value set by a client.
    static final int MSG_REGISTER_CLIENT = 1;
    static final int MSG_UNREGISTER_CLIENT = 2;
    static final int MSG_SET_INT_VALUE = 3;
    static final int MSG_SET_STRING_VALUE = 4;
    final Messenger mMessenger = new Messenger(new IncomingHandler()); // Target we publish for clients to send messages to IncomingHandler.


    @Override
    public IBinder onBind(Intent intent) {
        return mMessenger.getBinder();
    }
    class IncomingHandler extends Handler { // Handler of incoming messages from clients.
        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
            case MSG_REGISTER_CLIENT:
                mClients.add(msg.replyTo);
                break;
            case MSG_UNREGISTER_CLIENT:
                mClients.remove(msg.replyTo);
                break;
            case MSG_SET_INT_VALUE:
                incrementby = msg.arg1;
                break;
            default:
                super.handleMessage(msg);
            }
        }
    }
    private void sendMessageToUI(int intvaluetosend) {
        for (int i=mClients.size()-1; i>=0; i--) {
            try {
                // Send data as an Integer
                mClients.get(i).send(Message.obtain(null, MSG_SET_INT_VALUE, intvaluetosend, 0));

                //Send data as a String
                Bundle b = new Bundle();
                b.putString("str1", "ab" + intvaluetosend + "cd");
                Message msg = Message.obtain(null, MSG_SET_STRING_VALUE);
                msg.setData(b);
                mClients.get(i).send(msg);

            }
            catch (RemoteException e) {
                // The client is dead. Remove it from the list; we are going through the list from back to front so this is safe to do inside the loop.
                mClients.remove(i);
            }
        }
    }

    @Override
    public void onCreate() {
        super.onCreate();
        Log.i("MyService", "Service Started.");
        showNotification();
        timer.scheduleAtFixedRate(new TimerTask(){ public void run() {onTimerTick();}}, 0, 100L);
        isRunning = true;
    }
    private void showNotification() {
        nm = (NotificationManager)getSystemService(NOTIFICATION_SERVICE);
        // In this sample, we'll use the same text for the ticker and the expanded notification
        CharSequence text = getText(R.string.service_started);
        // Set the icon, scrolling text and timestamp
        Notification notification = new Notification(R.drawable.icon, text, System.currentTimeMillis());
        // The PendingIntent to launch our activity if the user selects this notification
        PendingIntent contentIntent = PendingIntent.getActivity(this, 0, new Intent(this, MainActivity.class), 0);
        // Set the info for the views that show in the notification panel.
        notification.setLatestEventInfo(this, getText(R.string.service_label), text, contentIntent);
        // Send the notification.
        // We use a layout id because it is a unique number.  We use it later to cancel.
        nm.notify(R.string.service_started, notification);
    }
    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        Log.i("MyService", "Received start id " + startId + ": " + intent);
        return START_STICKY; // run until explicitly stopped.
    }

    public static boolean isRunning()
    {
        return isRunning;
    }


    private void onTimerTick() {
        Log.i("TimerTick", "Timer doing work." + counter);
        try {
            counter += incrementby;
            sendMessageToUI(counter);

        }
        catch (Throwable t) { //you should always ultimately catch all exceptions in timer tasks.
            Log.e("TimerTick", "Timer Tick Failed.", t);
        }
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        if (timer != null) {timer.cancel();}
        counter=0;
        nm.cancel(R.string.service_started); // Cancel the persistent notification.
        Log.i("MyService", "Service Stopped.");
        isRunning = false;
    }
}
Lance Lefebure
quelle
53
Tolles Beispiel! Eine weitere nette Funktion: Wenn Sie android:process=:myservicenamedem serviceTag Ihres Dienstes in Ihrer manifest.xml ein Attribut hinzufügen, wie z. B. <service android:name="sname" android:process=":myservicename" />, wird Ihr Dienst als ein anderer Prozess ausgeführt - also in einem anderen Thread. Dies bedeutet, dass eine umfangreiche Berechnung / lange Anforderung durch den Dienst Ihren UI-Thread nicht hängen lässt.
Sydney
28
Ich weiß, dass Sie sich die Mühe gemacht haben, dies zu tun, aber es wäre sinnvoller, es auf Github oder einer ähnlichen Site zum Teilen von Quellcode zu veröffentlichen und den Link hier zu veröffentlichen. Es ist für die Leute einfacher, es auf diese Weise zum Laufen zu bringen.
Ehtesh Choudhury
25
Gutes Beispiel. Ich habe diesen Code in ein Online-Repo (mit geringfügigen Änderungen) für diejenigen gestellt, die klonen möchten
Alex Fu
7
Messaging ist nur dann wirklich erforderlich, wenn Ihr Dienst von anderen Anwendungen aufgerufen werden kann. Andernfalls bleiben Sie möglicherweise bei einem Ordner, der Ihnen einen Verweis auf den Dienst zurückgibt, und rufen einfach öffentliche Methoden auf.
Typ-a1pha
13
Sie sollten die Frage gestellt und dann selbst eine Antwort erstellt haben, nicht das Problem mit der Frage beantworten. Tolles Beispiel;)
7hi4g0

Antworten:

46

Schauen Sie sich das LocalService-Beispiel an .

Sie geben Serviceeine Instanz von sich an Verbraucher zurück, die anrufen onBind. Anschließend können Sie direkt mit dem Dienst interagieren, z. B. Ihre eigene Listener-Schnittstelle beim Dienst registrieren, um Rückrufe zu erhalten.

Christopher Orr
quelle
2
Das einzige Problem dabei ist, dass es keinen Messenger verwenden würde, also würde es diese Pseudofrage nicht beantworten. Ich habe einen LocalService verwendet, war aber froh, ein Beispiel für einen Messenger / Handler zu finden. Ich glaube nicht, dass ein LocalService in einen anderen Prozess integriert werden kann.
Ben
@ Christoper-Orr: Ich bin sehr dankbar, dass Sie diesen Link des Android BroadcastReceiverTutorials gepostet haben . Ich habe a verwendet, LocalBroadcastManagerum kontinuierlich Daten zwischen zwei ActivityInstanzen auszutauschen .
Dirk
Das Problem dabei LocalBroadcastManagerist, dass es nicht blockiert und Sie auf Ergebnisse warten müssen. Manchmal möchten Sie sofortige Ergebnisse.
TheRealChx101
Können Sie mir bitte bei dieser Frage helfen stackoverflow.com/questions/51508046/…
Rajesh K
20

Zum Senden von Daten an einen Dienst können Sie Folgendes verwenden:

Intent intent = new Intent(getApplicationContext(), YourService.class);
intent.putExtra("SomeData","ItValue");
startService(intent);

Und nach dem Dienst in onStartCommand () erhalten Sie Daten aus Absicht.

Zum Senden von Daten oder Ereignissen von einem Dienst an eine Anwendung (für eine oder mehrere Aktivitäten):

private void sendBroadcastMessage(String intentFilterName, int arg1, String extraKey) {
    Intent intent = new Intent(intentFilterName);
    if (arg1 != -1 && extraKey != null) {
        intent.putExtra(extraKey, arg1);
    }
    sendBroadcast(intent);
}

Diese Methode ruft von Ihrem Dienst auf. Sie können einfach Daten für Ihre Aktivität senden.

private void someTaskInYourService(){

    //For example you downloading from server 1000 files
    for(int i = 0; i < 1000; i++) {
        Thread.sleep(5000) // 5 seconds. Catch in try-catch block
        sendBroadCastMessage(Events.UPDATE_DOWNLOADING_PROGRESSBAR, i,0,"up_download_progress");
    }

Um ein Ereignis mit Daten zu empfangen, erstellen und registrieren Sie die Methode registerBroadcastReceivers () in Ihrer Aktivität:

private void registerBroadcastReceivers(){
    broadcastReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            int arg1 = intent.getIntExtra("up_download_progress",0);
            progressBar.setProgress(arg1);
        }
    };
    IntentFilter progressfilter = new IntentFilter(Events.UPDATE_DOWNLOADING_PROGRESS);
    registerReceiver(broadcastReceiver,progressfilter);

Um weitere Daten zu senden, können Sie die Methode ändern sendBroadcastMessage();. Denken Sie daran: Sie müssen Broadcasts in onResume () registrieren und die Registrierung in onStop () -Methoden aufheben!

AKTUALISIEREN

Bitte verwenden Sie nicht meine Art der Kommunikation zwischen Aktivität und Service. Das ist der falsche Weg. Für eine bessere Erfahrung verwenden Sie bitte spezielle Bibliotheken, wie uns:

1) EventBus von Greenrobot

2) Otto von Square Inc.

PS Ich verwende EventBus von Greenrobot nur in meinen Projekten.

a.black13
quelle
2
Wo muss ich den Empfänger in onResume und in onStop registrieren? Muss ich dies in der Aktivität tun?
user3233280
Ja. Um ein Ereignis vom Dienst zu empfangen, müssen Sie die Übertragung in onResume registrieren. Denken Sie daran, dass Sie die Registrierung von Broadcasts in onStop aufheben müssen. Jetzt empfehle ich nicht, meine Methode zu verwenden. Bitte verwenden Sie spezielle Bibliotheken für die Kommunikation mit anderen Ansichten / Aktivitäten / Diensten wie EventBus github.com/greenrobot/EventBus oder Otto github.com/square/otto
a.black13
1
Können Sie mir helfen, wie kann ich dies verwenden? Ich steckte in meinem Projekt in Service-Kommunikation
Benutzer3233280
8
Hat Google dagegen empfohlen, oder sagen Sie nur, dass es "falsch" ist, weil Sie der Meinung sind, dass die anderen Lösungen besser sind?
Kevin Krumwiede
plus eine für die Bereitstellung von Links zu EventBusund Otto.
Mohammed Ali
14

Hinweis: Sie müssen nicht überprüfen, ob Ihr Dienst ausgeführt wird CheckIfServiceIsRunning(), da er bindService()gestartet wird, wenn er nicht ausgeführt wird.

Außerdem: Wenn Sie das Telefon drehen, möchten Sie es nicht bindService()erneut, da onCreate()es erneut angerufen wird. Stellen Sie sicher onConfigurationChanged(), dass Sie dies definieren , um dies zu verhindern.

Irgendwer irgendwo
quelle
In meinem Fall muss der Dienst nicht ständig ausgeführt werden. Wenn der Dienst bereits ausgeführt wird, wenn die Aktivität gestartet wird, möchte ich ihn binden. Wenn der Dienst beim Start der Aktivität nicht ausgeführt wird, möchte ich den Dienst gestoppt lassen.
Lance Lefebure
1
Ich bin nicht sicher, ob dies der Fall ist. BindService startet den Dienst nicht. Können Sie bitte auf die Dokumentation verweisen?
Calin
1
developer.android.com/reference/android/app/Service.html Der erste Absatz besagtServices can be started with Context.startService() and Context.bindService()
Jemand irgendwo
8
Message msg = Message.obtain(null, 2, 0, 0);
                    Bundle bundle = new Bundle();
                    bundle.putString("url", url);
                    bundle.putString("names", names);
                    bundle.putString("captions",captions); 
                    msg.setData(bundle);

Sie senden es also an den Dienst. Danach erhalten.

user1964369
quelle
8

Alles ist in Ordnung. Gutes Beispiel für die activity/serviceKommunikation mit Messenger .

Ein Kommentar: Die Methode MyService.isRunning()ist nicht erforderlich. bindService()Kann beliebig oft durchgeführt werden. das schadet nicht.

Wenn MyService in einem anderen Prozess ausgeführt wird, gibt die statische Funktion MyService.isRunning()immer false zurück. Diese Funktion ist also nicht erforderlich.

Ishank Gupta
quelle
2

So habe ich Activity-> Service Communication implementiert: für meine Aktivität, die ich hatte

private static class MyResultReciever extends ResultReceiver {
     /**
     * Create a new ResultReceive to receive results.  Your
     * {@link #onReceiveResult} method will be called from the thread running
     * <var>handler</var> if given, or from an arbitrary thread if null.
     *
     * @param handler
     */
     public MyResultReciever(Handler handler) {
         super(handler);
     }

     @Override
     protected void onReceiveResult(int resultCode, Bundle resultData) {
         if (resultCode == 100) {
             //dostuff
         }
     }

Und dann habe ich damit meinen Service gestartet

protected void onCreate(Bundle savedInstanceState) {
MyResultReciever resultReciever = new MyResultReciever(handler);
        service = new Intent(this, MyService.class);
        service.putExtra("receiver", resultReciever);
        startService(service);
}

In meinem Dienst hatte ich

public int onStartCommand(Intent intent, int flags, int startId) {
    if (intent != null)
        resultReceiver = intent.getParcelableExtra("receiver");
    return Service.START_STICKY;
}

Hoffe das hilft

Ketrox
quelle
0

Mir scheint, Sie hätten Speicherplatz sparen können, indem Sie Ihre Aktivität mit "implementiert Handler.Callback" deklariert haben.

Quasaurier
quelle
0

Tolles Tutorial, fantastische Präsentation. Ordentlich, einfach, kurz und sehr erklärend. Obwohl notification.setLatestEventInfo(this, getText(R.string.service_label), text, contentIntent);Methode nicht mehr ist. Wie Trante hier sagte , wäre ein guter Ansatz:

private static final int NOTIFICATION_ID = 45349;

private void showNotification() {
    NotificationCompat.Builder builder =
            new NotificationCompat.Builder(this)
                    .setSmallIcon(R.mipmap.ic_launcher)
                    .setContentTitle("My Notification Title")
                    .setContentText("Something interesting happened");

    Intent targetIntent = new Intent(this, MainActivity.class);
    PendingIntent contentIntent = PendingIntent.getActivity(this, 0, targetIntent, PendingIntent.FLAG_UPDATE_CURRENT);
    builder.setContentIntent(contentIntent);
    _nManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
    _nManager.notify(NOTIFICATION_ID, builder.build());
}

@Override
public void onDestroy() {
    super.onDestroy();
    if (_timer != null) {_timer.cancel();}
    _counter=0;
    _nManager.cancel(NOTIFICATION_ID); // Cancel the persistent notification.
    Log.i("PlaybackService", "Service Stopped.");
    _isRunning = false;
}

Ich habe selbst überprüft, dass alles wie ein Zauber funktioniert (Aktivitäts- und Servicenamen können vom Original abweichen).

Grünhaut
quelle
0

Ich habe alle Antworten gesehen. Ich möchte jetzt jeden Tag den robustesten Weg erzählen . Dadurch können Sie zwischen Activity - Service - Dialog - Fragments(allem) kommunizieren .

EventBus

Diese Bibliothek, die ich in meinen Projekten verwende, hat großartige Funktionen im Zusammenhang mit Messaging.

EventBus in 3 Schritten

  1. Ereignisse definieren:

    public static class MessageEvent { /* Additional fields if needed */ }

  2. Abonnenten vorbereiten:

Deklarieren und kommentieren Sie Ihre Abonnementmethode und geben Sie optional einen Thread-Modus an :

@Subscribe(threadMode = ThreadMode.MAIN) 
public void onMessageEvent(MessageEvent event) {/* Do something */};

Registrieren Sie Ihren Abonnenten und heben Sie die Registrierung auf. Beispielsweise sollten sich Aktivitäten und Fragmente unter Android normalerweise entsprechend ihrem Lebenszyklus registrieren:

@Override
public void onStart() {
    super.onStart();
    EventBus.getDefault().register(this);
}

@Override
public void onStop() {
    super.onStop();
    EventBus.getDefault().unregister(this);
}
  1. Ereignisse veröffentlichen:

    EventBus.getDefault().post(new MessageEvent());

Fügen Sie diese Abhängigkeit einfach in Ihren App-Level-Gradle ein

compile 'org.greenrobot:eventbus:3.1.1'
Khemraj
quelle