使用WindowManager和Notification的服务

4

我有一个服务。我使用WindowManager在服务运行时显示一些UI。同时,在此服务的生命周期内,我也会显示通知。

下面是我的Service类:

public class DemoService extends Service implements View.OnClickListener {

private static final int mLayoutParamFlags = WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH
        | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL;

// Views
private View mDemoView;
private ImageButton mEndButton

@Override
public int onStartCommand(Intent intent, int flags, int startId) {

    showNotification();

    return START_STICKY;
}

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

    LayoutInflater layoutInflater = (LayoutInflater) getSystemService(LAYOUT_INFLATER_SERVICE);
    mDemoView = layoutInflater.inflate(R.layout.windowmanager_demo, null);

    WindowManager.LayoutParams params = new WindowManager.LayoutParams(
            WindowManager.LayoutParams.MATCH_PARENT,
            WindowManager.LayoutParams.MATCH_PARENT,
            WindowManager.LayoutParams.TYPE_SYSTEM_ALERT,
            mLayoutParamFlags,
            PixelFormat.TRANSLUCENT);

    mEndButton = (Button) view.findViewById(R.id.end_button);
    mEndButton.setOnClickListener(this);

    WindowManager windowManager = (WindowManager) getSystemService(WINDOW_SERVICE);
    windowManager.addView(mDemoView, params);
}

@Override
public void onDestroy() {
    super.onDestroy();
    // Remove notification
    stopForeground(true);
    // Remove WindowManager
    if(mDemoView != null){
        WindowManager wm = (WindowManager) getSystemService(WINDOW_SERVICE);
        wm.removeView(mDemoView);
    }
}

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

@Override
public void onClick(View view) {
    switch (view.getId()) {
        case R.id.end_button:
            endService();
            break;
    }
}

/**
 * Show notification
 */
private void showNotification() {
    NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(getApplicationContext())
            .setSmallIcon(R.mipmap.demoicon)
            .setContentTitle("Demo App")
            .setContentText("Demo Message");

    startForeground(R.string.demo_string, notificationBuilder.build());
}

private void endService() {
    // Stop demo service
    stopSelf();
}

以下是我想实现但不知道如何实现的事情:
  1. 当服务正在运行且WindowManager的UI可见时,如果我按下硬件返回/主页键,则WindowManager的UI应该消失,同时服务应继续运行。我不知道如何在服务中捕获返回键。
  2. 当我点击通知时,WindowManager的UI应该变为可见状态。
请帮我实现这两件事。
1个回答

2
  1. 为了捕获返回键,扩展你添加到WindowManager的ViewGroupView,并重写onKeyUpdispatchKeyEvent(并检查keyCode和跟踪ACTION_UP)。请注意,为了确保它有效,您必须检查您的LayoutParams标志及其类型,以便您的View可聚焦(例如,使用TYPE_SYSTEM_OVERLAY,窗口将无法聚焦),但是当您的View折叠时(如果您像Facebook Messenger Chat Heads那样做某些事情),您必须更新您的View LayoutParams以放置FLAG_NOT_FOCUSABLE标志。如果您未能这样做,则按返回键不会分派给底层Activity,而只会分派给您的窗口,这会导致用户卸载您的应用程序。
  2. 当你向通知添加操作时,你可以使用PendingIntent。在pendingIntent中,你可以添加一个显式的Intent。它可以是一个Service操作(不用担心,你的服务不会被启动两次,如果已经启动,只会调用运行实例的onStartCommand),一个BroadcastReceiver或一个Activity。服务操作可能是你想要的,但如果合适,也可以使用BroadcastReceiver。
请注意,Marshmallow 要求您将用户带到设置屏幕,以让他手动为您的应用启用“在其他应用程序上绘制”权限。您可以在 Android Developers page on G+ 上找到更多信息,他们最近发布了有关运行时权限的内容。

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