Подтвердить что ты не робот

Уведомление о блокировке Android Facebook

В последней версии Android-приложения 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);

в моей работе.

Также я попробовал этот пример: https://gist.github.com/daichan4649/5352944

И как я описал - все работает, но нет прозрачности.

Из моего наблюдения Facebook использует тему:

@android:style/Theme.Translucent.NoTitleBar

и не имеет разрешения:

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

Также я заметил, что уведомление об заблокированном экране касается касаний, поэтому мы не можем показывать уведомления из строки состояния по жесту.

Любые идеи о создании такого уведомления перед выпуском Android L.

4b9b3361

Ответ 1

Собственно, ferdy182 был/на что-то.

Вот что я получил с помощью android.permission.SYSTEM_ALERT_WINDOW:

enter image description here

Итак, я не мог сделать это с помощью Activity. Это просто не сработает. Мне пришлось реализовать Service, который добавил View, используя WindowManager.

Одним из возможных рабочих процессов будет: широковещательная передача будет получена с помощью 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 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" />

Ответ 2

Я думаю, что это, вероятно, использует тот же трюк, что и чаты для чата для Messenger.

В основном вы используете это разрешение "Android.permission.SYSTEM_ALERT_WINDOW" для отображения ваших представлений над другими приложениями.

Я не пробовал себя, но я уверен, что они использовали это.

Из документов "Позволяет приложению открывать окна с использованием типа TYPE_SYSTEM_ALERT, показанного поверх всех других приложений". http://developer.android.com/reference/android/Manifest.permission.html#SYSTEM_ALERT_WINDOW