HDMI(二):LVDS、HDMI双屏异显
一、隐藏上方TitleBar
在AndroidManifest.xml的配置文件里面的<activity>标签添加属性:
android:theme="@android:style/Theme.NoTitleBar.Fullscreen"
示例:
<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@android:style/Theme.NoTitleBar.Fullscreen" >
<activity
android:name=".MainActivity"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
二、daemon,副屏显示图片
2.1、权限
<!-- 读写存储卡权限的问题 -->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" />
<!-- 显示系统窗口权限 -->
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
<!-- 在 屏幕最顶部显示addview -->
<uses-permission android:name="android.permission.SYSTEM_OVERLAY_WINDOW" />
2.2、显示类,显示副屏
@SuppressLint("NewApi")
public class XHPresentation extends Presentation
{
public XHPresentation(Context outerContext, Display display) {
super(outerContext, display);
// TODO Auto-generated constructor stub
}
@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.second_screen);
}
}
2.3、在主程序中显示副显示器
// 双屏显示 DisplayManager mDisplayManager;// 屏幕管理类 Display[] displays;// 屏幕数组 mDisplayManager = (DisplayManager) MainActivity.this.getSystemService(Context.DISPLAY_SERVICE); displays = mDisplayManager.getDisplays(); // 得到显示器数组 XHPresentation mPresentation = new XHPresentation(getApplicationContext(), displays[1]);// displays[1]是副屏 mPresentation.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT); mPresentation.show();
三、daemon,副屏播放视频
3.1、MainActivity.java
package com.gatsby.dualscreen;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.hardware.display.DisplayManager;
import android.os.Bundle;
import android.util.Log;
import android.view.Display;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.WindowManager;
import android.widget.Button;
public class MainActivity extends Activity implements OnClickListener {
Button btn1, btn2;
Intent intentService;
private final static String SERVICE_ACTION = "com.xh.dualscreen.actions";
private boolean isShowSecondScreen = false;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main_screen);
btn1 = (Button) findViewById(R.id.btn1);
btn2 = (Button) findViewById(R.id.btn2);
btn1.setOnClickListener(this);
btn2.setOnClickListener(this);
intentService = new Intent(MainActivity.this, XHShowService.class);
startService(intentService);
isShowSecondScreen = true;
}
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
switch (v.getId()) {
case R.id.btn1:
// 双屏显示
break;
case R.id.btn2:
if (!isShowSecondScreen) {
Log.d("gatsby", "gatsby XHShowService!");
Intent i = new Intent(MainActivity.this, XHShowService.class);
startService(i);
isShowSecondScreen = true;
} else {
Log.d("gatsby", "gatsby XHShowService is started!");
Intent i = new Intent(SERVICE_ACTION);
i.putExtra("receiver_key", 0);
sendBroadcast(i);
isShowSecondScreen = false;
}
break;
}
}
@Override
protected void onDestroy() {
super.onDestroy();
Intent i = new Intent(SERVICE_ACTION);
i.putExtra("receiver_key", 0);
sendBroadcast(i);
isShowSecondScreen = false;
}
}
3.2、XHShowService.java
package com.gatsby.dualscreen;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import android.annotation.SuppressLint;
import android.app.Service;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.IntentFilter;
import android.graphics.PixelFormat;
import android.hardware.display.DisplayManager;
import android.media.AudioManager;
import android.media.MediaPlayer;
import android.os.IBinder;
import android.util.Log;
import android.view.Display;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.WindowManager;
import android.widget.LinearLayout;
public class XHShowService extends Service {
private static final String TAG = "gatsby";
// public final static String HDMI_PATH = "/mnt/sdcard/hdmi.mp4";
public final static String HDMI_PATH = "/mnt/sdcard/hdmi";
private List<String> hdmiVideoPath = new ArrayList<>();
private Display[] displays;
private MediaPlayer mBackgroundPlayer;
private SurfaceView presentSurface;
private XHPresentation myPresentation;
private DisplayManager mDisplayManager;
private int nowHdmiPosition = 0;
MsgReceiver receiver;
private final static String SERVICE_ACTION = "com.xh.dualscreen.actions";
// 接收activity 发送过来的广播,来作相应的播放处理。目前就做了一个切换功能。可以加上下一曲和暂停等一些功能。
class MsgReceiver extends BroadcastReceiver {
@SuppressLint("NewApi")
@Override
public void onReceive(Context context, Intent intent) {
Log.d(TAG, "XHShowService onReceive-->" + intent.getAction());
if (intent != null) {
if (intent.getIntExtra("receiver_key", -1) == 0) {
Log.d(TAG, "XHShowService onReceive getIntExtra ");
myPresentation.dismiss();
unregisterReceiver(receiver);
stopSelf();
}
}
}
}
@Override
public IBinder onBind(Intent intent) {
return null;
}
@SuppressLint("NewApi")
@Override
public void onCreate() {
super.onCreate();
Log.d(TAG, "XHShowService onCreate!!!");
// 获取显示设备
mDisplayManager = (DisplayManager) getSystemService(Context.DISPLAY_SERVICE);
displays = mDisplayManager.getDisplays();// get the number of displays
Log.d(TAG, "xhDisplays=" + displays.length);
if (displays.length > 1) {
showPresentation(displays[1]);// displays[0]:main_screen displays[1]:second_screen
// 注册广播
receiver = new MsgReceiver();
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(SERVICE_ACTION);
registerReceiver(receiver, intentFilter);
initViewSurface();
}
}
@SuppressLint({ "InflateParams", "NewApi" })
private void initViewSurface() {
mBackgroundPlayer = new MediaPlayer();
// ָ指定流媒体类型
mBackgroundPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
hdmiVideoPath = XHFileUtils.getPaths(HDMI_PATH);
WindowManager mWindowManager = (WindowManager) getSystemService(Context.WINDOW_SERVICE);
// 获取LayoutParams对象
WindowManager.LayoutParams wmParams = new WindowManager.LayoutParams();
wmParams.type = WindowManager.LayoutParams.TYPE_PHONE;
wmParams.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
wmParams.format = PixelFormat.RGBA_8888;
wmParams.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
| WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS;
wmParams.gravity = Gravity.LEFT | Gravity.TOP;
wmParams.x = 0;
wmParams.y = 0;
// 宽度和高度为0, 可以避免主屏退出后出现的主屏触摸和点击问题
wmParams.width = 0;
wmParams.height = 0;
LayoutInflater inflater = LayoutInflater.from(this);
LinearLayout presentationLayout = (LinearLayout) inflater.inflate(R.layout.second_screen, null);
presentationLayout.setFocusable(false);
mWindowManager.addView(presentationLayout, wmParams);
playVideo(mBackgroundPlayer, nowHdmiPosition, true);
}
// 将内容显示到display上面。
@SuppressLint("NewApi")
private void showPresentation(Display display) {
myPresentation = new XHPresentation(this, display, true);
myPresentation.setOnDismissListener(new DialogInterface.OnDismissListener() {
@Override
public void onDismiss(DialogInterface dialog) {
// 监听消失,保存当前播放位置。
}
});
myPresentation.getWindow().setType(WindowManager.LayoutParams.TYPE_PHONE);
myPresentation.show();
presentSurface = myPresentation.getSurface();
presentSurface.getHolder().addCallback(new MySurfaceCallback());
}
// 统一的播放界面
private void playVideo(MediaPlayer mediaPlayer, int pathIndex, boolean isFirstPlay) {
if (isFirstPlay) {
mediaPlayer.setOnCompletionListener(new MyVideoFinishListener());
try {
nowHdmiPosition = 0;
if ((hdmiVideoPath != null) && (hdmiVideoPath.size() > 0)) {
// mediaPlayer.setDataSource(HDMI_PATH);
mediaPlayer.setDataSource(hdmiVideoPath.get(0));
}
} catch (IOException e) {
e.printStackTrace();
}
try {
mediaPlayer.prepare();
} catch (IOException e) {
e.printStackTrace();
} catch (Exception e) {
}
mediaPlayer.start();
} else {
mediaPlayer.reset();
mediaPlayer.setOnCompletionListener(new MyVideoFinishListener());
try {
// mediaPlayer.setDataSource(HDMI_PATH);
mediaPlayer.setDataSource(hdmiVideoPath.get(pathIndex));
} catch (IOException e) {
e.printStackTrace();
}
try {
mediaPlayer.prepare();
} catch (IOException e) {
e.printStackTrace();
} catch (Exception e) {
}
mediaPlayer.start();
}
}
class MyVideoFinishListener implements MediaPlayer.OnCompletionListener {
@Override
public void onCompletion(MediaPlayer mp) {
nowHdmiPosition++;
if (nowHdmiPosition >= hdmiVideoPath.size()) {
nowHdmiPosition = 0;
}
playVideo(mp, nowHdmiPosition, false);
}
}
class MySurfaceCallback implements SurfaceHolder.Callback {
@Override
public void surfaceCreated(SurfaceHolder holder) {
mBackgroundPlayer.setDisplay(presentSurface.getHolder());
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
}
}
@Override
public void onDestroy() {
super.onDestroy();
mBackgroundPlayer.release();
}
}
https://download.csdn.net/download/qq_40949012/12651236


浙公网安备 33010602011771号