androidactivity-recognitionandroid-8.1-oreoexplicit-intent

Explicit intents don't works on Android 8.1


The code below works without any problem on pre-Oreo versions.

Although I user startForeground method and making explicit intent to get Activity values, onHandleIntent method is never called.

I cannot find any issue or solution about this issue.

Is there any chance to overcome this issue?

Note: I try on my phone which runs a custom ROM and I can not simulate on Android Emulator this circumstance.

AndroidManifest.xml file

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.myservice"
    android:versionCode="1"
    android:versionName="1.0">

    <application ... >

      <service android:name="com.MyService">
        <intent-filter>
          <action android:name="com.MyService"/>
        </intent-filter>
      </service>

      <uses-permission android:name="com.google.android.gms.permission.ACTIVITY_RECOGNITION" />

      <service android:name="com.myservice.ActivityHelper$ActivityRecognitionService" />

    </application>

</manifest>

MyService.java file

public class MyService extends Service {

    ...

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

        runServiceAtForeground();

        return START_STICKY;
    }


    private void runServiceAtForeground () {
        ...

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            ...
            mNotificationManager.createNotificationChannel(channel);
        }

        Intent i = new Intent(getApplicationContext(), MyService.class);
        PendingIntent pi = PendingIntent.getActivity(this, 0, i, 0);
        NotificationCompat.Builder notif = new NotificationCompat.Builder(this, channel_id);
        notif.setContentIntent(pi);

        // MAKING FOREGROUND SERVICE
        startForeground(notif_id, notif.build());

        // STARTING ACTIVITY RECOGNITION
        mActivityHelper.startObserving();

    }

    ...

}

ActivityHelper.java file

public class ActivityHelper {

    ...

    public void startObserving() {
        ActivityRecognitionClient arc = ActivityRecognition.getClient(context);

        Task<Void> task = arc.requestActivityUpdates(20000, getActivityDetectionPendingIntent());

        task.addOnSuccessListener(new OnSuccessListener<Void>() {...});

        task.addOnFailureListener(new OnFailureListener() {...});
    }

    private PendingIntent getActivityDetectionPendingIntent() {
            Intent i = new Intent(mContext, ActivityRecognitionService.class);

            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                return PendingIntent.getBroadcast(mContext, 0, i, PendingIntent.FLAG_UPDATE_CURRENT);
            } else {
                return PendingIntent.getService(mContext, 0, i, PendingIntent.FLAG_UPDATE_CURRENT);
            }
    }


    public static class ActivityRecognitionService extends IntentService {

        public ActivityRecognitionService() {
            super("ActivityRecognitionService");
        }

        @Override
        public void onCreate() {
            super.onCreate();
        }

        @Override
        protected void onHandleIntent(Intent intent) {

            // THIS METHOD IS NEVER RUN ON OREO

            if (ActivityRecognitionResult.hasResult(intent)) {
                ActivityRecognitionResult result = ActivityRecognitionResult.extractResult(intent);

                if (listener != null) {
                    Log.v(TAG, result.getMostProbableActivity().getType());
                }

                stopSelf();
            }
        }

    }

}

Solution

  • private PendingIntent getActivityDetectionPendingIntent() {
            Intent i = new Intent(mContext, ActivityRecognitionService.class);
    
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                return PendingIntent.getBroadcast(mContext, 0, i, PendingIntent.FLAG_UPDATE_CURRENT);
            } else {
                return PendingIntent.getService(mContext, 0, i, PendingIntent.FLAG_UPDATE_CURRENT);
            }
    }
    

    Either ActivityRecognitionService is a BroadcastReceiver or it is a Service. It cannot be both simultaneously. That does not change based upon what OS version the device is running. And since ActivityRecognitionService extends IntentService, PendingIntent.getBroadcast() will not give you a useful PendingIntent.

    Also: