Ví dụ: Giao tiếp giữa Hoạt động và Dịch vụ bằng Tin nhắn


584

Tôi không thể tìm thấy bất kỳ ví dụ nào về cách gửi tin nhắn giữa một hoạt động và dịch vụ và tôi đã dành quá nhiều giờ để tìm ra điều này. Dưới đây là một dự án ví dụ để người khác tham khảo.

Ví dụ này cho phép bạn bắt đầu hoặc dừng dịch vụ trực tiếp và liên kết / hủy liên kết riêng với dịch vụ. Khi dịch vụ đang chạy, nó sẽ tăng một số ở 10 Hz. Nếu hoạt động được liên kết với Service, nó sẽ hiển thị giá trị hiện tại. Dữ liệu được truyền dưới dạng Số nguyên và dưới dạng Chuỗi để bạn có thể xem cách thực hiện theo hai cách khác nhau. Ngoài ra còn có các nút trong hoạt động để gửi tin nhắn đến dịch vụ (thay đổi giá trị tăng dần theo giá trị).

Ảnh chụp màn hình:

Ảnh chụp màn hình ví dụ nhắn tin dịch vụ Android

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 \ value \ String.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;
    }
}

53
Ví dụ tuyệt vời! Một tính năng hay khác: Nếu bạn đặt android:process=:myservicenamethuộc tính cho servicethẻ dịch vụ của bạn trong tệp kê khai của bạn, như : <service android:name="sname" android:process=":myservicename" />, thì nó sẽ chạy dịch vụ của bạn như một quy trình khác - do đó trong một luồng khác. Điều này có nghĩa là, bất kỳ tính toán nặng nào được thực hiện / yêu cầu dài bởi dịch vụ sẽ không treo luồng UI của bạn.
sydd

28
Tôi biết bạn đã nỗ lực để làm điều này, nhưng sẽ có ý nghĩa hơn khi đưa nó lên github hoặc một trang web chia sẻ mã nguồn tương tự và đăng liên kết ở đây. Mọi người dễ dàng hơn để có được nó và chạy theo cách này.
Ehtesh Choudhury

25
Ví dụ tốt. Tôi đặt mã này trên một repo trực tuyến (với các sửa đổi nhỏ) cho những ai muốn sao chép: bitbucket.org/alexfu/androidserviceexample/src
Alex Fu

7
Nhắn tin chỉ thực sự cần thiết nếu dịch vụ của bạn có thể được gọi bởi các ứng dụng khác. Nếu không, bạn có thể sử dụng Binder để trả về cho bạn một tham chiếu đến Dịch vụ và chỉ cần gọi các phương thức công khai của nó.
loại-a1pha

13
Bạn nên có câu hỏi và sau đó tự tạo một câu trả lời, không trả lời vấn đề trên câu hỏi. Ví dụ tuyệt vời;)
7hi4g0

Câu trả lời:


46

Nhìn vào ví dụ LocalService .

Của bạn Servicetrả lại một ví dụ của chính nó cho người tiêu dùng gọi onBind. Sau đó, bạn có thể tương tác trực tiếp với dịch vụ, ví dụ: đăng ký giao diện người nghe của riêng bạn với dịch vụ, để bạn có thể nhận được các cuộc gọi lại.


2
Vấn đề duy nhất là nó sẽ không sử dụng Messenger, vì vậy nó sẽ không trả lời câu hỏi giả này. Tôi đã sử dụng LocalService, nhưng tôi rất vui khi tìm thấy một ví dụ về Messenger / Handler. Tôi không tin rằng LocalService có thể được đưa vào một quy trình khác.
Ben

@ Christoper-Orr: Tôi rất biết ơn bạn đã đăng liên kết đó của Android BroadcastReceiverhướng dẫn. Tôi đã sử dụng một LocalBroadcastManagerđể liên tục trao đổi dữ liệu giữa hai Activitytrường hợp.
Dirk

Vấn đề với LocalBroadcastManagernó là nó không chặn và bạn phải chờ kết quả. Đôi khi bạn muốn kết quả ngay lập tức.
TheRealChx101

Bạn có thể vui lòng giúp tôi với câu hỏi này stackoverflow.com/questions/51508046/
Kẻ

20

Để gửi dữ liệu đến một dịch vụ bạn có thể sử dụng:

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

Và sau khi phục vụ trong onStartCommand () lấy dữ liệu từ ý định.

Để gửi dữ liệu hoặc sự kiện từ một dịch vụ đến một ứng dụng (cho một hoặc nhiều hoạt động):

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

Phương pháp này được gọi từ dịch vụ của bạn. Bạn chỉ có thể gửi dữ liệu cho Hoạt động của mình.

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

Để nhận sự kiện có dữ liệu, hãy tạo và đăng ký phương thức registerBroadcastReceivers () trong hoạt động của bạn:

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

Để gửi thêm dữ liệu, bạn có thể sửa đổi phương pháp sendBroadcastMessage();. Hãy nhớ rằng: bạn phải đăng ký chương trình phát sóng trong các phương thức onResume () & hủy đăng ký trong các phương thức onStop ()!

CẬP NHẬT

Vui lòng không sử dụng loại liên lạc giữa Hoạt động & Dịch vụ của tôi. Đây là cách sai. Để có trải nghiệm tốt hơn, vui lòng sử dụng libs đặc biệt, chẳng hạn như chúng tôi:

1) EventBus từ greenrobot

2) Otto từ Square Inc

PS Tôi chỉ sử dụng EventBus từ greenrobot trong các dự án của mình,


2
Tôi cần đăng ký reciever ở đâu trong onResume và trong onStop tôi có thể cần phải làm gì trong hoạt động không?
dùng323280

Đúng. Để nhận sự kiện từ dịch vụ, bạn phải đăng ký phát trong onResume. Hãy nhớ rằng bạn phải hủy đăng ký phát trong onStop. Bây giờ, tôi không khuyên bạn nên sử dụng phương pháp của mình. Vui lòng sử dụng các lib đặc biệt để liên lạc với các chế độ / hoạt động / dịch vụ khác như EventBus github.com/greenrobot/EventBus hoặc Otto github.com/sapes/otto
a.black13

1
Bạn có thể vui lòng giúp tôi làm thế nào tôi có thể sử dụng cái này tôi bị mắc kẹt trong dự án của tôi trong giao tiếp dịch vụ
user3233280

8
Google có khuyến nghị chống lại điều này không, hay bạn chỉ nói là "sai" vì bạn nghĩ các giải pháp khác tốt hơn?
Kevin Krumwiede

cộng với một để cung cấp các liên kết đến EventBusOtto.
Mohammed Ali

14

Lưu ý: Bạn không cần kiểm tra xem dịch vụ của bạn có đang chạy hay không CheckIfServiceIsRunning(), vì bindService()sẽ khởi động nếu dịch vụ không chạy.

Ngoài ra: nếu bạn xoay điện thoại, bạn không muốn gọi bindService()lại, vì onCreate()sẽ được gọi lại. Hãy chắc chắn để xác định onConfigurationChanged()để ngăn chặn điều này.


Trong trường hợp của tôi, tôi không cần dịch vụ chạy mọi lúc. Nếu dịch vụ đã chạy khi hoạt động bắt đầu, thì tôi muốn liên kết với nó. Nếu dịch vụ không chạy khi hoạt động bắt đầu, tôi muốn dừng dịch vụ.
Lance Lefebure

1
Tôi không chắc điều này là đúng, bindService không khởi động dịch vụ, bạn có thể vui lòng chỉ vào tài liệu không?
Calin

1
developer.android.com/reference/android/app/Service.html Đoạn đầu tiên nêu rõServices can be started with Context.startService() and Context.bindService()
Ai đó ở đâu đó

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

Vì vậy, bạn gửi nó cho dịch vụ. Sau đó nhận.


8

Mọi thứ đều ổn. Ví dụ tốt về activity/servicegiao tiếp bằng Messenger .

Một nhận xét: phương pháp MyService.isRunning()không bắt buộc .. bindService()có thể được thực hiện bất kỳ số lần. không có hại trong đó.

Nếu MyService đang chạy trong một quy trình khác thì hàm tĩnh MyService.isRunning()sẽ luôn trả về false. Vì vậy, không cần chức năng này.


2

Đây là cách tôi bắt đầu Hoạt động-> Truyền thông dịch vụ: trên Hoạt động của tôi, tôi đã có

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

Và sau đó tôi đã sử dụng điều này để bắt đầu Dịch vụ của mình

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

Trong dịch vụ của tôi, tôi đã có

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

Hi vọng điêu nay co ich


0

Dường như với tôi, bạn có thể đã lưu một số bộ nhớ bằng cách khai báo hoạt động của mình bằng "thực hiện Handler.Callback"


0

Hướng dẫn tuyệt vời, trình bày tuyệt vời. Gọn gàng, đơn giản, ngắn gọn và rất lý giải. Mặc dù, notification.setLatestEventInfo(this, getText(R.string.service_label), text, contentIntent);phương pháp không còn nữa. Như trante đã nói ở đây , cách tiếp cận tốt sẽ là:

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

Tự kiểm tra, mọi thứ hoạt động như một bùa mê (tên hoạt động và dịch vụ có thể khác với bản gốc).


0

Tôi đã thấy tất cả các câu trả lời. Tôi muốn nói cách mạnh mẽ nhất bây giờ một ngày . Điều đó sẽ khiến bạn giao tiếp giữa Activity - Service - Dialog - Fragments(Mọi thứ).

Sự kiện

Lib này mà tôi đang sử dụng trong các dự án của tôi có các tính năng tuyệt vời liên quan đến nhắn tin.

EventBus trong 3 bước

  1. Xác định các sự kiện:

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

  2. Chuẩn bị thuê bao:

Khai báo và chú thích phương thức đăng ký của bạn, tùy chọn chỉ định chế độ luồng :

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

Đăng ký và hủy đăng ký thuê bao của bạn. Ví dụ: trên Android, các hoạt động và phân đoạn thường phải đăng ký theo vòng đời của chúng:

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

@Override
public void onStop() {
    super.onStop();
    EventBus.getDefault().unregister(this);
}
  1. Đăng sự kiện:

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

Chỉ cần thêm phụ thuộc này vào cấp độ ứng dụng của bạn

compile 'org.greenrobot:eventbus:3.1.1'
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.