简体   繁体   English

如何在没有解锁的情况下从锁屏小部件启动活动?

[英]How to launch an activity from a lockscreen widget, without unlocking?

I have a button on a lockscreen widget, and I'd like the button to launch an activity when pressed. 我在锁屏小部件上有一个按钮,我想要按下按钮来按下时启动一个活动。 If the screen is locked, I want the activity to appear over the lockscreen, without the user having to enter the PIN or pattern or whatever, and the lockscreen should reappear when the user leaves the activity. 如果屏幕被锁定,我希望活动显示在锁定屏幕上,而无需用户输入PIN或模式或其他任何内容,并且当用户离开活动时锁屏应重新出现。

I know about WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED , and my activity does appear over the lockscreen if I launch it manually using am start from an ADB shell. 我知道WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED ,如果我使用从ADB shell am start手动启动它,我的活动确实出现在锁屏上。 The problem is, when I press the button in the widget, it makes me enter the unlock PIN before it creates the activity at all. 问题是,当我按下小部件中的按钮时,它会让我在创建活动之前输入解锁PIN。

I have this code in my widget provider: 我在我的widget提供程序中有这个代码:

@Override
public void onUpdate(final Context context, final AppWidgetManager appWidgetManager, final int[] appWidgetIds) {
    for (final int appWidgetId : appWidgetIds) {
        // Get the RemoteViews for controlling this widget instance.
        final RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.my_widget);

        // Construct an intent to launch the activity.
        final Intent intent = new Intent(context, MyActivity.class);
        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

        // Attach the intent to the widget's button.
        final PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, 0);
        views.setOnClickPendingIntent(R.id.my_button, pendingIntent);

        appWidgetManager.updateAppWidget(appWidgetId, views);
    }
}

And here's the code in MyActivity : 这是MyActivity的代码:

public MyActivity() {
    Log.d(TAG, "Activity instantiated");
}

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

    // Allow this activity to appear over the lock screen.
    final Window window = getWindow();
    window.addFlags(WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED);

    setContentView(R.layout.my_activity);
}

When I press the button in the widget, I'm prompted for the unlock PIN. 当我按下小部件中的按钮时,系统会提示我输入解锁PIN码。 The log message in the activity's constructor doesn't appear until after I enter the PIN, which means that Android is deciding to ask for the pin before the FLAG_SHOW_WHEN_LOCKED can have any effect. 我输入PIN 之后 ,活动构造函数中的日志消息才会出现,这意味着Android在FLAG_SHOW_WHEN_LOCKED可能产生任何影响之前决定请求该引脚。

Is there a way to tell Android that I want to launch the activity while the screen is still locked? 有没有办法告诉Android我想在屏幕仍然锁定时启动活动? Maybe a flag that I can set on my Intent or PendingIntent ? 也许我可以在我的IntentPendingIntent上设置一个标志?

You can use a broadcast intent and listen to it in your widget provider, then on the onRecieve method, start the activity intent, that's will not unlock your device but will launch your activity on foreground without requesting user to unlock. 您可以使用广播意图并在窗口小部件提供程序中侦听它,然后在onRecieve方法上启动活动意图,这将不会解锁您的设备,但会在前台启动您的活动而无需请求用户解锁。

Intent broadcastIntent = new Intent("com.yourapp.yourbroadcast");
widget.setOnClickPendingIntent(R.id.yourButton,  
                               PendingIntent.getBroadcast(ctxt, 0, broadcastIntent, PendingIntent.FLAG_UPDATE_CURRENT));

On your onRecieve(Context ctx, Intent intent) : 在你的onRecieve(上下文ctx,意图意图):

if (intent.getAction().equals("com.yourapp.yourbroadcast"))
{ 
       final Intent intent = new Intent(context, MyActivity.class);
       intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
       ctx.startActivity(intent) ;
}

In your Manifest: 在你的清单中:

<receiver
        android:name=".YourWidget"
        android:label="Your Widget description" >
        <intent-filter>
            <action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
            <action android:name="com.yourpackage.widgetbroadcast" />
        </intent-filter>
        <meta-data
            android:name="android.appwidget.provider"
            android:resource="@xml/wisget_yourwidget" />
</receiver>

Your Widgetclass: 你的Widgetclass:

public class YourWidget extends AppWidgetProvider {
    @Override
    public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
        for (int i = 0; i < appWidgetIds.length; i++) {
            int appWidgetId = appWidgetIds[i];      
            RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.widget_layout);
            Intent intent = new Intent("com.yourpackage.widgetbroadcast");
            PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, intent, 0);
            views.setOnClickPendingIntent(R.id.widget_yourlayout, pendingIntent);
            appWidgetManager.updateAppWidget(appWidgetId, views);
        }
    }

    @Override
    public void onReceive(Context context, Intent intent) {
        super.onReceive(context, intent);
        if (intent.getAction().equals("com.yourpackage.widgetbroadcast")) {
            Intent intentStart = new Intent(context, MainActivity.class);           
            intentStart.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            context.startActivity(intentStart);
        }
    }
}

In your MainActivity: 在您的MainActivity中:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);        
    Window w = getWindow();
    w.addFlags(WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED);
    //Your code...
}

Make sure you set the Widow-Flag in the activity to FLAG_SHOW_WHEN_LOCKED and not to FLAG_DISMISS_KEYGUARD to keep the screen locked. 确保将活动中的Widow-Flag设置为FLAG_SHOW_WHEN_LOCKED,而不是FLAG_DISMISS_KEYGUARD以保持屏幕锁定。 This example will start the activity by clicking on the widget. 此示例将通过单击窗口小部件来启动活动。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM