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


项目中有个需求,通过拍照或者选取系统图片后,显示到控件上,并且要得到图片的实际路径。

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

android选择图片得到实际路径的总结_第1张图片


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 map = new HashMap();
				   	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 map = new HashMap();
				   	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 map = new HashMap();
		   	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、http://blog.csdn.net/tempersitu/article/details/20557383

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

3、http://blog.csdn.net/qq_28746251/article/details/50276703


你可能感兴趣的:(android选择图片得到实际路径的总结)