How to start new activity from lockscreen?
Asked Answered
C

1

7

I am creating simple widget for contact management, which allows user to dial and send sms to desired contact.

It works fine as "normal widget", but when I add it as lockscreen widget on Android 4.2, sms app or dial app does not start. Well in fact they star, but "behind" lockscreen, so user still must manually unlock screen to be able to dial/send sms.

I searched web for some solution, but nothing come in handy. I' am aware of FLAG_DISABLE_KEYGUARD or FLAG_SHOW_WHEN_LOCKED, but since sms/dial apps are not "mine" so i dont know if they set up proper flag. As a workaround i tried to create my activity which set those flag and then simply starts desired one (dial or sms), but this does not help.

There is a way to unlock screen, but this involves using KeyguardManager and KeyguardLock (which work fine), but in a result of using KeyguardLock.newKeyguardLock() I end up with phone not being able to turn lock automatically, surely because I do not release this lock (it causes lock to appear again, which is not what i want).

In fact, this widget should work simmilarly to default sms widget or mail widget on lock screen?

So, my question is, how to achieve that and start new activity from lockscreen?

Council answered 24/4, 2013 at 9:31 Comment(2)
Hi Filip. I was wondering about the same thing. I'm quite new to android. So can you help me a little here? How do you set click listeners to the buttons or view in the widget layout? Does that have something to do with the on onReceive method of your AppWidgetProvider Class?Reticular
Hi, Well, this is not so obvious and quite tricky to explain (not to mention implementing it:)). I took me a while to figure this out. In short, you need to use PendingIntent and RemoteView classes to achieve it. The best way is to look inside documentation. In short, when you have your view configured via RemoteView, just inject PendingIntent object into it via RemoteView#setOnClickFillInIntent method.Council
C
7

Well, i found solution myself. it turned out i was close :)

To launch 3rd party app/activity, simplest solution is to create some kind of proxy activity, which will set proper flags on window and then launches desired activity and FINISHES.

sample code is shown below:

calling intent in widget (calling proxy):

    @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);
}

in proxy activity just call:

    @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);


}
Council answered 24/4, 2013 at 11:36 Comment(1)
My two cents: Instead of using a handler, you can call startActivity() and finish() in onWindowsFocusChanged(pHasFocus) when pHasFocus is true.Pander

© 2022 - 2024 — McMap. All rights reserved.