调用安卓系统的相机,并保存相机拍下的图片。实现方法如下。
新建一个module,在activity_main布局中,添加一个button按键,这个按键为启动相机的按键。并添加一个imageview,来显示拍下的图片。
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity"
android:padding="16dp"
android:orientation="vertical">
<Button
android:id="@+id/button_camera"
android:text="打开相机1"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<ImageView
android:id="@+id/iv"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
回到MainActivity中:
package com.chase.cn.camera;
import android.app.Activity;
...
public class MainActivity extends Activity {
private Button button1;
private static int REQ_1 = 1;//定义一个request code
private ImageView imageview1;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
button1= (Button) findViewById(R.id.button_camera);
imageview1= (ImageView) findViewById(R.id.iv);
//设置点击事件,启动相机,这里用到了intent的action作用,这是intent通信的知识
button1.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
startActivityForResult(intent,REQ_1);//既然要启动相机传回照片,就要ForResult
}
});
/**
* 安卓系统考虑到data过大会造成溢出 所有intent返回的是一个缩略图
* @param requestCode
* @param resultCode
* @param data
*/
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == RESULT_OK){
if (requestCode==REQ_1){
Bundle bundle = data.getExtras();//bundle封装所有传递回来的数据
Bitmap bitmap = (Bitmap) bundle.get("data");//强制类型转换
imageview1.setImageBitmap(bitmap);
}
}
}
}
以上的方法使用intent action打开系统相机,并使用bundle封装所有传递回来的数据,然后转换为bitmap显示,但是不足之处在于,安卓系统考虑到data过大会造成溢出 所有intent返回的是一个缩略图,那么解决办法如下:
再在加一个按钮activity_mian中添加一个按钮:
<Button
android:id="@+id/button_camera2"
android:text="打开相机2"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
在Main_Activity中设置点击事件:
package com.chase.cn.camera;
import android.app.Activity;
...
public class MainActivity extends Activity {
private Button button1,button2;
private static int REQ_1 = 1;//request code
private static int REQ_2 = 2;
private ImageView imageview1;
private String mFilePath;//定义一个文件路径
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
button1= (Button) findViewById(R.id.button_camera);
button2 = (Button) findViewById(R.id.button_camera2);
imageview1= (ImageView) findViewById(R.id.iv);
mFilePath = Environment.getExternalStorageDirectory().getPath();//获取sd卡的路径
mFilePath = mFilePath+"/"+"temp.png";
button1.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
startActivityForResult(intent,REQ_1);
}
});
button2.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
Uri photoUri= Uri.fromFile(new File(mFilePath)); //这里使用android.net的uri
intent.putExtra(MediaStore.EXTRA_OUTPUT,photoUri); //完成系统拍照后存储路径的更改
startActivityForResult(intent,REQ_2);
}
});
}
/**
* 安卓系统考虑到data过大会造成溢出 所有intent返回的是一个缩略图
* @param requestCode
* @param resultCode
* @param data
*/
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == RESULT_OK){
if (requestCode==REQ_1){
Bundle bundle = data.getExtras();//bundle封装所有传递回来的数据
Bitmap bitmap = (Bitmap) bundle.get("data");//强制类型转换
imageview1.setImageBitmap(bitmap);
}else if (requestCode == REQ_2){//这里requestcode为REQ_2,解析图片
FileInputStream fis = null;
try {
fis = new FileInputStream(mFilePath);
Bitmap bitmap = BitmapFactory.decodeStream(fis);
imageview1.setImageBitmap(bitmap);//factory解析
} catch (FileNotFoundException e) {
e.printStackTrace();
}finally {
try {
fis.close();//关闭流
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
}
因为这里要进行读取SD卡,所以在Manifest中添加权限:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
如果运行报出警告:报出的警告是: Bitmap too large to be uploaded into a texture (440x6405, max=4096x4096):
经过查找资料是因为当开启硬件加速的时候,GPU对于openglRender 有一个限制,这个不同的手机会有不同的限制。
在Manifest中添加:
application android:hardwareAccelerated="false">把硬件加速设置为false
那么如何把自己的应用注册为一个相机应用,在intentfilter中添加:
<intent-filter>
<action android:name="android.media.action.IMAGE_CAPTURE" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>