基于Platinum库的DMS实现(android)

摘要:
=null){StringactionString=intent.getAction();如果(actionStriing!

接上篇博文:基于Platinum库的DMR实现(android)

文章讲述了如何使用Platinum库实现DMR

今天同样使用该库,来讲解一下DMS的实现

关于该库如何编译,请参考这篇博文:NDK下 将Platinum SDK 编译成so库 (android - upnp)

下面给出运行效果图:

基于Platinum库的DMS实现(android)第1张

界面很简单,就是一些开关和设备名以及设备运行状态的展现

下面看看代码片段:

JNI接口文件:

public class DMSJniInterface {
    static {
        System.loadLibrary("git-platinum");
    }
    public static native int startServer(byte[] rootDir,byte[] name ,byte[] uid);
    public static native int stopServer();  
    public static native boolean enableLogPrint(boolean flag);
    //////////////////////////////////////////////////////////////////////////////////////////           
    public static  int startServer(String rootDir, String name ,String uid){
    	if (rootDir == null){
    		rootDir = "";
    	}
    	if (name == null){
    		name = "";
    	}
    	if (uid == null){
    		uid = "";
    	}
    	int ret = -1;
    	try {
    		ret = startServer(rootDir.getBytes("utf-8"), name.getBytes("utf-8"), uid.getBytes("utf-8"));
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		}
    	return ret;
    }
}

后台服务:

public class DMSService extends Service implements IBaseEngine{
	private static final CommonLog log = LogFactory.createLog();
	public static final String START_SERVER_ENGINE = "com.geniusgithub.start.dmsengine";
	public static final String RESTART_SERVER_ENGINE = "com.geniusgithub.restart.dmsengine";
	private DMSWorkThread mWorkThread;
	private Handler mHandler;
	private static final int START_ENGINE_MSG_ID = 0x0001;
	private static final int RESTART_ENGINE_MSG_ID = 0x0002;
	private static final int DELAY_TIME = 1000;
	private MediaStoreCenter mMediaStoreCenter;
	@Override
	public IBinder onBind(Intent intent) {
		return null;
	}
	@Override
	public void onCreate() {
		super.onCreate();		
		initService();	
		log.e("MediaServerService onCreate");
	}
	@Override
	public void onDestroy() {
		unInitService();	
		log.e("MediaServerService onDestroy");
		super.onDestroy();
	}
	@Override
	public int onStartCommand(Intent intent, int flags, int startId) {
		if (intent != null){
			String actionString = intent.getAction();
			if (actionString != null){		
				if (actionString.equalsIgnoreCase(START_SERVER_ENGINE)){
					delayToSendStartMsg();
				}else if (actionString.equalsIgnoreCase(RESTART_SERVER_ENGINE)){
					delayToSendRestartMsg();
				}
			}
		}	
		return super.onStartCommand(intent, flags, startId);
	}
	private void initService(){
		mWorkThread = new DMSWorkThread(this);
		mHandler = new Handler(){
			@Override
			public void handleMessage(Message msg) {
				switch(msg.what){
				case START_ENGINE_MSG_ID:
					startEngine();
					break;
				case RESTART_ENGINE_MSG_ID:
					restartEngine();
					break;
				}
			}
		};
		mMediaStoreCenter = MediaStoreCenter.getInstance();
		mMediaStoreCenter.clearWebFolder();
		mMediaStoreCenter.createWebFolder();
		mMediaStoreCenter.doScanMedia();
	}
	private void unInitService(){
		stopEngine();
		removeStartMsg();
		removeRestartMsg();
		mMediaStoreCenter.clearAllData();
	}
	private void delayToSendStartMsg(){
		removeStartMsg();
		mHandler.sendEmptyMessageDelayed(START_ENGINE_MSG_ID, DELAY_TIME);
	}
	private void delayToSendRestartMsg(){
		removeStartMsg();
		removeRestartMsg();
		mHandler.sendEmptyMessageDelayed(RESTART_ENGINE_MSG_ID, DELAY_TIME);
	}
	private void removeStartMsg(){
		mHandler.removeMessages(START_ENGINE_MSG_ID);
	}
	private void removeRestartMsg(){
		mHandler.removeMessages(RESTART_ENGINE_MSG_ID);	
	}
	@Override
	public boolean startEngine() {
		awakeWorkThread();
		return true;
	}
	@Override
	public boolean stopEngine() {
		mWorkThread.setParam("", "", "");
		exitWorkThread();
		return true;
	}
	@Override
	public boolean restartEngine() {
		String friendName = DlnaUtils.getDevName(this);
		String uuid = DlnaUtils.creat12BitUUID(this);
		mWorkThread.setParam(mMediaStoreCenter.getRootDir(), friendName, uuid);
		if (mWorkThread.isAlive()){
			mWorkThread.restartEngine();
		}else{
			mWorkThread.start();
		}
		return true;
	}
	private void awakeWorkThread(){
		String friendName = DlnaUtils.getDevName(this);
		String uuid = DlnaUtils.creat12BitUUID(this);
		mWorkThread.setParam(mMediaStoreCenter.getRootDir(), friendName, uuid);
		if (mWorkThread.isAlive()){
			mWorkThread.awakeThread();
		}else{
			mWorkThread.start();
		}
	}
	private void exitWorkThread(){
		if (mWorkThread != null && mWorkThread.isAlive()){
			mWorkThread.exit();
			long time1 = System.currentTimeMillis();
			while(mWorkThread.isAlive()){
				try {
					Thread.sleep(100);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
			long time2 = System.currentTimeMillis();
			log.e("exitWorkThread cost time:" + (time2 - time1));
			mWorkThread = null;
		}
	}
}

工作线程:

public class DMSWorkThread extends Thread implements IBaseEngine{
	private static final CommonLog log = LogFactory.createLog();
	private static final int CHECK_INTERVAL = 30 * 1000; 
	private Context mContext = null;
	private boolean mStartSuccess = false;
	private boolean mExitFlag = false;
	private String mRootdir = "";
	private String mFriendName = "";
	private String mUUID = "";	
	private ServerApplication mApplication;
	public DMSWorkThread(Context context){
		mContext = context;
		mApplication = ServerApplication.getInstance();
	}
	public void  setFlag(boolean flag){
		mStartSuccess = flag;
	}
	public void setParam(String rootDir, String friendName, String uuid){
		mRootdir = rootDir;
		mFriendName = friendName;
		mUUID = uuid;
		mApplication.updateDevInfo(mRootdir, mFriendName, mUUID);
	}
	public void awakeThread(){
		synchronized (this) {
			notifyAll();
		}
	}
	public void exit(){
		mExitFlag = true;
		awakeThread();
	}
	@Override
	public void run() {
		log.e("DMSWorkThread run...");
		while(true)
		{
			if (mExitFlag){
				stopEngine();
				break;
			}
			refreshNotify();
			synchronized(this)
			{				
				try
				{
					wait(CHECK_INTERVAL);
				}
				catch(Exception e)
				{
					e.printStackTrace();
				}								
			}
			if (mExitFlag){
				stopEngine();
				break;
			}
		}
		log.e("DMSWorkThread over...");
	}
	public void refreshNotify(){
		if (!CommonUtil.checkNetworkState(mContext)){
			return ;
		}
		if (!mStartSuccess){
			stopEngine();
			try {
				Thread.sleep(200);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			boolean ret = startEngine();
			if (ret){
				mStartSuccess = true;
			}
		}
	}
	@Override
	public boolean startEngine() {
		if (mFriendName.length() == 0){
			return false;
		}
		int ret = DMSJniInterface.startServer(mRootdir, mFriendName, mUUID);
		boolean result = (ret == 0 ? true : false);
		mApplication.setDevStatus(result);
		return result;
	}
	@Override
	public boolean stopEngine() {
		DMSJniInterface.stopServer();
		mApplication.setDevStatus(false);
		return true;
	}
	@Override
	public boolean restartEngine() {
		setFlag(false);
		awakeThread();
		return true;
	}
}

多媒体遍历:

public class MediaScannerCenter {
	private static final CommonLog log = LogFactory.createLog();
	public static final int AUDIO_TYPE = 0;
	public static final int VIDEO_TYPE = 1;
	public static final int IMAGE_TYPE = 2;
	String AUDIO_PATH = MediaStore.Audio.AudioColumns.DATA;
	String AUDIO_DISPLAYHNAME = MediaStore.Audio.AudioColumns.DISPLAY_NAME;
	String AUDIO_COLUMN_STRS[] = {AUDIO_PATH, AUDIO_DISPLAYHNAME};
	String VIDEO_PATH = MediaStore.Video.VideoColumns.DATA;
	String VIDEO_DISPLAYHNAME  = MediaStore.Video.VideoColumns.DISPLAY_NAME;
	String VIDEO_COLUMN_STRS[] = {VIDEO_PATH, VIDEO_DISPLAYHNAME};
	String IMAGE_PATH = MediaStore.Images.ImageColumns.DATA;
	String IMAGE_DISPLAYHNAME  = MediaStore.Images.ImageColumns.DISPLAY_NAME;
	String IMAGE_COLUMN_STRS[] = {IMAGE_PATH, IMAGE_DISPLAYHNAME};
	private static  MediaScannerCenter mInstance;
	private Context mContext;
	private ScanMediaThread mediaThread;
	private MediaScannerCenter(Context context) {
		mContext = context;
		initData();
	}
	public static synchronized MediaScannerCenter getInstance() {
		if (mInstance == null){
			mInstance  = new MediaScannerCenter(ServerApplication.getInstance());
		}
		return mInstance;
	}
	private void initData(){
	}
	public synchronized boolean startScanThread(IMediaScanListener listener){
		if (mediaThread == null || !mediaThread.isAlive()){
			mediaThread = new ScanMediaThread(listener);
			mediaThread.start();
		}
		return true;
	}
	public synchronized void stopScanThread(){
		if (mediaThread != null){
			if (mediaThread.isAlive()){
				mediaThread.exit();
			}
			mediaThread = null;
		}
	}
	public synchronized boolean isThreadOver(){
		if (mediaThread != null && mediaThread.isAlive()){
			return false;
		}
		return true;
	}
	private  boolean scanMusic(IMediaScanListener listener, ICancelScanMedia cancelObser) throws Exception {
		Cursor cursor = mContext.getContentResolver().query(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, 
				AUDIO_COLUMN_STRS, 
				null, 
				null,
				AUDIO_DISPLAYHNAME);				
		if (cursor != null)
		{
			int count = cursor.getCount();
			if (count != 0)
			{
				int _name_index = cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.DISPLAY_NAME);
	     		int _dir_index = cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.DATA);
	    		if (cursor.moveToFirst()) {  
	         		do { 
	         			if (cancelObser.ifCancel()){
	         				return false;
	         			}
	         			String srcpath = cursor.getString(_dir_index);
	         			String name = cursor.getString(_name_index);
	         			listener.mediaScan(AUDIO_TYPE, srcpath, name);
	         		} while (cursor.moveToNext());  
	         	}  			
			}		
			cursor.close();
			return true;
		}
		return false;
	}
	private  boolean scanVideo(IMediaScanListener listener, ICancelScanMedia cancelObser) throws Exception {
		Cursor cursor = mContext.getContentResolver().query(MediaStore.Video.Media.EXTERNAL_CONTENT_URI, 
				VIDEO_COLUMN_STRS, 
				null, 
				null,
				VIDEO_DISPLAYHNAME);				
		if (cursor != null)
		{
			int count = cursor.getCount();
			if (count != 0)
			{
				int _name_index = cursor.getColumnIndexOrThrow(MediaStore.Video.Media.DISPLAY_NAME);
	     		int _dir_index = cursor.getColumnIndexOrThrow(MediaStore.Video.Media.DATA);
	    		if (cursor.moveToFirst()) {  
	         		do { 
	         			if (cancelObser.ifCancel()){
	         				return false;
	         			}
	         			String srcpath = cursor.getString(_dir_index);
	         			String name = cursor.getString(_name_index);
	         			listener.mediaScan(VIDEO_TYPE, srcpath, name);
	         		} while (cursor.moveToNext());  
	         	}  			
			}		
			cursor.close();
			return true;
		}
		return false;
	}
	private  boolean scanImage(IMediaScanListener listener, ICancelScanMedia cancelObser) throws Exception {
		Cursor cursor = mContext.getContentResolver().query(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, 
				IMAGE_COLUMN_STRS, 
				null, 
				null,
				IMAGE_DISPLAYHNAME);				
		if (cursor != null)
		{
			int count = cursor.getCount();
			if (count != 0)
			{
				int _name_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DISPLAY_NAME);
	     		int _dir_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
	    		if (cursor.moveToFirst()) {  
	         		do { 
	         			if (cancelObser.ifCancel()){
	         				return false;
	         			}
	         			String srcpath = cursor.getString(_dir_index);
	         			String name = cursor.getString(_name_index);
	         			listener.mediaScan(IMAGE_TYPE, srcpath, name);
	         		} while (cursor.moveToNext());  
	         	}  			
			}		
			cursor.close();
			return true;
		}
		return false;
	}
	public class ScanMediaThread extends Thread implements ICancelScanMedia{
		IMediaScanListener mListener;
		boolean exitFlag = false;
		public ScanMediaThread(IMediaScanListener listener){
			mListener = listener;
		}
		public void exit(){
			exitFlag = true;
		}
		@Override
		public void run() {
			try {
				scanMusic(mListener, this);
				scanVideo(mListener, this);
				scanImage(mListener, this);
			} catch (Exception e) {
				e.printStackTrace();
			}
			super.run();
		}
		@Override
		public boolean ifCancel() {
			return exitFlag;
		}	
	}
	public  interface ICancelScanMedia{
		public boolean ifCancel();
	}
}

startServer和stopServer分别对应设备的开启关闭

在startServer需要传入的三个参数分别是根目录,设备名和设备ID

在本地构建好web目录后将根目录路径设置进去

然后开启一个线程来浏览本地多媒体文件并通过创建软链接来映射本地路径和web路径

详看这个类:

public class MediaStoreCenter implements IMediaScanListener{
	private static final CommonLog log = LogFactory.createLog();
	private static  MediaStoreCenter mInstance;
	private Context mContext;
	private String mShareRootPath = "";
	private String mImageFolderPath = "";
	private String mVideoFolderPath = "";
	private String mAudioFolderPath = "";
	private MediaScannerCenter mMediaScannerCenter;
	private Map<String, String> mMediaStoreMap = new HashMap<String, String>();
	private MediaStoreCenter(Context context) {
		mContext = context;
		initData();
	}
	public static synchronized MediaStoreCenter getInstance() {
		if (mInstance == null){
			mInstance  = new MediaStoreCenter(ServerApplication.getInstance());
		}
		return mInstance;
	}
	private void initData(){
		mShareRootPath = mContext.getFilesDir().getAbsolutePath()+"/" + "rootFolder";
		mImageFolderPath = mShareRootPath + "/" + "Image";
		mVideoFolderPath = mShareRootPath + "/" + "Video";
		mAudioFolderPath = mShareRootPath + "/" + "Audio";
		mMediaScannerCenter = MediaScannerCenter.getInstance();
	}
	public String getRootDir(){
		return mShareRootPath;
	}
	public void clearAllData(){
		stopScanMedia();
		clearMediaCache();
		clearWebFolder();
	}
	public boolean createWebFolder(){
		boolean ret = FileHelper.createDirectory(mShareRootPath);
		if (!ret){
			return false;
		}
		FileHelper.createDirectory(mImageFolderPath);
		FileHelper.createDirectory(mVideoFolderPath);
		FileHelper.createDirectory(mAudioFolderPath);
		return true;
	}
	public boolean clearWebFolder(){
		long time = System.currentTimeMillis();
		boolean ret = FileHelper.deleteDirectory(mShareRootPath);
		long time1 = System.currentTimeMillis();
		log.e("clearWebFolder cost : " + (time1 - time));
		return ret;
	}
	public void clearMediaCache(){
		mMediaStoreMap.clear();
	}
	public void doScanMedia(){
		mMediaScannerCenter.startScanThread(this);
	}
	public void stopScanMedia(){
		mMediaScannerCenter.stopScanThread();
		while(!mMediaScannerCenter.isThreadOver()){
			try {
				Thread.sleep(100);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
	}
	@Override
	public void mediaScan(int mediaType, String mediaPath, String mediaName) {
		switch (mediaType) {
		case MediaScannerCenter.AUDIO_TYPE:
			mapAudio(mediaPath, mediaName);
			break;
		case MediaScannerCenter.VIDEO_TYPE:
			mapVideo(mediaPath, mediaName);
			break;
		case MediaScannerCenter.IMAGE_TYPE:
		    mapImage(mediaPath, mediaName);
			break;
		default:
			break;
		}
	}
	private void mapAudio( String mediaPath, String mediaName){
		String webPath = mAudioFolderPath + "/" + mediaName;
		mMediaStoreMap.put(mediaPath, webPath);
		softLinkMode(mediaPath, webPath);
	}
	private void mapVideo( String mediaPath, String mediaName){
		String webPath = mVideoFolderPath + "/" + mediaName;
		mMediaStoreMap.put(mediaPath, webPath);
		softLinkMode(mediaPath, webPath);
	}
	private void mapImage( String mediaPath, String mediaName){
		String webPath = mImageFolderPath + "/" + mediaName;
		mMediaStoreMap.put(mediaPath, webPath);
		softLinkMode(mediaPath, webPath);
	}
	private boolean softLinkMode(String localPath, String webPath){
		Process p;
		int status;
		try {
			long time = System.currentTimeMillis();
			String cmd = "ln -s " + localPath + " "+ webPath;
			p = Runtime.getRuntime().exec(cmd);
			releaseProcessStream(p);
			status = p.waitFor();		
			if (status == 0) {
				return true;//success
			} else {
				log.e("status = " + status + ", run ln -s failed !localPath = " + localPath);
				return false;
			}
		}catch (Exception e) {
			log.e("Catch Exceptino run ln -s failed !localPath = " + localPath);
			return false;
		}
	}
	private void releaseProcessStream(Process p) throws IOException{
		InputStream stderr = p.getErrorStream();
		InputStreamReader isr = new InputStreamReader(stderr);
		BufferedReader br = new BufferedReader(isr);
		String line = null;
		while ( (line = br.readLine()) != null)
			System.out.println(line);
	}
}

这样控制点访问的时候就可以浏览到多媒体文件了

关键代码大都已经贴出来了,详情大家downcode去了解吧

Github下载页:https://github.com/geniusgithub/MediaServer

当然关于android上的DMS实现网上已有一个不错的开源项目wireme

下载地址http://code.google.com/p/wireme/

用的是cling库,下载链接https://github.com/4thline/cling

不过Platinum库在稳定性方面还是要胜过其它java库的,而且效率也高,所以推荐大家使用

DLNA开发文档链接:http://download.csdn.net/detail/geniuseoe2012/4969961

morebrilliant,PleasepayattentiontomyCSDNblog-->http://blog.csdn.net/geniuseoe2012

免责声明:文章转载自《基于Platinum库的DMS实现(android)》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇推荐一个好的分区软件win7调整磁盘的大小WPF自定义窗口(Windows Server 2012 Style)下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

http协议的POST传数据

PostRequest使用StreamWriter对象写入请求流,不需要使用HttpUtility.UrlEncode显示转码,而下面的需要显示转码,还需要将参数转为字节码 蛋疼…………。 public static string PostRequest(string url, string postData) { HttpWebRequest httpW...

Go源代码安全审计工具之gosec

gosec分析Go源代码以查找可能导致安全问题的常见编程错误。 它通过扫描Go AST检查源代码是否存在安全问题。 https://github.com/securego/gosec gosec v2.4.0 gosec - Golang security checker gosec analyzes Go source code to look for...

Java数组,去掉重复值、增加、删除数组元素

import java.util.List; import java.util.ArrayList; import java.util.Set; import java.util.HashSet; public class lzwCode { public static void main(String [] args) {...

使用 C++ 处理 JSON 数据交换格式 .

使用C++ 处理JSON 数据交换格式 一、摘要 JSON 的全称为:JavaScript Object Notation,顾名思义,JSON 是用于标记Javascript 对象的,JSON 官方的解释为:JSON 是一种轻量级的数据传输格式。 本文并不详细介绍JSON 本身的细节,旨在讨论如何使用C++ 语言来处理JSON。关于JSON 更具体的信息,...

DevExpress WinForm MVVM数据和属性绑定指南(Part 1)

根据您绑定的属性,存在以下三种可能的情况: 常规绑定- ViewModel属性绑定到任何不可编辑的View元素属性。由于该元素不可编辑,因此您无需将更新通知发送回绑定属性(单向绑定)。 数据绑定- Model属性(数据字段)绑定到编辑器属性。如果用户可以更改编辑器值,则需要更新绑定属性(双向绑定)。 属性依赖- 来自同一个ViewModel的两个属性被绑...

带中文的字符串截取

最近在页面展示的时候遇到这样的场景,文字有可能超长,却又不允许换行。 当然,可以用高超的css来搞定。但如果你想要让多余的文字用“...”来代替,并且要兼容很多浏览器,这种时候用css也会很头疼吧。 1.C#对中文字符串的截取 与英文字符相比,我们把中文字符按两个占位来计算,对于带中文的字符串截取,要面临两个问题: 1.无法截取半个中文字符; 2.对于除...