20169221 2016-2017-2《移動平臺開發》第十二週學習總結

獲取圖片

1.從本地相冊獲取照片:

protected void getImageFromAlbum() {  
       Intent intent = new Intent(Intent.ACTION_PICK);  
       intent.setType("image/*");//相片類型

2.從相機獲取文件

Camera.java
經過源碼能夠發現,輸出的圖片有2個分支
若是你沒有指定Intent裏面的Extra參數,它就返回一個序列化(putExtra("data", bitmap))的Bitmap,從理論上來講,這樣的代碼寫的很爛,屬於Magic Number。
若是你指定了Intent裏面的Extra參數MediaStore.EXTRA_OUTPUT,拍照後它就直接把bitmap寫到了Uri裏面了,返回是空
使用範圍:得到很小的預覽圖,用於設置頭像等地方。
返回示例:bitmap = data.getExtras().getParcelable("data");java

public final static int REQUEST_IMAGE_CAPTURE = 1;

//start
Intent intent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
startActivityForResult(intent, REQUEST_IMAGE_CAPTURE);

//receive
@Override protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    if (resultCode != RESULT_OK) {
      Log.d(TAG, "canceled or other exception!");
      return;
    }

    if (requestCode == REQUEST_IMAGE_CAPTURE) {
      Log.d(TAG, "REQUEST_IMAGE_CAPTURE");
      Bitmap bitmap;
      try {
     
        bitmap = data.getExtras().getParcelable("data"); 
        //TODO:do something with bitmap, Do NOT forget call Bitmap.recycler();
        mCameraImageview.setImageBitmap(bitmap);
      } catch (ClassCastException e){
           //do something with exceptions
        e.printStackTrace();
      } 
    }

  }

得到原始的拍照文件
使用範圍:用於處理大的圖片,好比使用濾鏡,上傳原始圖像等操做,注意Uri不要用data私有目錄,不然相機是寫不進去的。android

public final static int REQUEST_IMAGE_CAPTURE = 1;
Uri outputFileUri;

//start
  @OnClick(R.id.itemSelectCamera) void itemSelectCamera() {
    File file = FileUtils.createImageFile();
    outputFileUri = Uri.fromFile(file);
    Intent captureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
    captureIntent.putExtra(MediaStore.EXTRA_OUTPUT, outputFileUri);
    startActivityForResult(captureIntent, REQUEST_IMAGE_CAPTURE);
  }

//receive
@Override protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);

    if (resultCode != RESULT_OK) {
      Log.d(TAG, "canceled or other exception!");
      return;
    }

    if (requestCode == REQUEST_IMAGE_CAPTURE) {
      Log.d(TAG, "REQUEST_IMAGE_CAPTURE");
      //TODO:Use the Uri 
      Intent intent = new Intent(this, ImageFilterActivity.class);
      intent.setData(outputFileUri);
      startActivity(intent);
    }

  }

關於文件如何建立,目前我找到的就是這個最穩定了,寫到SD卡根目錄,data目錄(Context.getXXDir())是私有目錄,其它程序(好比Camera)是寫不進去的app

public class FileUtils {

  public static File createImageFile() {
    // Create an image file name
    String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
    String imageFileName = "JPEG_" + timeStamp + "_";
    try {
      File image = File.createTempFile(imageFileName,  /* prefix */
          ".jpg",         /* suffix */
          Environment.getExternalStorageDirectory()      /* directory */);
      return image;
    } catch (IOException e) {
      //do noting
      return null;
    }
  }
}

製做視頻

第一步:在Eclipse中建立一個名爲AndroidCamera的Android工程,可參見Helloworld的例子;
第二步:在AndroidManifest.xml中添加使用Camera相關的聲明以下:ide

<uses-feature android:name="android.hardware.camera" android:required="false" />  
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

第三步:編寫AndroidCameraActivity類,以下:函數

import java.io.File;  
import java.text.SimpleDateFormat;  
import java.util.Date;  
import android.app.Activity;  
import android.content.Intent;  
import android.net.Uri;  
import android.os.Bundle;  
import android.os.Environment;  
import android.provider.MediaStore;  
import android.widget.Toast;  
  
public class AndroidCameraActivity extends Activity {  
    private static final int CAPTURE_VIDEO_ACTIVITY_REQUEST_CODE = 200;    
        
    private Intent intent  = null;    
    private Uri fileUri    = null;    
    
    @Override    
    protected void onCreate(Bundle savedInstanceState) {    
        super.onCreate(savedInstanceState);    
        setContentView(R.layout.main);    
            
        intent = new Intent(MediaStore.ACTION_VIDEO_CAPTURE);//create a intent to record video    
        fileUri = getOutputMediaFileUri(); // create a file Uri to save the video  
          
        // set the video file name  
        intent.putExtra(MediaStore.EXTRA_OUTPUT, fileUri);     
          
        // set the video quality high  
        intent.putExtra(MediaStore.EXTRA_VIDEO_QUALITY, 1);   
  
        // start the video capture Intent  
        startActivityForResult(intent, CAPTURE_VIDEO_ACTIVITY_REQUEST_CODE);    
    }    
    
    @Override    
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {    
        super.onActivityResult(requestCode, resultCode, data);    
            
        if(requestCode == CAPTURE_VIDEO_ACTIVITY_REQUEST_CODE) {    
            if (resultCode == RESULT_OK) {    
                // video captured and saved to fileUri specified in the Intent    
                Toast.makeText(this, "Video saved to:\n" +    
                         data.getData(),     
                         Toast.LENGTH_LONG).show();    
            } else if (resultCode == RESULT_CANCELED) {    
                // User cancelled the video capture    
            }    
        }    
    }    
        
    /** Create a File Uri for saving a video */    
    private static Uri getOutputMediaFileUri(){    
        //get the mobile Pictures directory  
        File picDir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES);  
  
        //get the current time  
        String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());   
          
        File videoFile = new File(picDir.getPath() + File.separator + "VIDEO_"+ timeStamp + ".mp4");    
    
        return Uri.fromFile(videoFile);  
    }    
}

聲音錄製

MediaRecorder類詳解
手機通常都有麥克風和攝像頭,而Android系統就能夠利用這些硬件來錄製音視頻了。
爲了增長對錄製音視頻的支持,Android系統提供了一個MediaRecorder的類。
結構:ui

Java.lang.Object
android.media.MediaRecorder

與MediaPlayer類很是類似MediaRecorder也有它本身的狀態圖。下面是關於MediaRecorder的各個狀態的介紹:
Initial:初始狀態,當使用new()方法建立一個MediaRecorder對象或者調用了reset()方法時,該MediaRecorder對象處於Initial狀態。在設定視頻源或者音頻源以後將轉換爲Initialized狀態。另外,在除Released狀態外的其它狀態經過調用reset()方法均可以使MediaRecorder進入該狀態。
Initialized:已初始化狀態,能夠經過在Initial狀態調用setAudioSource()或setVideoSource()方法進入該狀態。在這個狀態能夠經過setOutputFormat()方法設置輸出格式,此時MediaRecorder轉換爲DataSourceConfigured狀態。另外,經過reset()方法進入Initial狀態。
DataSourceConfigured:數據源配置狀態,這期間能夠設定編碼方式、輸出文件、屏幕旋轉、預覽顯示等等。能夠在Initialized狀態經過setOutputFormat()方法進入該狀態。另外,能夠經過reset()方法回到Initial狀態,或者經過prepare()方法到達Prepared狀態。
Prepared:就緒狀態,在DataSourceConfigured狀態經過prepare()方法進入該狀態。在這個狀態能夠經過start()進入錄製狀態。另外,能夠經過reset()方法回到Initialized狀態。
Recording:錄製狀態,能夠在Prepared狀態經過調用start()方法進入該狀態。另外,它能夠經過stop()方法或reset()方法回到Initial狀態。
Released:釋放狀態(官方文檔給出的詞叫作Idle state 空閒狀態),能夠經過在Initial狀態調用release()方法來進入這個狀態,這時將會釋放全部和MediaRecorder對象綁定的資源。
Error:錯誤狀態,當錯誤發生的時候進入這個狀態,它能夠經過reset()方法進入Initial狀態。
提示:與MediaPlayer類似使用MediaRecorder錄音錄像時須要嚴格遵照狀態圖說明中的函數調用前後順序,在不一樣的狀態調用不一樣的函數,不然會出現異常。
實例描述了的建立過程this

MediaRecorder recorder=newMediaRecorder();
 recorder.setAudioSource(MediaRecorder.AudioSource.MIC);
 recorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
 recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
 recorder.setOutputFile(PATH_NAME);
 recorder.prepare();
 recorder.start();  // Recording is now started
 ...
 recorder.stop();
 recorder.reset();  // You can reuse the object by going back to setAudioSource() step
 recorder.release();// Now the object cannot be reused

實踐
使用MediaRecorder錄製聲音的:
1) 建立 MediaRecorder 對象。
2) 調用MediaRecorder對象的setAudioSource()方法設置聲音來源,通常傳入 MediaRecorder. AudioSource.MIC參數指定錄製來自麥克風的聲音。
3) 調用MediaRecorder對象的setOutputFormat()設置所錄製的音頻文件的格式。
4) 調用MediaRecorder 對象的setAudioEncoder()、setAudioEncodingBitRate(intbitRate)、 setAudioSamplingRate(int samplingRate)設置所錄製的聲音的編碼格式、編碼位率、採樣率等, 這些參數將能夠控制所錄製的聲音的品質、文件的大小。通常來講,聲音品質越好,聲音文件越大。
5) 調用MediaRecorder的setOutputFile(Stringpath)方法設置錄製的音頻文件的保存位置。
6) 調用MediaRecorder的prepare()方法準備錄製。
7) 調用MediaRecorder對象的start()方法開始錄製。
8) 錄製完成,調用MediaRecorder對象的stop()方法中止錄製,並調用release()方法釋放資源。編碼

<span style="font-size:18px;">package com.jph.recordsound;  
  
import java.io.File;  
import org.crazyit.sound.R;  
import android.app.Activity;  
import android.media.MediaRecorder;  
import android.os.Bundle;  
import android.os.Environment;  
import android.view.View;  
import android.view.View.OnClickListener;  
import android.widget.ImageButton;  
import android.widget.Toast;  
  
  
public class RecordSound extends Activity  
    implements OnClickListener  
{  
    // 定義界面上的兩個按鈕  
    ImageButton record, stop;  
    // 系統的音頻文件  
    File soundFile;  
    MediaRecorder mRecorder;  
  
    @Override  
    public void onCreate(Bundle savedInstanceState)  
    {  
        super.onCreate(savedInstanceState);  
        setContentView(R.layout.main);  
        // 獲取程序界面中的兩個按鈕  
        record = (ImageButton) findViewById(R.id.record);  
        stop = (ImageButton) findViewById(R.id.stop);  
        // 爲兩個按鈕的單擊事件綁定監聽器  
        record.setOnClickListener(this);  
        stop.setOnClickListener(this);  
    }  
  
    @Override  
    public void onDestroy()  
    {  
        if (soundFile != null && soundFile.exists())  
        {  
            // 中止錄音  
            mRecorder.stop();  
            // 釋放資源  
            mRecorder.release();  
            mRecorder = null;  
        }  
        super.onDestroy();  
    }  
  
    @Override  
    public void onClick(View source)  
    {  
        switch (source.getId())  
        {  
        // 單擊錄音按鈕  
            case R.id.record:  
                if (!Environment.getExternalStorageState().equals(  
                    android.os.Environment.MEDIA_MOUNTED))  
                {  
                    Toast.makeText(RecordSound.this, "SD卡不存在,請插入SD卡!",  
                        Toast.LENGTH_SHORT).show();  
                    return;  
                }  
                try  
                {  
                    // 建立保存錄音的音頻文件  
                    soundFile = new File(Environment  
                        .getExternalStorageDirectory().getCanonicalFile()  
                        + "/sound.amr");  
                    mRecorder = new MediaRecorder();  
                    // 設置錄音的聲音來源  
                    mRecorder.setAudioSource(MediaRecorder  
                        .AudioSource.MIC);  
                    // 設置錄製的聲音的輸出格式(必須在設置聲音編碼格式以前設置)  
                    mRecorder.setOutputFormat(MediaRecorder  
                        .OutputFormat.AMR_NB);  
                    // 設置聲音編碼的格式  
                    mRecorder.setAudioEncoder(MediaRecorder  
                        .AudioEncoder.AMR_NB);  
                    mRecorder.setOutputFile(soundFile.getAbsolutePath());  
                    mRecorder.prepare();  
                    // 開始錄音  
                    mRecorder.start();  //①  
                }  
                catch (Exception e)  
                {  
                    e.printStackTrace();  
                }  
                break;  
            // 單擊中止按鈕  
            case R.id.stop:  
                if (soundFile != null && soundFile.exists())  
                {  
                    // 中止錄音  
                    mRecorder.stop();  //②  
                    // 釋放資源  
                    mRecorder.release();  //③  
                    mRecorder = null;  
                }  
                break;  
        }  
    }  
}</span>

結果圖
spa

相關文章
相關標籤/搜索