Android secondary screen call

Android native secondary screen function API, no need to integrate SDK.

The specific calling process is as follows

-Second screen application permission

Add the following code to Androidmanifest.xml:

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

==Simple function example==

Renderings:

main screen:

 Secondary screen initial page:

 The secondary screen receives the main screen information page:

code show as below:

1. Define the dual-screen Service and declare it in the manifest file

public class DualScreenService extends Service {

    public static final String SUB_ACTIVITY_TEST_UPDATE_CONTENT = "sub_activity_test_update_content";
    // 获取设备上的屏幕
    DisplayManager mDisplayManager;// 屏幕管理器
    Display[] displays;// 屏幕数组
    SubPresentation subPresentation; // (继承Presentation)

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

    @Override
    public void onCreate() {
        super.onCreate();
        // 双屏异显
        mDisplayManager = (DisplayManager) this.getSystemService(Context.DISPLAY_SERVICE);
        displays = mDisplayManager.getDisplays();
        registerRecevicer();
    }

    private void registerRecevicer() {
        IntentFilter filter = new IntentFilter();
        filter.addAction(SUB_ACTIVITY_TEST_UPDATE_CONTENT);
        registerReceiver(receiver, filter);
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        showView();
        return super.onStartCommand(intent, flags, startId);
    }

    @SuppressLint("NewApi")
    private void showView() {
        if (displays.length < 2) {
            Toast.makeText(getApplicationContext(), "开启副屏失败", Toast.LENGTH_SHORT).show();
            return;
        }
        subPresentation = new SubPresentation(getApplicationContext(), displays[1]);// displays[1]是副屏
        subPresentation.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
        subPresentation.setCancelable(false);
        subPresentation.show();
    }

    BroadcastReceiver receiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();
            switch (action) {
                case SUB_ACTIVITY_TEST_UPDATE_CONTENT:
                    subPresentation.updateContent(intent.getStringExtra("content"));
                    break;
                default:
                    break;
            }
        }
    };
}

<service
    android:name=".DualScreenService"
    android:exported="false" />

2. Custom secondary screen demo class

public class SubPresentation extends Presentation {

    private ActivitySubScreenBinding binding;

    public SubPresentation(Context mContext, Display display) {
        super(mContext, display);
        binding = ActivitySubScreenBinding.inflate(getLayoutInflater());
        setContentView(binding.getRoot());
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    }

    public void updateContent(String content) {
        binding.tvContent.setText("接收到:"+content);
    }

}

Description: The above two classes are the two most basic classes of the secondary screen function. The service mainly declares the creation of the secondary screen service, creates and receives system broadcasts, and handles the information transmission between the main and secondary screens. SubPresentation can be understood as a sub-screen page, a bit of the concept of Activity, in which it mainly deals with changes on the sub-screen UI.

According to the example picture, we only click the button on the main screen, send "Hello" to the secondary screen, and display it.

Then we declare a SUB_ACTIVITY_TEST_UPDATE_CONTENT instruction name, that is, as long as this instruction is found in the broadcast, we will call the updateContent method of subPresentation, and then change the text attribute of binding.tvContent

MainActivity code

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        checkDualScreenPermission();
        Button btn_send = findViewById(R.id.btn_send);
        btn_send.setOnClickListener(view -> {
            Intent intent = new Intent();
            intent.setAction(DualScreenService.SUB_ACTIVITY_TEST_UPDATE_CONTENT);
            intent.putExtra("content", "你好!");
            sendBroadcast(intent);
        });
    }

    public void checkDualScreenPermission() {
        if (Build.VERSION.SDK_INT >= 23) {
            if (!Settings.canDrawOverlays(MainActivity.this)) {
                new CommonDialog.Builder(this).setTitle("提示")
                        .setContent("副屏功能需要开启相关权限")
                        .setEnsureStr("前往设置")
                        .setCancelStr("退出应用")
                        .setEnsureClick(v1 -> {
                            Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION,
                                    Uri.parse("package:" + getPackageName()));
                            startActivityForResult(intent, 10);
                        })
                        .setCancelClick(v -> {
                            finish();
                        })
                        .show();
            } else {
                Intent service = new Intent();
                service.setPackage(this.getPackageName());// 这里你需要设置你应用的包名
                service.setClass(this, DualScreenService.class);
                this.startService(service);
            }
        }
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (requestCode == 10) {
            if (Build.VERSION.SDK_INT >= 23) {
                if (!Settings.canDrawOverlays(this)) {
                    // SYSTEM_ALERT_WINDOW permission not granted...
                    new CommonDialog.Builder(this).setTitle("提示")
                            .setContent("权限被拒绝或未开启")
                            .setEnsureStr("前往设置")
                            .setCancelStr("退出应用")
                            .setEnsureClick(v1 -> {
                                Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION,
                                        Uri.parse("package:" + getPackageName()));
                                startActivityForResult(intent, 10);
                            })
                            .setCancelClick(v -> {
                                finish();
                            })
                            .show();
                } else {
                    Intent service = new Intent();
                    service.setPackage(this.getPackageName());// 这里你需要设置你应用的包名
                    service.setClass(this, DualScreenService.class);
                    this.startService(service);
                }
            }
        }
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        Intent service = new Intent();
        service.setPackage(getPackageName());// 这里你需要设置你应用的包名
        service.setClass(MainActivity.this, DualScreenService.class);
        stopService(service);
    }
}

illustrate:

1. Android calls the secondary screen, you need to set permissions, as shown below

 

Here, jumping to the setting page to open the permission needs to interact with the user, and handle the situation where the user clicks the "Go to Settings" button, but returns without turning on the switch, and intercepts it to avoid subsequent crashes or abnormal display on the secondary screen.

In the code, checkDualScreenPermission() and onActivityResult() handle the logic

2. The specific code to call the secondary screen

Intent intent = new Intent();
intent.setAction(DualScreenService.SUB_ACTIVITY_TEST_UPDATE_CONTENT);
intent.putExtra("content", "你好!");
sendBroadcast(intent);

3. In order to avoid resource waste, when the app exits, it is necessary to log out of the service

@Override
protected void onDestroy() {
    super.onDestroy();
    Intent service = new Intent();
    service.setPackage(getPackageName());// 这里你需要设置你应用的包名
    service.setClass(MainActivity.this, DualScreenService.class);
    stopService(service);
}

Written later, in addition to String text, you can also pass all supported data types or serialized object data through intent to realize various UI scenarios required in the business. Here is just the simplest display. If you need the actual code, you can refer to the actual business code of the catering retail member.

demo source code

Guess you like

Origin blog.csdn.net/weixin_53324308/article/details/129966488