使用WindowManager和通知进行服务

时间:2015-11-16 18:53:08

标签: android notifications android-service android-windowmanager

我有服务。我已经使用WindowManager在Service的运行时显示了一些UI。此外,我在本服务的有效期内也会显示通知。

以下是我的服务类

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应该可见。

  3. 请帮我实现这两件事。

1 个答案:

答案 0 :(得分:2)

  1. 要捕获后退键,请扩展要添加到WindowManager的ViewGroupView,并覆盖onKeyUpdispatchKeyEvent(并检查keyCode和跟踪ACTION_UP)。请注意,要确保其有效,您必须检查LayoutParams标记及其类型,以便您的视图可以调焦(例如,使用TYPE_SYSTEM_OVERLAY,窗口无法调整),当您的视图折叠时(如果您执行Facebook Messenger聊天头),您必须更新View LayoutParams以放置标记FLAG_NOT_FOCUSABLE。如果你没有这样做,按下后退键不会被分派到底层的活动,而只会被发送到你的窗口,这会让用户卸载你的应用程序。
  2. 向通知添加操作时,使用PendingIntent。在pendingIntent中,您可以添加显式Intent。它可以是Service操作(不用担心,您的服务无法启动两次,只有onStartCommand将在正在运行的实例上调用,如果已经启动),BroadcastReceiver或Activity。服务操作是您可能想要的,但您也可以使用BroadcastReceivers。
  3. 请注意,Marshmallow要求您将用户带到“设置”屏幕,让他手动为您的应用启用“覆盖其他应用”权限。您可以在Android Developers page on G+上找到有关最近发布的有关运行时权限的更多信息。