Android开发手机相机应用
1.开发环境
Android Studio
2.实现方法
(1)AndroidManifest.xml文件的配置
需要在默认的基础上面加上
<uses-permission android:name="android.permission.CAMERA"/>
这里解释一下<uses-permission>的意思Android SDK中定义的访问某些功能的权限参数,当应用程序需要使用这些功能的时候需要使用<user-permission/>标注明确的权限。
<permission/>意思是:一个应用程序自定义的权限,可以供其他应用程序使用本应用的说明
贴出我的AndroidManifest.xml文件信息
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.chen.myapplication">
<uses-permission android:name="android.permission.CAMERA"/>
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
(2)布局activity_main.xml文件配置
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.example.chen.myapplication.MainActivity">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginBottom="8dp"
app:layout_constraintBottom_toBottomOf="parent"
tools:layout_editor_absoluteX="8dp"
tools:ignore="MissingConstraints">
<SurfaceView
android:id="@+id/surfaceView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_alignParentEnd="true"
android:layout_toEndOf="@+id/imageView"
tools:layout_editor_absoluteX="8dp"
tools:layout_editor_absoluteY="8dp" />
<Button
android:id="@+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:text="拍照"
tools:layout_editor_absoluteX="160dp"
tools:layout_editor_absoluteY="447dp" />
<ImageView
android:id="@+id/imageView"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_alignParentStart="true"
android:layout_alignParentTop="true"
app:srcCompat="@android:color/background_light"
tools:layout_editor_absoluteX="8dp"
tools:layout_editor_absoluteY="8dp" />
</RelativeLayout>
</android.support.constraint.ConstraintLayout>
(3)MainActivity的类信息
package com.example.chen.myapplication;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.ImageFormat;
import android.hardware.Camera;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import java.io.IOException;
public class MainActivity extends AppCompatActivity implements SurfaceHolder.Callback ,View.OnClickListener{
private Button btn;//按钮的在代码中的体现,btn为名称可随意更改
private SurfaceView mSurFaceView;
private ImageView mImageView;
private SurfaceHolder mSurfaceHolder;//用于获取SurfaceView的句柄,使其能被mCamera使用,以打开相机
private Camera mCamera;//照相机的个体。
private Camera.Parameters parameters;//相机的参数设置的变量
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//接下来的代码是将布局中的工具和代码中的个体对应起来,或者说联系起来
btn = (Button) findViewById(R.id.button);
mSurFaceView = (SurfaceView) findViewById(R.id.surfaceView);
mImageView = (ImageView) findViewById(R.id.imageView);
//在此之后就可以使用btn、mSurfaceView、mImageView来对布局中的工具进行操作了
mImageView.setVisibility(View.GONE);//设置这个工具不可见
btn.setText("拍照");//如代码所示,可以更改按钮的名字
mSurfaceHolder = mSurFaceView.getHolder();//代码作用直译即可
mSurfaceHolder.addCallback(this);
btn.setOnClickListener(this);//设置按钮监听事件,这样当用户按按钮的时候就可以在单击事件函数里得到单击的信息了
}
//在Surface创建的时候执行这个函数
@Override
public void surfaceCreated(SurfaceHolder holder) {
mCamera = Camera.open();//打开摄像头(后摄像头),效果就是从此,mCamera就控制了手机的摄像头
try{
mCamera.setPreviewDisplay(mSurfaceHolder);//之后,mCamera从摄像机里获得的图像,就会实时的显示在mSurfaceView中。
mCamera.setDisplayOrientation(90);//使你预览的画面呈现为正常的视觉画面,可是删除此行试试效果
parameters = mCamera.getParameters();//将现在camera的参数设置保存到变量parameter中
//接下来的代码是对mCamera参数的调整,或者说设置
parameters.setPreviewSize(parameters.getSupportedPreviewSizes().get(0).width,parameters.getSupportedPreviewSizes().get(0).height);//设置预览的尺寸,通过此种方法可设置为最大预览尺寸(我觉得)
parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_AUTO); //设置适合照片对焦
parameters.setRotation(90);//跟mCamera.setDisplayOrientation(90);有类似的作用
parameters.setPictureFormat(ImageFormat.JPEG);//设置得到的照片模式
mCamera.setParameters(parameters);//这就是将我们改变的相机参数设置到相机里了
mCamera.startPreview();//开始预览相机画面
}catch (IOException e){//如果上面try中的代码有代码执行出错,就会来到这里
e.printStackTrace();
mCamera.release();//释放摄像头,避免发生一直占用摄像头的情况
mCamera=null;//使mCamera为空,就是不代表任何东西。这也是保护代码
}
}
//在Surface被改变的时候执行这个函数
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
//此处不填任何代码,因为本程序中不需要这个功能,但是这个函数不能删除
}
//在Surface销毁的时候执行这个函数
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
mCamera.setPreviewCallback(null);
mCamera.stopPreview();//停止预览,毕竟Surface都已经销毁了
mCamera.release();
mCamera=null;
}
//单击事件,这个函数收集所有的单击事件
@Override
public void onClick(View v) {
if(v.getId()==R.id.button){//当用户单击的是button的时候执行下面的代码
mCamera.autoFocus(null);//聚焦
mCamera.takePicture(null,null,mPictureCallback);//开始照相,mPictureCallback为回调函数
}
}
private Camera.PictureCallback mPictureCallback = new Camera.PictureCallback() {
@Override
public void onPictureTaken(byte[] data, Camera camera) {
mImageView.setVisibility(View.VISIBLE);//设置这个工具可见
Bitmap btm = BitmapFactory.decodeByteArray(data, 0, data.length);//将照片数据变成图像
mImageView.setImageBitmap(btm);//显示这个图像
}
};
}
(4)打包APP,然后安装在手机即可(虚拟器一般跑不出来哦,需要手机测试)
会弹出成功标志,然后点击locate即可调到APP打包好的文件.