简体   繁体   中英

How to stop IntentService Android

I have build an IntentService in Android.

So if I received a pushNotification message, I muse stopped this service.

public class DosimeterDataSensingService extends IntentService {
    private static final String TAG = "DosimeterDataSensingService";
    public static boolean isStarted = false;
    private Context mContext;
    private int mStatus;
    private BluetoothDevice mDevice;
    private BluetoothGatt mConnGatt;
    private boolean notificationsEnabled;
    private long dosimeterScanningTime;
    private boolean isThreadStarted = false;
    private List<DosimeterDataRequest.DataBean> dosimeterDataList;
    private List<DosimeterDataRequest.DataBean> dosimeterDataListMqtt;
    private DosimeterMqttParcel dosimeterMqttParcel = new DosimeterMqttParcel();
    private DosimeterDataRequest dosimeterDataRequest;
    private String macAddress;
    private boolean isRecordingEnabled = false;
    private String dose = "";
    private int battery = -1;
    private Boolean syncRadiactionWS = false;
    private Boolean syncRadiactionMQTT = false;
    /**
     * Creates an IntentService.  Invoked by your subclass's constructor.
     *
     * @param name Used to name the worker thread, important only for debugging.
     */
    public DosimeterDataSensingService(String name) {
        super(name);
    }

    public DosimeterDataSensingService() {
        super(null);
    }


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

    @Override
    protected void onHandleIntent(@Nullable Intent intent) {
        Log.d("dosimetro", "ON HANDLE INTENT");
        if(intent!=null){
            String action = intent.getStringExtra(PreferenceHandler.ACTION_STOP);

            Log.d("dosimetro", action!=null ? action : "no action");
            if(action!=null && action.equals(PreferenceHandler.ACTION_STOP)){
                Log.d("dosimetro", "fermo il servizio");
                String syncScanTime = PreferenceHandler.readString(getApplicationContext(), PreferenceHandler.DOSIMETER_SCANNING_TIME, null);
                Log.d("dosimetro", syncScanTime!=null ? syncScanTime : "nullo");
                String syncRotTime = PreferenceHandler.readString(getApplicationContext(), PreferenceHandler.DOSIMETER_ROTATION_TIME, null);
                Log.d("dosimetro", syncRotTime!=null ? syncRotTime : "nullo");
                super.stopSelf();
                Log.d("dosimetro", "ho stoppato");
                onDestroy();
                return;
            }
        }
    }

    @Override
    public void onCreate() {
        super.onCreate();
        Paper.init(this);
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            NotificationChannel channel = createNotificationChannel();
        }

        NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(this, getString(R.string.default_notification_channel_id))
                .setSmallIcon(R.drawable.logoxhdpi)
                .setCategory(Notification.CATEGORY_SERVICE)
                .setContentTitle("Cardio App")
                .setContentText("Getting data from Dosimeter")
                .setPriority(NotificationCompat.PRIORITY_DEFAULT);

        Notification notification = mBuilder.build();
        startForeground((int) (System.currentTimeMillis() + 1), notification);
        isStarted = true;

        if (PreferenceHandler.readString(this, PreferenceHandler.TYPE_USER, null).equals("2")) {
            checkDosage();
        }
        List<GetAssignedDevicesListResponse.Parameters> preferenzeParametri= Paper.book().read(PreferenceHandler.PARAMETRI_VITALI, new ArrayList<>());
        if(preferenzeParametri!=null && preferenzeParametri.size()>0){
            for (GetAssignedDevicesListResponse.Parameters p: preferenzeParametri) {
                if(p.getIdParameter() == PreferenceHandler.ID_RADIACTION){
                    //VERIFICO COME L'RR DEVE ESSERE SINCRONIZZATO
                    syncRadiactionWS = p.getSyncWs()!=null ? p.getSyncWs() : false;
                    syncRadiactionMQTT =  p.getSyncMqtt()!=null ? p.getSyncMqtt() : false;
                    Log.e("DOSIMETER", "syncRadiactionWS true");
                }
            }
        }else{
            Log.e("DOSIMETER", "paperi init false");
        }

        checkBattery();
        Log.i("SCANNINGTIME", "SYNC WS STARTED");
        syncRadiactionLevel();
        syncMqtt();
    }


    @Override
    public void onDestroy() {
        Log.d("DOSIMETRO", "ondestroy");
        isStarted = false;
        disconnectDosimeter();
        super.onDestroy();
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        super.onStartCommand(intent, flags, startId);

        return START_STICKY;
    }



    @SuppressLint("LongLogTag")
    public void disconnectDosimeter() {

        if (mConnGatt != null) {
            isThreadStarted = false;
            if ((mStatus != BluetoothProfile.STATE_DISCONNECTING)
                    && (mStatus != BluetoothProfile.STATE_DISCONNECTED)) {
                mConnGatt.disconnect();
                mConnGatt.close();
                mConnGatt = null;
                mStatus = BluetoothProfile.STATE_DISCONNECTED;
            }
        }
        try {
            Method m = mDevice.getClass().getMethod("removeBond", (Class[]) null);
            m.invoke(mDevice, (Object[]) null);
        } catch (Exception e) {
            Log.e(TAG, e.getMessage());
        }

        Log.v("Dosimeter", "isRecordingEnabled" + isRecordingEnabled);
        Log.v("Dosimeter", "Disconnecteddd");
    }




    /**
     * Enable recording of values
     */
    private void startRecordingData() {
        String dosimeterRotation = PreferenceHandler.readString(getApplicationContext(), PreferenceHandler.DOSIMETER_ROTATION_TIME, null);
        Log.i("ROTATIONTIME", dosimeterRotation);
        long dosimeterRotationTime = 0L;
        if (dosimeterRotation != null) {
            dosimeterRotationTime = Long.parseLong(dosimeterRotation);
            new Handler().postDelayed(() -> {
                isRecordingEnabled = true;
                isThreadStarted = false;
            }, dosimeterRotationTime);
        }
    }



}

To stop the service I m using this code:

Intent i = new Intent(this, DosimeterDataSensingService.class);
i.putExtra(PreferenceHandler.ACTION_STOP,PreferenceHandler.ACTION_STOP);
stopService(new Intent(this, DosimeterDataSensingService.class));

From my log I can see that the system call

super.stopSelf();
onDestroy();

method but the IntentService works always.

You need not call stopSelf() or stopService() for IntentService .

As per the description mentioned in Docs:

Because most of the started services don't need to handle multiple requests simultaneously (which can actually be a dangerous multi-threading scenario), it's best that you implement your service using the IntentService class.

The IntentService class does the following:

It creates a default worker thread that executes all of the intents that are delivered to onStartCommand(), separate from your application's main thread.

Creates a work queue that passes one intent at a time to your onHandleIntent() implementation, so you never have to worry about multi-threading.

Stops the service after all of the start requests are handled, **so you never have to call stopSelf().**

Provides a default implementation of onBind() that returns null.

Provides a default implementation of onStartCommand() that sends the intent to the work queue and then to your onHandleIntent() implementation.

If the service is still running may be some intents are running.

Hope this helps.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM