Android調(diào)用系統(tǒng)照相機(jī)拍照與攝像的方法
前言
在很多場(chǎng)景中,都需要用到攝像頭去拍攝照片或視頻,在照片或視頻的基礎(chǔ)之上進(jìn)行處理。但是Android系統(tǒng)源碼是開(kāi)源的,很多設(shè)備廠商均可使用,并且定制比較混亂。一般而言,在需要用到攝像頭拍照或攝像的時(shí)候,均會(huì)直接調(diào)用系統(tǒng)現(xiàn)有的相機(jī)應(yīng)用,去進(jìn)行拍照或攝像,我們只取它拍攝的結(jié)果進(jìn)行處理,這樣避免了不同設(shè)備的攝像頭的一些細(xì)節(jié)問(wèn)題。本篇博客將介紹在Android應(yīng)用中,如何調(diào)用系統(tǒng)現(xiàn)有的相機(jī)應(yīng)用去拍攝照片與短片,并對(duì)其進(jìn)行處理,最后均會(huì)以一個(gè)簡(jiǎn)單的Demo來(lái)演示效果。
1、系統(tǒng)現(xiàn)有相機(jī)應(yīng)用的調(diào)用
對(duì)于如何調(diào)用系統(tǒng)現(xiàn)有應(yīng)用,之前就有講解,這里簡(jiǎn)單再說(shuō)一下。在開(kāi)發(fā)的應(yīng)用中調(diào)用系統(tǒng)現(xiàn)有應(yīng)用,需要使用Intent指定開(kāi)啟的應(yīng)用的Action和Category,然后通過(guò)startActivity(Intent)或者startActivityForResult(Intent,int)開(kāi)啟指定的Activity,如果使用startActivityForResult()方法開(kāi)啟并需要返回值,再重寫(xiě)onActivityResult(int,int,Intent)即可。
先來(lái)看看系統(tǒng)現(xiàn)有相機(jī)應(yīng)用的AndroidManifest.xml清單文件定義的Activity:
<activity android:name="com.android.camera.Camera" android:clearTaskOnLaunch="true" android:configChanges="orientation|keyboardHidden" android:screenOrientation="landscape" android:taskAffinity="android.task.camera" android:theme="@android:style/Theme.Black.NoTitleBar.Fullscreen" > <intent-filter> <action android:name="android.intent.action.MAIN" /> <categroy android:name="android.intent.category.DEFAULT" /> <categroy android:name="android.intent.category.LAUNCHER" /> </intent-filter> <intent-filter> <action android:name="android.media.action.IMAGE_CAPTURE" /> <categroy android:name="android.intent.category.DEFAULT" /> </intent-filter> <intent-filter> <action android:name="android.media.action.STILL_IMAGE_CAMERA" /> <categroy android:name="android.intent.category.DEFAULT" /> </intent-filter> </activity> <activity android:name="com.android.camera.VideoCamera" android:clearTaskOnLaunch="true" android:configChanges="origientation|keyboardHidden" android:label="@string/video_camera_label" android:screenOrientation="landscape" android:taskAffinity="android.task.camcorder" android:theme="@android:style/theme.Black.NoTitleBar.Fullscreen" > <intent-filter> <action android:name="android.media.action.VIDEO_CAMERA" /> <categroy android:name="android.intent.category.DEFAULT" /> </intent-filter> <intent-filter> <action android:name="android.media.action.VIDEO_CAPTURE" /> <categroy android:name="android.intent.category.DEFAULT" /> </intent-filter> </activity>
它定義了兩個(gè)Activity,com.android.camera.Camera表示照相機(jī),com.android.camera.VideoCamera表示攝像機(jī)。從字面意思可以看出,為了捕獲系統(tǒng)相機(jī)返回的數(shù)據(jù),一般需要使用一下兩個(gè)Action即可開(kāi)啟照相機(jī)與攝像機(jī):
- android.media.action.IMAGE_CAPTURE:Intent的Action類型,從現(xiàn)有的相機(jī)應(yīng)用中請(qǐng)求一張圖片。
- android.media.action.VIDEO_CAPTURE:Intent的Action類型,從現(xiàn)有的相機(jī)應(yīng)用中請(qǐng)求一段視頻。
上面兩個(gè)參數(shù),均在MediaStore類中以靜態(tài)常量的形式定義好了,分別是:MediaStore.ACTION_IMAGE_CAPTURE(相機(jī))和MediaStore.ACTION_VIDEO_CAPTURE(攝像機(jī))。
2、系統(tǒng)現(xiàn)有相機(jī)拍攝照片
上面介紹到,開(kāi)啟系統(tǒng)現(xiàn)有相機(jī)應(yīng)用拍攝照片,需要用的MediaStore.ACTION_IMAGE_CAPTURE作為Intent的action開(kāi)啟Activity即可。但是在使用系統(tǒng)現(xiàn)有相機(jī)用用的時(shí)候,默認(rèn)會(huì)把圖片保存到系統(tǒng)圖庫(kù)的目錄下,如果需要指定圖片文件的保存路徑,需要額外在Intent中設(shè)置。
設(shè)置系統(tǒng)現(xiàn)有相機(jī)應(yīng)用的拍攝照片的保存路徑,需要用Intent.putExtra()方法通過(guò)MediaStore.EXTRA_OUTPUT去設(shè)置Intent的額外數(shù)據(jù),這里傳遞的是一個(gè)Uri參數(shù),可以是一個(gè)文件路徑的Uri。
Intent intent=new Intent(); // 指定開(kāi)啟系統(tǒng)相機(jī)的Action intent.setAction(MediaStore.ACTION_IMAGE_CAPTURE); intent.addCategory(Intent.CATEGORY_DEFAULT); // 根據(jù)文件地址創(chuàng)建文件 File file=new File(FILE_PATH); // 把文件地址轉(zhuǎn)換成Uri格式 Uri uri=Uri.fromFile(file); // 設(shè)置系統(tǒng)相機(jī)拍攝照片完成后圖片文件的存放地址 intent.putExtra(MediaStore.EXTRA_OUTPUT, uri);
3、獲取系統(tǒng)現(xiàn)有相機(jī)拍攝的圖片
在新開(kāi)啟的Activity中,如果需要獲取它的返回值,則需要使用startActivityForResult(Intent,int)方法開(kāi)啟Activity,并重寫(xiě)onActivityResult(int,int,Intent)獲取系統(tǒng)相機(jī)的返回?cái)?shù)據(jù),那么我們只需要在onActivityResult()中獲取到返回值即可。
系統(tǒng)相機(jī)拍攝的照片,如果不指定路徑,會(huì)保存在系統(tǒng)默認(rèn)文件夾下,可以使用Intent.getExtra()方法得到,得到的是一個(gè)Uri地址,表示了一個(gè)內(nèi)容提供者的地址。如果通過(guò)MediaStore.EXTRA_OUTPUT指定了保存路徑,那么通過(guò)Intent.getExtra()得到的將是一個(gè)空地址,但是既然是我們指定的地址,那么也不愁找不到它了。
4、系統(tǒng)現(xiàn)有相機(jī)拍攝圖片Demo
上面講解了如何在開(kāi)發(fā)的應(yīng)用中使用系統(tǒng)相機(jī)拍攝照片并獲得它所涉及到的內(nèi)容,下面通過(guò)一個(gè)簡(jiǎn)單的Demo演示一下。在Demo中,有兩個(gè)Button分別以指定路徑的方式和不指定路徑的方式啟動(dòng)系統(tǒng)相機(jī),并獲取返回值顯示到ImageView中,Demo中注釋比較詳細(xì),這里不再累述了。
布局代碼:activity_syscamera.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <Button android:id="@+id/btn_StartCamera" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="系統(tǒng)相機(jī)拍照--指定路徑到SD卡" /> <Button android:id="@+id/btn_StartCameraInGallery" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="系統(tǒng)相機(jī)拍照--默認(rèn)圖庫(kù)" /> <ImageView android:id="@+id/iv_CameraImg" android:layout_width="match_parent" android:layout_height="match_parent" /> </LinearLayout>
實(shí)現(xiàn)代碼:SysCameraActivity.java
package cn.bgxt.callsystemcamera;
import java.io.File;
import android.app.Activity;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.Bundle;
import android.provider.MediaStore;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
public class SysCameraActivity extends Activity {
private Button btn_StartCamera, btn_StartCameraInGallery;
private ImageView iv_CameraImg;
private static final String TAG = "main";
private static final String FILE_PATH = "/sdcard/syscamera.jpg";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_syscamera);
btn_StartCamera = (Button) findViewById(R.id.btn_StartCamera);
btn_StartCameraInGallery = (Button) findViewById(R.id.btn_StartCameraInGallery);
iv_CameraImg = (ImageView) findViewById(R.id.iv_CameraImg);
btn_StartCamera.setOnClickListener(click);
btn_StartCameraInGallery.setOnClickListener(click);
}
private View.OnClickListener click = new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = null;
switch (v.getId()) {
// 指定相機(jī)拍攝照片保存地址
case R.id.btn_StartCamera:
intent = new Intent();
// 指定開(kāi)啟系統(tǒng)相機(jī)的Action
intent.setAction(MediaStore.ACTION_IMAGE_CAPTURE);
intent.addCategory(Intent.CATEGORY_DEFAULT);
// 根據(jù)文件地址創(chuàng)建文件
File file = new File(FILE_PATH);
if (file.exists()) {
file.delete();
}
// 把文件地址轉(zhuǎn)換成Uri格式
Uri uri = Uri.fromFile(file);
// 設(shè)置系統(tǒng)相機(jī)拍攝照片完成后圖片文件的存放地址
intent.putExtra(MediaStore.EXTRA_OUTPUT, uri);
startActivityForResult(intent, 0);
break;
// 不指定相機(jī)拍攝照片保存地址
case R.id.btn_StartCameraInGallery:
intent = new Intent();
// 指定開(kāi)啟系統(tǒng)相機(jī)的Action
intent.setAction(MediaStore.ACTION_IMAGE_CAPTURE);
intent.addCategory(Intent.CATEGORY_DEFAULT);
startActivityForResult(intent, 1);
break;
default:
break;
}
}
};
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
Log.i(TAG, "系統(tǒng)相機(jī)拍照完成,resultCode="+resultCode);
if (requestCode == 0) {
File file = new File(FILE_PATH);
Uri uri = Uri.fromFile(file);
iv_CameraImg.setImageURI(uri);
} else if (requestCode == 1) {
Log.i(TAG, "默認(rèn)content地址:"+data.getData());
iv_CameraImg.setImageURI(data.getData());
}
}
}
效果展示:

這里只是簡(jiǎn)單的演示了如何調(diào)用系統(tǒng)現(xiàn)有的相機(jī)應(yīng)用獲取拍攝的圖片,沒(méi)有做圖片資源的回收,所以可能會(huì)有內(nèi)存溢出的錯(cuò)誤,重新啟動(dòng)應(yīng)用即可。
5、系統(tǒng)現(xiàn)有相機(jī)拍攝視頻
從系統(tǒng)現(xiàn)有的相機(jī)應(yīng)用中獲取拍攝的視頻,與獲取拍攝的圖片過(guò)程大致相同,但是它除了可以通過(guò)putExtra()設(shè)置MediaStore.EXTRA_OUTPUT輸出路徑外,還可以設(shè)置其它值,這里簡(jiǎn)單介紹一下:
- MediaStore.EXTRA_OUTPUT:設(shè)置媒體文件的保存路徑。
- MediaStore.EXTRA_VIDEO_QUALITY:設(shè)置視頻錄制的質(zhì)量,0為低質(zhì)量,1為高質(zhì)量。
- MediaStore.EXTRA_DURATION_LIMIT:設(shè)置視頻最大允許錄制的時(shí)長(zhǎng),單位為毫秒。
- MediaStore.EXTRA_SIZE_LIMIT:指定視頻最大允許的尺寸,單位為byte。
6、系統(tǒng)現(xiàn)有相機(jī)拍攝視頻Demo
既然和拍攝照片的流程一樣,這里就不再累述了,直接上Demo。在Demo中通過(guò)一個(gè)Button啟動(dòng)一個(gè)系統(tǒng)現(xiàn)有相機(jī)拍攝視頻,最后保存在SD卡上。
實(shí)現(xiàn)代碼:
package cn.bgxt.callsystemcamera;
import java.io.File;
import android.app.Activity;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.provider.MediaStore;
import android.util.Log;
import android.view.View;
import android.widget.Button;
public class SysVideoCameraActivity extends Activity {
private Button btn_StartVideoCamera;
private static final String FILE_PATH = "/sdcard/sysvideocamera.3gp";
private static final String TAG="main";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_sysvideocamera);
btn_StartVideoCamera = (Button) findViewById(R.id.btn_StartVideoCamera);
btn_StartVideoCamera.setOnClickListener(click);
}
private View.OnClickListener click = new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent();
intent.setAction("android.media.action.VIDEO_CAPTURE");
intent.addCategory("android.intent.category.DEFAULT");
File file = new File(FILE_PATH);
if(file.exists()){
file.delete();
}
Uri uri = Uri.fromFile(file);
intent.putExtra(MediaStore.EXTRA_OUTPUT, uri);
startActivityForResult(intent, 0);
}
};
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
Log.i(TAG, "拍攝完成,resultCode="+requestCode);
}
}
效果展示:

源碼下載:Android調(diào)用系統(tǒng)照相機(jī)拍照與攝像
總結(jié)
到此就把如何使用系統(tǒng)現(xiàn)有相機(jī)應(yīng)用拍攝照片與視頻都講解清楚了,在非相機(jī)相關(guān)的項(xiàng)目中,如果需要拍照的話,一般都是調(diào)用系統(tǒng)現(xiàn)有的相機(jī)應(yīng)用,而不會(huì)直接調(diào)用Camera硬件去獲取圖像。
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
Android Flutter基于WebSocket實(shí)現(xiàn)即時(shí)通訊功能
WebSocket是一種在單個(gè)TCP連接上進(jìn)行全雙工通信的協(xié)議。本文將利用Flutter WebSocket實(shí)現(xiàn)即時(shí)通訊功能,文中示例代碼講解詳細(xì),感興趣的可以了解一下2022-03-03
Android實(shí)現(xiàn)布局動(dòng)畫(huà)和共享動(dòng)畫(huà)的結(jié)合效果
今天給大家?guī)?lái)能夠提升用戶體驗(yàn)感的交互動(dòng)畫(huà),使用起來(lái)非常簡(jiǎn)單,體驗(yàn)效果非常贊,其中僅使用到布局動(dòng)畫(huà)和共享動(dòng)畫(huà),文章通過(guò)代碼示例介紹的非常詳細(xì),感興趣的同學(xué)可以自己動(dòng)手試一試2023-09-09
Android使用Intent啟動(dòng)其他非系統(tǒng)應(yīng)用程序的方法
這篇文章主要介紹了Android使用Intent啟動(dòng)其他非系統(tǒng)應(yīng)用程序的方法,實(shí)例分析了Intent調(diào)用系統(tǒng)應(yīng)用程序的相關(guān)技巧,需要的朋友可以參考下2015-12-12
Android中AlertDialog用法實(shí)例分析
這篇文章主要介紹了Android中AlertDialog用法,結(jié)合實(shí)例形式簡(jiǎn)單分析了AlertDialog的基本調(diào)用與功能實(shí)現(xiàn)技巧,需要的朋友可以參考下2016-01-01
Android音視頻開(kāi)發(fā)之MediaPlayer使用教程
Android多媒體框架支持播放提供了MediaPlayerAPI,可以通過(guò)MediaPlayer來(lái)實(shí)現(xiàn)媒體文件播放??梢哉f(shuō)MediaPlayer是非常方便使用的多媒體播放器。本文將詳細(xì)講解MediaPlayer的使用,需要的可以參考一下2022-04-04
Android TextView實(shí)現(xiàn)詞組高亮的示例代碼
本篇文章主要介紹了Android TextView實(shí)現(xiàn)詞組高亮的示例代碼,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-10-10
Android入門之TabHost與TabWidget實(shí)例解析
這篇文章主要介紹了Android入門之TabHost與TabWidget,對(duì)于Android初學(xué)者有一定的學(xué)習(xí)借鑒價(jià)值,需要的朋友可以參考下2014-08-08

