锁屏界面通知操作按钮无法点击

4
为了更好地支持Android 5通知,我现在将我的应用程序的通知可见性设置为“public”。在考虑过Lollipop Notification setVisibility() Does Not Work?上的答案后,通知现在按预期显示。但是,当我想要点击通知的操作按钮时,我必须先解锁设备,这是不应该需要的。(该操作显示密码数据库已解锁,并且操作按钮将锁定数据库。)
这是我使用创建通知的代码(使用Xamarin的Mono for Android):
NotificationCompat.Builder builder =
                new NotificationCompat.Builder(this)
                    .SetOngoing(true)
                    .SetSmallIcon(Resource.Drawable.ic_notify)
                    .SetLargeIcon(...)
                    .SetVisibility((int)Android.App.NotificationVisibility.Public)
                    .SetContentTitle(...)
                    .SetContentText(...);

builder.AddAction(Resource.Drawable.ic_action_lock, GetString(Resource.String.menu_lock), PendingIntent.GetBroadcast(this, 0, new Intent(Intents.LockDatabase), PendingIntentFlags.UpdateCurrent));

这里的this是一个服务实例。

我知道MediaStyle通知有可点击的按钮,但感觉使用MediaStyle似乎是一种hack方式,因为它并不与媒体有关。有没有办法让我的操作可在锁定屏幕上使用?


你是在尝试创建一个悬浮通知吗? - user2511882
2个回答

4

不要添加一个操作,而是定义你自己的通知布局,并通过RemoteView连接一个pendingIntent来触发它。 (下面的示例基于Holo外观和感觉,并仍然需要更新为lollipop。 您可以在sdk的android-21 / data / res文件夹中找到所有正确的资源)

// NOTE: while creating pendingIntent: requestcode must be different!
NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(myService)
        .setSmallIcon(R.drawable.notification_icon).setContentTitle("My Title")
        .setContentText("Service running in the background");
Intent openIntent = new Intent(MainActivity.this, MainActivity.class);
PendingIntent pOpenIntent = PendingIntent.getActivity(this, 0, openIntent, 0);
mBuilder.setContentIntent(pOpenIntent);

// Notification with exit button if supported
String ACTION_NOTIFICATION_EXITACTIVITY = "com.jmols.example.exitactivity";
Intent exitIntent = new Intent();
exitIntent.setAction(ACTION_NOTIFICATION_EXITACTIVITY);
PendingIntent pExitIntent = PendingIntent.getBroadcast(this, 1, exitIntent, 0);
RemoteViews view = new RemoteViews(getPackageName(), R.layout.notification_discoveryservice);
view.setOnClickPendingIntent(R.id.notification_closebtn_ib, pExitIntent);
mBuilder.setContent(view);

使用通知布局:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:internal="http://schemas.android.com/apk/prv/res/android"
    android:id="@+id/status_bar_latest_event_content"
    android:layout_width="match_parent"
    android:layout_height="64dp"
    internal:layout_maxHeight="64dp"
    internal:layout_minHeight="64dp" >

    <ImageView
        android:id="@+id/notification_icon_iv"
        android:layout_width="64dp"
        android:layout_height="64dp"
        android:padding="10dp"
        android:layout_alignParentLeft="true"
        android:scaleType="center"
        android:src="@drawable/notification_icon"
        android:background="#3333B5E5" />

    <ImageButton
        android:id="@+id/notification_closebtn_ib"
        android:layout_width="40dp"
        android:layout_height="40dp"
        android:layout_alignParentRight="true"
        android:layout_centerVertical="true"
        android:scaleType="centerInside"
        android:src="@drawable/notification_exitbtn"
        android:background="@drawable/notification_imagebtn_bg"/>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_gravity="fill_vertical"
        android:gravity="top"
        android:minHeight="64dp"
        android:layout_toRightOf="@id/notification_icon_iv"
        android:layout_toLeftOf="@id/notification_closebtn_ib"
        android:orientation="vertical"
        android:paddingBottom="2dp"
        android:paddingEnd="8dp"
        android:paddingTop="2dp" >

        <TextView
            android:id="@+id/notification_title_tv"
            style="@android:style/TextAppearance.StatusBar.EventContent.Title"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginLeft="8dp"
            android:ellipsize="marquee"
            android:paddingTop="6dp"
            android:singleLine="true"
            android:text="JMols Service" />

        <TextView
            android:id="@+id/notification_contenttext_tv"
            style="@android:style/TextAppearance.StatusBar.EventContent"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginLeft="8dp"
            android:ellipsize="marquee"
            android:singleLine="true"
            android:text="Service running in the background" />

    </LinearLayout>

</RelativeLayout>

通知的背景颜色为:

<selector xmlns:android="http://schemas.android.com/apk/res/android"
    android:exitFadeDuration="@android:integer/config_mediumAnimTime">

    <item android:state_pressed="true"  android:drawable="@drawable/notification_bg_normal_pressed" />
    <item android:state_pressed="false" android:drawable="@drawable/notification_bg_normal" />
</selector>

notification_bg_normal.9 notification_bg_normal_pressed.9

通知图像按钮的背景是:


注:该内容涉及IT技术,翻译时需要注意专业术语的准确性和易懂性。
<selector xmlns:android="http://schemas.android.com/apk/res/android"
    android:exitFadeDuration="@android:integer/config_mediumAnimTime">

    <item android:state_pressed="true"  android:drawable="@drawable/notification_imagebtn_bg_normal_pressed" />
    <item android:state_pressed="false" android:drawable="@drawable/notification_imagebtn_bg_normal" />
</selector>

notification_imagebtn_bg_normal.9.png notification_imagebtn_bg_normal_pressed.9.png


1
我真的希望有一个更简单的解决方案,但看起来你的方法是正确的。谢谢! - Philipp
这是一个服务的事实是否是这个解决方案的重要组成部分?我无法使其工作,但可能是完全不同的问题。(对于感兴趣的人,请参见https://dev59.com/ZlsX5IYBdhLWcg3wf_v3) - Nanne
那个 xmlns:internal 是怎么回事? - arekolek

0

我认为Android只允许从锁屏界面控制媒体播放,其他通知必须先解锁屏幕才能启动活动,这是出于安全考虑。例如,您可能想知道是否收到新邮件,甚至可能想显示刚到达的某些邮件内容,但您可能不希望在设备被锁定时给他人访问您的电子邮件账户留下漏洞。在媒体播放控制用例中,没有这样的安全问题。


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