手機(jī)的相機(jī)功能是當(dāng)前大家玩拍照的一個(gè)必備功能,本篇的學(xué)習(xí),我認(rèn)為網(wǎng)上的一篇博文的講解更容易理解一下,這里就轉(zhuǎn)一下博文,自己把自己遇到的的問(wèn)題給補(bǔ)充進(jìn)來(lái)。引用的博文地址: http://xblia.iteye.com/blog/1167964
目前的智能 手機(jī) 擁有很多強(qiáng)大的功能,例如攝像頭、 GPS 和無(wú)線上網(wǎng)等,現(xiàn)在是我們開(kāi)始充分使用這些功能的時(shí)候了,在本篇文章中我們一起學(xué)習(xí),如何在谷歌Android編程環(huán)境中,以最簡(jiǎn)單的方式實(shí)現(xiàn)谷歌Android攝像頭拍照。
在本文示例中,我們需要用到兩個(gè)文件:布局文件和Activity文件。
【提示】:在Android 1.5(代號(hào)cupcake)發(fā)布之后,在 安全 方面有諸多改進(jìn),其中之一與攝像頭權(quán)限控制有關(guān)。在此之前,你能夠創(chuàng)建無(wú)需用戶許可就可實(shí)現(xiàn)拍照的應(yīng)用。現(xiàn)在該問(wèn)題已被修復(fù),如果你想在自己的應(yīng)用中使用攝像頭,需要在AndroidManifest.xml中增加以下代碼:
<uses-permission android:name="android.permission.CAMERA"/>
沒(méi)有此授權(quán)代碼,程序會(huì)報(bào):Fail to connect to camera service 錯(cuò)誤。
1.設(shè)定攝像頭布局
這是開(kāi)發(fā)工作的基礎(chǔ),也就是說(shuō)我們希望在應(yīng)用程序中增加多少輔助性元素,如攝像頭各種功能按鈕等。在本文中我們采取最簡(jiǎn)方式,除了拍照外,沒(méi)有多余攝像頭功能。下面我們一起看一下本文示例將要用到的布局文件“main.xml”。
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<SurfaceView
android:id="@+id/surface_camera"
android:layout_width="fill_parent"
android:layout_height="10dip"
android:layout_weight="1" >
</SurfaceView>
</LinearLayout>
該布局非常簡(jiǎn)單,只有一個(gè)LinearLayout視圖組,在它下面只有一個(gè)SurfaceView視圖,也就是我們的攝像頭 屏幕 。
【提示】:記住不要在資源文件名稱中使用大寫字母,如果你把該文件命名為“CameraSurface.xml”,會(huì)給你帶來(lái)不必要的麻煩。
2.攝像頭實(shí)現(xiàn)CameraActivity代碼
package com.jercy.android.Camera;
import java.io.IOException;
import android.app.Activity;
import android.graphics.PixelFormat;
import android.hardware.Camera;
import android.os.Bundle;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.Window;
import android.view.WindowManager;
public class CameraActivity extends Activity implements SurfaceHolder.Callback {
private static final String TAG="CameraActivity";
private Camera mCamera;
private SurfaceView mSurfaceView;
private SurfaceHolder mSurfaceHolder;
private boolean mPreviewRunning = false;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getWindow().setFormat(PixelFormat.TRANSLUCENT); //屏幕格式為“半透明”。
requestWindowFeature(Window.FEATURE_NO_TITLE); //攝像頭預(yù)覽界面將通過(guò)全屏顯示,沒(méi)有“標(biāo)題(title)”
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,WindowManager.LayoutParams.FLAG_FULLSCREEN);
setContentView(R.layout.main); //設(shè)定Activity的布局為前面我們創(chuàng)建的main布局
mSurfaceView = (SurfaceView) findViewById(R.id.surface_camera);
mSurfaceHolder = mSurfaceView.getHolder(); //surfaceview中獲得了holder
mSurfaceHolder.addCallback(this); //并增加callback功能到“this”。這意味著我們的操作(activity)將可以管理這個(gè)surfaceview。
mSurfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
}
@Override
public void surfaceCreated(SurfaceHolder holder) {
// TODO Auto-generated method stub
Log.i(TAG, "調(diào)用了CameraActivity的surfaceCreated方法");
//mCamera是“Camera”類的一個(gè)對(duì)象。在surfaceCreated方法中我們“打開(kāi)”攝像頭。這就是啟動(dòng)它的方式
mCamera = Camera.open();
}
@Override
/**
* 該方法讓攝像頭做好拍照準(zhǔn)備,設(shè)定它的參數(shù),并開(kāi)始在Android屏幕中啟動(dòng)預(yù)覽畫(huà)面。
* 當(dāng)mPreviewRunning為true時(shí),意味著攝像頭處于激活狀態(tài),并未被關(guān)閉,因此我們可以使用它。
*/
public void surfaceChanged(SurfaceHolder holder, int format, int width,
int height) {
// TODO Auto-generated method stub
Log.i(TAG, "調(diào)用了CameraActivity的surfaceChanged方法");
if(mPreviewRunning) {
mCamera.stopPreview();
}
Camera.Parameters p = mCamera.getParameters();
p.setPreviewSize(width, height);
mCamera.setParameters(p);
try {
mCamera.setPreviewDisplay(holder);
} catch (IOException e) {
e.printStackTrace();
}
mCamera.startPreview();
mPreviewRunning = true;
}
@Override
/**
* 通過(guò)這個(gè)方法,我們停止攝像頭,并釋放相關(guān)的資源。正如大家所看到的,我們?cè)谶@兒設(shè)置mPreviewRunning為false,
* 以此來(lái)防止在surfaceChanged方法中的沖突。因?yàn)檫@意味著我們已經(jīng)關(guān)閉了攝像頭,而且我們不能再設(shè)置其參數(shù)或在攝像頭中啟動(dòng)圖像預(yù)覽
*/
public void surfaceDestroyed(SurfaceHolder holder) {
// TODO Auto-generated method stub
Log.i(TAG, "調(diào)用了CameraActivity的surfaceDestroyed方法");
mCamera.stopPreview();
mPreviewRunning = false;
mCamera.release();
}
/**
* 當(dāng)拍照時(shí),該方法被調(diào)用。舉例來(lái)說(shuō),你可以在界面上創(chuàng)建一個(gè)OnClickListener,當(dāng)你點(diǎn)擊屏幕時(shí),
* 調(diào)用PictureCallBack方法。 這個(gè)方法會(huì)向你提供圖像的字節(jié)數(shù)組,
* 然后你可以使用Android提供的Bitmap和BitmapFactory類,將其從字節(jié)數(shù)組轉(zhuǎn)換成你想要的圖像格式。
*/
Camera.PictureCallback mPictureCallback = new Camera.PictureCallback() {
public void onPictureTaken(byte[] imageData, Camera c) {
}
};
}
分析Activity類,實(shí)現(xiàn)SurfaceHolder.Callback接口:
接口SurfaceHolder.Callback被用來(lái)接收攝像頭預(yù)覽界面變化的信息。它實(shí)現(xiàn)了三個(gè)方法:
surfaceChanged
當(dāng)預(yù)覽界面的格式和大小發(fā)生改變時(shí),該方法被調(diào)用。
surfaceCreated
初次實(shí)例化,預(yù)覽界面被創(chuàng)建時(shí),該方法被調(diào)用。
surfaceDestroyed
當(dāng)預(yù)覽界面被關(guān)閉時(shí),該方法被調(diào)用。
如下圖為運(yùn)行程序,并且點(diǎn)擊取消按鈕退出程序過(guò)程的Log日志:
11-14 08:24:10.420: I/CameraActivity(426): 調(diào)用了CameraActivity的surfaceCreated方法
11-14 08:24:20.374: I/CameraActivity(426): 調(diào)用了CameraActivity的surfaceChanged方法
11-14 08:24:32.899: W/KeyCharacterMap(426): No keyboard for id 0
11-14 08:24:32.899: W/KeyCharacterMap(426): Using default keymap: /system/usr/keychars/qwerty.kcm.bin
11-14 08:24:35.746: I/CameraActivity(426): 調(diào)用了CameraActivity的surfaceDestroyed方法
效果圖:
更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主
微信掃碼或搜索:z360901061
微信掃一掃加我為好友
QQ號(hào)聯(lián)系: 360901061
您的支持是博主寫作最大的動(dòng)力,如果您喜歡我的文章,感覺(jué)我的文章對(duì)您有幫助,請(qǐng)用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點(diǎn)擊下面給點(diǎn)支持吧,站長(zhǎng)非常感激您!手機(jī)微信長(zhǎng)按不能支付解決辦法:請(qǐng)將微信支付二維碼保存到相冊(cè),切換到微信,然后點(diǎn)擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對(duì)您有幫助就好】元

