如何从锁屏界面启动新的活动?

7
我正在创建一个简单的联系人管理小部件,允许用户拨打电话和发送短信给所需联系人。
当我将其添加为Android 4.2上的锁屏小部件时,它作为“普通小部件”正常工作,但是短信应用程序或拨号应用程序不会启动。实际上,它们确实启动了,但是在锁屏后面,因此用户仍然必须手动解锁屏幕才能拨打/发送短信。
我在网上搜索了一些解决方案,但没有找到合适的。我知道FLAG_DISABLE_KEYGUARD或FLAG_SHOW_WHEN_LOCKED,但由于短信/拨号应用程序不是“我的”,所以我不知道它们是否设置了正确的标志。作为解决方法,我尝试创建自己的活动来设置这些标志,然后简单地启动所需的一个(拨号或短信),但这并没有帮助。
有一种解锁屏幕的方法,但这涉及使用KeyguardManager和KeyguardLock(它们工作得很好),但是在使用KeyguardLock.newKeyguardLock()时,我最终无法自动关闭锁定,肯定是因为我没有释放这个锁(它会导致锁再次出现,这不是我想要的)。
实际上,这个小部件应该与锁屏上的默认短信小部件或邮件小部件类似工作?
所以,我的问题是,如何实现从锁屏开始新活动?

嗨,菲利普。我也在想同样的问题。我对Android还很陌生。你能帮我一下吗?如何将点击监听器设置到小部件布局中的按钮或视图上?这与AppWidgetProvider类的onReceive方法有关吗? - user2357448
嗨, 好的,这并不是很明显,而且相当棘手,难以解释(更不用说实现它了:))。我花了一段时间才弄清楚这个问题。简而言之,您需要使用PendingIntentRemoteView类来实现它。最好的方法是查看文档。简而言之,当您通过RemoteView配置视图时,只需通过RemoteView#setOnClickFillInIntent方法将PendingIntent对象注入其中即可。 - Filip Zymek
1个回答

7

嗯,我自己找到了解决方案。原来我已经接近了 :)

要启动第三方应用程序/活动,最简单的解决方案是创建某种代理活动,该代理活动将在窗口上设置正确的标志,然后启动所需的活动并结束。

下面显示了示例代码:

在小部件中调用意图(调用代理):

    @Override
public void onReceive(Context context, Intent intent) {
    Utilities.printLog(TAG, "onReceive");
    Utilities.printLog(TAG, "intent: " + intent);
    if (intent.getAction().equals(ACTION)) {

        final String number = intent.getStringExtra(EXTRAS);
        Toast.makeText(context, "Selected number: " + number,
                Toast.LENGTH_SHORT)
                .show();


        /** REMOVING KEYGUARD RECEIVER **/
        // not really an option - lock is still holded by widget and screen
        // cannot be locked again ;(
        // KeyguardManager keyguardManager = (KeyguardManager) context
        // .getSystemService(Context.KEYGUARD_SERVICE);
        // KeyguardLock lock = keyguardManager
        // .newKeyguardLock(Context.KEYGUARD_SERVICE);
        // lock.disableKeyguard();

        final Intent activity = new Intent(context, MainActivity.class);
        activity.putExtras(intent.getExtras());
        activity.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        activity.addFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
        activity.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
        context.startActivity(activity);
    }

    super.onReceive(context, intent);
}

在代理活动中只需调用:

    @Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    getWindow().requestFeature(Window.FEATURE_NO_TITLE);
    // getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
    getWindow().addFlags(WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED);
    getWindow().addFlags(WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD);

    final Intent callingIntent = getIntent();

    final String actionToLaunch = callingIntent.getStringExtra(ContactsStackWidgetProvider.ACTION);
    final String number = callingIntent.getStringExtra(ContactsStackWidgetProvider.EXTRAS);

    final Intent activity = new Intent();
    if (actionToLaunch.equals(Intent.ACTION_DIAL)) {
        activity.setAction(Intent.ACTION_DIAL);
        activity.setData(Uri.parse("tel:"+number));
    } else if (actionToLaunch.equals(Intent.ACTION_SENDTO)) {
        activity.setAction(Intent.ACTION_SENDTO);
        activity.setData(Uri.parse("sms:"+number));
    } else {
        throw new IllegalArgumentException("Unrecognized action: "
                + actionToLaunch);
    }

    new Handler().postDelayed(new Runnable() {

        @Override
        public void run() {
            startActivity(activity);
            finish();//it is important to finish, but after a small delay
        }
    }, 50L);


}

我的建议是:不要使用handler,而是在onWindowsFocusChanged(pHasFocus)中当pHasFocus为true时调用startActivity()finish() - mamuso

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