Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to start new activity from lockscreen?

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?

like image 440
Filip Zymek Avatar asked Apr 24 '13 09:04

Filip Zymek


1 Answers

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


}
like image 169
Filip Zymek Avatar answered Sep 18 '22 16:09

Filip Zymek