1、先写xml界面代码如下:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent"> <Button android:id="@+id/take_photo" android:text="拍照" android:layout_width="match_parent" android:layout_height="wrap_content" /> <ImageView android:id="@+id/picture" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center_horizontal"/> </LinearLayout>
放了两个控件,一个用来拍照,一个用来显示照片。
2、MainActivity代码如下:
public class MainActivity extends AppCompatActivity { public static final int TAKE_PHOTO=1; private ImageView picture; private Uri ImageUri; private Button takePhoto; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); takePhoto= (Button) findViewById(R.id.take_photo); takePhoto.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { //创建File对象,用于存储拍照后的图片 File outputImage=new File(getExternalCacheDir(),"outputImage.jpg"); try { if (outputImage.exists()){ outputImage.delete(); } outputImage.createNewFile(); } catch (IOException e) { e.printStackTrace(); } if (Build.VERSION.SDK_INT>=24){ ImageUri= FileProvider.getUriForFile(MainActivity.this, "com.example.camerralbumtest.fileprovider",outputImage); }else { ImageUri=Uri.fromFile(outputImage); } //启动相机程序 Intent intent=new Intent("android.media.action.IMAGE_CAPTURE"); intent.putExtra(MediaStore.EXTRA_OUTPUT,ImageUri); startActivityForResult(intent,TAKE_PHOTO); } }); } @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { switch (requestCode){ case TAKE_PHOTO: if (resultCode==RESULT_OK){ try { //将拍摄的照片显示出来 Bitmap bitmap= BitmapFactory.decodeStream(getContentResolver().openInputStream(ImageUri)); picture.setImageBitmap(bitmap); } catch (FileNotFoundException e) { e.printStackTrace(); } } break; default: break; } } }
i:先绑定两个控件,
ii:在拍照的时候,创建了一个File对象outputImage,用于存放摄像头拍下的照片命名为:output_image.jpg 。getExteralCacheDir是指把照片存放在手机SD卡的应用关联缓存目录下面。具体路径是/sdcard/Android/data/<package name>/cache。
iii:进行判断,如果outputImage文件已经存在,则把它删除,不存在,则创建这样一个文件。
iv:再进行判断,若手机版本低于Android7.0 ,就调用Uri的fromFile()方法将File对象outputImage转换成Uri对象,这个Uri对象标识着output_iamge.jpg这张真实照片的本地真实路径;若手机版本高于7.0,也就是sdk大于等于24时,就调用FileProvider的getUriForFile()方法将File对象outputImage转换成一个封装过的Uri对象,getUriForFile()方法接收3个参数,第一个时上下文,第二个是任意唯一的字符串,第三个是是我们创建的File对象outputImage。
v:启动相机程序,构建Intent,将intent的动作指定为IMAGE_CAPTURE,再调用putExtra方法指定图片的输出地址,这里填入刚刚得到的uri对象。最后调用startActivityForResult来启动活动。
vi:刚才我们开启活动使用的是startActivityForResult,因此拍照结束后会有结果返回到onActivityResult()方法中,因此要重写这个方法。
vii:若发现拍照成功,就可以调用BitmapFactory的decodeStream方法将output_image.jpg这张图片解析成Bitmap对象,然后把它设置到ImageView中显示出来。
3、前面提到若手机版本大于7.0时,我们用到了内容提供器FileProvider,因此需要在Manifest文件中注册一下,代码如下:
<provider android:authorities="com.example.camerralbumtest.fileprovider" android:name="android.support.v4.content.FileProvider" android:exported="false" android:grantUriPermissions="true"> <meta-data android:name="android.support.FILE_PROVIDER_PATHS" android:resource="@xml/file_paths"/> </provider>
这里,android:name是固定的,android:authorities属性的值就是我们之前写的getUriForFile方法的第二个参数,还需要在<provider>标签内部使用<meta-data>用来指定Uri的共享路径,并引用了一个我们创建好的file_path的xml界面。界面代码如下:
<?xml version="1.0" encoding="utf-8"?> <paths xmlns:android="http://schemas.android.com/apk/res/android"> <external-path name="my_images" path=""/> </paths>
<external-path name="my_images" path=""/>
上面这一句就是用来指定Uri共享的,name属性值随便填,path属性的值表示共享的具体路径,这里设置为空值表示整个SD卡共享。
4、访问SD卡是需要权限的,因此记得在Manifest文件中加入权限如下:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>这样就全部完成啦,快来启动吧。