前言
有个需求要监听HDMI,然后把应用放到第二屏的操作。第一步:百度,Google看看有没有实现好的,按照百度的监听广播,在AndroidManifest.xml注册,然后插着HDMI开机的话要知道是否连着就要去读一个sys的文件。我按照操作来一遍,无卵用!!
所以下面是我的实现方法:
插拔HDMI
广播监听,肯定是要的
V/ActivityManager( 947): Broadcast sticky: Intent { act=android.intent.action.HDMI_PLUGGED flg=0x4000010 (has extras) } ordered=false userid=-1
但是我们监听即可
private static final String ACTION_HDMI_PLUGGED = "android.intent.action.HDMI_PLUGGED";
private static final String EXTRA_HDMI_PLUGGED_STATE = "state";
private BroadcastReceiver mReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (ACTION_HDMI_PLUGGED.equals(action)) {
mIsHDMIPlugged = intent.getBooleanExtra(EXTRA_HDMI_PLUGGED_STATE, false);
Log.d(TAG, "onReceive:mIsHDMIPlugged = " + mIsHDMIPlugged);
}
}
};
注意事项
1、需要在代码注册广播,在AndroidManifest.xml中注册无效,要在代码中注册
2、从log中可以得出,该广播为粘性广播,连接hdmi之后开机也可以收到广播的。
知其然
为什么只能在代码中注册呢?看下发广播的代码吧。
ps:源码为Android 7.1
void initializeHdmiState() {
boolean plugged = false;
// watch for HDMI plug messages if the hdmi switch exists
if (new File("/sys/devices/virtual/switch/hdmi/state").exists()) {
mHDMIObserver.startObserving("DEVPATH=/devices/virtual/switch/hdmi");
//也是去读文件的数据
final String filename = "/sys/class/switch/hdmi/state";
FileReader reader = null;
try {
reader = new FileReader(filename);
char[] buf = new char[15];
int n = reader.read(buf);
if (n > 1) {
plugged = 0 != Integer.parseInt(new String(buf, 0, n-1));
}
} catch (IOException ex) {
Slog.w(TAG, "Couldn't read hdmi state from " + filename + ": " + ex);
} catch (NumberFormatException ex) {
Slog.w(TAG, "Couldn't read hdmi state from " + filename + ": " + ex);
} finally {
if (reader != null) {
try {
reader.close();
} catch (IOException ex) {
}
}
}
}
// This dance forces the code in setHdmiPlugged to run.
// Always do this so the sticky intent is stuck (to false) if there is no hdmi.
mHdmiPlugged = !plugged;
setHdmiPlugged(!mHdmiPlugged);
}
//由kernel上报的监听事件
private UEventObserver mHDMIObserver = new UEventObserver() {
@Override
public void onUEvent(UEventObserver.UEvent event) {
setHdmiPlugged("1".equals(event.get("SWITCH_STATE")));
}
};
//发广播出来
void setHdmiPlugged(boolean plugged) {
if (mHdmiPlugged != plugged) {
mHdmiPlugged = plugged;
updateRotation(true, true);
Intent intent = new Intent(ACTION_HDMI_PLUGGED);
//这个flags:启动检查时只能接受在代码中注册的Receiver
intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
intent.putExtra(EXTRA_HDMI_PLUGGED_STATE, plugged);
//粘性广播没有限制,即便后来注册的intent也可以收到这个广播
mContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL);
}
}