调用android系统相机拍照并保存

叁歲伎倆 2022-08-08 05:15 156阅读 0赞

很好的一篇文章,仅供学习,转载地址:http://www.cnblogs.com/mengdd/archive/2013/03/31/2991932.html

通过Intent直接调用系统相机

  直接调用系统的相机应用,只需要在Intent对象中传入相应的参数即可,总体来说需要以下三步

  1. Compose a Camera Intent

  MediaStore.ACTION_IMAGE_CAPTURE 拍照;

  MediaStore.ACTION_VIDEO_CAPTURE录像。

  2. Start the Camera Intent

  使用startActivityForResult()方法,并传入上面的intent对象。

  之后,系统自带的相机应用就会启动,用户就可以用它来拍照或者录像。

  3. Receive the Intent Result

  用onActivityResult()接收传回的图像,当用户拍完照片或者录像,或者取消后,系统都会调用这个函数。

关于接收图像

  如果不设置接收图像的部分,拍照完毕后将会返回到原来的activity,相片会自动存储在拍照应用的默认存储位置。

  为了接收图像,需要做以下几个工作:

  1.指定图像的存储位置,一般图像都是存储在外部存储设备,即SD卡上。

  你可以考虑的标准的位置有以下两个:

  Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES)

  这个方法返回图像和视频的标准共享位置,别的应用也可以访问,如果你的应用被卸载了,这个路径下的文件是会保留的。

  为了区分,你可以在这个路径下为你的应用创建一个子文件夹。

  Context.getExternalFilesDir(Environment.DIRECTORY_PICTURES)

  这个方法返回的路径是和你的应用相关的一个存储图像和视频的方法。

  如果应用被卸载,这个路径下的东西全都会被删除。

  这个路径没有什么安全性限制,别的应用也可以自由访问里面的文件。

  2.为了接收intent的结果,需要覆写activity中的 onActivityResult() 方法。

  前面说过,可以不设置相机返回的图像结果的操作,此时在startActivityForResult()中不需要给intent传入额外的数据,这样在onActivityResult()回调时,返回的Intent data不为null,照片存在系统默认的图片存储路径下。

  但是如果想得到这个图像,你必须制定要存储的目标File,并且把它作为URI传给启动的intent,使用MediaStore.EXTRA_OUTPUT作为关键字。

  这样的话,拍摄出来的照片将会存在这个特殊指定的地方,此时没有thumbnail会被返回给activity的回调函数,所以接收到的Intent data为null。

程序实例

  附上程序代码,其中视频存储的返回结果部分没有写代码,视频拍摄后会存入系统应用的默认位置。

  1. 系统自带相机应用测试
  2. package com.example.hellocamera;
  3. import java.io.File;
  4. import java.text.SimpleDateFormat;
  5. import java.util.Date;
  6. import android.app.Activity;
  7. import android.content.Intent;
  8. import android.graphics.Bitmap;
  9. import android.graphics.BitmapFactory;
  10. import android.net.Uri;
  11. import android.os.Bundle;
  12. import android.os.Environment;
  13. import android.provider.MediaStore;
  14. import android.util.Log;
  15. import android.view.View;
  16. import android.view.View.OnClickListener;
  17. import android.widget.Button;
  18. import android.widget.ImageView;
  19. import android.widget.Toast;
  20. public class HelloCameraActivity extends Activity
  21. {
  22. private static final String LOG_TAG = "HelloCamera";
  23. private static final int CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE = 100;
  24. private static final int CAPTURE_VIDEO_ACTIVITY_REQUEST_CODE = 200;
  25. private Button takePicBtn = null;
  26. private Button takeVideoBtn = null;
  27. private ImageView imageView = null;
  28. private Uri fileUri;
  29. @Override
  30. public void onCreate(Bundle savedInstanceState)
  31. {
  32. Log.d(LOG_TAG, "onCreate");
  33. super.onCreate(savedInstanceState);
  34. setContentView(R.layout.activity_hello_camera);
  35. takePicBtn = (Button) findViewById(R.id.buttonPicture);
  36. takePicBtn.setOnClickListener(takePiClickListener);
  37. takeVideoBtn = (Button) findViewById(R.id.buttonVideo);
  38. takeVideoBtn.setOnClickListener(takeVideoClickListener);
  39. imageView = (ImageView) findViewById(R.id.imageView1);
  40. }
  41. private final OnClickListener takePiClickListener = new View.OnClickListener()
  42. {
  43. @Override
  44. public void onClick(View v)
  45. {
  46. Log.d(LOG_TAG, "Take Picture Button Click");
  47. // 利用系统自带的相机应用:拍照
  48. Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
  49. // create a file to save the image
  50. fileUri = getOutputMediaFileUri(MEDIA_TYPE_IMAGE);
  51. // 此处这句intent的值设置关系到后面的onActivityResult中会进入那个分支,即关系到data是否为null,如果此处指定,则后来的data为null
  52. // set the image file name
  53. intent.putExtra(MediaStore.EXTRA_OUTPUT, fileUri);
  54. startActivityForResult(intent, CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE);
  55. }
  56. };
  57. private final OnClickListener takeVideoClickListener = new View.OnClickListener()
  58. {
  59. @Override
  60. public void onClick(View v)
  61. {
  62. Log.d(LOG_TAG, "Take Video Button Click");
  63. // 摄像
  64. Intent intent = new Intent(MediaStore.ACTION_VIDEO_CAPTURE);
  65. // create a file to save the video
  66. fileUri = getOutputMediaFileUri(MEDIA_TYPE_VIDEO);
  67. // set the image file name
  68. intent.putExtra(MediaStore.EXTRA_OUTPUT, fileUri);
  69. // set the video image quality to high
  70. intent.putExtra(MediaStore.EXTRA_VIDEO_QUALITY, 1);
  71. startActivityForResult(intent, CAPTURE_VIDEO_ACTIVITY_REQUEST_CODE);
  72. }
  73. };
  74. public static final int MEDIA_TYPE_IMAGE = 1;
  75. public static final int MEDIA_TYPE_VIDEO = 2;
  76. /** Create a file Uri for saving an image or video */
  77. private static Uri getOutputMediaFileUri(int type)
  78. {
  79. return Uri.fromFile(getOutputMediaFile(type));
  80. }
  81. /** Create a File for saving an image or video */
  82. private static File getOutputMediaFile(int type)
  83. {
  84. // To be safe, you should check that the SDCard is mounted
  85. // using Environment.getExternalStorageState() before doing this.
  86. File mediaStorageDir = null;
  87. try
  88. {
  89. // This location works best if you want the created images to be
  90. // shared
  91. // between applications and persist after your app has been
  92. // uninstalled.
  93. mediaStorageDir = new File(
  94. Environment
  95. .getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES),
  96. "MyCameraApp");
  97. Log.d(LOG_TAG, "Successfully created mediaStorageDir: "
  98. + mediaStorageDir);
  99. }
  100. catch (Exception e)
  101. {
  102. e.printStackTrace();
  103. Log.d(LOG_TAG, "Error in Creating mediaStorageDir: "
  104. + mediaStorageDir);
  105. }
  106. // Create the storage directory if it does not exist
  107. if (!mediaStorageDir.exists())
  108. {
  109. if (!mediaStorageDir.mkdirs())
  110. {
  111. // 在SD卡上创建文件夹需要权限:
  112. // <uses-permission
  113. // android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
  114. Log.d(LOG_TAG,
  115. "failed to create directory, check if you have the WRITE_EXTERNAL_STORAGE permission");
  116. return null;
  117. }
  118. }
  119. // Create a media file name
  120. String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss")
  121. .format(new Date());
  122. File mediaFile;
  123. if (type == MEDIA_TYPE_IMAGE)
  124. {
  125. mediaFile = new File(mediaStorageDir.getPath() + File.separator
  126. + "IMG_" + timeStamp + ".jpg");
  127. }
  128. else if (type == MEDIA_TYPE_VIDEO)
  129. {
  130. mediaFile = new File(mediaStorageDir.getPath() + File.separator
  131. + "VID_" + timeStamp + ".mp4");
  132. }
  133. else
  134. {
  135. return null;
  136. }
  137. return mediaFile;
  138. }
  139. @Override
  140. protected void onActivityResult(int requestCode, int resultCode, Intent data)
  141. {
  142. super.onActivityResult(requestCode, resultCode, data);
  143. Log.d(LOG_TAG, "onActivityResult: requestCode: " + requestCode
  144. + ", resultCode: " + requestCode + ", data: " + data);
  145. // 如果是拍照
  146. if (CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE == requestCode)
  147. {
  148. Log.d(LOG_TAG, "CAPTURE_IMAGE");
  149. if (RESULT_OK == resultCode)
  150. {
  151. Log.d(LOG_TAG, "RESULT_OK");
  152. // Check if the result includes a thumbnail Bitmap
  153. if (data != null)
  154. {
  155. // 没有指定特定存储路径的时候
  156. Log.d(LOG_TAG,
  157. "data is NOT null, file on default position.");
  158. // 指定了存储路径的时候(intent.putExtra(MediaStore.EXTRA_OUTPUT,fileUri);)
  159. // Image captured and saved to fileUri specified in the
  160. // Intent
  161. Toast.makeText(this, "Image saved to:\n" + data.getData(),
  162. Toast.LENGTH_LONG).show();
  163. if (data.hasExtra("data"))
  164. {
  165. Bitmap thumbnail = data.getParcelableExtra("data");
  166. imageView.setImageBitmap(thumbnail);
  167. }
  168. }
  169. else
  170. {
  171. Log.d(LOG_TAG,
  172. "data IS null, file saved on target position.");
  173. // If there is no thumbnail image data, the image
  174. // will have been stored in the target output URI.
  175. // Resize the full image to fit in out image view.
  176. int width = imageView.getWidth();
  177. int height = imageView.getHeight();
  178. BitmapFactory.Options factoryOptions = new BitmapFactory.Options();
  179. factoryOptions.inJustDecodeBounds = true;
  180. BitmapFactory.decodeFile(fileUri.getPath(), factoryOptions);
  181. int imageWidth = factoryOptions.outWidth;
  182. int imageHeight = factoryOptions.outHeight;
  183. // Determine how much to scale down the image
  184. int scaleFactor = Math.min(imageWidth / width, imageHeight
  185. / height);
  186. // Decode the image file into a Bitmap sized to fill the
  187. // View
  188. factoryOptions.inJustDecodeBounds = false;
  189. factoryOptions.inSampleSize = scaleFactor;
  190. factoryOptions.inPurgeable = true;
  191. Bitmap bitmap = BitmapFactory.decodeFile(fileUri.getPath(),
  192. factoryOptions);
  193. imageView.setImageBitmap(bitmap);
  194. }
  195. }
  196. else if (resultCode == RESULT_CANCELED)
  197. {
  198. // User cancelled the image capture
  199. }
  200. else
  201. {
  202. // Image capture failed, advise user
  203. }
  204. }
  205. // 如果是录像
  206. if (requestCode == CAPTURE_VIDEO_ACTIVITY_REQUEST_CODE)
  207. {
  208. Log.d(LOG_TAG, "CAPTURE_VIDEO");
  209. if (resultCode == RESULT_OK)
  210. {
  211. }
  212. else if (resultCode == RESULT_CANCELED)
  213. {
  214. // User cancelled the video capture
  215. }
  216. else
  217. {
  218. // Video capture failed, advise user
  219. }
  220. }
  221. }
  222. }

发表评论

表情:
评论列表 (有 0 条评论,156人围观)

还没有评论,来说两句吧...

相关阅读

    相关 Android拍照保存

    1、拍照是在安卓开发中常用到的一个功能,所以需要熟练掌握 2、实现的功能是:拍照、保存到指定文件夹、照片可以命名 3、先获得读取文件夹的权限: <uses-per