2
votes

When app is running and device is locked I'm able to start the activity. But when app is in background and device is locked not able to start the activity even though I'm getting the control in BroadcastReceiver class. This is my intent call.

context.startActivity(new Intent(context, ReceiveCallActivity.class)
                    .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
                    .setAction(Intent.ACTION_ANSWER)
                    .putExtra("title", intent.getStringExtra("title"))
                    .putExtra("action", intent.getStringExtra("action")));

Manifest of Activity

<activity
            android:name=".ReceiveCallActivity"
            android:configChanges="orientation|keyboardHidden|screenSize"
            android:excludeFromRecents="true"
            android:launchMode="singleTop"
            android:showOnLockScreen="true"
            android:showWhenLocked="true"
            android:turnScreenOn="true"
            android:windowSoftInputMode="adjustPan|stateHidden" />

ReceiveCallActivity.class

 @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O_MR1) {
            setShowWhenLocked(true);
            setTurnScreenOn(true);
        } else {
            getWindow().addFlags(WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED
                    | WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD
                    | WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON
                    | WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON
                    | WindowManager.LayoutParams.FLAG_ALLOW_LOCK_WHILE_SCREEN_ON);
        }
        setContentView(R.layout.receive_call_activity);
        ...
        ...
}

setShowWhenLocked(true) && setTurnScreenOn(true) helps to open app even if device is locked but app has to be in foreground for that.

PS: I'm getting the control in BroadcastReceiver in all scenarios.

TIA

1
No you cant do that. You can do one thing the code running in ReceiveCallActivity you can call it in BroadcastReceiver .user10351180
ReceiveCallActivity is a call answer-decline screen with UI. Btw Skype app opens when it receives call in all scenarios.Shahal
@Shahal, 1. On which version you are trying 2. Android 10 Restricted background activityॐ Rakesh Kumar
I was checking different permissions given to Skype from Settings, and noticed 'Show on Lock Screen' is enabled while the same was disabled for my App. On enabling it, BroadcastReceiver is able to open Activity in all scenarios. I read it's a issue with Xiamoi devices(I'm using Note 5 Pro).Shahal
On Android 10 when app is in background, I'm showing notification with RemoteViews.Shahal

1 Answers

0
votes

I was checking different permissions given to Skype from Settings, and noticed 'Show on Lock Screen' is enabled while the same was disabled for my App. On enabling it, BroadcastReceiver is able to open Activity in all scenarios. I read it's a issue with Xiamoi devices(I'm using Note 5 Pro).

EDIT

For Android 10 need to add USE_FULL_SCREEN_INTENT permission in manifest. Then when the screen is locked, PendingIntent set as FullScreenIntent on NotificationCompat.Builder will be called.

My Notification code:

private void showCallNotification(Map<String, String> dataMap) {

//CREATING pendingIntent
...
...
...

        PendingIntent fullScreenPendingIntent = PendingIntent.getActivity(this, 2, fullScreenIntent, PendingIntent.FLAG_UPDATE_CURRENT);
        PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
        PendingIntent cancelPendingIntent = PendingIntent.getBroadcast(this, 1, cancelIntent, PendingIntent.FLAG_UPDATE_CURRENT);

        RemoteViews notificationLayout = new RemoteViews(getPackageName(), R.layout.notification_small);
        notificationLayout.setTextViewText(R.id.tvTitle, dataMap.get("sender"));
        notificationLayout.setTextViewText(R.id.tvContent, getString(R.string.incoming_call));
        notificationLayout.setOnClickPendingIntent(R.id.tvAccept, pendingIntent);
        notificationLayout.setOnClickPendingIntent(R.id.tvDecline, cancelPendingIntent);

        RemoteViews notificationLayoutExpanded = new RemoteViews(getPackageName(), R.layout.notification_large);
        notificationLayoutExpanded.setTextViewText(R.id.tvTitle, dataMap.get("sender"));
        notificationLayoutExpanded.setTextViewText(R.id.tvContent, getString(R.string.incoming_call));
        notificationLayoutExpanded.setOnClickPendingIntent(R.id.btAccept, pendingIntent);
        notificationLayoutExpanded.setOnClickPendingIntent(R.id.btDecline, cancelPendingIntent);

        NotificationCompat.Builder builder = new NotificationCompat.Builder(this, AppConstants.CALL_CHANNEL_ID)
                .setSmallIcon(R.drawable.ic_notification)
                .setContentTitle(dataMap.get("sender"))
                .setContentText(getString(R.string.incoming_call))
                .setAutoCancel(true)
                .setTimeoutAfter(CALL_DISMISS_TIME)
                .setVisibility(NotificationCompat.VISIBILITY_PUBLIC)
                .setCustomBigContentView(notificationLayout)
                .setCustomContentView(notificationLayoutExpanded)
                .setPriority(NotificationCompat.PRIORITY_HIGH)
                .setContentIntent(fullScreenPendingIntent)
                .setFullScreenIntent(fullScreenPendingIntent, true);

        if (Build.VERSION.SDK_INT < 26) {
            builder.setPriority(NotificationCompat.PRIORITY_MAX);
        }

        NotificationManagerCompat notificationManager = NotificationManagerCompat.from(this);
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            createCallNotificationChannel();
        }

        notificationManager.notify(notificationId, builder.build());
}

And i call it like this

onMessageReceived()

if (Build.VERSION.SDK_INT > 28) {
   if (isAppOnForeground(getApplicationContext())) {
       sendBroadcast(remoteMessage);
   } else {
       showCallNotification(dataMap);
   }
} else {
   sendBroadcast(remoteMessage);
}