基於Platinum庫的DMS實現(android)

接上篇博文:基於Platinum庫的DMR實現(android)java

文章講述瞭如何使用Platinum庫實現DMRandroid

今天一樣使用該庫,來說解一下DMS的實現git

 

 

關於該庫如何編譯,請參考這篇博文: NDK下 將Platinum SDK 編譯成so庫 (android - upnp)github

 

 

 

下面給出運行效果圖:web

界面很簡單,就是一些開關和設備名以及設備運行狀態的展示ide

 

下面看看代碼片斷:ui

JNI接口文件:this

 

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;
    }
    
}



 

後臺服務:google

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;
		}
	}


}


工做線程:.net

 

 

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);
	}
}

 

 

這樣控制點訪問的時候就能夠瀏覽到多媒體文件了

關鍵代碼大都已經貼出來了,詳情你們down code去了解吧 

 

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

 

more brilliant,Please pay attention to my CSDN blog -->http://blog.csdn.net/geniuseoe2012  

相關文章
相關標籤/搜索