100字范文,内容丰富有趣,生活中的好帮手!
100字范文 > Android studio实现调用相机实现拍照 录像 读取相册并展示在新的页面的功能

Android studio实现调用相机实现拍照 录像 读取相册并展示在新的页面的功能

时间:2019-05-18 02:43:12

相关推荐

Android studio实现调用相机实现拍照 录像 读取相册并展示在新的页面的功能

本篇文章代码实现的功能是调用手机自带的相机进行拍照、录像和读取相册的功能,并将照片或者视频在指定的页面展示的功能。

我的效果是第一页的布局会有拍照、录像、读取相册以及展示视频的选项。选择拍照或读取相册后,跳转到新的Intent进行操作并展示在ImageView中;选择录像会打开摄像头开始录像并保存在手机sd卡某一确定的缓存路径下;选择展示视频会展示这一确定的缓存路径下的视频文件。

下面是代码部分:

首先要对AndroidMainifest.xml进行设置,主要是存储权限的获得

<?xml version="1.0" encoding="utf-8"?><manifest xmlns:android="/apk/res/android"package="com.mapscanner.mapscanner"><uses-feature android:name="android.hardware.camera2"android:required="true" /><uses-permission android:name="android.permission.CAMERA" /><uses-feature android:name="android.hardware.camera" /><uses-feature android:name="android.hardware.camera.autofocus" /><uses-permission android:name="android.permission.FLASHLIGHT" /><uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /><uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /><uses-permission android:name="android.permission.INTERNET" /><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" /><action android:name="android.media.action.IMAGE_CAPTURE" /><category android:name="android.intent.category.LAUNCHER" /></intent-filter></activity><provider android:name="android.support.v4.content.FileProvider"android:authorities="com.MapScanner.MapScanner"android:exported="false"android:grantUriPermissions="true"><meta-dataandroid:name="android.support.FILE_PROVIDER_PATHS"android:resource="@xml/file_paths" /></provider><activity android:name=".Second_Activity" /><activity android:name=".Image_album_showActivity" /></application>12345678910111213141516171819222324252627282930313233343536373839404142434445

因为上面有一句android:resource=”@xml/file_paths”,是说在xml文件夹下定义了file_paths的值,所以我们 右键Resource new一个category取名为xml,会看到Resource下面出现了一个名为xml的文件夹,再右键文件夹选择new-> XML resource file,创建一个资源文件,并输入下面代码。

<?xml version="1.0" encoding="utf-8"?><paths xmlns:android="/apk/res/android"><external-path name="my_images" path="" /></paths>1234

下面首先看一下布局文件MainActivity.xml

<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="/apk/res/android"android:orientation="vertical"android:layout_width="match_parent"android:layout_height="match_parent"><Button android:id="@+id/take_photo"android:layout_width="match_parent"android:layout_height="wrap_content"android:text="Take Photos" /><Button android:id="@+id/take_video"android:layout_width="match_parent"android:layout_height="wrap_content"android:text="Take videos" /><Button android:id="@+id/choose_from_album"android:layout_width="match_parent"android:layout_height="wrap_content"android:text="Choose From Album" /><Button android:id="@+id/show_videos"android:layout_width="match_parent"android:layout_height="wrap_content"android:text="Show previous video" /></LinearLayout>12345678910111213141516171819222324252627282930

下面是MainActivity内的内容,主要实现摁键的跳转以及参数传递的功能

package com.mapscanner.mapscanner;import android.Manifest;import android.annotation.TargetApi;import android.app.Activity;import android.content.ContentUris;import android.content.Intent;import android.content.pm.PackageManager;import android.database.Cursor;import android.graphics.Bitmap;import android.graphics.BitmapFactory;import .Uri;import android.os.Build;import android.os.Bundle;import android.os.Environment;import android.provider.DocumentsContract;import android.provider.MediaStore;import android.support.annotation.NonNull;import android.support.v4.app.ActivityCompat;import android.support.v4.content.ContextCompat;import android.support.v4.content.FileProvider;import android.support.v7.app.AppCompatActivity;import android.util.Log;import android.view.View;import android.widget.Button;import android.widget.ImageView;import android.widget.MediaController;import android.widget.Toast;import android.widget.VideoView;import java.io.File;import java.io.IOException;public class MainActivity extends AppCompatActivity {public static final int TAKE_PHOTO = 1;public static final int CHOOSE_PHOTO = 2;/*用来记录录像存储路径*/File file = new File(Environment.getExternalStorageDirectory().getPath() + "/video.mp4");//设置录像存储路径Uri uri = Uri.fromFile(file);//文件转成Uri格式@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);Button takePhoto = (Button) findViewById(R.id.take_photo);Button chooseFromAlbum = (Button) findViewById(R.id.choose_from_album);Button takeVideo = (Button) findViewById(R.id.take_video);Button showVideo = (Button) findViewById(R.id.show_videos);//对照相功能的响应takePhoto.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {// 在新的Intent里面打开,并且传递TAKE_PHOTO选项Intent intent = new Intent();intent.setClass(MainActivity.this, Image_album_showActivity.class);//也可以这样写intent.setClass(MainActivity.this, OtherActivity.class);Bundle bundle = new Bundle();bundle.putInt("id", TAKE_PHOTO);//使用显式Intent传递参数,用以区分功能intent.putExtras(bundle);MainActivity.this.startActivity(intent);//启动新的Intent}});//设置相册选择的响应chooseFromAlbum.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {// 在新的Intent里面打开,并且传递CHOOSE_PHOTO选项Intent intent = new Intent();intent.setClass(MainActivity.this, Image_album_showActivity.class);//也可以这样写intent.setClass(MainActivity.this, OtherActivity.class);Bundle bundle = new Bundle();bundle.putInt("id", CHOOSE_PHOTO);intent.putExtras(bundle);MainActivity.this.startActivity(intent);}});//设置录像选择的响应takeVideo.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {// 保存录像到指定的路径// File file = new File("storage/sdcard1/video.mp4" );//设置录像存储路径try {if (file.exists()) {file.delete();}file.createNewFile();} catch (IOException e) {e.printStackTrace();}// 激活系统的照相机进行录像,通过Intent激活相机并实现录像功能Intent intent = new Intent();intent.setAction("android.media.action.VIDEO_CAPTURE");intent.addCategory("android.intent.category.DEFAULT");intent.putExtra(MediaStore.EXTRA_OUTPUT, uri);startActivityForResult(intent, 0);}});showVideo.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {//initVideoPath();Intent intent = new Intent();intent.setClass(MainActivity.this, Second_Activity.class);//也可以这样写intent.setClass(MainActivity.this, OtherActivity.class);MainActivity.this.startActivity(intent);setContentView(R.layout.activity_second_);}});}}12345678910111213141516171819222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118

接着点击包名new一下,选择Activity->Empty Activity生成一组配套的布局和类的文件,取名为image_album_show实现对拍照和读取相册的响应。

下面是对拍照和读取相册进行响应的布局文件Activity_image_album_show.xml

<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="/apk/res/android"xmlns:app="/apk/res-auto"android:orientation="vertical"xmlns:tools="/tools"android:layout_width="match_parent"android:layout_height="match_parent"tools:context=".Image_album_showActivity"><Button android:id="@+id/Return_Back_to_page1"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="Return to previous page" /><ImageView android:id="@+id/V_Image"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_gravity="center_horizontal"/></LinearLayout>1234567891011121314151617181922

下面是与Activity_image_album_show.xml配套的image_album_showActivity文件

package com.mapscanner.mapscanner;import android.Manifest;import android.annotation.TargetApi;import android.content.ContentUris;import android.content.Intent;import android.content.pm.PackageManager;import android.database.Cursor;import android.graphics.Bitmap;import android.graphics.BitmapFactory;import .Uri;import android.os.Build;import android.provider.DocumentsContract;import android.provider.MediaStore;import android.support.v4.app.ActivityCompat;import android.support.v4.content.ContextCompat;import android.support.v4.content.FileProvider;import android.support.v7.app.AppCompatActivity;import android.os.Bundle;import android.util.Log;import android.view.View;import android.widget.Button;import android.widget.ImageView;import android.widget.Toast;import java.io.File;import java.io.IOException;public class Image_album_showActivity extends AppCompatActivity {private ImageView picture;private Uri imageUri;private Button Return_page;public static final int TAKE_PHOTO = 1;public static final int CHOOSE_PHOTO = 2;//接受前一个Intent传入的idprivate Bundle bundle;private int Show_Choice;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_image_album_show);picture = (ImageView) findViewById(R.id.V_Image);Return_page=(Button)findViewById(R.id.Return_Back_to_page1);bundle = this.getIntent().getExtras();Show_Choice=bundle.getInt("id");Return_page.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {Intent intent= new Intent();intent.setClass(Image_album_showActivity.this, MainActivity.class);//也可以这样写intent.setClass(MainActivity.this, OtherActivity.class);startActivity(intent);}});//接收Intent传递的id值,并判断,照相功能为1,打开相册功能为2switch (Show_Choice){//如果传递为TAKE_PHOTOcase TAKE_PHOTO:{File outputImage = new File(getExternalCacheDir(), "output_image.jpg");try {if (outputImage.exists()) {outputImage.delete();}outputImage.createNewFile();} catch (IOException e) {e.printStackTrace();}//判断版本号if (Build.VERSION.SDK_INT < 24) {imageUri = Uri.fromFile(outputImage);} else {imageUri = FileProvider.getUriForFile(Image_album_showActivity.this, "com.MapScanner.MapScanner", outputImage);}// 启动相机程序Intent intent = new Intent("android.media.action.IMAGE_CAPTURE");intent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri);startActivityForResult(intent, 1);try {// 将拍摄的照片显示出来Bitmap bitmap = BitmapFactory.decodeStream(getContentResolver().openInputStream(imageUri));picture.setImageBitmap(bitmap);} catch (Exception e) {e.printStackTrace();}}break;//如果传递为CHOOSE_PHOTOcase CHOOSE_PHOTO:{//如果没有权限则申请权限if (ContextCompat.checkSelfPermission(Image_album_showActivity.this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {ActivityCompat.requestPermissions(Image_album_showActivity.this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 1);}//调用打开相册openAlbum();}default:break;}}private void openAlbum() {Intent intent = new Intent("android.intent.action.GET_CONTENT");intent.setType("image/*");startActivityForResult(intent, CHOOSE_PHOTO); // 打开相册}@Overridepublic void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {switch (requestCode) {case 1:if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {openAlbum();}else {Toast.makeText(this, "You denied the permission", Toast.LENGTH_SHORT).show();}break;default:break;}}@Overrideprotected void onActivityResult(int requestCode, int resultCode, Intent data) {switch (Show_Choice) {case 1:try {// 将拍摄的照片显示出来Bitmap bitmap = BitmapFactory.decodeStream(getContentResolver().openInputStream(imageUri));picture.setImageBitmap(bitmap);} catch (Exception e) {e.printStackTrace();}break;case 2:// 判断手机系统版本号if (Build.VERSION.SDK_INT >= 19) {// 4.4及以上系统使用这个方法处理图片handleImageOnKitKat(data);}else {// 4.4以下系统使用这个方法处理图片handleImageBeforeKitKat(data);}break;default:break;}}@TargetApi(19)private void handleImageOnKitKat(Intent data) {String imagePath = null;Uri uri = data.getData();Log.d("TAG", "handleImageOnKitKat: uri is " + uri);if (DocumentsContract.isDocumentUri(this, uri)) {// 如果是document类型的Uri,则通过document id处理String docId = DocumentsContract.getDocumentId(uri);if("com.android.providers.media.documents".equals(uri.getAuthority())) {String id = docId.split(":")[1]; // 解析出数字格式的idString selection = MediaStore.Images.Media._ID + "=" + id;imagePath = getImagePath(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, selection);}else if ("com.android.providers.downloads.documents".equals(uri.getAuthority())) {Uri contentUri = ContentUris.withAppendedId(Uri.parse("content://downloads/public_downloads"), Long.valueOf(docId));imagePath = getImagePath(contentUri, null);}}else if ("content".equalsIgnoreCase(uri.getScheme())) {// 如果是content类型的Uri,则使用普通方式处理imagePath = getImagePath(uri, null);}else if ("file".equalsIgnoreCase(uri.getScheme())) {// 如果是file类型的Uri,直接获取图片路径即可imagePath = uri.getPath();}displayImage(imagePath); // 根据图片路径显示图片}private void handleImageBeforeKitKat(Intent data) {Uri uri = data.getData();String imagePath = getImagePath(uri, null);displayImage(imagePath);}private String getImagePath(Uri uri, String selection) {String path = null;// 通过Uri和selection来获取真实的图片路径Cursor cursor = getContentResolver().query(uri, null, selection, null, null);if (cursor != null) {if (cursor.moveToFirst()) {path = cursor.getString(cursor.getColumnIndex(MediaStore.Images.Media.DATA));}cursor.close();}return path;}private void displayImage(String imagePath) {if (imagePath != null) {Bitmap bitmap = BitmapFactory.decodeFile(imagePath);picture.setImageBitmap(bitmap);}else {Toast.makeText(this, "failed to get image", Toast.LENGTH_SHORT).show();}}}123456789101112131415161718192223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920002203204205206207208209210211212

下面再新建一个Activity->EmptyActivity用于对视频的展示,我取名为Second_Activity,设置了一个button用于返回前一个activity以及用于视频展示的videoview控件。

还是先看一下布局文件activit_second_.xml

<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="/apk/res/android"xmlns:app="/apk/res-auto"android:orientation="vertical"xmlns:tools="/tools"android:layout_width="match_parent"android:layout_height="match_parent"tools:context=".Second_Activity"><Button android:id="@+id/Return_Back"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="Return to previous page" /><VideoView android:id="@+id/V_video"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_gravity="center_horizontal"/></LinearLayout>1234567891011121314151617181922

下面是Second_Activity中的内容

package com.mapscanner.mapscanner;import android.Manifest;import android.content.Intent;import android.content.pm.PackageManager;import .Uri;import android.os.Environment;import android.support.v4.app.ActivityCompat;import android.support.v4.content.ContextCompat;import android.support.v7.app.AppCompatActivity;import android.os.Bundle;import android.view.View;import android.widget.Button;import android.widget.MediaController;import android.widget.Toast;import android.widget.VideoView;import java.io.File;public class Second_Activity extends AppCompatActivity {private VideoView mVideo;private Button Turn_back;File file = new File(Environment.getExternalStorageDirectory().getPath()+"/video.mp4" );//设置录像存储路径Uri uri = Uri.fromFile(file);//文件转成Uri格式@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_second_);Turn_back=(Button)findViewById(R.id.Return_Back);mVideo=(VideoView)findViewById(R.id.V_video);initVideoPath();Turn_back.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {Intent intent= new Intent();intent.setClass(Second_Activity.this, MainActivity.class);//也可以这样写intent.setClass(MainActivity.this, OtherActivity.class);startActivity(intent);}});}private void initVideoPath() {if (ContextCompat.checkSelfPermission(Second_Activity.this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {ActivityCompat.requestPermissions(Second_Activity.this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 1);}Toast.makeText(this, "have found video", Toast.LENGTH_SHORT).show();mVideo.setVideoURI(uri);mVideo.setVideoPath(file.getAbsolutePath());MediaController mediaController=new MediaController(this);mVideo.setMediaController(mediaController);mediaController.setMediaPlayer(mVideo);mVideo.requestFocus();mVideo.start();}}123456789101112131415161718192223242526272829303132333435363738394041424344454647484950515253545556

以上代码主要借鉴与《第一行代码》以及网上的一些实例,在理解后进行了综合的应用,解决了我需要的功能,值得一提的是,本实例调用的相机是利用Intent对本机的相机进行了捕获从而实现媒体设备的使用功能,还有一种实现方法是调用camera库实现此功能。我在其它文章会介绍camera的使用以及如何通过Socket实现实时视频的传输。

最后附上自己总结的一些经验,因为我都是用真机测试程序,有时会出现程序打不开闪退的现象,总结后主要有:

1、可能未获得权限,比如使用媒体设备,比如读取内存都需要获得权限,如果未获得权限就会闪退。

2、当跳转到一个新的页面时,都会有setContentView(R.layout.xxxxx_);

而对于button等的响应需要用到xxx=(Button)findViewById(R.id.xxx); findViewById必须放在setContentView后面,否则会找不到此按钮而闪退。

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。