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

  

 

posted @ 2020-07-22 10:52  CrushGirl  阅读(1265)  评论(0编辑  收藏  举报