1、獲取本地所有視頻
public void getLoadMedia() { Cursor cursor = UILApplication.instance.getApplicationContext().getContentResolver().query(MediaStore.Video.Media.EXTERNAL_CONTENT_URI, null, null, null, MediaStore.Video.Media.DEFAULT_SORT_ORDER); try { for (cursor.moveToFirst(); !cursor.isAfterLast(); cursor.moveToNext()) { int id = cursor.getInt(cursor.getColumnIndexOrThrow(MediaStore.Video.Media._ID)); // id String displayName =cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Video.Media.TITLE)); String album = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Video.Media.ALBUM)); // 專輯 String artist = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Video.Media.ARTIST)); // 藝術家 String title = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Video.Media.DISPLAY_NAME)); // 顯示名稱 String mimeType =cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Video.Media.MIME_TYPE)); String path = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Video.Media.DATA)); // 路徑 long duration = cursor.getInt(cursor.getColumnIndexOrThrow(MediaStore.Video.Media.DURATION)); // 時長 long size = cursor.getLong(cursor.getColumnIndexOrThrow(MediaStore.Video.Media.SIZE)); // 大小 String resolution =cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Video.Media.RESOLUTION)); } } catch (Exception e) { e.printStackTrace(); } finally { cursor.close(); } }
2、獲取拍照視頻
//create new Intent Intent intent = new Intent(MediaStore.ACTION_VIDEO_CAPTURE); try { fileUri = Uri.fromFile(createMediaFile()); // create a file to save the video } catch (IOException e) { e.printStackTrace(); } intent.putExtra(MediaStore.EXTRA_OUTPUT, fileUri); // set the image file name intent.putExtra(MediaStore.EXTRA_VIDEO_QUALITY, 1); // set the video image quality to high // start the Video Capture Intent startActivityForResult(intent, CAPTURE_VIDEO_ACTIVITY_REQUEST_CODE);
public static final String[] videoCursorCols = new String[] { MediaStore.Video.Media._ID, MediaStore.Video.Media.DISPLAY_NAME, MediaStore.Video.Media.TITLE, MediaStore.Video.Media.DURATION, MediaStore.Video.Media.ARTIST, MediaStore.Video.Media.ALBUM, MediaStore.Video.Media.RESOLUTION, MediaStore.Video.Media.MIME_TYPE, MediaStore.Video.Media.SIZE, MediaStore.Video.Media.DATA }; public static Video fileUriForVideo(Activity activity, Uri uri) { Cursor cursor = activity.getContentResolver().query(uri, videoCursorCols, null, null, null); if (cursor == null || cursor.getCount() == 0) { return null; } else { Video video = new Video(); cursor.moveToFirst(); /* file name */ if (cursor.getString(1) != null) { video.setName(cursor.getString(1)); } /* media name */ if (cursor.getString(2) != null) { video.setDisplayName(cursor.getString(2)); } /* play duration */ if (cursor.getString(3) != null) { video.setTimelong((cursor.getInt(3) / 1000) + "s"); } /* artist */ if (cursor.getString(4) != null) { video.setSinger(cursor.getString(4)); } /* album */ if (cursor.getString(5) != null) { video.setAlbum(cursor.getString(5)); } /* resolution */ if (cursor.getString(6) != null) { video.setResolution(cursor.getString(6)); } /* media type */ if (cursor.getString(7) != null) { video.setMimeType(cursor.getString(7).trim()); } /* media size */ if (cursor.getString(8) != null) { video.setDownfilesize(new java.text.DecimalFormat("#.00").format((cursor.getInt(8) / 1024.0 / 1024.0)) + " MB"); } /* media file path */ if (cursor.getString(9) != null) { video.setVoiceurl(cursor.getString(9)); } if (cursor != null) { cursor.close(); } return video; } }
播放視頻
private void initView() { String url="http://ivi.bupt.edu.cn/hls/cctv6hd.m3u8"; VideoView videoView=findViewById(R.id.mVideoView); videoView.setVideoPath(url); videoView.requestFocus(); videoView.start(); }
1、開始錄制
首先實例化一個MediaRecord對象,對其中開始設置。我在這里遇到的問題是時音頻文件的存儲位置。代碼中getCacheDir得到的是內部緩存目錄,這個目錄可以通過file exploer看到,具體在data/data/app名稱/cache。file exploer在windows->show view->other中找到。先打開它,在啟動模擬器,剛開始啟動時可以發現窗口中出現文件列表。
private void StartAudio(){//開始錄制 recorder = new MediaRecorder(); recorder.setAudioSource(MediaRecorder.AudioSource.MIC);//從麥克風采集聲音 recorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP); //內容輸出格式 recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB); //輸出到緩存目錄,此處可以添加上傳錄音的功能,也可以存到其他位置 audioFile = new File(getCacheDir(), "recoder"+ "_" + System.currentTimeMillis() + ".3gp"); recorder.setOutputFile(audioFile.getAbsolutePath()); try { recorder.prepare(); } catch (IOException e) { e.printStackTrace(); } recorder.start(); record=true; Log.i(tag,"開始錄制!"); StartButton.setEnabled(false); StopButton.setEnabled(true); PlayButton.setEnabled(false); }
2、結束錄制
一開始運行時stop函數出現各種問題,后來總結可能是start函數根本沒有運行。可惜我也是剛接觸它,並不熟悉過程。之后查了很多文章,可以用Log.i進行輸出,大致相當於C++中的printf函數。所以一定是要在start之后才能stop。
private void StopAudio(){ //結束錄制 recorder.stop(); //recorder.reset(); //14:19添加修改 recorder.release(); Log.i(tag,"停止錄制!"); record=false; //更新狀態 //PlayButton.setEnabled(true); StartButton.setEnabled(true); StopButton.setEnabled(false); PlayButton.setEnabled(true); }
private void PlayAudio(){ player = new MediaPlayer(); try { player.setDataSource(audioFile.getAbsolutePath()); player.prepare(); player.start(); } catch (IOException e) { e.printStackTrace(); } StartButton.setEnabled(true); StopButton.setEnabled(false); PlayButton.setEnabled(false); }
1.從本地相冊獲取照片:
一般就是寫出這個方法
protected void getImageFromAlbum() { Intent intent = new Intent(Intent.ACTION_PICK); intent.setType("image/*");//相片類型 startActivityForResult(intent, REQUEST_CODE_PICK_IMAGE); }
2.從照相機獲取照片
一般就是寫出這個方法
protected void getImageFromCamera() { String state = Environment.getExternalStorageState(); if (state.equals(Environment.MEDIA_MOUNTED)) { Intent getImageByCamera = new Intent("android.media.action.IMAGE_CAPTURE"); startActivityForResult(getImageByCamera, REQUEST_CODE_CAPTURE_CAMEIA); } else { Toast.makeText(getApplicationContext(), "請確認已經插入SD卡", Toast.LENGTH_LONG).show(); } }
寫完這個方法后,一般我們還需要通過響應這個方法去獲取圖片
@Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { if (requestCode == REQUEST_CODE_PICK_IMAGE) { Uri uri = data.getData(); //to do find the path of pic } else if (requestCode == REQUEST_CODE_CAPTURE_CAMEIA ) { Uri uri = data.getData(); //to do find the path of pic } }
但是,有時候我們會發現用相機拍攝獲取照片的時候,得到的 uri 是 null 的,這是因為android把拍攝的圖片封裝到bundle中傳遞回來,但是根據不同的機器獲得相片的方式不太一樣,可能有的相機能夠通過
inten.getData()獲取到uri
然后再根據uri獲取數據的路徑,在封裝成bitmap,但有時候有的相機獲取到的是null的,這時候我們該怎么辦呢?
其實這時候我們就應該從bundle中獲取數據,通過
(Bitmap) bundle.get("data")
獲取到相機圖片的bitmap數據。
為了能夠同時適應上述兩種情況,我們這時候就應該在獲取圖片時做判斷了。我們可以在響應的時候做一個判斷:
@Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { if (requestCode == REQUEST_CODE_PICK_IMAGE) { Uri uri = data.getData(); //to do find the path of pic by uri } else if (requestCode == REQUEST_CODE_CAPTURE_CAMEIA ) { Uri uri = data.getData(); if(uri == null){ //use bundle to get data Bundle bundle = data.getExtras(); if (bundle != null) { Bitmap photo = (Bitmap) bundle.get("data"); //get bitmap } else { Toast.makeText(getApplicationContext(), "err****", Toast.LENGTH_LONG).show(); return; } }else{ //to do find the path of pic by uri } } }
后面的過程就需要通過bitmap轉化成相應的圖片文件了。不過得到最終的圖片是被壓縮了的。如果我們想得到相機拍攝出來的原照片在
Intent getImageByCamera = new Intent("android.media.action.IMAGE_CAPTURE");
之后我們直接講文件先保存到指定的路徑filepath,然后直接在
onActivityResult(int requestCode, int resultCode, Intent data)
中把filepath傳遞過去
示例代碼
protected void getImageFromCamera() { String state = Environment.getExternalStorageState(); if (state.equals(Environment.MEDIA_MOUNTED)) { Intent getImageByCamera = new Intent("android.media.action.IMAGE_CAPTURE"); String out_file_path = Constant.SAVED_IMAGE_DIR_PATH; File dir = new File(out_file_path); if (!dir.exists()) { dir.mkdirs(); } capturePath = Constant.SAVED_IMAGE_DIR_PATH + System.currentTimeMillis() + ".jpg"; getImageByCamera.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(new File(capturePath))); getImageByCamera.putExtra(MediaStore.EXTRA_VIDEO_QUALITY, 1); startActivityForResult(getImageByCamera, Constant.REQUEST_CODE_CAPTURE_CAMEIA); } else { Toast.makeText(getApplicationContext(), "請確認已經插入SD卡", Toast.LENGTH_LONG).show(); } }
刷新媒體庫
1. 問題概述
使用我們自己寫的程序生成一張圖像或者一段視頻,存放在SD卡的某個位置下,之后打開系統自帶媒體庫(圖庫)無法找到對於的圖像和視頻。連上電腦打開相應文件夾也找不到相應的文件?但是當手機重啟之后,不管是在媒體庫里找還是連上電腦搜索都可以找到。這其中發生了啥?
2. 問題原因
Android 內部維護了很多數據庫,比如媒體數據庫、聯系人數據庫等等。你在生成視頻后並沒有將視頻的位置添加到這個數據庫中。所以找不到唄。但是系統在每次重啟后會自動更新一遍數據庫,所以重啟就可以找到了。
3. 如何解決
android可以手動更新媒體數據庫,通常的做法都是發送廣播
sendBroadcast(new Intent(Intent.ACTION_MEDIA_MOUNTED, dirUri)); //刷新sd卡 sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE,fileUri)); //刷新單個文件
目前在android API 23下直接刷新SD卡是會報錯的,被系統禁止了,我屢次使用刷新單個文件都不怎么見效果。網上有個人說采用廣播的方式刷新文件是可以的,一般沒效果都是因為文件路徑沒有寫對。這個供各位參考。
我實現媒體庫數據的自動更新采用以下代碼
/* * Copyright (c) 2016. All rights reserved * Created by GH_HOME on 16-12-12 下午3:04 * Last modified 16-12-12 下午2:41 * */ package com.test; import java.io.File; import android.content.Context; import android.media.MediaScannerConnection; import android.media.MediaScannerConnection.MediaScannerConnectionClient; import android.net.Uri; import android.util.Log; public class SingleMediaScanner implements MediaScannerConnectionClient { private MediaScannerConnection mMs; private File mFile; public SingleMediaScanner(Context context, File f) { mFile = f; mMs = new MediaScannerConnection(context, this); mMs.connect(); } @Override public void onMediaScannerConnected() { mMs.scanFile(mFile.getAbsolutePath(), null); } @Override public void onScanCompleted(String path, Uri uri) { mMs.disconnect(); Log.i("TAG", "Finished scanning " + path); } }
調用方式為
new SingleMediaScanner(this, mOutputFile);
其中this為你當前的activity,mOutputFile為你生成的文件。在文件生成之后調用即可。