Taras
Taras

Reputation: 2576

Run a separate application on secondary monitor

Android supports rendering apps to secondary screen (added in 4.2), but is it possible to run one application on a primary monitor and another application on secondary monitor?

Upvotes: 5

Views: 8533

Answers (2)

Naren
Naren

Reputation: 61

Android Oreo enabled feature to launch application in secondary screen.

Step1 : Need to enable secondary_displays feature in the AOSP level.

Step2 : Get setLaunchDisplayId In the application level .

Step3 : Via intent send activityOptions to your second activity.

Step4 : Finally,your application launch only in secondary screen.

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

Thank you

Upvotes: 3

CommonsWare
CommonsWare

Reputation: 1007554

The Android SDK ships with a Presentation class that allows the foreground activity to display alternate content on an external display. This was built with an eye towards "second screen" apps, where you might be watching a movie on the external display and using the touchscreen to control playback, chat with friends, etc. The limitation of Presentation is that it is effectively a Dialog, and therefore only works when driven by the foreground activity.

However, it is possible, using WindowManager, to have a Service display content on an external display. I have a PresentationService class that demonstrates the technique and simplifies its use. Given a Display object representing the external display (e.g., DisplayManager), you can have WindowManager direct content to that Display, from some View that you inflate or otherwise create.

/***
  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));
      }
    });
  }
}

(source from v0.4.6)

Upvotes: 7

Related Questions