[Перевод] Подробные шаги простой многоэкранной функции отображения на основе Android Studio и связанных с ними простых механизмов.

Оглавление

Действия по реализации простой функции многоэкранного отображения на основе Android Studio и связанных с ней простых механизмов

1. Краткое введение

2. Принцип реализации

3. Вопросы, требующие внимания

4. Среда разработки

5. Этапы реализации

6. Код ключа

приложение:

7. Обработка ошибок: Android: невозможно добавить окно, доступ запрещен для этого типа окна

8. Справочник по онлайн-информации: три способа реализации двухэкранного дисплея Android.

1. Первый метод реализации двухэкранного другого дисплея (официально предоставленная презентация)

2. Метод реализации двухэкранного разного отображения (одновременного отображения).

3. Существует еще один способ добиться разного отображения на двух экранах с помощью проекции.Каждая проекция будет отображать всплывающее окно для подтверждения, которое имеет определенные ограничения.


1. Краткое введение

Некоторые основные операции в разработке для Android отсортированы для последующего использования.

В этом разделе рассказывается, что в разработке для Android не существует уникального способа просто реализовать различные функции отображения на нескольких экранах, и исправления приветствуются.

2. Принцип реализации

1. Наследовать официальный класс, предоставляемый Presentation, который эквивалентен специальному всплывающему окну.

3. Вопросы, требующие внимания

1. Добавьте разрешения: <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />

2. Когда приложение открыто одновременно, получите разрешение ACTION_MANAGE_OVERLAY_PERMISSION

4. Среда разработки

Android-студия 4.1.1

5. Этапы реализации

1. Откройте Android Studio и создайте новый проект.

2. Выберите «Телефон и планшет» — «EmptyActivity», нажмите «Далее».

3. В соответствии с вашими потребностями выполните некоторые соответствующие настройки, а затем нажмите кнопку Готово.

4. Вот возьмем в качестве примера двойной экран, создадим новый скрипт и напишем логический код

5. Добавьте логику кода для получения соответствующих разрешений и получения соответствующих экранов в MainActivity.java следующим образом.

6. Поскольку версия SDK среды разработки — 27 (Android 8.1), тип настройки — WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY, и вам может потребоваться внести небольшие изменения в соответствии с вашей собственной версией SDK.

В противном случае может быть сообщено об ошибке: например, android.view.WindowManager$BadTokenException: невозможно добавить окно android.view.ViewRootImpl$W@40ec8528 -- разрешение отклонено для этого типа окна

7. В зависимости от версии, соответствующее разрешение приложения, в противном случае может быть сообщено об ошибке или разные многоэкранные дисплеи

8. Поскольку необходимо отключить функцию многоэкранного отображения в зависимости от фонового переключения приложения и от того, закрыто оно или нет, статус приложения мониторинга отображается и отменяется.

А именно: показать() или отклонить()

9. Добавьте соответствующие разрешения в AndroidManifest.xml.

<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />

10. Соответствующий файл layout.xml показан на рисунке ниже, что удобно для многоэкранного отображения.

11. В это время Build-Make проект, подключите несколько экранов мобильного телефона, и вы можете увидеть эффект многоэкранного разного отображения.

6. Код ключа

1、РазноеDislay.java

import android.app.Presentation;
import android.content.Context;
import android.os.Bundle;
import android.view.Display;
 
public class DifferentDislay extends Presentation {
 
    public DifferentDislay(Context outerContext, Display display) {
        super(outerContext,display);
 
    }
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.mylayout);
    }
}

2、MainActivity.java

 
import android.app.Activity;
import android.app.Application;
import android.app.Presentation;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.graphics.PixelFormat;
import android.hardware.display.DisplayManager;
import android.net.Uri;
import android.os.Build;
import android.provider.Settings;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.Display;
import android.view.WindowManager;
 
public class MainActivity extends AppCompatActivity {
 
    private static final String TAG = "XANTest";
    DifferentDislay mPresentation;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        GetPermission();
 
        multiScreenDisplay();
    }
 
    void multiScreenDisplay(){
        //双屏显示
        DisplayManager mDisplayManager;//屏幕管理类
        Display[] displays;//屏幕数组
 
        mDisplayManager =(DisplayManager)MainActivity.this.getSystemService(Context.DISPLAY_SERVICE);
        displays =mDisplayManager.getDisplays(); //得到显示器数组
 
        Log.i(TAG, "multiScreenDisplay: displays count = " + displays.length);
 
        if (displays.length > 1){
 
            mPresentation =new DifferentDislay
                    (getApplicationContext(),displays[1]);//displays[1]是副屏
 
            mPresentation.getWindow().setType(WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY);
 
 
//            if you use apiLevel >= 19, don't use
//
//            WindowManager.LayoutParams.type = WindowManager.LayoutParams.TYPE_SYSTEM_ALERT
//
//            which gets the following error:
//
//            android.view.WindowManager$BadTokenException: Unable to add window android.view.ViewRootImpl$W@40ec8528 -- permission denied for this window type
//
//            Use this instead:
//
//            LayoutParams.TYPE_TOAST or TYPE_APPLICATION_PANEL
 
 
            mPresentation.show();
        }
 
 
    }
 
    void GetPermission(){
        if(Build.VERSION.SDK_INT >= 23) {
            if (!Settings.canDrawOverlays(this)) {
                Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION,
                        Uri.parse("package:" + getPackageName()));
                startActivityForResult(intent, 1234);
            }
        }
        else
        {
            Intent intent = new Intent(this, Service.class);
            startService(intent);
        }
 
    }
 
    @Override
    protected void onStop() {
        super.onStop();
        if (mPresentation != null) {
            mPresentation.dismiss();
        }
    }
 
    @Override
    protected void onResume() {
        super.onResume();
        if (mPresentation != null) {
            mPresentation.show();
        }
    }
 
    @Override
    protected void onDestroy() {
        super.onDestroy();
        if (mPresentation != null) {
            mPresentation.dismiss();
        }
    }
 
 
}

3、AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.testmultiscreendisplay0407">
 
    <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
 
    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/Theme.TestMultiScreenDisplay0407">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
 
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>
 
</manifest>

4、activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">
 
    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Hello World!"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent" />
 
</android.support.constraint.ConstraintLayout>

5, mylayout.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
 
    <TextView
        android:id="@+id/textView"
        android:layout_width="match_parent"
        android:layout_height="658dp"
        android:layout_weight="1"
        android:text="MyTestScreen"
        android:textSize="100dp"
        />
</LinearLayout>

приложение:

7. Обработка ошибок: Android: невозможно добавить окно, доступ запрещен для этого типа окна

Ссылка: Android: невозможно добавить окно. Разрешение отклонено для этого типа окна – 2 Ответа

8. Справочник по онлайн-информации: три способа реализации двухэкранного дисплея Android.

Справочный адрес сообщения в блоге: три способа реализации двухэкранного режима Android, разные display_createddisplaycontext_I am a фактически смертный блог-блог CSDN

В эпоху, когда различные продукты полны идей, спрос также становится все более и более новым.Недавно автор разработал набор приложений с двумя экранами для различных дисплеев. теперь подведем некоторые итоги

1. Первый метод реализации двухэкранного другого дисплея (официально предоставленная презентация)

Android предоставляет класс Presentation для реализации второго экрана, наследующий Presentation для реализации второго экрана, который эквивалентен специальному всплывающему окну (конкретная реализация).

 public class DifferentDislay extends Presentation {
        public DifferentDislay(Context outerContext, Display display) {
            super(outerContext,display);
           
        }
     
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.diffrentdisplay);
        }
    }

Цитировать:

 //双屏显示
            DisplayManager mDisplayManager;//屏幕管理类
            Display[] displays;//屏幕数组
            mDisplayManager =(DisplayManager)MainActivity.this.getSystemService(Context.DISPLAY_SERVICE);
            displays =mDisplayManager.getDisplays(); //得到显示器数组
            DifferentDislay mPresentation =new DifferentDislay
            (getApplicationContext(),displays[1]);//displays[1]是副屏
            mPresentation.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
            mPresentation.show();

Требуемые разрешения:

<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
        <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
        <uses-permission android:name="android.permission.TYPE_APPLICATION_OVERLAY" />
        <uses-permission android:name="android.permission.SYSTEM_OVERLAY_WINDOW" />
        <uses-permission android:name="android.permission.INTERNET" />
        <uses-permission android:name="android.permission.FOREGROUND_SERVICE" />

Примечание: Вышеупомянутый вариант отображения на двух экранах реализован с помощью Presentation.Этот метод больше подходит для независимой работы на двух экранах без связи.Если имеется одновременный дисплей на двух экранах или некоторая синхронизация данных между ними, это будет более хлопотный.

Например: адаптация воспроизведения основного экрана -> проекция на второй экран, вышеописанный метод неприменим, так как предполагает адаптацию синхронного отображения, а основной и дополнительный экраны должны запускать плеер для его достижения, что является огромной тратой Производительность устройства относительно хорошая, и это также может быть реализовано таким образом. Если производительность устройства не очень хорошая, видео зависнет после использования этого метода. В тяжелых случаях может произойти сбой декодирования. , а видео не воспроизводится и т.д. Ряд сопутствующих проблем

Для вышеупомянутого открытия второго экрана с одновременным отображением на двух экранах и воспроизведением видео я сделал большое улучшение на исходной основе, что позволяет избежать потери производительности, вызванной запуском двух игроков.

2. Метод реализации двухэкранного разного отображения (одновременного отображения).

Я считаю, что соотечественники, которые делают двухэкранное разное отображение, должны были прочитать исходный код Презентации.Исходный код показывает, что Презентация реализована по наследству и Диалогу.Я также упоминал в начале статьи, что второй экран можно рассматривать как специальный диалог.

Когда я исследовал исходный код Presentation, я обнаружил, что он получает окно через Window w = getWindow();. Мы все знаем, что Window — это окно верхнего уровня Android, когда мы разрабатываем Android. Видя это, я удивляюсь, почему Я не могу напрямую создать окно.Затем получить массив экрана и поместить его на второй экран? смотреть вниз  

 public void addPresentation(Context paramContext) {
            Display display = ((MediaRouter) paramContext.getSystemService(Context.MEDIA_ROUTER_SERVICE)).getSelectedRoute(2).getPresentationDisplay();
            this.secondDisplay = display;
            if (display != null) {
                this.windowManager = (WindowManager) paramContext.createDisplayContext(display).getSystemService(Context.WINDOW_SERVICE);
                this.secondDisplayContext = paramContext.createDisplayContext(this.secondDisplay);
                return;
            }
        }

В приведенном выше коде мы получаем оконный менеджер и создаем второй экран через paramContext.createDisplayContext(this.secondDisplay);

После создания второго экрана добавим вид на второй экран      

 public View addView(int paramInt) {
            this.view = View.inflate(this.secondDisplayContext, paramInt, null);
            this.layoutParams = new WindowManager.LayoutParams(2003, 3, 3);
            if (Build.VERSION.SDK_INT >= 23) {
                this.layoutParams.type = 2038;
            } else {
                this.layoutParams.type = 2003;
            }
            this.windowManager.addView(this.view, this.layoutParams);
            return this.view;
        }

Таким образом, наш второй экран завершен, нам осталось только создать макет в соответствии с нашими потребностями, вызвать метод addView для его добавления, вернуть добавленный вид и работать в основном классе для решения проблемы синхронизации данных. .

Ниже приведен полный код   

public class HelpHandPresentation {
        private WindowManager.LayoutParams layoutParams;
     
        private Display secondDisplay;
     
        private Context secondDisplayContext;
     
        private View view;
     
        private WindowManager windowManager;
     
        public void addPresentation(Context paramContext) {
            Display display = ((MediaRouter) paramContext.getSystemService(Context.MEDIA_ROUTER_SERVICE)).getSelectedRoute(2).getPresentationDisplay();
            this.secondDisplay = display;
            if (display != null) {
                this.windowManager = (WindowManager) paramContext.createDisplayContext(display).getSystemService(Context.WINDOW_SERVICE);
                this.secondDisplayContext = paramContext.createDisplayContext(this.secondDisplay);
                return;
            }
        }
     
        public View addView(int paramInt) {
            this.view = View.inflate(this.secondDisplayContext, paramInt, null);
            this.layoutParams = new WindowManager.LayoutParams(2003, 3, 3);
            if (Build.VERSION.SDK_INT >= 23) {
                this.layoutParams.type = 2038;
            } else {
                this.layoutParams.type = 2003;
            }
            this.windowManager.addView(this.view, this.layoutParams);
            return this.view;
        }
     
        public void presentationAddView() {
            this.windowManager.addView(this.view, this.layoutParams);
        }
     
        public void removeLayoutView() {
            this.windowManager.removeView(this.view);
        }
    }

Эквивалент класса инструмента, только что скопированного в проект, можно использовать напрямую

Ниже показано, как звонить

    HelpHandPresentation helpHandPresentation = new HelpHandPresentation();
    helpHandPresentation.addPresentation(контекст);
    Представление вида = helpHandPresentation.addView(layout);

Всего три строки кода, легко вызвать

3. Существует еще один способ добиться разного отображения на двух экранах с помощью проекции.Каждая проекция будет отображать всплывающее окно для подтверждения, которое имеет определенные ограничения.

 (MediaProjectionManager) getSystemService(Context.MEDIA_PROJECTION_SERVICE);

Если вам интересно, вы можете взглянуть на реализацию исходного кода MediaProjectionManager, которая описана здесь.

Supongo que te gusta

Origin blog.csdn.net/qq_27489007/article/details/131330444
Recomendado
Clasificación