Android 獲取視頻照片與刷新媒體庫*


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為你生成的文件。在文件生成之后調用即可。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM