您的位置:首页 > 移动开发 > Android开发

android选择图片得到实际路径的总结

2015-12-14 18:28 585 查看
项目中有个需求,通过拍照或者选取系统图片后,显示到控件上,并且要得到图片的实际路径。

自己用的是华为手机,4.0系统。发现选取图片,有2个不同的选项,分别是“图库”和“文件管理”,如下图所示



1、通过系统拍照,得到的uri地址是

file:///mnt/sdcard/DCIM/camera/faceImage.JPEG


2、通过文件管理器,得到的uri地址是

file:///mnt/sdcard/20140724181622520977.jpg


3、通过图库,得到的图片uri地址是

content://media/external/images/media/888737


我们发现,得到图片的地址有2种类型,以file开头和content开头的,但是以content开头的,没有路径,只有图片编号的uri.这就导致接下来无法根据图片实际路径,

所以需要要一个方法,把content的变成实际真实文件路径,加上一个方法如下即可

private String getRealPathFromURI(Uri contentUri) { //传入图片uri地址
String[] proj = { MediaStore.Images.Media.DATA };
CursorLoader loader = new CursorLoader(getActivity(), contentUri, proj, null, null, null);
Cursor cursor = loader.loadInBackground();
int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
cursor.moveToFirst();
return cursor.getString(column_index);
}
前后的结果如下,可以看到我们通过这个方法得到了图片的真实路径



总结,在获取图片路径时候,要先判断uri字符串是否包含 content ,如果有的话,就要转换。如果以file开头的,就不管它

String textPre=uri.toString();//得到图片uri地址字符串
//图片文件的路径 ,有2种格式
//华为手机从图库选择的结果 ,以content开头
//content://media/external/images/media/888737

//华为手机从文件选择器的结果,或者系统拍照也是如下的结果,以file开头
//  file:///mnt/sdcard2/%E7%A8%8B%E5%BA%8F%E5%91%98%E6%97%A5%E5%B8%B8.jpg

System.out.println("转换前的地址是 :   "+textPre);

if(uri.toString().contains("content://")){ //如果包含有content开头,需要转化为其实际路径,不能用content开头
text=getRealPathFromURI(uri);
}else{
text=textPre;       //如果用file开头,不用转化
}

System.out.println("转换后的地址是 :   "+text);
headPicName=text.substring(text.lastIndexOf("/")+1);//保存图片的文件名,注意索引加1
System.out.println("选取图片的地址是:  "+headPicName);


最后附上自己一个源代码,是上一篇的更新

package com.qinghui.sslq.fragment;

import java.io.File;
import java.io.FileOutputStream;
import java.util.HashMap;
import java.util.Map;

import com.lidroid.xutils.ViewUtils;
import com.lidroid.xutils.view.annotation.ViewInject;
import com.qinghui.sslq.R;
import com.qinghui.sslq.activity.LoginActivity;
import com.qinghui.sslq.activity.ShowContentActivity;
import com.qinghui.sslq.entity.Detail;
import com.qinghui.sslq.util.CommonUtil;
import com.qinghui.sslq.util.NetWebServiceUtil;
import com.qinghui.sslq.util.PromptUtil;
import com.qinghui.sslq.util.ScreenManager;
import com.qinghui.sslq.util.NetWebServiceUtil.WebServiceCallBack;
import com.qinghui.sslq.util.XmlPullManager;
import com.qinghui.sslq.view.SelectPicPopupWindow;

import android.app.ActionBar;
import android.app.AlertDialog;
import android.app.Dialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.Bitmap.CompressFormat;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.provider.MediaStore;
import android.support.v4.content.CursorLoader;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.PopupWindow;
import android.widget.RelativeLayout;
import android.widget.TextView;
import android.widget.Toast;

public class PersonListFragment extends BaseFragment implements OnClickListener {

private View view;
private Bundle bundle;

private String headPicName;

@ViewInject(R.id.leftIcon)
private TextView leftIcon; // 标题栏右面的文字
@ViewInject(R.id.titleText)
private TextView titleText;// 标题栏中心的文字

@ViewInject(R.id.userName)
private TextView userName; //用户名

@ViewInject(R.id.gender)
private TextView gender; //性别

@ViewInject(R.id.phoneNumber)   //电话
private TextView phoneNumber;

@ViewInject(R.id.change_userheadimg)     //修改头像
private RelativeLayout change_userheadimg;

@ViewInject(R.id.useHelp)
private RelativeLayout useHelp; //使用帮助
@ViewInject(R.id.changeGender)
private RelativeLayout changeGender; //修改性别

@ViewInject(R.id.change_userPassword) //修改密码
private RelativeLayout change_userPassword;

@ViewInject(R.id.messageNotify) //消息提醒
private RelativeLayout messageNotify;

@ViewInject(R.id.changeUserName) //消息提醒
private RelativeLayout changeUserName;

@ViewInject(R.id.updateVersion) //版本更新
private RelativeLayout updateVersion;

@ViewInject(R.id.loginCurrent) //退出登录
private RelativeLayout loginCurrent;

@ViewInject(R.id.modifyPhoneNum)
private RelativeLayout modifyPhoneNum; //修改绑定手机

private PopupWindow popupWindow;
private Detail detail;
protected String genderId;
private static final String IMAGE_FILE_NAME = "faceImage.JPEG";

private static final int CAMERA_REQUEST_CODE = 2;
private static final int IMAGE_REQUEST_CODE = 1;
private static final int RESULT_REQUEST_CODE = 3;

private Bitmap photo;// 暂存图片

@ViewInject(R.id.userimg)
private ImageView userimg; // 头像
private File f;

protected View createView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {

view=View.inflate(getActivity(), R.layout.fragment_personlist, null);
ViewUtils.inject(this, view);
initViews();//初始化控件,设置自己的内容信息
initData();
return view;
}

private void initViews() {
leftIcon.setVisibility(View.INVISIBLE);
titleText.setText("个人中心");
bundle=getArguments();
detail=(Detail) bundle.getSerializable("detailObjcet");
System.out.println("第2次打印实体"+detail);

if(detail!=null){
userName.setText(detail.getLogin().getAccount_name());//设置名字
if(detail.getLogin().getAccount_sex()==1){ //设置性别
gender.setText("男");
}else{
gender.setText("女");
}
phoneNumber.setText(detail.getLogin().getAccount_mobile());//设置电话
}

f = new File(Environment.getExternalStorageDirectory().getAbsolutePath() + "/" +"head_pic.jpg");

if(f.exists()){
userimg.setImageURI(Uri.fromFile(f));
}else{
userimg.setImageResource(R.drawable.ic_launcher);
}

}

private void initData() {
change_userheadimg.setOnClickListener(this);
//useHelp.setOnClickListener(this);
change_userPassword.setOnClickListener(this);
changeUserName.setOnClickListener(this);
//messageNotify.setOnClickListener(this);
//updateVersion.setOnClickListener(this);
loginCurrent.setOnClickListener(this);
changeGender.setOnClickListener(this);
//modifyPhoneNum.setOnClickListener(this);
}

@Override
public void onClick(View view) {

int id =view.getId();
switch (id ) {
case R.id.change_userheadimg:
//切换头像的弹出窗口
popupWindow=new SelectPicPopupWindow(getActivity(), itemsOnClick);
popupWindow.showAtLocation(getActivity().findViewById(android.R.id.tabs),
Gravity.BOTTOM, 0, 0);

break;

case R.id.changeGender:
//修改性别

final String[] genders=getResources().getStringArray(R.array.gender);
new AlertDialog.Builder(getActivity())
.setTitle("修改您的性别")
.setItems(R.array.gender, new DialogInterface.OnClickListener() {
/**当点击对话框的列表项时,回调该方法
* dialog:AlertDialog
* which:你点了哪一个列表项
*/
@Override
public void onClick(DialogInterface dialog, int which) {
gender.setText(genders[which]);
genderId=changeGenderToId(genders[which]);
//	发送网络请求修改性别

Map<String, Object> map = new HashMap<String, Object>();
map.put("ACCOUNT_CODE",detail.getLogin().getAccount_code());
map.put("ACCOUNT_NAME",userName.getText().toString().trim());
map.put("ACCOUNT_SEX", genderId);

final Dialog pDialog=  PromptUtil.showProgressDialog(getActivity());
try {
NetWebServiceUtil.doSoapRequest("/service/PersonalCenterWebservice","modifyPersonal","MODIFY", map, new WebServiceCallBack() {

@Override
public void callBack(String result) {
PromptUtil.closeProgressDialog(pDialog);
if(result!=null){

if(XmlPullManager.parseOneXml(result).getResult()==1){
PromptUtil.toast(getActivity(),"修改成功");
}else if(XmlPullManager.parseOneXml(result).getResult()==2){
PromptUtil.toast(getActivity(),"用户名不存在");

}else{
PromptUtil.toast(getActivity(),"修改失败");
}

}else{
PromptUtil.toast(getActivity(),"服务端数据错误");
}
}
});
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}

private String changeGenderToId(String string) {
// TODO Auto-generated method stub
if(string.equals("男")){
return "1";
}else{
return "2";
}
}
})
.create()
.show();

break;
case R.id.useHelp:
//使用帮助
break;

case R.id.changeUserName:
//修改用户名

//使用自定义的对话框
final Dialog dialog=new Dialog(getActivity(),R.style.MyDialogTheme);//创建对话框对象
//设置内容视图,重新布局一个新的
dialog.setContentView(R.layout.diy_change_name_dialog);
//通过父控件获取自定义对话框的确定按钮控件
Button button=(Button) dialog.findViewById(R.id.confirm);
//对按钮设置点击监听事件
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//输出用户输入的类型信息
EditText edit =(EditText) dialog.findViewById(R.id.newAcountName);

String name_txt=edit.getText().toString().trim();
userName.setText(name_txt);
String genderID = changeGenderToId(gender.getText().toString());

//	发送网络请求修改性别

Map<String, Object> map = new HashMap<String, Object>();
map.put("ACCOUNT_CODE",detail.getLogin().getAccount_code());
map.put("ACCOUNT_NAME",name_txt);
map.put("ACCOUNT_SEX", genderID);

final Dialog pDialog=  PromptUtil.showProgressDialog(getActivity());
try {
NetWebServiceUtil.doSoapRequest("/service/PersonalCenterWebservice","modifyPersonal","MODIFY", map, new WebServiceCallBack() {

@Override
public void callBack(String result) {

PromptUtil.closeProgressDialog(pDialog);
if(result!=null){

if(XmlPullManager.parseOneXml(result).getResult()==1){
PromptUtil.toast(getActivity(),"修改成功");
}else if(XmlPullManager.parseOneXml(result).getResult()==2){
PromptUtil.toast(getActivity(),"用户名不存在");

}else{
PromptUtil.toast(getActivity(),"修改失败");
}

}else{
PromptUtil.toast(getActivity(),"服务端数据错误");
}

}
});
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

dialog.dismiss();//消失,解雇
}

private String changeGenderToId(String string) {
// TODO Auto-generated method stub
if(string.equals("男")){
return "1";
}else{
return "2";
}
}
});
dialog.show();//显示对话框 ,当点击Dialog对象,默认不会消失

break;

case R.id.modifyPhoneNum:
//修改绑定手机
System.out.println("修改绑定手机");

break;

case R.id.change_userPassword:
//修改密码
Intent intent=new Intent(getActivity(), ShowContentActivity.class);
bundle.putString("start_tag", "change_password");
intent.putExtras(bundle);
startActivity(intent);
break;

case R.id.updateVersion:
//版本更新
break;

case R.id.loginCurrent:
//退出登录
PromptUtil.ExitSystem(getActivity());
//	Intent intent=new Intent(getActivity(), LoginActivity.class);
//	startActivity(intent);
break;

default:
break;
}

}
//这里面的是popupWindow里面的点击事件
private OnClickListener itemsOnClick = new OnClickListener() {
public void onClick(View v) {
//销毁popup窗口
popupWindow.dismiss();

switch (v.getId()) {

case R.id.btn_pick_photo:
//	Toast.makeText(getActivity(), "这个是选择图片", 1).show();

Intent intentFromGallery = new Intent(Intent.ACTION_GET_CONTENT);
intentFromGallery.addCategory(Intent.CATEGORY_OPENABLE);
intentFromGallery.setType("image/**"); // 设置文件类型
startActivityForResult(intentFromGallery, IMAGE_REQUEST_CODE);
break;

case R.id.btn_take_photo:
//	Toast.makeText(getActivity(), "这个是拍图片", 1).show();
Intent intentFromCapture = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
try {
File file = new File(Environment.getExternalStorageDirectory()
+ "/DCIM/camera/", IMAGE_FILE_NAME);
Uri imageUri = Uri.fromFile(file);//拍照时,将拍得的照片先保存在本地
intentFromCapture.putExtra(MediaStore.EXTRA_OUTPUT, imageUri);//然后到时照片就会保存到你指定的那个路径的IMAGE_FILE_NAME文件了.
startActivityForResult(intentFromCapture, CAMERA_REQUEST_CODE);
} catch (Exception e) {
e.printStackTrace();
}
break;
}
}
};

public void onActivityResult(int requestCode, int resultCode, Intent data) {
if (resultCode != 0) {
switch (requestCode) {

// 这个是选择图片的请求码
case IMAGE_REQUEST_CODE:
startPhotoZoom(data.getData());
break;

// 这个是拍照的请求码
case CAMERA_REQUEST_CODE:
// 先查看是否有外存储卡
if (Environment.getExternalStorageState().equals(
Environment.MEDIA_MOUNTED)) {

File tempFile = new File(
Environment.getExternalStorageDirectory()
+ "/DCIM/camera/" + IMAGE_FILE_NAME);
startPhotoZoom(Uri.fromFile(tempFile));//拍照时,将拍得的照片先保存在本地
} else {
Toast.makeText(getActivity(), "未找到存储卡,无法存储照片!",
Toast.LENGTH_LONG).show();
}
break;

case RESULT_REQUEST_CODE:
if (data != null) {
getImageToView(data);
}
break;
}
}
super.onActivityResult(requestCode, resultCode, data);
}

private void getImageToView(Intent data) {
Bundle extras = data.getExtras();

if (null != extras) {
photo = extras.getParcelable("data");
userimg.setImageBitmap(photo);//给控件添加选择后的图片,而且这个图片是压缩过的??这里有疑问

FileOutputStream out=null;

//这里以后保存了图片后,要保存到外存中
if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
try {
//这个是自己保存一份到外存,方便下次读取图像图片
f = new File(Environment.getExternalStorageDirectory().getAbsolutePath() + "/" +"head_pic.jpg");
if (!f.exists()) {
f.createNewFile();
}
out=new FileOutputStream(f);
photo.compress(CompressFormat.JPEG, 80, out);

//还要把图片上传到服务端去保存,保持系统的一致性
uploadToWeb(photo);

//	photo.recycle(); //加上这句图片会变黑??待解决

} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}

/**上传头像图片到服务端
* @param bitmap
* @author hemiy
*/
private void uploadToWeb(Bitmap bitmap) {
Map<String, Object> map = new HashMap<String, Object>();
map.put("ACCOUNT_CODE",detail.getLogin().getAccount_code());
map.put("FILENAME",headPicName);
map.put("CONTENT", CommonUtil.encodeBitmapToBase64Str(bitmap));

final Dialog pDialog=  PromptUtil.showProgressDialog(getActivity());

try {
NetWebServiceUtil.doSoapRequest("/service/PersonalCenterWebservice","uploadHeadPic","INPUT", map, new WebServiceCallBack() {

@Override
public void callBack(String result) {
PromptUtil.closeProgressDialog(pDialog);
if(result!=null){

Detail detailResult=XmlPullManager.parseOneXml(result);
check(detailResult.getResult());//检查回传结果

}else{
PromptUtil.toast(getActivity(), "服务端传输错误");
}

}

private void check(int result) {
switch (result) {
case 0:
PromptUtil.toast(getActivity(), "头像上传失败");
break;
case 1:
PromptUtil.toast(getActivity(), "头像上传成功");
break;
case 2:
PromptUtil.toast(getActivity(), "上传参数错误");
break;

default:
break;
}

}
});
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

}

private void startPhotoZoom(Uri uri) {
String text=null;
Intent intent = new Intent("com.android.camera.action.CROP");
intent.setDataAndType(uri, "image/*");
intent.putExtra("crop", "true");
// aspectX aspectY 是宽高的比例
intent.putExtra("aspectX", 1);
intent.putExtra("aspectY", 1);
intent.putExtra("outputX", 320);
intent.putExtra("outputY", 320);
intent.putExtra("scale", true);
intent.putExtra("return-data", true);

String textPre=uri.toString();
//图片文件的路径 ,有2种格式
//华为手机从图库选择的结果 ,以content开头
//content://media/external/images/media/888737

//华为手机从文件选择器的结果,系统拍照也是如下的结果,以file开头
//  file:///mnt/sdcard2/%E7%A8%8B%E5%BA%8F%E5%91%98%E6%97%A5%E5%B8%B8.jpg

System.out.println("转换前的地址是 :   "+textPre);

if(uri.toString().contains("content://")){ //如果包含有content开头,需要转化为其实际路径,不能用content开头
text=getRealPathFromURI(uri);
}else{
text=textPre;       //如果用file开头,不用转化
}

System.out.println("转换后的地址是 :   "+text);
headPicName=text.substring(text.lastIndexOf("/")+1);//保存图片的文件名,注意索引加1
System.out.println("选取图片的地址是:  "+headPicName);
startActivityForResult(intent, RESULT_REQUEST_CODE);

};

/**
* http://ask.csdn.net/questions/293 参考网页
* 把content开头的文件,得到其实际路径
* @param contentUri
* @return
* @author hemiy
*/
private String getRealPathFromURI(Uri contentUri) {
String[] proj = { MediaStore.Images.Media.DATA };
CursorLoader loader = new CursorLoader(getActivity(), contentUri, proj, null, null, null);
Cursor cursor = loader.loadInBackground();
int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
cursor.moveToFirst();
return cursor.getString(column_index);
}
}


参考文章

1、/article/8700038.html

2、http://ask.csdn.net/questions/293

3、/article/8832336.html
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: