如何检测 Zidoo Digital Android Box 连接或断开连接的 HDMI 状态?
How to detect status HDMI in connected or disconnected for Zidoo Digital Android Box?
我正在使用用于 HDMI 的 ziddo 数字盒播放视频。我连接和断开 HDMI 时出现问题。它正在冻结屏幕。
我正在使用此代码:
public class RealtekSurfaceView extends SurfaceView {
public static final String TAG = "RealtekSurfaceView";
//A reference to the context
private Context mContext = null;
//Reference to ViewGroup
private ViewGroup mViewGroup = null;
//Integers to keep the width, height and FPS
private int width = 0;
private int height = 0;
private int fps = 0;
//Reference to the Surface holder
private SurfaceHolder mSurfaceHolder = null;
private SurfaceHolder.Callback mSurfaceHolderCallback = null;
//Reference to the Broadcast receiver
private BroadcastReceiver mHdmiRxReceiver = null;
//Boolean to indicate if the HDMI IN is connected
private boolean isConnected = false;
//A few constants to pass the data along
public static final int DISPLAY = 0;
public static final int DISPLAYTIME = 200;
//A reference to a handler
Handler mHandler = null;
//Reference to realtek hdmi manager
private RtkHDMIRxManager mRtkHdmiManager = null;
//Boolean to identify if the display is ON or OFF
public static boolean isPreviewAvailable = false;
//A boolean to denote if we are displaying already
private boolean isDisplayOn = false;
String videoPath;
String videoType;
boolean HDMI_AV=false;
//Constructor to the RealtekSurfaceView class, this will take care of populating the context, view group, surface holder.
//It will also take care of setting up the surfaceholder callback
public RealtekSurfaceView(Context ctx, ViewGroup viewGroup) {
super(ctx);
this.mContext = ctx;
this.mViewGroup = viewGroup;
this.mSurfaceHolder = getHolder();
//Add the callback
mSurfaceHolderCallback = new SurfaceCallback();
mSurfaceHolder.addCallback(mSurfaceHolderCallback);
init();
}
public RealtekSurfaceView(Context context,String filePath,String videoType,int x,int y,int width,int height,boolean HDMI_AV){
super(context);
// TODO Auto-generated constructor stub
this.mContext=context;
this.videoType=videoType;
this.width=width;
this.height=height;
this.HDMI_AV=HDMI_AV;
this.videoPath=filePath;
this.mSurfaceHolder = getHolder();
this.mSurfaceHolder.addCallback(new SurfaceCallback());
this.mSurfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
setBackgroundColor(Color.TRANSPARENT);
}
public void init() {
//Make the handler instance ready to be used by remaining components
mHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case DISPLAY:
if (isConnected) {
play();
}
break;
default:
break;
}
}
};
initHdmiConnect();
}
//Start listening to and processing the incoming HDMI IN connection from the Realtek internal classes
private void initHdmiConnect() {
mHdmiRxReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
isConnected = intent.getBooleanExtra(HDMIRxStatus.EXTRA_HDMIRX_PLUGGED_STATE, false);
if (isConnected) {
play();
} else {
stop();
}
}
};
isConnected = isHdmiConnected(mContext);
mContext.registerReceiver(mHdmiRxReceiver, new IntentFilter(HDMIRxStatus.ACTION_HDMIRX_PLUGGED));
}
//Function to determine if the HDMI IN is connected
public static boolean isHdmiConnected(Context ctx) {
Intent batteryStatus = ctx.registerReceiver(null, new IntentFilter(HDMIRxStatus.ACTION_HDMIRX_PLUGGED));
if(null != batteryStatus) {
return batteryStatus.getBooleanExtra(HDMIRxStatus.EXTRA_HDMIRX_PLUGGED_STATE, false);
} else {
return false;
}
}
//The surfaceholder.callback implementation, this will try to launch/stop the play by appropriately setting up few variables
private final class SurfaceCallback implements SurfaceHolder.Callback {
@Override
public void surfaceChanged(SurfaceHolder surfaceHolder, int i, int i1, int i2) {
Log.i("RealtekSurface", "changed");
}
@Override
public void surfaceCreated(SurfaceHolder surfaceHolder) {
isPreviewAvailable = true;
play();
}
@Override
public void surfaceDestroyed(SurfaceHolder surfaceHolder) {
isPreviewAvailable = false;
stop();
}
}
public boolean play() {
this.setVisibility(View.VISIBLE);
if (!isDisplayOn && isPreviewAvailable) {
mRtkHdmiManager = new RtkHDMIRxManager();
if (null != mRtkHdmiManager) {
HDMIRxStatus mHdmiRxStatus = mRtkHdmiManager.getHDMIRxStatus();
if (mHdmiRxStatus != null && mHdmiRxStatus.status == HDMIRxStatus.STATUS_READY) {
if (mRtkHdmiManager.open() != 0) {
//TODO write code for retrying the same after "t" time using the handler
height = 0;
width = 0;
mRtkHdmiManager = null;
mHandler.sendEmptyMessageDelayed(DISPLAY, DISPLAYTIME);
return false;
}
HDMIRxParameters mHdmiRxParams = mRtkHdmiManager.getParameters();
getSupportedPreviewSizes(mHdmiRxParams, mHdmiRxStatus.width, mHdmiRxStatus.height);
fps = getSupportedFps(mHdmiRxParams);
} else {
if(null!=mHandler)
mHandler.sendEmptyMessageDelayed(DISPLAY, DISPLAYTIME);
return false;
}
//Following is the code to play
try {
mRtkHdmiManager.setPreviewDisplay(mSurfaceHolder);
HDMIRxParameters mParams = new HDMIRxParameters();
mParams.setPreviewSize(width, height);
mParams.setPreviewFrameRate(fps);
mRtkHdmiManager.setParameters(mParams);
mRtkHdmiManager.play();
isDisplayOn = true;
} catch (Exception e) {
stop();
e.printStackTrace();
}
}
} else if (!isPreviewAvailable) {
//TODO write code for retrying the same after "t" time using the handler
if(null!=mHandler)
mHandler.sendEmptyMessageDelayed(DISPLAY, DISPLAYTIME);
return false;
} else {
return false;
}
return true;
}
private void stop() {
//Reset the visibility of the surface view to invisible, else the HDMI IN will not be able to retrieve this view
this.setVisibility(View.INVISIBLE);
//Destroy the instance of the running RealTek Manager after stopping that
if (mRtkHdmiManager != null) {
mRtkHdmiManager.stop();
mRtkHdmiManager.release();
mRtkHdmiManager = null;
}
//Reset the booleans to their origin values
isDisplayOn = false;
width = 0;
height = 0;
fps = 0;
}
private int getSupportedFps(HDMIRxParameters mHdmiRxParameters) {
List<Integer> previewFrameRates = mHdmiRxParameters.getSupportedPreviewFrameRates();
int fps = 0;
if (previewFrameRates != null && previewFrameRates.size() > 0) {
fps = previewFrameRates.get(previewFrameRates.size() - 1);
} else {
fps = 30;
}
return fps;
}
private void getSupportedPreviewSizes(HDMIRxParameters mHdmiRxParams, int rxWidth, int rxHeight) {
List<RtkHDMIRxManager.Size> mPreviewSizes = mHdmiRxParams.getSupportedPreviewSizes();
int retWidth = 0, retHeight = 0;
if (mPreviewSizes == null || mPreviewSizes.size() <= 0) {
return;
}
for (int i = 0; i < mPreviewSizes.size(); i++) {
if (mPreviewSizes.get(i) != null && rxWidth == mPreviewSizes.get(i).width) {
retWidth = mPreviewSizes.get(i).width;
retHeight = mPreviewSizes.get(i).height;
if (rxHeight == mPreviewSizes.get(i).height) {
break;
}
}
}
if (retWidth == 0 && retHeight == 0) {
if (mPreviewSizes.get(mPreviewSizes.size() - 1) != null) {
width = mPreviewSizes.get(mPreviewSizes.size() - 1).width;
height = mPreviewSizes.get(mPreviewSizes.size() - 1).height;
}
}
width = retWidth;
height = retHeight;
}
}
当我断开和连接 HDMI 时,它应该会刷新屏幕。代码中存在一些问题,无法在 运行.
时创建广播断开连接和连接状态
您的代码中存在一个问题:
public RealtekSurfaceView(Context context,String filePath,String videoType,int x,int y,int width,int height,boolean HDMI_AV){
super(context);
this.mContext=context;
this.videoType=videoType;
this.width=width;
this.height=height;
this.HDMI_AV=HDMI_AV;
this.videoPath=filePath;
this.mSurfaceHolder = getHolder();
this.mSurfaceHolder.addCallback(new SurfaceCallback());
this.mSurfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
setBackgroundColor(Color.TRANSPARENT);
init(); <-- you have to add this, as you are forgetting to initialize the broadcast receiver
}
我正在使用用于 HDMI 的 ziddo 数字盒播放视频。我连接和断开 HDMI 时出现问题。它正在冻结屏幕。 我正在使用此代码:
public class RealtekSurfaceView extends SurfaceView {
public static final String TAG = "RealtekSurfaceView";
//A reference to the context
private Context mContext = null;
//Reference to ViewGroup
private ViewGroup mViewGroup = null;
//Integers to keep the width, height and FPS
private int width = 0;
private int height = 0;
private int fps = 0;
//Reference to the Surface holder
private SurfaceHolder mSurfaceHolder = null;
private SurfaceHolder.Callback mSurfaceHolderCallback = null;
//Reference to the Broadcast receiver
private BroadcastReceiver mHdmiRxReceiver = null;
//Boolean to indicate if the HDMI IN is connected
private boolean isConnected = false;
//A few constants to pass the data along
public static final int DISPLAY = 0;
public static final int DISPLAYTIME = 200;
//A reference to a handler
Handler mHandler = null;
//Reference to realtek hdmi manager
private RtkHDMIRxManager mRtkHdmiManager = null;
//Boolean to identify if the display is ON or OFF
public static boolean isPreviewAvailable = false;
//A boolean to denote if we are displaying already
private boolean isDisplayOn = false;
String videoPath;
String videoType;
boolean HDMI_AV=false;
//Constructor to the RealtekSurfaceView class, this will take care of populating the context, view group, surface holder.
//It will also take care of setting up the surfaceholder callback
public RealtekSurfaceView(Context ctx, ViewGroup viewGroup) {
super(ctx);
this.mContext = ctx;
this.mViewGroup = viewGroup;
this.mSurfaceHolder = getHolder();
//Add the callback
mSurfaceHolderCallback = new SurfaceCallback();
mSurfaceHolder.addCallback(mSurfaceHolderCallback);
init();
}
public RealtekSurfaceView(Context context,String filePath,String videoType,int x,int y,int width,int height,boolean HDMI_AV){
super(context);
// TODO Auto-generated constructor stub
this.mContext=context;
this.videoType=videoType;
this.width=width;
this.height=height;
this.HDMI_AV=HDMI_AV;
this.videoPath=filePath;
this.mSurfaceHolder = getHolder();
this.mSurfaceHolder.addCallback(new SurfaceCallback());
this.mSurfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
setBackgroundColor(Color.TRANSPARENT);
}
public void init() {
//Make the handler instance ready to be used by remaining components
mHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case DISPLAY:
if (isConnected) {
play();
}
break;
default:
break;
}
}
};
initHdmiConnect();
}
//Start listening to and processing the incoming HDMI IN connection from the Realtek internal classes
private void initHdmiConnect() {
mHdmiRxReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
isConnected = intent.getBooleanExtra(HDMIRxStatus.EXTRA_HDMIRX_PLUGGED_STATE, false);
if (isConnected) {
play();
} else {
stop();
}
}
};
isConnected = isHdmiConnected(mContext);
mContext.registerReceiver(mHdmiRxReceiver, new IntentFilter(HDMIRxStatus.ACTION_HDMIRX_PLUGGED));
}
//Function to determine if the HDMI IN is connected
public static boolean isHdmiConnected(Context ctx) {
Intent batteryStatus = ctx.registerReceiver(null, new IntentFilter(HDMIRxStatus.ACTION_HDMIRX_PLUGGED));
if(null != batteryStatus) {
return batteryStatus.getBooleanExtra(HDMIRxStatus.EXTRA_HDMIRX_PLUGGED_STATE, false);
} else {
return false;
}
}
//The surfaceholder.callback implementation, this will try to launch/stop the play by appropriately setting up few variables
private final class SurfaceCallback implements SurfaceHolder.Callback {
@Override
public void surfaceChanged(SurfaceHolder surfaceHolder, int i, int i1, int i2) {
Log.i("RealtekSurface", "changed");
}
@Override
public void surfaceCreated(SurfaceHolder surfaceHolder) {
isPreviewAvailable = true;
play();
}
@Override
public void surfaceDestroyed(SurfaceHolder surfaceHolder) {
isPreviewAvailable = false;
stop();
}
}
public boolean play() {
this.setVisibility(View.VISIBLE);
if (!isDisplayOn && isPreviewAvailable) {
mRtkHdmiManager = new RtkHDMIRxManager();
if (null != mRtkHdmiManager) {
HDMIRxStatus mHdmiRxStatus = mRtkHdmiManager.getHDMIRxStatus();
if (mHdmiRxStatus != null && mHdmiRxStatus.status == HDMIRxStatus.STATUS_READY) {
if (mRtkHdmiManager.open() != 0) {
//TODO write code for retrying the same after "t" time using the handler
height = 0;
width = 0;
mRtkHdmiManager = null;
mHandler.sendEmptyMessageDelayed(DISPLAY, DISPLAYTIME);
return false;
}
HDMIRxParameters mHdmiRxParams = mRtkHdmiManager.getParameters();
getSupportedPreviewSizes(mHdmiRxParams, mHdmiRxStatus.width, mHdmiRxStatus.height);
fps = getSupportedFps(mHdmiRxParams);
} else {
if(null!=mHandler)
mHandler.sendEmptyMessageDelayed(DISPLAY, DISPLAYTIME);
return false;
}
//Following is the code to play
try {
mRtkHdmiManager.setPreviewDisplay(mSurfaceHolder);
HDMIRxParameters mParams = new HDMIRxParameters();
mParams.setPreviewSize(width, height);
mParams.setPreviewFrameRate(fps);
mRtkHdmiManager.setParameters(mParams);
mRtkHdmiManager.play();
isDisplayOn = true;
} catch (Exception e) {
stop();
e.printStackTrace();
}
}
} else if (!isPreviewAvailable) {
//TODO write code for retrying the same after "t" time using the handler
if(null!=mHandler)
mHandler.sendEmptyMessageDelayed(DISPLAY, DISPLAYTIME);
return false;
} else {
return false;
}
return true;
}
private void stop() {
//Reset the visibility of the surface view to invisible, else the HDMI IN will not be able to retrieve this view
this.setVisibility(View.INVISIBLE);
//Destroy the instance of the running RealTek Manager after stopping that
if (mRtkHdmiManager != null) {
mRtkHdmiManager.stop();
mRtkHdmiManager.release();
mRtkHdmiManager = null;
}
//Reset the booleans to their origin values
isDisplayOn = false;
width = 0;
height = 0;
fps = 0;
}
private int getSupportedFps(HDMIRxParameters mHdmiRxParameters) {
List<Integer> previewFrameRates = mHdmiRxParameters.getSupportedPreviewFrameRates();
int fps = 0;
if (previewFrameRates != null && previewFrameRates.size() > 0) {
fps = previewFrameRates.get(previewFrameRates.size() - 1);
} else {
fps = 30;
}
return fps;
}
private void getSupportedPreviewSizes(HDMIRxParameters mHdmiRxParams, int rxWidth, int rxHeight) {
List<RtkHDMIRxManager.Size> mPreviewSizes = mHdmiRxParams.getSupportedPreviewSizes();
int retWidth = 0, retHeight = 0;
if (mPreviewSizes == null || mPreviewSizes.size() <= 0) {
return;
}
for (int i = 0; i < mPreviewSizes.size(); i++) {
if (mPreviewSizes.get(i) != null && rxWidth == mPreviewSizes.get(i).width) {
retWidth = mPreviewSizes.get(i).width;
retHeight = mPreviewSizes.get(i).height;
if (rxHeight == mPreviewSizes.get(i).height) {
break;
}
}
}
if (retWidth == 0 && retHeight == 0) {
if (mPreviewSizes.get(mPreviewSizes.size() - 1) != null) {
width = mPreviewSizes.get(mPreviewSizes.size() - 1).width;
height = mPreviewSizes.get(mPreviewSizes.size() - 1).height;
}
}
width = retWidth;
height = retHeight;
}
}
当我断开和连接 HDMI 时,它应该会刷新屏幕。代码中存在一些问题,无法在 运行.
时创建广播断开连接和连接状态您的代码中存在一个问题:
public RealtekSurfaceView(Context context,String filePath,String videoType,int x,int y,int width,int height,boolean HDMI_AV){
super(context);
this.mContext=context;
this.videoType=videoType;
this.width=width;
this.height=height;
this.HDMI_AV=HDMI_AV;
this.videoPath=filePath;
this.mSurfaceHolder = getHolder();
this.mSurfaceHolder.addCallback(new SurfaceCallback());
this.mSurfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
setBackgroundColor(Color.TRANSPARENT);
init(); <-- you have to add this, as you are forgetting to initialize the broadcast receiver
}