Übergeben Sie Daten von Aktivität mit einer Absicht an den Dienst

Antworten:

39

Erster Kontext (kann Aktivität / Service usw. sein)

Für Service müssen Sie onStartCommand überschreiben, auf das Sie direkten Zugriff haben intent:

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

Sie haben einige Möglichkeiten:

1) Verwenden Sie das Bundle aus der Absicht :

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

2) Erstellen Sie ein neues Bundle

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

3) Verwenden Sie die Verknüpfungsmethode putExtra () des Intent

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

Neuer Kontext (kann Aktivität / Service usw. sein)

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

HINWEIS: Bundles verfügen über die Methoden "get" und "put" für alle primitiven Typen, Parcelables und Serializables. Ich habe Strings nur zu Demonstrationszwecken verwendet.

Pentium10
quelle
29
Wir können die Methode getIntent () jedoch nicht in einem Dienst verwenden. Wie kann dies erreicht werden, wenn wir Wert von Aktivität zu Service senden?
Chanaka udaya
4
Verwenden Sie einfach Intent, es ist kein getIntent () erforderlich
Neelay Srivastava
Dies sollte nicht die akzeptierte Antwort sein, da dies nicht die richtige Lösung für Dienste ist.
NoHarmDan
210

Um eine genaue Antwort auf diese Frage zum Thema "Senden von Daten über eine Absicht von einer Aktivität an einen Dienst" zu erhalten, müssen Sie die onStartCommand()Methode überschreiben, mit der Sie das Absichtsobjekt erhalten:

Wenn Sie eine erstellen Service, sollten Sie die onStartCommand()Methode überschreiben. Wenn Sie sich die Signatur unten genau ansehen, erhalten Sie hier das intentObjekt, das an sie übergeben wird:

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

Aus einer Aktivität heraus erstellen Sie das Intent-Objekt, um den Dienst zu starten, und platzieren Ihre Daten dann im Intent-Objekt, z. B. möchten Sie ein UserIDvon Activityan übergeben Service:

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

Wenn der Dienst gestartet wird, wird seine onStartCommand()Methode aufgerufen, sodass Sie in dieser Methode beispielsweise den Wert (UserID) aus dem Intent-Objekt abrufen können

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

Hinweis: Die obige Antwort gibt an, dass eine Intent with- getIntent()Methode abgerufen werden soll, die im Kontext eines Dienstes nicht korrekt ist

user_CC
quelle
50
Dies sollte die akzeptierte Antwort gewesen sein. Die akzeptierte Antwort ist für den Service falsch.
Zeeshan
1
Ich habe diesen Fehler:Unable to start service Intent: not found
fullOfQuestion
9

Wenn Sie Ihren Dienst binden, erhalten Sie das Extra in onBind(Intent intent).

Aktivität:

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

Bedienung:

@Override
public IBinder onBind(Intent intent) {
    mTourName = intent.getStringExtra("tour_name");
    return mBinder;
}
Martin Pfeffer
quelle
@ChefPharaoh das ist eine gute Frage. Versuchen Sie, die Werte der Absicht zu protokollieren. Arrays.toString(yourAry[])wird dir hier helfen.
Martin Pfeffer
1
Da ich eine benutzerdefinierte Klasse bestehen wollte, stellte ich fest, dass ich nur die Paketschnittstelle implementieren musste und alles gut war. Trotzdem danke.
Chef Pharao
6

Eine andere Möglichkeit ist die Verwendung von intent.getAction:

Im Dienst:

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

In Aktivität:

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

Schließlich In Manifest-Datei:

<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>
Carlos Gómez
quelle
Sie starten den Dienst mehrmals ... bedeutet dies, dass jedes Mal mehrere Instanzen desselben Dienstes erstellt werden?
oshurmamadov
4
Dienste haben ein Singleton-Muster. stackoverflow.com/questions/2518238/…
Carlos Gómez
"switch (action)" action kann null sein
Marian Paździoch
Nicht in meinem Code: Der Dienst wird immer mit einer Methode aufgerufen. In jedem Fall ist es ein einfacher Code, der erklärt, wie es geht. In einem realen Programm müssen Sie diese Dinge immer überprüfen und auch, ob die Parameter mit den entsprechenden Werten ankommen
Carlos Gómez
2

Aktivität:

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

Bedienung:

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

Dies ist ein viel besserer und sicherer Weg. Arbeiten wie ein Zauber!

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

Anstatt von :

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

Wenn Sie den zweiten Versuch ausführen, wird die folgende Fehlermeldung angezeigt : java.lang.IllegalArgumentException: Die Dienstabsicht muss explizit sein: Absicht {act = com.floatingwidgetchathead_demo.SampleService.ACTION_START}

Dann ist Ihr Service so:

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;

}
Debasish Ghosh
quelle
1

Übergeben Sie Daten von Activity an IntentService

So übergebe ich Daten von Activityan IntentService.

Eine meiner Anwendungen hat dieses Szenario.

MusicActivity ------ url (String) ------> DownloadSongService

1) Daten senden (Aktivitätscode)

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

2) Daten in Service abrufen (IntentService-Code)
Sie können auf die Intent in der onHandleIntent()Methode zugreifen

public class DownloadSongService extends IntentService {

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

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

        //  Download File logic
    
    }

}
Rohit Singh
quelle
0

Service: Startservice kann Nebenwirkungen verursachen, die beste Möglichkeit, Messenger zu verwenden und Daten weiterzugeben.

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

Aktivität: Lassen Sie Messenger von Intent ausfüllen, übergeben Sie die Daten und geben Sie die Nachricht an den Dienst zurück

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);
}
Surya
quelle
0

Wenn Sie Kotlin verwenden, können Sie den folgenden Code ausprobieren:

In der Sendetätigkeit

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

Im Dienste,

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

}
Codemaker
quelle