Android 9.0(Pie):当手机被锁定时从服务启动活动

3

你好,我正在开发一个应用的VoIP功能,并尝试处理应用程序被杀死的情况。我的想法是使用FCM通知并运行活动,显示用户接收呼叫屏幕。当手机未锁定时,它按预期工作,但当手机锁定时就不是这样了。

我尝试了以下方法:

  if (Build.VERSION.SDK_INT > Build.VERSION_CODES.O_MR1) {
      setShowWhenLocked(true);
      setTurnScreenOn(true);
    }else{
    getWindow().addFlags(WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED);
    getWindow().addFlags(WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD);
    getWindow().addFlags(WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON);
    getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
    }

我尝试在清单文件中为活动添加标志但没有成功。我还尝试将它放在 super.onCreate() 之前,在 super.onCreate() 之后以及在 setContentView() 之后,但都没有成功。

我只想要与Viber和WhatsApp相同的行为。但目前我已经没有想法他们是如何做到的。

我在PocoPhone F1上使用了最新的更新来测试以上代码。

编辑

这里是FirebaseMessagingService的一部分,我在其中接收和处理推送通知。

public class NotificationService extends FirebaseMessagingService {
  private static final String TYPE = "type";
  private static final String VIDEO_CALL = "video_call";

  @Override public void onMessageReceived(RemoteMessage remoteMessage){
       Map<String,String> data = remoteMessage.getData();

       if(data.containsKey(TYPE) && data.get(TYPE).equals(VIDEO_CALL)){
        Intent videoCallIntent = new Intent(this, VideoCallActivity.class);
        videoCallIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        startActivity(videoCallIntent);
       }
  }

}

这是推送通知的有效载荷

{
    "to": "...",
    "data" : {
     "type" : "video_call"
     },
    "priority":"high",
    "ttl": 3600
 }

更新:

我设法解决了这个问题。Alex的回答是正确的,但小米设备在设置中有一个“在锁定屏幕上显示”的选项,我需要启用它。这也是我对Android操作系统感到有点沮丧的原因之一。


你能否提供更多关于实现的信息?你是否发送静默推送消息并且这些消息能够到达应用程序?请添加 FirebaseMessagingService 实现和一个完整的推送消息 json 数据 样例,该样例是发送给应用程序的。 - Alex
@Alex 我更新了问题。 - harisk92
2个回答

3

同时,在高API级别下,请求KEYGUARD_SERVICE以便解除锁屏。请在if语句中添加此请求(在setTurnScreenOn(true);之后):

    KeyguardManager keyguardManager = (KeyguardManager) getSystemService(Context.KEYGUARD_SERVICE);
    if (keyguardManager!= null) {
        keyguardManager.requestDismissKeyguard(this, null);
    }

好的,这也可能与接收或处理推送消息有关,您能提供更多信息吗?(请参见问题的评论) - Alex
Alex我更新了问题并将这个答案标记为正确的。感谢你的帮助伙计。 - harisk92
欢迎,很棒现在它可以工作了!关于那些设备设置中的选项,你发现得真好@harisk92 - Alex
在调用dismiss之后,是否需要恢复键盘保护状态? - Ender2050

1
在您的活动的onCreate()中,您需要进行以下更改。即使设备被锁定,此处的活动也会显示一个红色的空活动。
public class LockScreenActivity extends AppCompatActivity {

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        //modify window flags so as to display it on lock screen
        Window window = getWindow();
        window.addFlags(WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED
                | WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON
                | WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);

        // to wake up screen
        PowerManager pm = (PowerManager) getApplicationContext().getSystemService(Context.POWER_SERVICE);
        int wakeFlags = PowerManager.FULL_WAKE_LOCK | PowerManager.ACQUIRE_CAUSES_WAKEUP;
        if (Build.VERSION.SDK_INT <= 15) {
            wakeFlags |= PowerManager.SCREEN_BRIGHT_WAKE_LOCK;
        }

        PowerManager.WakeLock wakeLock = pm.newWakeLock(wakeFlags, "MyApp:Call");
        wakeLock.acquire(30000); //wakelock for 30 sec

        View view = new View(this);
        view.setBackgroundColor(Color.RED);
        setContentView(view);
    }

}

记得在清单文件中添加WAKE_LOCK权限。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接