全网整合营销服务商

电脑端+手机端+微信端=数据同步管理

免费咨询热线:400-708-3566

Android实现简单图库辅助器

写在前面

实际开发经常会遇到读取相册或者拍照功能,网上也很非常多图库框架,都各有风格,也因此与自己的项目格格不入。再者,框架API太多,需要的配置太多,还要吃力研究。所以,本人摸索大多图库框架,提炼核心,写一个只提供核心的辅助类,剩下的就可以自行玩耍。

实现步骤

第一步,创建辅助类,使用弱引用持有Activity,防止内存溢出。

  public class GalleryHelper{

    private Activity mActivity;

    public GalleryHelper(Activity activity) {
      mActivity = new WeakReference<>(activity).get();
    }
  }

第二步,创建文件夹实体类,代表文件夹数据。paths集合是文件夹下的所有路径。

public final class FolderEntity {

  private int num;
  private String name;
  private List<String> paths = new ArrayList<>();

  public int getNum() {
    return paths.size();
  }

  public List<String> getPaths() {
    return paths;
  }

  public void setName(String name) {
    this.name = name;
  }
}

第三步,首先获取手机所有的图片,在Activity里有getLoaderManager方法获取一个LoaderManager实例,该类用于异步加载手机内数据监测,这里不做多分析。我们调用它的initLoader方法,前两个参数这里不需要,只要实现LoaderCallbacks接口,并且指定Cursor类型。LoaderCallbacks接口有三个覆盖方法,我们需要用到的是onCreateLoader方法和onLoadFinished方法,前者是初始化Loader,后者是加载完成后的回调。

  mActivity.getLoaderManager().initLoader(0, null, new LoaderManager.LoaderCallbacks<Cursor>() {
      @Override
      public Loader<Cursor> onCreateLoader(int i, Bundle bundle) {
      }

      @Override
      public void onLoadFinished(Loader<Cursor> loader, Cursor cursor) {
      }

      @Override
      public void onLoaderReset(Loader<Cursor> loader) {

      }
    });

在onCreateLoader方法里,初始化CursorLoader,参数跟Cursor类下的query一样,第一个参数指定外部村粗多媒体URI;第二个参数是查找结果字段,这里只要了路径;第三个参数和第四个参数是搜索条件,条件为搜索jpeg格式和png格式,最后一个是按时间倒序搜索。

  public Loader<Cursor> onCreateLoader(int i, Bundle bundle) {
     return new CursorLoader(mActivity,
         MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
         new String[]{MediaStore.Images.Media.DATA},
         MediaStore.Images.Media.MIME_TYPE + "=? or "
             + MediaStore.Images.Media.MIME_TYPE + "=?",
         new String[]{"image/jpeg", "image/png"},
         MediaStore.Images.Media.DATE_ADDED + " DESC");
   }

CursorLoader初始化完成之后,搜索的结果会回调在onLoadFinished方法。这时就可以处理搜索出来的图片路径。因为图片路径是没有分类,这里采用HashMap分类,以文件夹路径为key,具体文件夹FolderEntity类为value,如果当前图片路径的文件夹不存在则创建FolderEntity并且放入HashMap,存在则获取FolderEntity。

  public void onLoadFinished(Loader<Cursor> loader, Cursor cursor) {
     HashMap<String, FolderEntity> folderEntityHashMap = new HashMap<String, FolderEntity>();
      if (cursor != null) {
        while (cursor.moveToNext()) {
          //图片路径
          String path = cursor.getString(
          cursor.getColumnIndex(MediaStore.Images.Media.DATA));

          // 路径不存在或者文件不存在就跳过
          File file = new File(path);
          if (TextUtils.isEmpty(path) || !file.exists()) {
            continue;
          }
          String folerPath = file.getParent();
          FolderEntity folderEntity;
          if (folderEntityHashMap.containsKey(folerPath)) {
            folderEntity = folderEntityHashMap.get(folerPath);
          } else {
            folderEntity = new FolderEntity();
            folderEntityHashMap.put(file.getParentFile().getName(), folderEntity);
          }
          folderEntity.getPaths().add(path);
        }
        cursor.close();
      }

    }

但是数据是要提供给外部的,HashMap就显得很麻烦,所以要转换ArrayList,并且按数量大小进行顺序。

    private ArrayList<FolderEntity> map2List(HashMap<String, FolderEntity> mediaBeanMap) {
      Iterator<FolderEntity> iterator = mediaBeanMap.values().iterator();
      ArrayList<FolderEntity> list = new ArrayList<FolderEntity>();
      while (iterator.hasNext()) {
        list.add(iterator.next());
      }
      Collections.sort(list, new Comparator<FolderEntity>() {
        @Override
        public int compare(FolderEntity lhs, FolderEntity rhs) {
          return lhs.getNum() > rhs.getNum() ? 1 : -1;
        }
      });
      return list;
    }

使用接口将数据提供给外部。

  public interface GalleryCallback {
    void complete(List<FolderEntity> list);
  }

  callback.complete(map2List(folderEntityHashMap));

第四步是实现拍照功能,这里实现是创建文件再启动拍照功能。

  File imageStoreDir = new File(Environment.getExternalStorageDirectory(),
      "/DCIM/" + mActivity.getResources().getString(R.string.app_name));
  if (!imageStoreDir.exists()) {
    imageStoreDir.mkdir();
  }
  Intent captureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
  if (captureIntent.resolveActivity(mActivity.getPackageManager()) != null) {
    SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMddHHmmss", Locale.CHINA);
    String filename = String.format("IMG%s", dateFormat.format(new Date()));
    imagePath = new File(imageStoreDir, filename).getAbsolutePath();
    captureIntent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(new File(imagePath)));
    mActivity.startActivityForResult(new Intent(
        MediaStore.ACTION_IMAGE_CAPTURE), REQUEST_CODE);
  }

定义回调接口,接收Activit的onActivityResult方法,表示回调成功把上面创建好的文件路径提供外部。

  public interface CameraCallback {
    void complete(String path);
  }

  public void onActivityResult(int requestCode, int resultCode) {
    if (Activity.RESULT_OK == resultCode && REQUEST_CODE == requestCode) {
      if (cameraCallback != null) {
        cameraCallback.complete(imagePath);
      }
    }
  }

外部调用

  galleryHelper = new GalleryHelper(this);
    galleryHelper.loadImages(new GalleryHelper.GalleryCallback() {
      @Override
      public void complete(List<FolderEntity> list) {
        //加载本地图片返回结果
      }
    });

 findViewById(R.id.btn_camera).setOnClickListener(new View.OnClickListener() {
     @Override
     public void onClick(View v) {
       galleryHelper.openCamera(new GalleryHelper.CameraCallback() {
         @Override
         public void complete(String path) {
         //拍照返回结果
         }
       });
     }
   });

  @Override
  protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    //使用拍照,必须接收Activity的onActivityResult方法
    galleryHelper.onActivityResult(requestCode, resultCode);
  }

别忘了加权限,这里为了简单实现,我把targetSdkVersion设置23以下,23和23以上的需要自行加上动态权限。

  <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
  <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
  <uses-permission android:name="android.permission.CAMERA" />
  <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" />

整体就完成了,使用非常方便,有了这图库辅助器就可以自定义风格,再也不用受约束。网上大多开源图片选择器的搜索图片都是如此,但这例子难免有bug,不足之处望指教。

github地址:https://github.com/tanxinye/GalleryHelper

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。


# Android  # 图库辅助器  # Android实现调用系统图库与相机设置头像并保存在本地及服务器  # Android编程实现调用系统图库与裁剪图片功能  # android图库竖屏不显示status bar的解决方法  # android图库播放幻灯片时按power键灭屏再亮屏显示keyguard  # 回调  # 不存在  # 太多  # 就可以  # 加载  # 提供给  # 自己的  # 的是  # 都是  # 第一个  # 不需要  # 网上  # 我把  # 也很  # 第二个  # 自定义  # 但这  # 各有  # 格格不入  # 别忘了 


相关文章: 重庆市网站制作公司,重庆招聘网站哪个好?  详解jQuery停止动画——stop()方法的使用  公司门户网站制作公司有哪些,怎样使用wordpress制作一个企业网站?  如何在阿里云域名上完成建站全流程?  seo网站制作优化,网站SEO优化步骤有哪些?  建站之星安装路径如何正确选择及配置?  ,如何利用word制作宣传手册?  如何在阿里云购买域名并搭建网站?  如何快速使用云服务器搭建个人网站?  官网自助建站平台指南:在线制作、快速建站与模板选择全解析  PHP正则匹配日期和时间(时间戳转换)的实例代码  济南专业网站制作公司,济南信息工程学校怎么样?  整蛊网站制作软件,手机不停的收到各种网站的验证码短信,是手机病毒还是人为恶搞?有这种手机病毒吗?  python的本地网站制作,如何创建本地站点?  PHP 500报错的快速解决方法  如何在IIS中新建站点并配置端口与物理路径?  自助网站制作软件,个人如何自助建网站?  如何用IIS7快速搭建并优化网站站点?  七夕网站制作视频,七夕大促活动怎么报名?  建站主机无法访问?如何排查域名与服务器问题  TestNG的testng.xml配置文件怎么写  手机网站制作与建设方案,手机网站如何建设?  建站之星如何保障用户数据免受黑客入侵?  北京的网站制作公司有哪些,哪个视频网站最好?  广州商城建站系统开发成本与周期如何控制?  如何在阿里云ECS服务器部署织梦CMS网站?  如何在IIS中新建站点并解决端口绑定冲突?  如何使用Golang table-driven基准测试_多组数据测量函数效率  建站之星备案流程有哪些注意事项?  深圳网站制作公司好吗,在深圳找工作哪个网站最好啊?  如何快速查询域名建站关键信息?  如何在云主机快速搭建网站站点?  怎么将XML数据可视化 D3.js加载XML  陕西网站制作公司有哪些,陕西凌云电器有限公司官网?  如何在阿里云通过域名搭建网站?  定制建站是什么?如何实现个性化需求?  网站插件制作软件免费下载,网页视频怎么下到本地插件?  网站app免费制作软件,能免费看各大网站视频的手机app?  如何获取开源自助建站系统免费下载链接?  完全自定义免费建站平台:主题模板在线生成一站式服务  建站主机解析:虚拟主机配置与服务器选择指南  ,网页ppt怎么弄成自己的ppt?  建站ABC备案流程中有哪些关键注意事项?  定制建站流程解析:需求评估与SEO优化功能开发指南  如何在搬瓦工VPS快速搭建网站?  实现点击下箭头变上箭头来回切换的两种方法【推荐】  建站之星免费模板:自助建站系统与智能响应式一键生成  定制建站如何定义?其核心优势是什么?  企业宣传片制作网站有哪些,传媒公司怎么找企业宣传片项目?  公众号网站制作网页,微信公众号怎么制作? 

您的项目需求

*请认真填写需求信息,我们会在24小时内与您取得联系。