学向勤中得,萤窗万卷书。这篇文章主要讲述Android中通过访问本地相册或者相机设置用户头像相关的知识,希望能为你提供帮助。
目前几乎所有的APP在用户注册时都会有设置头像的需求,大致分为三种情况:
(1)通过获取本地相册的图片,经过裁剪后作为头像。
(2)通过启动手机相机,现拍图片然后裁剪作为头像。
(3)在APP中添加一些自带的头像资源,供用户选择(不够人性化,目前很少使用)。
这次我们简单介绍下通过获取本地相册以及相机拍摄的方法设置头像,实现思路如下:
(1)通过startActivityForResult方法,分别传递调用系统相册的Intent和调用相机拍照的Intent来做选择
(2)调用android系统中自带的图片剪裁,实现图片的剪裁并在onActivityResult方法中获取数据。
关于如何处理Activity的返回结果,请参照往期博文《Android中Activity处理返回结果的实现方式》。
本次演示效果如下(分别为从本地相册获取以及从相机拍摄获取头像):
文章图片
文章图片
简单布局文件这里不再做赘述,本次试验使用隐式intent调用相机以及本地相册,未在配置清单上添加权限,依然可以调用。java实现代码如下:
1 import android.content.Intent; 2 import android.graphics.Bitmap; 3 import android.net.Uri; 4 import android.os.Bundle; 5 import android.os.Environment; 6 import android.provider.MediaStore; 7 import android.support.v7.app.AppCompatActivity; 8 import android.view.View; 9 import android.widget.Button; 10 import android.widget.ImageView; 11 import android.widget.Toast; 12 import java.io.File; 13 14 public class MainActivity extends AppCompatActivity implements View.OnClickListener { 15private Button buttonLocal, buttonCamera; 16private ImageView imageView; 17//相机拍摄的头像文件(本次演示存放在SD卡根目录下) 18private static final File USER_ICON = new File(Environment.getExternalStorageDirectory(), "user_icon.jpg"); 19//请求识别码(分别为本地相册、相机、图片裁剪) 20private static final int CODE_PHOTO_REQUEST = 1; 21private static final int CODE_CAMERA_REQUEST = 2; 22private static final int CODE_PHOTO_CLIP = 3; 23@Override 24protected void onCreate(Bundle savedInstanceState) { 25super.onCreate(savedInstanceState); 26setContentView(R.layout.activity_main); 27buttonLocal = (Button) findViewById(R.id.buttonLocal); 28buttonCamera = (Button) findViewById(R.id.buttonCamera); 29imageView = (ImageView) findViewById(R.id.imageView); 30buttonLocal.setOnClickListener(this); 31buttonCamera.setOnClickListener(this); 32} 33//设置点击事件 34@Override 35public void onClick(View view) { 36switch (view.getId()) { 37case R.id.buttonLocal: 38//调用获取本地图片的方法 39getPicFromLocal(); 40break; 41case R.id.buttonCamera: 42//调用相机拍照的方法 43getPicFromCamera(); 44break; 45default: 46break; 47} 48} 49/** 50* 从本机相册获取图片 51*/ 52private void getPicFromLocal() { 53Intent intent = new Intent(); 54// 获取本地相册方法一 55intent.setAction(Intent.ACTION_GET_CONTENT); 56intent.setType("image/*"); 57//获取本地相册方法二 58 //intent.setAction(Intent.ACTION_PICK); 59 //intent.setDataAndType(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, 60 //"image/*"); 61startActivityForResult(intent, CODE_PHOTO_REQUEST); 62} 63/** 64* 通过相机拍摄获取图片, 65* 并存入设置的路径中 66*/ 67private void getPicFromCamera() { 68Intent intent = new Intent(); 69intent.setAction(MediaStore.ACTION_IMAGE_CAPTURE); 70// 下面这句指定调用相机拍照后的照片存储的路径 71intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(USER_ICON)); 72startActivityForResult(intent, CODE_CAMERA_REQUEST); 73} 74/** 75* 图片裁剪 76* 77* @param uri 78*/ 79private void photoClip(Uri uri) { 80// 调用系统中自带的图片剪裁 81Intent intent = new Intent(); 82intent.setAction("com.android.camera.action.CROP"); 83intent.setDataAndType(uri, "image/*"); 84// 下面这个crop=true是设置在开启的Intent中设置显示的VIEW可裁剪 85intent.putExtra("crop", "true"); 86// aspectX aspectY 是宽高的比例 87intent.putExtra("aspectX", 1); 88intent.putExtra("aspectY", 1); 89/*outputX outputY 是裁剪图片宽高 90*这里仅仅是头像展示,不建议将值设置过高 91* 否则超过binder机制的缓存大小的1M限制 92* 报TransactionTooLargeException 93*/ 94intent.putExtra("outputX", 150); 95intent.putExtra("outputY", 150); 96intent.putExtra("return-data", true); 97startActivityForResult(intent, CODE_PHOTO_CLIP); 98} 99/** 100* 提取保存裁剪之后的图片数据,并设置头像部分的View 101*/ 102private void setImageToHeadView(Intent intent) { 103Bundle extras = intent.getExtras(); 104if (extras != null) { 105Bitmap photo = extras.getParcelable("data"); 106imageView.setImageBitmap(photo); 107} 108} 109@Override 110protected void onActivityResult(int requestCode, int resultCode, Intent data) { 111// 用户没有进行有效的设置操作,返回 112if (resultCode == RESULT_CANCELED) { 113Toast.makeText(MainActivity.this, "取消", Toast.LENGTH_LONG).show(); 114return; 115} 116switch (requestCode) { 117case CODE_CAMERA_REQUEST: 118if (USER_ICON.exists()) { 119photoClip(Uri.fromFile(USER_ICON)); 120} 121break; 122case CODE_PHOTO_REQUEST: 123if (data != null) { 124photoClip(data.getData()); 125} 126break; 127case CODE_PHOTO_CLIP: 128if (data != null) { 129setImageToHeadView(data); 130} 131break; 132} 133super.onActivityResult(requestCode, resultCode, data); 134} 135 }
【Android中通过访问本地相册或者相机设置用户头像】这里要注意的是在裁剪图片时,长和宽不要设置太大,否则超过binder机制的缓存大小的限制(受手机配置影响).报TransactionTooLargeException,在代码中已经做了详细标注,请各位看官在实现的时候万万注意。
推荐阅读
- Ubuntu下Android Studio安装配置和使用
- AndroidStudio Gradle版本不匹配问题
- Android开发之视频播放调用setVideoPath()方法
- VS2015下的Android开发系列01——开发环境配置及注意事项
- Android openGL ES 2.0里Surfaceview背景透明
- android textview段落开头空格问题
- android:layout_gravity和android:gravity的区别
- Android 性能优化(使用 Lint 优化代码去除多余资源)
- Android实现录屏直播ScreenRecorder的简单分析