在辅助监视器上运行单独的应用程序

时间:2017-03-02 22:28:26

标签: android

Android支持将应用程序渲染到辅助屏幕(在4.2中添加),但是可以在主监视器上运行一个应用程序而在辅助监视器上运行另一个应用程序吗?

2 个答案:

答案 0 :(得分:1)

Android SDK附带Presentation类,允许前台活动在外部显示器上显示备用内容。这是建立在第二屏和第二屏的基础上的。应用程序,您可能正在外部显示器上观看电影,使用触摸屏控制播放,与朋友聊天等。Presentation的限制是它实际上是Dialog,因此仅在前台活动的驱动下工作。

但是,使用WindowManager可以在外部显示器上显示Service个显示内容。我有a PresentationService class来演示该技术并简化其使用。给定代表外部显示的Display对象(例如,DisplayManager),您可以从WindowManager Display获得View个直接内容或以其他方式创造。

/***
  Copyright (c) 2014 CommonsWare, LLC

  Licensed under the Apache License, Version 2.0 (the "License"); you may
  not use this file except in compliance with the License. You may obtain
  a copy of the License at
    http://www.apache.org/licenses/LICENSE-2.0
  Unless required by applicable law or agreed to in writing, software
  distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions and
  limitations under the License.
 */

package com.commonsware.cwac.preso;

import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.graphics.PixelFormat;
import android.os.IBinder;
import android.view.ContextThemeWrapper;
import android.view.Display;
import android.view.LayoutInflater;
import android.view.View;
import android.view.WindowManager;

/**
 * A service that drives a presentation from the background. Use this when
 * presentations need to span activities or when they should be occurring even
 * if the app's UI has moved to the background.
 *
 * This is an abstract class -- create a subclass and override getThemeId() and
 * buildPresoView().
 */
public abstract class PresentationService extends Service implements
    PresentationHelper.Listener {
  /**
   * @return the theme to use for driving the resources used by
   * this presentation
   */
  protected abstract int getThemeId();

  /**
   * Override this to provide the UI that goes into the presentation.
   * This works somewhat like a fragment's onCreateView().
   *
   * @param ctxt a Context, in case you need one, but note that it will
   *            <i>not</i> be an activity
   * @param inflater a LayoutInflater, in case you need one for creating
   *                 the UI
   * @return the View that should be shown on the external display
   */
  protected abstract View buildPresoView(Context ctxt,
                                         LayoutInflater inflater);

  private WindowManager wm=null;
  private View presoView=null;
  private PresentationHelper helper=null;

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

  /**
   * {@inheritDoc}
   */
  @Override
  public void onCreate() {
    super.onCreate();

    helper=new PresentationHelper(this, this);
    helper.onResume();
  }

  /**
   * {@inheritDoc}
   */
  @Override
  public void onDestroy() {
    helper.onPause();

    super.onDestroy();
  }

  /**
   * {@inheritDoc}
   */
  @Override
  public void showPreso(Display display) {
    Context presoContext=createPresoContext(display);
    LayoutInflater inflater=LayoutInflater.from(presoContext);

    wm=
        (WindowManager)presoContext.getSystemService(Context.WINDOW_SERVICE);

    presoView=buildPresoView(presoContext, inflater);
    wm.addView(presoView, buildLayoutParams());
  }

  /**
   * {@inheritDoc}
   */
  @Override
  public void clearPreso(boolean switchToInline) {
    if (presoView != null) {
      try {
        wm.removeView(presoView);
      }
      catch (Exception e) {
        // probably the window is gone, don't worry, be
        // happy
      }
    }

    presoView=null;
  }

  protected WindowManager.LayoutParams buildLayoutParams() {
    return(new WindowManager.LayoutParams(
                                          WindowManager.LayoutParams.MATCH_PARENT,
                                          WindowManager.LayoutParams.MATCH_PARENT,
                                          0,
                                          0,
                                          WindowManager.LayoutParams.TYPE_TOAST,
                                          0, PixelFormat.OPAQUE));
  }

  private Context createPresoContext(Display display) {
    Context displayContext=createDisplayContext(display);
    final WindowManager wm=
        (WindowManager)displayContext.getSystemService(WINDOW_SERVICE);

    return(new ContextThemeWrapper(displayContext, getThemeId()) {
      @Override
      public Object getSystemService(String name) {
        if (Context.WINDOW_SERVICE.equals(name)) {
          return(wm);
        }

        return(super.getSystemService(name));
      }
    });
  }
}

(来自v0.4.6

答案 1 :(得分:0)

启用了Android Oreo的功能可在辅助屏幕中启动应用程序。

第一步:需要在AOSP级别启用 secondary_displays 功能。

Step2:在应用程序级别获取 setLaunchDisplayId

第3步:通过意图将activityOptions发送到第二个活动。

第4步:最后,您的应用程序仅在辅助屏幕中启动。

参考:https://developer.android.com/about/versions/oreo/android-8.0.html

谢谢