CLOSE_SYSTEM_DIALOGS广播后,三星设备不会关闭应用程序抽屉

时间:2017-03-31 08:01:19

标签: android

我正在为Android 6.0开发一个简单的Kiosk模式应用程序。我拥有小米,HTC,联想等设备上的所有功能,但我无法在任何三星设备上运行任何功能。

该功能是使用

自动关闭每个系统系统对话框
Intent closeDialog = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
sendBroadcast(closeDialog);

这是从服务广播的。

在我的另一台非三星设备上,一切正常,所有系统对话框都关闭,但在任何三星设备(S5,S6边缘......)上,此广播都会被忽略,例如应用程序抽屉保持打开状态。

我观察到,即使使用ADB广播此意图,app抽屉也会保持打开状态,但是例如,如果我从adb广播,则关闭设备对话框会关闭。

请注意,这不是此软件上下文中的恶意操作,这适用于客户端,需要此功能并且已完全征求。

我已经对三星诺克斯进行了研究,但是我们必须获得使用诺克斯标准SDK的许可证,这不属于本项目范围内的内容。

所以我的问题是:您是否知道如何在安装了Knox的三星设备上完成这项工作(使用ACTION_CLOSE_SYSTEM_DIALOGS意图关闭应用程序抽屉)?

感谢。

2 个答案:

答案 0 :(得分:2)

尝试这样做:

 @Override
public void onWindowFocusChanged(boolean focus) {
        super.onWindowFocusChanged(focus);

        if (! focus) {
            Intent close= new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
            sendBroadcast(close);
        }
    }

答案 1 :(得分:0)

最常见的解决方案的问题是对话框是完全不同的窗口,因此您也需要覆盖它们上的onWindowsFocusChanged。那会导致很多工作,再加上菜单也打开了同样的缺陷来调用电源菜单。

我发现的最佳解决方案是实现一项服务,以在检测到长按电源键时关闭系统对话框。我在两个LG设备(Android 5.1.1和6.0)上进行了测试,并通过服务调用了它,效果很好:

sendBroadcast(new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS));

但是在三星平板电脑(Android 5.1.1)上,它尝试了几种没有运气的不同解决方案后,无法正常工作。当向活动发送意图并让活动发送广播时,我终于使它工作了:

将此添加到您的清单:

<service 
        android:name="com.mypackage.services.PowerButtonService"
        android:enabled="true"
        android:exported="true"
        android:permission="android.permission.SYSTEM_ALERT_WINDOW"
        android:stopWithTask="true"/>

<activity
    android:name="com.mypackage.activities.CloseSystemDialogActivity"
    android:launchMode="singleTask">

    <intent-filter>
        <action android:name="CloseSystemDialogActivity.ACTION_CLOSE_DIALOGS"/>
        <category android:name="android.intent.category.DEFAULT"/>
    </intent-filter>
</activity>

服务:

public class PowerButtonService extends Service {
    private View view;
    private WindowManager windowManager;

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

        LinearLayout linearLayout = new LinearLayout(getApplicationContext()) {
            @SuppressWarnings("unused")
            public void onCloseSystemDialogs(String reason) {
                if ("globalactions".equals(reason)) {
                    final Intent intent = new Intent(CloseSystemDialogActivity.ACTION_CLOSE_DIALOGS);
                    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                    startActivity(intent);
                }
            }
        };

        linearLayout.setFocusable(true);

        WindowManager.LayoutParams params = new WindowManager.LayoutParams(100, 100, WindowManager.LayoutParams.TYPE_SYSTEM_ALERT,
                                                                           WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL | WindowManager.LayoutParams.FLAG_FULLSCREEN
                                                                           | WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN | WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON
                                                                           | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE, PixelFormat.TRANSLUCENT);
        params.gravity = Gravity.START | Gravity.CENTER_VERTICAL;

        view = LayoutInflater.from(this).inflate(R.layout.empty, linearLayout);
        windowManager = (WindowManager) getSystemService(WINDOW_SERVICE);
        windowManager.addView(view, params);
    }

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

    @Override
    public void onDestroy() {
        super.onDestroy();
        // VERY IMPORTANT
        windowManager.removeView(view);
    }

    @Override
    public int onStartCommand(final Intent intent, final int flags, final int startId) {
        return START_STICKY;
    }
}

虚拟活动:

public class CloseSystemDialogActivity extends Activity {
    public static final String ACTION_CLOSE_DIALOGS = "CloseSystemDialogActivity.ACTION_CLOSE_DIALOGS";

    @Override
    protected void onCreate(@Nullable final Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        sendBroadcast(new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS));
        finish();
    }
}

请注意,您需要启动和停止服务,否则,当您的应用程序未运行(不在自助服务机模式下)时,您可能无法调用电源菜单。