安卓Facebook锁屏通知

19

在最新版本的安卓应用Facebook中,它展示了锁屏通知功能,就像这张截图所示:

screenshot

有没有人尝试过实现这个功能?

我知道在锁屏界面上方显示活动页面很简单,但不幸的是,它不能与半透明背景一起使用。基本上它能够工作,但在我们的活动页面下面会看到启动器屏幕,而不是锁屏界面(就像在这种情况下,锁屏界面也是透明的)。

我现在尝试的是:

getWindow().addFlags(WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON);

在我的Activity中。

我也尝试了这个例子:https://gist.github.com/daichan4649/5352944

正如我所描述的-一切都可以工作但没有透明度。

根据我的观察,Facebook使用主题:

@android:style/Theme.Translucent.NoTitleBar

并且没有权限:

<uses-permission android:name="android.permission.DISABLE_KEYGUARD" />

我注意到锁屏通知会占用触摸操作,因此我们无法通过手势在状态栏中显示通知。

在Android L发布之前有什么创意可以创建这种通知吗?


可以尝试创建一个带有背景图像的活动(背景图像可以半透明吗)? - Seshu Vinay
如果我使用半透明样式,我会在我的Activity下面看到启动器屏幕,而不是锁定屏幕。如果我不使用半透明,那么在图像背景下方会有黑色背景(来自窗口)。 - froger_mcs
我觉得在原生的安卓系统上不可能实现。这个功能是专门运行在HTC One M8上,它运行的是带有Sense 6的Android 4.4.2系统。参考链接:http://techcrunch.com/2014/07/08/facebook-tests-android-l-style-lock-screen-notifications/ 和 http://lifehacker.com/floatify-brings-android-ls-new-notifications-to-any-and-1601708892。 - rupesh jain
一种实现此功能的方法是实现自定义锁屏以显示通知。这就是市场上许多应用程序正在做的事情。 - rupesh jain
Facebook的锁屏通知应该是与设备和锁屏无关的。我很确定我所附加的屏幕截图是展示原生Android的Nexus 5。我有HTC M8,也能看到同样的通知。 - froger_mcs
显示剩余3条评论
2个回答

19

实际上,ferdy182 是对的。

这是我使用 android.permission.SYSTEM_ALERT_WINDOW 得到的结果:

enter image description here

所以,我无法使用 Activity 完成这个任务。它根本行不通。我必须实现一个 Service ,并使用 WindowManager 添加一个 View

可能的工作流程如下:你的 BroadcastReceiver 接收到广播 => 启动服务 => 服务添加所需的视图。

现在,看看代码(注释解释了一些东西):

public class MyService extends Service {

    View mView;

    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    @Override
    public void onCreate() {
        super.onCreate();

        // instance of WindowManager
        WindowManager mWindowManager = (WindowManager) getSystemService(WINDOW_SERVICE);

        LayoutInflater mInflater = (LayoutInflater) 
                                      getSystemService(Context.LAYOUT_INFLATER_SERVICE);

        // inflate required layout file
        mView = mInflater.inflate(R.layout.abc, null);

        // attach OnClickListener
        mView.findViewById(R.id.some_id).setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                // you can fire an Intent accordingly - to deal with the click event
                // stop the service - this also removes `mView` from the window
                // because onDestroy() is called - that's where we remove `mView`
                stopSelf();
            }
        });

        // the LayoutParams for `mView`
        // main attraction here is `TYPE_SYSTEM_ERROR`
        // as you noted above, `TYPE_SYSTEM_ALERT` does not work on the lockscreen
        // `TYPE_SYSTEM_OVERLAY` works very well but is focusable - no click events
        // `TYPE_SYSTEM_ERROR` supports all these requirements
        WindowManager.LayoutParams mLayoutParams = new WindowManager.LayoutParams(
            ViewGroup.LayoutParams.WRAP_CONTENT, 
            ViewGroup.LayoutParams.WRAP_CONTENT, 0, 0,
            WindowManager.LayoutParams.TYPE_SYSTEM_ERROR,
            WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED
                    | WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD
                    | WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON
                    | WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON, 
                      PixelFormat.RGBA_8888);

        // finally, add the view to window
        mWindowManager.addView(mView, mLayoutParams);
    }

    @Override
    public void onDestroy() {
        super.onDestroy();

        // remove `mView` from the window
        removeViewFromWindow();
    }

    // Removes `mView` from the window
    public void removeNow() {
        if (mView != null) {
            WindowManager wm = (WindowManager) getSystemService(WINDOW_SERVICE);
            wm.removeView(mView);
        }
    }
}

最后,将权限添加到您的应用程序清单中:

<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />

1
@roiberg 是的。我认为放上截图会让这一点更清楚。 - Vikram
2
@roiberg 啊。对不起啊。我不知道你是在问点击性。而且点击功能非常正常。 - Vikram
是的,可点击性是一个问题。 - roiberg
@Vikram 只需添加 SYSTEM_ALERT_WINDOW 权限即可。GCM 通知可以显示在锁屏界面上吗?对我来说没有起作用。请告诉我更多的信息。 - Huy Tower

0

我认为它可能使用了与Messenger的聊天头气泡相同的技巧。

基本上,您可以使用此权限 "android.permission.SYSTEM_ALERT_WINDOW" 在其他应用程序上方显示您的视图。

我自己还没有尝试过,但我非常确定他们使用了这个。

从文档中得知: “允许应用程序使用类型TYPE_SYSTEM_ALERT打开窗口,在所有其他应用程序的顶部显示。” http://developer.android.com/reference/android/Manifest.permission.html#SYSTEM_ALERT_WINDOW


1
它会显示在所有其他应用程序的顶部,但不会显示在锁屏界面的顶部。这就是为什么您无法在锁屏界面上看到聊天头像的原因。 - froger_mcs

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