Starten Sie den Dienst in Android

115

Ich möchte einen Dienst anrufen, wenn eine bestimmte Aktivität beginnt. Hier ist also die Service-Klasse:

public class UpdaterServiceManager extends Service {

    private final int UPDATE_INTERVAL = 60 * 1000;
    private Timer timer = new Timer();
    private static final int NOTIFICATION_EX = 1;
    private NotificationManager notificationManager;

    public UpdaterServiceManager() {}

    @Override
    public IBinder onBind(Intent intent) {
        // TODO Auto-generated method stub
        return null;
    }

    @Override
    public void onCreate() {
        // Code to execute when the service is first created
    }

    @Override
    public void onDestroy() {
        if (timer != null) {
            timer.cancel();
        }
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startid) {
        notificationManager = (NotificationManager) 
                getSystemService(Context.NOTIFICATION_SERVICE);
        int icon = android.R.drawable.stat_notify_sync;
        CharSequence tickerText = "Hello";
        long when = System.currentTimeMillis();
        Notification notification = new Notification(icon, tickerText, when);
        Context context = getApplicationContext();
        CharSequence contentTitle = "My notification";
        CharSequence contentText = "Hello World!";
        Intent notificationIntent = new Intent(this, Main.class);
        PendingIntent contentIntent = PendingIntent.getActivity(this, 0,
                notificationIntent, 0);
        notification.setLatestEventInfo(context, contentTitle, contentText,
                contentIntent);
        notificationManager.notify(NOTIFICATION_EX, notification);
        Toast.makeText(this, "Started!", Toast.LENGTH_LONG);
        timer.scheduleAtFixedRate(new TimerTask() {

            @Override
            public void run() {
                // Check if there are updates here and notify if true
            }
        }, 0, UPDATE_INTERVAL);
        return START_STICKY;
    }

    private void stopService() {
        if (timer != null) timer.cancel();
    }
}

Und so nenne ich es:

Intent serviceIntent = new Intent();
serviceIntent.setAction("cidadaos.cidade.data.UpdaterServiceManager");
startService(serviceIntent);

Das Problem ist, dass nichts passiert. Der obige Codeblock wird am Ende der Aktivität aufgerufen onCreate. Ich habe bereits debuggt und es wird keine Ausnahme ausgelöst.

Irgendeine Idee?

Miguel Ribeiro
quelle
1
Vorsicht bei Timern - AFAIK Wenn Ihr Dienst heruntergefahren wird, um Ressourcen freizugeben, wird dieser Timer beim Neustart des Dienstes nicht neu gestartet. Sie haben Recht START_STICKY, der Dienst wird neu gestartet, aber dann wird nur onCreate aufgerufen und die Timer-Variable wird nicht neu initialisiert. Sie können mit START_REDELIVER_INTENTdem Alarmdienst oder dem API 21 Job Scheduler spielen, um dies zu beheben.
Georg
Falls Sie es vergessen haben, stellen Sie sicher, dass Sie den Dienst im Android-Manifest mithilfe <service android:name="your.package.name.here.ServiceClass" />des Anwendungs-Tags registriert haben .
Japheth Ongeri - Inkalimeva

Antworten:

277

Wahrscheinlich haben Sie den Dienst nicht in Ihrem Manifest oder es gibt keinen <intent-filter>, der Ihrer Aktion entspricht. Wenn Sie LogCat (über adb logcat, DDMS oder die DDMS-Perspektive in Eclipse) untersuchen, sollten einige Warnungen angezeigt werden, die möglicherweise hilfreich sind.

Wahrscheinlicher ist, dass Sie den Dienst über Folgendes starten sollten:

startService(new Intent(this, UpdaterServiceManager.class));
CommonsWare
quelle
1
Wie können Sie debuggen? Ich habe nie meinen Dienst angerufen, mein Debugg zeigt nichts an
Lieferung
Fügen Sie überall eine Menge Log.e-Tags hinzu: Bevor Sie den Dienst starten, das Ergebnis der Dienstabsicht, innerhalb der Dienstklasse, in die er reisen würde (onCreate, onDestroy, alle Methoden).
Zoe
Es funktioniert für meine Apps auf Android SDK 26+, aber nicht auf Android SDK 25 oder niedriger. Gibt es eine Lösung?
Mahidul Islam
@ MahidulIslam: Ich empfehle Ihnen, eine separate Frage zum Stapelüberlauf zu stellen, in der Sie ein minimal reproduzierbares Beispiel bereitstellen können, in dem Ihr Problem und Ihre Symptome ausführlicher erläutert werden.
CommonsWare
@ CommonsWare Ich habe bereits eine Frage gestellt und das ist: - stackoverflow.com/questions/49232627/…
Mahidul Islam
81
startService(new Intent(this, MyService.class));

Nur diese Zeile zu schreiben, hat mir nicht gereicht. Der Service hat immer noch nicht funktioniert. Alles hatte erst nach der Registrierung des Dienstes bei Manifest funktioniert

<application
    android:icon="@drawable/ic_launcher"
    android:label="@string/app_name" >

    ...

    <service
        android:name=".MyService"
        android:label="My Service" >
    </service>
</application>
Vitalii Korsakov
quelle
1
Bestes Beispiel, um alles über Dienste in Android zu erfahren coderzpassion.com/implement-service-android und Entschuldigung für die Verspätung
Jagjit Singh
55

Java - Code für Start - Service :

Starten Sie den Dienst ab Aktivität :

startService(new Intent(MyActivity.this, MyService.class));

Starten Sie den Dienst von Fragment :

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

MyService.java :

import android.app.Service;
import android.content.Intent;
import android.os.Handler;
import android.os.IBinder;
import android.util.Log;

public class MyService extends Service {

    private static String TAG = "MyService";
    private Handler handler;
    private Runnable runnable;
    private final int runTime = 5000;

    @Override
    public void onCreate() {
        super.onCreate();
        Log.i(TAG, "onCreate");

        handler = new Handler();
        runnable = new Runnable() {
            @Override
            public void run() {

                handler.postDelayed(runnable, runTime);
            }
        };
        handler.post(runnable);
    }

    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    @Override
    public void onDestroy() {
        if (handler != null) {
            handler.removeCallbacks(runnable);
        }
        super.onDestroy();
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        return START_STICKY;
    }

    @SuppressWarnings("deprecation")
    @Override
    public void onStart(Intent intent, int startId) {
        super.onStart(intent, startId);
        Log.i(TAG, "onStart");
    }

}

Definieren Sie diesen Service in der Manifestdatei des Projekts:

Fügen Sie das folgende Tag in die Manifest- Datei ein:

<service android:enabled="true" android:name="com.my.packagename.MyService" />

Getan

Hiren Patel
quelle
7
Um wie viel verbessert sich die Leistung, wenn ich Aktivitäten und Dienste im selben Paket belasse? Das habe ich noch nie gehört.
OneWorld
Vielleicht bedeuteten sie Leistung in einem sehr vagen, lockeren Sinne, nicht in Bezug auf die Laufgeschwindigkeit?
Anubian Noob
3

Ich mache es gerne dynamischer

Class<?> serviceMonitor = MyService.class; 


private void startMyService() { context.startService(new Intent(context, serviceMonitor)); }
private void stopMyService()  { context.stopService(new Intent(context, serviceMonitor));  }

Vergiss das Manifest nicht

<service android:enabled="true" android:name=".MyService.class" />
Joolah
quelle
1
Intent serviceIntent = new Intent(this,YourActivity.class);

startService(serviceIntent);

Service im Manifist hinzufügen

<service android:enabled="true" android:name="YourActivity.class" />

Zum Ausführen eines Dienstes auf oreo und größeren Geräten verwenden Sie den Bodendienst und zeigen dem Benutzer eine Benachrichtigung an

Oder verwenden Sie den Geofencing-Dienst für die Standortaktualisierung in der Hintergrundreferenz http://stackoverflow.com/questions/tagged/google-play-services

Asif Mehmood
quelle