Android 选择相册照片并返回功能的实现代码

首先由于进行读写操作,要在 AndroidManifest.xml中声明权限:

<uses-permission android:name=“android.permission.READ_EXTERNAL_STORAGE” />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> 

调用系统相册:

private static final int CHOOSE_PHOTO=0;
Intent intent = new Intent(“android.intent.action.GET_CONTENT”);
intent.setType(”image/*”);
startActivityForResult(intent, CHOOSE_PHOTO);
[java] view plain copy
private static final int CHOOSE_PHOTO=0;
Intent intent = new Intent("android.intent.action.GET_CONTENT");
intent.setType("image/*");
startActivityForResult(intent, CHOOSE_PHOTO); 

然后回调:

@Override
  protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    switch (requestCode) {
      case CHOOSE_PHOTO:
        if (resultCode == RESULT_OK) {
          Bitmap bitmap = null;
          //判断手机系统版本号
          if (Build.VERSION.SDK_INT >= 19) {
            //4.4及以上系统使用这个方法处理图片
            bitmap = ImgUtil.handleImageOnKitKat(this, data);    //ImgUtil是自己实现的一个工具类
          } else {
            //4.4以下系统使用这个方法处理图片
            bitmap = ImgUtil.handleImageBeforeKitKat(this, data);
          }
          ImageView view = (ImageView) findViewById(R.id.personal_info_header_img);
          view.setImageBitmap(bitmap);
        }
        break;
      default:
        break;
    }
  } 
@Override
  protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    switch (requestCode) {
      case CHOOSE_PHOTO:
        if (resultCode == RESULT_OK) {
          Bitmap bitmap = null;
          //判断手机系统版本号
          if (Build.VERSION.SDK_INT >= 19) {
            //4.4及以上系统使用这个方法处理图片
            bitmap = ImgUtil.handleImageOnKitKat(this, data);    //ImgUtil是自己实现的一个工具类
          } else {
            //4.4以下系统使用这个方法处理图片
            bitmap = ImgUtil.handleImageBeforeKitKat(this, data);
          }
          ImageView view = (ImageView) findViewById(R.id.personal_info_header_img);
          view.setImageBitmap(bitmap);
        }
        break;
      default:
        break;
    }
  } 

将对图像的相关操作封装成一个ImgUtil类,便于使用:

import android.annotation.TargetApi;
import android.content.ContentUris;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.preference.PreferenceManager;
import android.provider.DocumentsContract;
import android.provider.MediaStore;
import android.text.TextUtils;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
/**
 * Created by wbin on 2016/3/22.
 */
public class ImgUtil {
  //4.4及以上系统使用这个方法处理图片
  @TargetApi(19)
  public static Bitmap handleImageOnKitKat(Context context, Intent data) {
    String imagePath = null;
    Uri uri = data.getData();
    if (DocumentsContract.isDocumentUri(context, uri)) {
      //如果是document类型的Uri,则通过document id处理
      String docId = DocumentsContract.getDocumentId(uri);
      if (“com.android.providers.media.documents”.equals(uri.getAuthority())) {
        String id = docId.split(”:”)[1]; //解析出数字格式的id
        String selection = MediaStore.Images.Media._ID + ”=” + id;
        imagePath = getImagePath(context, MediaStore.Images.Media.EXTERNAL_CONTENT_URI, selection);
      } else if (“com.android.providers.downloads.documents”.equals(uri.getAuthority())) {
        Uri contentUri = ContentUris.withAppendedId(
            Uri.parse(”content://downloads/public_downloads”), Long.valueOf(docId));
        imagePath = getImagePath(context, contentUri, null);
      }
    } else if (“content”.equalsIgnoreCase(uri.getScheme())) {
      //如果不是document类型的Uri,则使用普通方式处理
      imagePath = getImagePath(context, uri, null);
    }
    return getImage(imagePath);
  }
  //4.4以下系统使用这个方法处理图片
  public static Bitmap handleImageBeforeKitKat(Context context, Intent data) {
    Uri uri = data.getData();
    String imagePath = getImagePath(context, uri, null);
    return getImage(imagePath);
  }
  public static String getImagePath(Context context, Uri uri, String selection) {
    String path = null;
    //通过Uri和selection来获取真实的图片路径
    Cursor cursor = context.getContentResolver().query(uri, null, selection, null, null);
    if (cursor != null) {
      if (cursor.moveToFirst()) {
        path = cursor.getString(cursor.getColumnIndex(MediaStore.Images.Media.DATA));
      }
      cursor.close();
    }
    return path;
  }
  //对bitmap进行质量压缩
  public static Bitmap compressImage(Bitmap image) {
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    image.compress(Bitmap.CompressFormat.JPEG, 100, baos);//质量压缩方法,这里100表示不压缩,把压缩后的数据存放到baos中
    int options = 100;
    while (baos.toByteArray().length / 1024 > 100) {  //循环判断如果压缩后图片是否大于100kb,大于继续压缩
      baos.reset();//重置baos即清空baos
      image.compress(Bitmap.CompressFormat.JPEG, options, baos);//这里压缩options%,把压缩后的数据存放到baos中
      options -= 10;//每次都减少10
    }
    ByteArrayInputStream isBm = new ByteArrayInputStream(baos.toByteArray());//把压缩后的数据baos存放到ByteArrayInputStream中
    Bitmap bitmap = BitmapFactory.decodeStream(isBm, null, null);//把ByteArrayInputStream数据生成图片
    return bitmap;
  }
  //传入图片路径,返回压缩后的bitmap
  public static Bitmap getImage(String srcPath) {
    if (TextUtils.isEmpty(srcPath)) //如果图片路径为空 直接返回
      return null;
    BitmapFactory.Options newOpts = new BitmapFactory.Options();
    //开始读入图片,此时把options.inJustDecodeBounds 设回true了
    newOpts.inJustDecodeBounds = true;
    Bitmap bitmap = BitmapFactory.decodeFile(srcPath, newOpts);//此时返回bm为空
    newOpts.inJustDecodeBounds = false;
    int w = newOpts.outWidth;
    int h = newOpts.outHeight;
    //现在主流手机比较多是800*480分辨率,所以高和宽我们设置为
    float hh = 800f;//这里设置高度为800f
    float ww = 480f;//这里设置宽度为480f
    //缩放比。由于是固定比例缩放,只用高或者宽其中一个数据进行计算即可
    int be = 1;//be=1表示不缩放
    if (w > h && w > ww) {//如果宽度大的话根据宽度固定大小缩放
      be = (int) (newOpts.outWidth / ww);
    } else if (w < h && h > hh) {//如果高度高的话根据宽度固定大小缩放
      be = (int) (newOpts.outHeight / hh);
    }
    if (be <= 0)
      be = 1;
    newOpts.inSampleSize = be;//设置缩放比例
    //重新读入图片,注意此时已经把options.inJustDecodeBounds 设回false了
    bitmap = BitmapFactory.decodeFile(srcPath, newOpts);
    return compressImage(bitmap);//压缩好比例大小后再进行质量压缩
  }
} 
import android.annotation.TargetApi;
import android.content.ContentUris;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.preference.PreferenceManager;
import android.provider.DocumentsContract;
import android.provider.MediaStore;
import android.text.TextUtils;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
/**
 * Created by wbin on 2016/3/22.
 */
public class ImgUtil {
  //4.4及以上系统使用这个方法处理图片
  @TargetApi(19)
  public static Bitmap handleImageOnKitKat(Context context, Intent data) {
    String imagePath = null;
    Uri uri = data.getData();
    if (DocumentsContract.isDocumentUri(context, uri)) {
      //如果是document类型的Uri,则通过document id处理
      String docId = DocumentsContract.getDocumentId(uri);
      if ("com.android.providers.media.documents".equals(uri.getAuthority())) {
        String id = docId.split(":")[1]; //解析出数字格式的id
        String selection = MediaStore.Images.Media._ID + "=" + id;
        imagePath = getImagePath(context, MediaStore.Images.Media.EXTERNAL_CONTENT_URI, selection);
      } else if ("com.android.providers.downloads.documents".equals(uri.getAuthority())) {
        Uri contentUri = ContentUris.withAppendedId(
            Uri.parse("content://downloads/public_downloads"), Long.valueOf(docId));
        imagePath = getImagePath(context, contentUri, null);
      }
    } else if ("content".equalsIgnoreCase(uri.getScheme())) {
      //如果不是document类型的Uri,则使用普通方式处理
      imagePath = getImagePath(context, uri, null);
    }
    return getImage(imagePath);
  }
  //4.4以下系统使用这个方法处理图片
  public static Bitmap handleImageBeforeKitKat(Context context, Intent data) {
    Uri uri = data.getData();
    String imagePath = getImagePath(context, uri, null);
    return getImage(imagePath);
  }
  public static String getImagePath(Context context, Uri uri, String selection) {
    String path = null;
    //通过Uri和selection来获取真实的图片路径
    Cursor cursor = context.getContentResolver().query(uri, null, selection, null, null);
    if (cursor != null) {
      if (cursor.moveToFirst()) {
        path = cursor.getString(cursor.getColumnIndex(MediaStore.Images.Media.DATA));
      }
      cursor.close();
    }
    return path;
  }
  //对bitmap进行质量压缩
  public static Bitmap compressImage(Bitmap image) {
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    image.compress(Bitmap.CompressFormat.JPEG, 100, baos);//质量压缩方法,这里100表示不压缩,把压缩后的数据存放到baos中
    int options = 100;
    while (baos.toByteArray().length / 1024 > 100) {  //循环判断如果压缩后图片是否大于100kb,大于继续压缩
      baos.reset();//重置baos即清空baos
      image.compress(Bitmap.CompressFormat.JPEG, options, baos);//这里压缩options%,把压缩后的数据存放到baos中
      options -= 10;//每次都减少10
    }
    ByteArrayInputStream isBm = new ByteArrayInputStream(baos.toByteArray());//把压缩后的数据baos存放到ByteArrayInputStream中
    Bitmap bitmap = BitmapFactory.decodeStream(isBm, null, null);//把ByteArrayInputStream数据生成图片
    return bitmap;
  }
  //传入图片路径,返回压缩后的bitmap
  public static Bitmap getImage(String srcPath) {
    if (TextUtils.isEmpty(srcPath)) //如果图片路径为空 直接返回
      return null;
    BitmapFactory.Options newOpts = new BitmapFactory.Options();
    //开始读入图片,此时把options.inJustDecodeBounds 设回true了
    newOpts.inJustDecodeBounds = true;
    Bitmap bitmap = BitmapFactory.decodeFile(srcPath, newOpts);//此时返回bm为空
    newOpts.inJustDecodeBounds = false;
    int w = newOpts.outWidth;
    int h = newOpts.outHeight;
    //现在主流手机比较多是800*480分辨率,所以高和宽我们设置为
    float hh = 800f;//这里设置高度为800f
    float ww = 480f;//这里设置宽度为480f
    //缩放比。由于是固定比例缩放,只用高或者宽其中一个数据进行计算即可
    int be = 1;//be=1表示不缩放
    if (w > h && w > ww) {//如果宽度大的话根据宽度固定大小缩放
      be = (int) (newOpts.outWidth / ww);
    } else if (w < h && h > hh) {//如果高度高的话根据宽度固定大小缩放
      be = (int) (newOpts.outHeight / hh);
    }
    if (be <= 0)
      be = 1;
    newOpts.inSampleSize = be;//设置缩放比例
    //重新读入图片,注意此时已经把options.inJustDecodeBounds 设回false了
    bitmap = BitmapFactory.decodeFile(srcPath, newOpts);
    return compressImage(bitmap);//压缩好比例大小后再进行质量压缩
  }
} 

为了兼容新老版本的手机,我们做了一个判断,如果是4.4及以上系统的手机就调用handleImageOnKitKat()方法来处理图片,否则就调用handleImageBeforeKitKat()方法来处理图片。之所以要这么做,是因为Android系统从4.4版本开始,选取相册的图片不再返回图片真是的Uri了,而是一个封装过的Uri,因此如果是4.4版本以上的手机需要对这个Uri进行解析才行。

当然了,获取到图片路径后不推荐直接使用 BitmapFactory.decodeFile(imgPath)来获取bitmap,因为某些图片体积可能很大,直接加载到内存中有可能会导致程序崩溃(我就遇到过了..你可以直接加载手机高像素拍的原图片试试看=。=)。 所以更好的做法是先对图片进行适当的压缩,然后再加载到内存中(上述代码中实现了)。

总结

以上所述是小编给大家介绍的Android 选择相册照片并返回功能的实现代码,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对我们网站的支持!

(0)

相关推荐

  • Android实现拍照、选择相册图片并裁剪功能

    通过拍照或相册中获取图片,并进行裁剪操作,然后把图片显示到ImageView上.  当然也可以上传到服务器(项目中绝大部分情况是上传到服务器),参考网上资料及结合项目实际情况,  测试了多款手机暂时没有发现严重问题.代码有注释,直接贴代码: public class UploadPicActivity extends Activity implements View.OnClickListener { private Button take_photo_btn; private Button s

  • Android开发从相册中选取照片的示例代码

    最近项目在做一个功能:就是需要从用户选择头像跳转到相册选择图片,这应该是一个很简单的需求,但是在网上搜了一下有好多都讲的很乱,其实用几十行代码就可以实现的为什么要说的那么复杂呢,下面就简单说一下喽. 下面说两种方法分别是直接选择相册返回,另外一种为选择相册之后进行裁剪.先上效果图 (1)直接选择相册后返回 第一步就是主要跳转的相册 //在这里跳转到手机系统相册里面 Intent intent = new Intent( Intent.ACTION_PICK, android.provider.M

  • android相册选择图片的编码实现代码

    android相机拍照直接选取图片固然方便,但是更多的时候,我们需要从手机已有的图片中选择一张来使用.这次就练习如何从相册中选择图片吧. 首先在 activity_main.xml 文件中增加一个 Button,用来触发从相册中选择图片的功能. <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk

  • Android编程图片操作类定义与用法示例【拍照,相册选图及裁剪】

    本文实例讲述了Android编程图片操作类定义与用法.分享给大家供大家参考,具体如下: 主界面类:拍照及选择相册图片 import android.app.Activity; import android.content.Intent; import android.graphics.Bitmap; import android.net.Uri; import android.os.Bundle; import android.provider.MediaStore; import androi

  • Android通过手机拍照或从本地相册选取图片设置头像

    像微信.QQ.微博等社交类的APP,通常都有设置头像的功能,设置头像通常有两种方式: 1.让用户通过选择本地相册之类的图片库中已有的图像,裁剪后作为头像. 2.让用户启动手机的相机拍照,拍完照片后裁剪,然后作为头像. 我现在写一个简单的完整代码例子,说明如何在android中实现上述两个头像设置功能. MainActivity.Java文件: package zhangpgil.photo; import java.io.File; import android.support.v7.app.A

  • Android7.0实现拍照和相册选取图片功能

    由于android 7.0新增了动态权限,所以我们在做拍照和相册选取功能的时候,需要申请添加动态权限 实现效果图: (1)在res目录下,新建xml文件夹 ,在xml文件夹中新建一个filepaths.xml <?xml version="1.0" encoding="utf-8"?> <resources> <external-path name="images" path="test/"/&g

  • Android 实现IOS选择拍照相册底部弹出的实例

    Android 实现IOS选择拍照相册底部弹出的实例 效果图 1. AndroidStudio使用 dependencies { compile 'com.guoqi.widget:actionsheet:1.0' } 2. 使用 //1.实现接口 implements ActionSheet.OnActionSheetSelected //2.在某个点击事件中添加: ActionSheet.showSheet(this, this, null); //3.然后重写点击方法: @Override

  • Android工具类ImgUtil选择相机和系统相册

    本文实例为大家分享了Android选择相机和系统相册的具体代码,供大家参考,具体内容如下 说明: Android选择相机和系统相册 代码: 1.打开系统相机和系统相册工具类 package com.gxjl.pe.gxjlpesdk.util; import android.Manifest; import android.app.Activity; import android.app.ActivityManager; import android.app.AlertDialog; impor

  • Android开发实现从相册中选择照片功能详解

    本文实例讲述了Android开发实现从相册中选择照片功能.分享给大家供大家参考,具体如下: 实际效果图: 代码实现: 1. 权限配置 2. 点击事件绑定 3. 相册访问 4. 根据路径设置图片 5. 其他方法 权限 首先,现在 mainfest.xml 文件中添加以下权限: <!--获取照片权限--> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/> <us

  • Android 选择相册照片并返回功能的实现代码

    首先由于进行读写操作,要在 AndroidManifest.xml中声明权限: <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> 调用系统相册: private static final in

  • Android仿微信右滑返回功能的实例代码

    先上效果图,如下: 先分析一下功能的主要技术点,右滑即手势判断,当滑到一直距离时才执行返回,并且手指按下的位置是在屏幕的最左边(这个也是有一定范围的),  这些可以实现onTouchEvent来实现. 接着就是返回时,有滑动效果,很显然这个是Acitivty切换动画实现的.好啦,分析完了就开干.下面上代码: @Override public boolean onTouchEvent(MotionEvent event) { switch (event.getAction()){ case Mot

  • Android实现显示和隐藏密码功能的示例代码

    在前端中我们知道用javascript就可以可以很容易实现,那么在Android中怎么实现这个功能呢? Java代码 package com.example.test2; import androidx.appcompat.app.AppCompatActivity; import android.os.Bundle; import android.text.method.HideReturnsTransformationMethod; import android.text.method.Pa

  • Android中使用ShareSDK集成分享功能的实例代码

    引言 现在APP开发集成分享功能已经是非常普遍的需求了.其他集成分享技术我没有使用过,今天我就来介绍下使用ShareSDK来进行分享功能开发的一些基本步骤和注意点,帮助朋友们避免一些坑.好了,下面切入正题正式开始介绍. 1.ShareSDK开发包及配置 这个不用多说,去他们官网看找SDK开发包和集成文档即可. Android版本地址:http://www.mob.com/downloadDetail/ShareSDK/android. 注意:记得要注册ShareSDK账号获取AppKey哦.这些

  • Android 中TeaPickerView数据级联选择器功能的实例代码

    Github地址 YangsBryant/TeaPickerView (Github排版比较好,建议进入这里查看详情,如果觉得好,点个star吧!) 引入module allprojects { repositories { google() jcenter() maven { url 'https://www.jitpack.io' } } } implementation 'com.github.YangsBryant:TeaPickerView:1.0.2' 主要代码 public cla

  • Android简单的短信验证功能的实现代码

    相信有很多朋友在做三方登陆的时候会加入短信验证的功能,最近刚好被分配安排实现这一需求,本人新手一枚,特地去网上搜了资料,目前用的比较多的大汉.云通讯还有MOB的smssdk,对比之下,最终选择了完全免费的MOB产品试试手,下面就是我在使用sdk过程中一些心得,希望看到的大神给点建议,喜欢的给个小心心就好. 首先我上网百度了下Mob的官网(http://www.mob.com/)作为第一次使用习惯性的先打开文档介绍,关于使用方法这里介绍的算是比较详细的,我这里也不做赘述了,整个文档浏览了一遍,介绍

  • JS点击图片弹出文件选择框并覆盖原图功能的实现代码

    简单说下原理,把显示的图片的<img>标签 和上传文件的 <input> 标签放在同一个div下,设置<img>的大小和<input>的大小一样,<input> 设置透明度为0,用定位和设置优先级把input浮动在<img>上方,这样点击图片就能选择上传图片,选择完图片后获取图片地址,替换掉原来的默认图片就能实现覆盖原图功能. js代码: <script type="text/javascript" src=

  • Android加载loading对话框的功能及实例代码(不退出沉浸式效果)

    一.自定义Dialog 在沉浸式效果下,当界面弹出对话框时,对话框将获取到焦点,这将导致界面退出沉浸式效果,那么是不是能通过屏蔽对话框获取焦点来达到不退出沉浸式的目的呢.说干就干,我们先来看一下改善后的效果图. 普通对话框弹出效果 LoadingDialog弹出效果 自定义LoadingDialog public class LoadingDialog extends Dialog { public LoadingDialog(Context context) { super(context);

  • Android 本地广播和强制下线功能的实现代码

    一.使用本地广播 1.本地广播一个举例 package com.example.broadcasttest2; import android.app.Activity; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.net.Conn

  • Android悬浮球及全局返回功能的实现示例

    先来一发效果图: 前面是返回效果,最后一下是实现home键的效果 前言 很久之前,就想做一个悬浮球了,毕竟是程序猿嘛,有想要的功能的时候总是想自己尝试一下,于是兴致勃勃的找了好久,都没有找到全局返回功能该如何实现!最后也无疾而终,就在前两天,又想到了这个功能,今天硬是花了好久,从一个同类软件获得了一点灵感,有一个关键的地方被我察觉到了,顺着这个思路找了很多资料,便实现了全局返回功能. 思路 废话不多说了,说说主要的思路吧,关键的一个类就是:AccessibilityService,官方文档地址,

随机推荐