Android异显注意事项

1,085 阅读2分钟

「这是我参与2022首次更文挑战的第26天,活动详情查看:2022首次更文挑战

Android异显注意事项

大部分的手机实际上不支持异显的,所以目前来说异显是个小众的应用场景。大部分需要的是同屏应用,即屏幕投影到大屏上,但这样的话需要显示器有软件支持,比如苹果的AirPlay。这篇文章的目的是为了记录一些奇葩的注意事项。

监听HDMI连接事件

坑:先说坑,在华为某机型上监听不到,也无法判断HDMI连接状态.
导致的问题: 理想状态是在HDMI连接之后,显示副屏,由于我们无法知道HDMI连接状态,所以每次显示副屏,就需要在确保连接HDMI之后手动通过按钮打开。

我目前还不知道怎么解决这个问题,有知道的麻烦指引一下。

在RK某系列的主板上测试可用。

  • 方法: 广播监听

通过注册动态广播监听HDMI的连接和断开事件。

广播代码:

public class HdmiListener extends BroadcastReceiver {

   private final String TAG = "HdmiListener";

   private final static String HDMI_ACTION = "android.intent.action.HDMI_PLUGGED";

   private final HdmiStateCallback mHdmiStateCallback;

   public HdmiListener(HdmiStateCallback callback) {
       this.mHdmiStateCallback = callback;
   }

   @Override
   public void onReceive(Context context, Intent intent) {
       if (intent.getAction() != null) {
           String action = intent.getAction();
           if (TextUtils.equals(HDMI_ACTION, action)) {
               //HDMI插拔的广播事件
               boolean state = intent.getBooleanExtra("state", false);
               //事件返回一个Boolean类型的state值,根据state值可以判断其状态,true表已连接,false表断开。
               Log.e("HdmiListener", "state:" + state);
               if (mHdmiStateCallback != null)
                   mHdmiStateCallback.hdmiState(state);
           }
       }
   }

   public interface HdmiStateCallback {
       void hdmiState(boolean isConnected);
   }

}

Activity 代码

       // 动态注册广播
        IntentFilter intentFilter = new IntentFilter();
        intentFilter.addAction(HDMI_ACTION);
        mHdmiListener = new HdmiListener(this);
        registerReceiver(mHdmiListener, intentFilter);


 @Override
    public void hdmiState(boolean isConnected) {
        Log.d(TAG, "isConnected:" + isConnected);
        if (isConnected) {
            try {
                Thread.sleep(2000);
                showPresentation();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

值得注意的是,在链接HDMI之后,不能立刻去操作副屏,需要增加2秒的延时,之后才可以显示副屏。

判断是否连接HDMI

上诉代码是监听HDMI连接和断开的事件。还有一种方法可以通过读取本地文件判断HDMI是否连接。

/**
     * 广播只能监听HDMI的插拔 第一次进入程序时不知道HDMI的连接状态
     * 此时需要去读系统文件去判断HDMI的连接状态
     *
     * @return true 连接 false 未连接
     */

    public static boolean isHdmiSwitchSet() {
        // The file '/sys/devices/virtual/switch/hdmi/state' holds an int -- if it's 1 then an HDMI device is connected.
        // An alternative file to check is '/sys/class/switch/hdmi/state' which exists instead on certain devices.
        File switchFile = new File("/sys/devices/virtual/switch/hdmi/state");
        if (!switchFile.exists()) {
            switchFile = new File("/sys/class/switch/hdmi/state");
        }
        try {
            Scanner switchFileScanner = new Scanner(switchFile);
            int switchValue = switchFileScanner.nextInt();
            switchFileScanner.close();
            return switchValue > 0;
        } catch (Exception e) {
            return false;
        }
    }

同样的这个方法在华为某平板上依旧不起作用,在RK系列的主板上有效。
网上有一种说法是,第一次不会响应HDMI广播事件,我自己试下来,是能监听到了。
这两种方法配合着一起使用,就能完全判断HDMI连接状态了。