对于现在的手机应用而言,要想获得更多的人的使用,就需要给用户更多的自由功能才行,这也是基于用户体验开发软件的核心思想,一切以用户为中心,想用户之所想,做用户之所需。今天我就来谈一谈刚学到的一个关于设置用户头像的小技巧。
可行性分析
要想实现设置自定义的头像功能,我们通常来说会有两种选择,那就是拍照或者从手机图库里面获取。今天就来讲一讲,这两种方式实现的细节的地方。
- 首先是拍照实现:原理上将,最简单的实现就是调用系统自带的照相机。这样最为省事嘛。当然了,您也可以通过使用自己开发的一个照相应用来实现这一功能(可以参考我之前的这篇文章做自己的安卓拍照应用,其实很简单)。但是这里并不建议您这样做,毕竟重复造轮子是没有任何意义的嘛,更何况自己实现的应用还不一定有人家系统自带的好使呢。
- 然后是从本地的图库中选取一张图片来作为结果使用。这样最为方便,因为大部分的用户会使用图库中的图片滴。但是这种方式灵活性较差,因为用户很有可能只想上传自己的自拍照片。这样的话,我们就需要实现上面的那个功能了。
我的Demo
首先是布局文件,这里仅仅是两个按钮(分别用于实现上面的两种方式),和一个用于显示图层的ImageView。仅此而已。所以就不在此列出代码了。
然后是Java代码,这里就贴出来吧,方便大家浏览。
package com.example.intenttest;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import android.app.Activity;
import android.content.ContentResolver;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
public class MainActivity extends Activity {
private Button btn_capture;
private Button btn_getPicture;
private ImageView imageView;
public void init() {
btn_capture = (Button) findViewById(R.id.btn_capture);
btn_getPicture = (Button) findViewById(R.id.btn_choose);
imageView = (ImageView) findViewById(R.id.imageview);
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
init();
}
/**
* 调用系统的拍照
* @param view
*/
public void beginCapture(View view) {
Intent intent = new Intent(
android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
startActivityForResult(intent, 1001);
}
/**
* 从手机的本地图库中选择一张图片作为头像资源
* @param view
*/
public void getPicture(View view) {
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
intent.setType("image/*");
intent.putExtra("crop", true);
intent.putExtra("return-data", true);
startActivityForResult(intent, 1002);
}
/**
* 将上面的Intent中的返回的结果分别显示到相关的ImageView上
*/
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
//调用系统相机,获得照片资源,选要注意的是这里的data 是存在于内存中的
if (requestCode == 1001 && resultCode == RESULT_OK) {
Bundle bundle = data.getExtras();
Bitmap bitmap = (Bitmap) bundle.get("data");
imageView.setImageBitmap(bitmap);
}
//使用图库资源,以ContentProvider的方式来实现
if (requestCode == 1002 && resultCode == RESULT_OK) {
InputStream is = null;
try {
Uri uri = data.getData();
ContentResolver resolver = getContentResolver();
is = resolver.openInputStream(uri);
Bitmap bitmap = BitmapFactory.decodeStream(is);
imageView.setImageBitmap(bitmap);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally {
if(is!=null) {
try {
is.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
is = null;
}
}
}
}
}
代码实现原理详解
首先是第一种方式,我们可以看到如下核心代码:
Intent intent = new Intent(
android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
startActivityForResult(intent, 1001);
以及:
//调用系统相机,获得照片资源,选要注意的是这里的data 是存在于内存中的
if (requestCode == 1001 && resultCode == RESULT_OK) {
Bundle bundle = data.getExtras();
Bitmap bitmap = (Bitmap) bundle.get("data");
imageView.setImageBitmap(bitmap);
}
这样做的核心就在于那个Intent了,其指定了是从android.provider.MediaStore.ACTION_IMAGE_CAPTURE,这样就可以在onActivityResult方法中将处理的结果通过转换成一个位图的方式设置到ImageView上,实现用户头像设置。
然后是第二种方式,
/**
* 从手机的本地图库中选择一张图片作为头像资源
* @param view
*/
public void getPicture(View view) {
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
intent.setType("image/*");
intent.putExtra("crop", true);
intent.putExtra("return-data", true);
startActivityForResult(intent, 1002);
}
//使用图库资源,以ContentProvider的方式来实现
if (requestCode == 1002 && resultCode == RESULT_OK) {
InputStream is = null;
try {
Uri uri = data.getData();
ContentResolver resolver = getContentResolver();
is = resolver.openInputStream(uri);
Bitmap bitmap = BitmapFactory.decodeStream(is);
imageView.setImageBitmap(bitmap);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally {
if(is!=null) {
try {
is.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
is = null;
}
}
}
这里是借助于ContentProvider,来获取共享的资源。借助于getContentProvider()方法,然后得到一个目标图片的输入流,转换成位图,最后设置到我们的ImageView上,这样同样可以实现我们的头像设置功能。
总结
今天的这个小技巧,虽然很简单,但是实用性还是很高的。我们在日常的额开发过程中遇到的额可能不是简单的直接在本地实现头像的额更换,但是我们可以再一个Service中来实现上传的功能,借助于流的形式,原理上市相似的。
对于代码,如果您发现了一些问题,欢迎批评指正。