Передача данных из Activity в Service с помощью Intent

Как мне получить данные в Android Service, которые были переданы при вызове Activity?


person GobiasKoffi    schedule 20.07.2010    source источник


Ответы (9)


Первый контекст (может быть Activity/Service и т. д.)

Для Сервиса вам нужно переопределить onStartCommand там у вас есть прямой доступ к intent:

Override
public int onStartCommand(Intent intent, int flags, int startId) {

У вас есть несколько вариантов:

1) Используйте Bundle из Намерение:

Intent mIntent = new Intent(this, Example.class);
Bundle extras = mIntent.getExtras();
extras.putString(key, value);  

2) Создать новый пакет

Intent mIntent = new Intent(this, Example.class);
Bundle mBundle = new Bundle();
mBundle.extras.putString(key, value);
mIntent.putExtras(mBundle);

3) Используйте putExtra() быстрый метод Intent

Intent mIntent = new Intent(this, Example.class);
mIntent.putExtra(key, value);

Новый контекст (может быть Activity/Service и т. д.)

Intent myIntent = getIntent(); // this getter is just for example purpose, can differ
if (myIntent !=null && myIntent.getExtras()!=null)
     String value = myIntent.getExtras().getString(key);
}

ПРИМЕЧАНИЕ. Пакеты имеют методы "get" и "put" для всех примитивных типов, Parcelables и Serializables. Я просто использовал строки в демонстрационных целях.

person Pentium10    schedule 20.07.2010
comment
Но мы не можем использовать метод getIntent() внутри службы. Как этого добиться, когда мы отправляем значение из действия в службу? - person Chanaka udaya; 07.04.2013
comment
просто используйте намерение, getIntent() не требуется - person Neelay Srivastava; 08.12.2016
comment
Это не должен быть принятый ответ, так как это неправильное решение для сервисов. - person NoHarmDan; 29.08.2019

Для точного ответа на этот вопрос «Как отправлять данные через намерение из действия в службу» вам нужно переопределить метод onStartCommand(), в котором вы получаете объект намерения:

Когда вы создаете Service, вы должны переопределить метод onStartCommand(), поэтому, если вы внимательно посмотрите на подпись ниже, вы получите объект intent, который передается ему:

  public int onStartCommand(Intent intent, int flags, int startId)

Таким образом, из действия вы создадите объект намерения для запуска службы, а затем поместите свои данные в объект намерения, например, вы хотите передать UserID из Activity в Service:

 Intent serviceIntent = new Intent(YourService.class.getName())
 serviceIntent.putExtra("UserID", "123456");
 context.startService(serviceIntent);

Когда служба запущена, будет вызван ее метод onStartCommand(), поэтому в этом методе вы можете получить значение (UserID) из объекта намерения, например.

public int onStartCommand (Intent intent, int flags, int startId) {
    String userID = intent.getStringExtra("UserID");
    return START_STICKY;
}

Примечание. В приведенном выше ответе указано получить намерение с помощью метода getIntent(), который неверен в контексте службы.

person user_CC    schedule 09.04.2013
comment
Это должен был быть принятый ответ. Принятый ответ неверен для Сервиса. - person zeeshan; 06.07.2014
comment
У меня такая ошибка: Unable to start service Intent: not found - person fullOfQuestion; 30.07.2016

Если вы привяжете свою услугу, вы получите Экстра в onBind(Intent intent).

Мероприятия:

 Intent intent = new Intent(this, LocationService.class);                                                                                     
 intent.putExtra("tour_name", mTourName);                    
 bindService(intent, mServiceConnection, BIND_AUTO_CREATE); 

Услуга:

@Override
public IBinder onBind(Intent intent) {
    mTourName = intent.getStringExtra("tour_name");
    return mBinder;
}
person Martin Pfeffer    schedule 24.05.2016
comment
@ChefPharaoh, это хороший вопрос. Попробуйте записать значения намерения. Arrays.toString(yourAry[]) поможет вам здесь. - person Martin Pfeffer; 08.06.2017
comment
Поскольку я хотел передать пользовательский класс, я понял, что мне просто нужно реализовать интерфейс, который можно разделить, и все было хорошо. Спасибо хоть. - person Chef Pharaoh; 08.06.2017

Другая возможность - использовать намерение.getAction:

В сервисе:

public class SampleService inherits Service{
    static final String ACTION_START = "com.yourcompany.yourapp.SampleService.ACTION_START";
    static final String ACTION_DO_SOMETHING_1 = "com.yourcompany.yourapp.SampleService.DO_SOMETHING_1";
    static final String ACTION_DO_SOMETHING_2 = "com.yourcompany.yourapp.SampleService.DO_SOMETHING_2";
    static final String ACTION_STOP_SERVICE = "com.yourcompany.yourapp.SampleService.STOP_SERVICE";

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        String action = intent.getAction();
        //System.out.println("ACTION: "+action);
        switch (action){
            case ACTION_START:
                startingService(intent.getIntExtra("valueStart",0));
                break;
            case ACTION_DO_SOMETHING_1:
                int value1,value2;
                value1=intent.getIntExtra("value1",0);
                value2=intent.getIntExtra("value2",0);
                doSomething1(value1,value2);
                break;
            case ACTION_DO_SOMETHING_2:
                value1=intent.getIntExtra("value1",0);
                value2=intent.getIntExtra("value2",0);
                doSomething2(value1,value2);
                break;
            case ACTION_STOP_SERVICE:
                stopService();
                break;
        }
        return START_STICKY;
    }

    public void startingService(int value){
        //calling when start
    }

    public void doSomething1(int value1, int value2){
        //...
    }

    public void doSomething2(int value1, int value2){
        //...
    }

    public void stopService(){
        //...destroy/release objects
        stopself();
    }
}

В действии:

public void startService(int value){
    Intent myIntent = new Intent(SampleService.ACTION_START);
    myIntent.putExtra("valueStart",value);
    startService(myIntent);
}

public void serviceDoSomething1(int value1, int value2){
    Intent myIntent = new Intent(SampleService.ACTION_DO_SOMETHING_1);
    myIntent.putExtra("value1",value1);
    myIntent.putExtra("value2",value2);
    startService(myIntent);
}

public void serviceDoSomething2(int value1, int value2){
    Intent myIntent = new Intent(SampleService.ACTION_DO_SOMETHING_2);
    myIntent.putExtra("value1",value1);
    myIntent.putExtra("value2",value2);
    startService(myIntent);
}

public void endService(){
    Intent myIntent = new Intent(SampleService.STOP_SERVICE);
    startService(myIntent);
}

Наконец, в файле манифеста:

<service android:name=".SampleService">
    <intent-filter>
        <action android:name="com.yourcompany.yourapp.SampleService.ACTION_START"/>
        <action android:name="com.yourcompany.yourapp.SampleService.DO_SOMETHING_1"/>
        <action android:name="com.yourcompany.yourapp.SampleService.DO_SOMETHING_2"/>
        <action android:name="com.yourcompany.yourapp.SampleService.STOP_SERVICE"/>
    </intent-filter>
</service>
person Carlos Gómez    schedule 02.04.2017
comment
Вы запускаете службу несколько раз... означает ли это, что каждый раз будет создаваться несколько экземпляров одной и той же службы? - person oshurmamadov; 05.05.2017
comment
Сервисы имеют одноэлементный шаблон. stackoverflow.com/questions/2518238/ - person Carlos Gómez; 06.05.2017
comment
действие переключателя (действия) может быть нулевым - person Marian Paździoch; 16.01.2018
comment
Не в моем коде: служба всегда вызывается с использованием метода. В любом случае, это простой код, чтобы объяснить, как это сделать. В реальной программе вы всегда должны проверять эти вещи, а также, приходят ли параметры с соответствующими значениями. - person Carlos Gómez; 17.01.2018

Мероприятия:

int number = 5;
Intent i = new Intent(this, MyService.class);
i.putExtra("MyNumber", number);
startService(i);

Услуга:

@Override
public int onStartCommand(Intent intent, int flags, int startId) {
    if (intent != null && intent.getExtras() != null){
        int number = intent.getIntExtra("MyNumber", 0);
    }
}
person vishalknishad    schedule 15.09.2017

Это гораздо лучший и безопасный способ. Работает как шарм!

   private void startFloatingWidgetService() {
        startService(new Intent(MainActivity.this,FloatingWidgetService.class)
                .setAction(FloatingWidgetService.ACTION_PLAY));
    }

вместо :

 private void startFloatingWidgetService() {
        startService(new Intent(FloatingWidgetService.ACTION_PLAY));
    }

Потому что, когда вы пробуете второй, вы получаете сообщение об ошибке: java.lang.IllegalArgumentException: намерение службы должно быть явным: намерение {act=com.floatingwidgetchathead_demo.SampleService.ACTION_START

Тогда ваш сервис будет таким:

static final String ACTION_START = "com.floatingwidgetchathead_demo.SampleService.ACTION_START";
    static final String ACTION_PLAY = "com.floatingwidgetchathead_demo.SampleService.ACTION_PLAY";
    static final String ACTION_PAUSE = "com.floatingwidgetchathead_demo.SampleService.ACTION_PAUSE";
    static final String ACTION_DESTROY = "com.yourcompany.yourapp.SampleService.ACTION_DESTROY";

 @SuppressLint("LogConditional")
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
    String action = intent.getAction();
    //System.out.println("ACTION: "+action);
    switch (action){
        case ACTION_START:
            Log.d(TAG, "onStartCommand: "+action);
            break;
        case ACTION_PLAY:
            Log.d(TAG, "onStartCommand: "+action);
           addRemoveView();
           addFloatingWidgetView();
            break;
        case ACTION_PAUSE:
            Log.d(TAG, "onStartCommand: "+action);
            break;
        case ACTION_DESTROY:
            Log.d(TAG, "onStartCommand: "+action);
            break;
    }
    return START_STICKY;

}
person Debasish Ghosh    schedule 20.11.2018

Передать данные из Activity в IntentService

Вот как я передаю данные от Activity к IntentService.

В одном из моих приложений есть такой сценарий.

MusicActivity ------ URL (строка) ------ › DownloadSongService

1) Отправить данные (код активности)

  Intent intent  = new Intent(MusicActivity.class, DownloadSongService.class);
  String songUrl = "something"; 
  intent.putExtra(YOUR_KEY_SONG_NAME, songUrl);
  startService(intent);

2) Получить данные в службе (код IntentService)
Вы можете получить доступ к намерению в методе onHandleIntent()

public class DownloadSongService extends IntentService {

    @Override
    protected void onHandleIntent(@Nullable Intent intent) {

        String songUrl = intent.getStringExtra("YOUR_KEY_SONG_NAME");

        //  Download File logic
    
    }

}
person Rohit Singh    schedule 21.12.2018

Служба: startservice может вызвать побочные эффекты, лучший способ использовать мессенджер и передавать данные.

private CallBackHandler mServiceHandler= new CallBackHandler(this);
private Messenger mServiceMessenger=null;
//flag with which the activity sends the data to service
private static final int DO_SOMETHING=1;

private static class CallBackHandler extends android.os.Handler {

private final WeakReference<Service> mService;

public CallBackHandler(Service service) {
    mService= new WeakReference<Service>(service);
}

public void handleMessage(Message msg) {
    //Log.d("CallBackHandler","Msg::"+msg);
    if(DO_SOMETHING==msg.arg1)
    mSoftKeyService.get().dosomthing()
}
}

Действие: Получите Messenger от Intent, заполните его, передайте данные и передайте сообщение обратно в службу.

private Messenger mServiceMessenger;
@Override
protected void onCreate(Bundle savedInstanceState) {
mServiceMessenger = (Messenger)extras.getParcelable("myHandler");
}


private void sendDatatoService(String data){
Intent serviceIntent= new 
Intent(BaseActivity.this,Service.class);
Message msg = Message.obtain();
msg.obj =data;
msg.arg1=Service.DO_SOMETHING;
mServiceMessenger.send(msg);
}
person surya    schedule 17.01.2018

Если вы используете kotlin, вы можете попробовать следующий код:

В отправке активности

  val intent = Intent(context, RecorderService::class.java);
  intent.putExtra("filename", filename);
  context.startService(intent)

На службе,

override fun onStartCommand(intent: Intent, flags: Int, startId: Int): Int {
    super.onStartCommand(intent, flags, startId)

    if (intent != null && intent.extras != null)
       val filename = intent.getStringExtra("filename")

}
person Codemaker    schedule 03.08.2020