开发中基本上都会有头像上传的功能,有的app还需要多张图片同时上传,下面简单将头像上传以及多张图片上传功能整理一下。图片选择仿照微信选择图片的界面。【参考】 多图片选择器

!!!推荐一个动态权限请求的框架: 动态权限申请

下面先看一下想要实现的效果图:多张图片

22222.png

选择图片:

33333.png

头像上传:

11111.png

一、头像上传(单张图片上传,可设置图片裁剪的比例)

1、选择图片前请求读写权限。

//先请求权限,再进行操作

AndPermission.with(MainActivity.this)

.requestCode(300)

.permission(

Manifest.permission.WRITE_EXTERNAL_STORAGE,

Manifest.permission.READ_EXTERNAL_STORAGE)

.callback(this)

.start();

权限申请注解

// 成功回调的方法,用注解即可,这里的300就是请求时的requestCode。

@PermissionYes(300)

private void getPermissionYes(List grantedPermissions) {

// TODO 申请权限成功。

if(AndPermission.hasPermission(this,grantedPermissions)) {

// TODO 执行拥有权限时的下一步。

chooseImage();

} else {

// 使用AndPermission提供的默认设置dialog,用户点击确定后会打开App的设置页面让用户授权。

AndPermission.defaultSettingDialog(this, 300).show();

// 建议:自定义这个Dialog,提示具体需要开启什么权限,自定义Dialog具体实现上面有示例代码。

}

}

@PermissionNo(300)

private void getPermissionNo(List deniedPermissions) {

// TODO 申请权限失败。

if(AndPermission.hasPermission(this,deniedPermissions)) {

// TODO 执行拥有权限时的下一步。

} else {

// 使用AndPermission提供的默认设置dialog,用户点击确定后会打开App的设置页面让用户授权。

AndPermission.defaultSettingDialog(this, 300).show();

// 建议:自定义这个Dialog,提示具体需要开启什么权限,自定义Dialog具体实现上面有示例代码。

}

}

2、初始化图片选择器,设置裁剪形状为正方形。

private ImagePicker getImagePickerSquare() {//正方形

ImagePicker imagePicker = ImagePicker.getInstance();

imagePicker.setImageLoader(new GlideImageLoader()); //设置图片加载器

imagePicker.setShowCamera(true); //显示拍照按钮

imagePicker.setCrop(true); //允许裁剪(单选才有效)

imagePicker.setSaveRectangle(true); //是否按矩形区域保存

imagePicker.setMultiMode(false); //多选

imagePicker.setStyle(CropImageView.Style.RECTANGLE); //裁剪框的形状

imagePicker.setFocusWidth(800); //裁剪框的宽度。单位像素(圆形自动取宽高最小值)

imagePicker.setFocusHeight(800); //裁剪框的高度。单位像素(圆形自动取宽高最小值)

imagePicker.setOutPutX(1000); //保存文件的宽度。单位像素

imagePicker.setOutPutY(1000); //保存文件的高度。单位像素

return imagePicker;

}

3、选择图片。chooseImage()

private void chooseImage() {

List names = new ArrayList<>();

names.add("拍照");

names.add("从相册选择");

showDialog(new PictureChooseDialog.SelectDialogListener() {

@Override

public void onItemClick(AdapterView> parent, View view, int position, long id) {

switch (position) {

case 0: // 直接调起相机

//打开选择,本次允许选择的数量

getImagePickerSquare().setSelectLimit(maxImgCount - selImageList.size());

Intent intent = new Intent(MainActivity.this, ImageGridActivity.class);

intent.putExtra(ImageGridActivity.EXTRAS_TAKE_PICKERS,true); // 是否是直接打开相机

startActivityForResult(intent, REQUEST_CODE_SELECT);

break;

case 1:

//打开选择,本次允许选择的数量

getImagePickerSquare().setSelectLimit(maxImgCount - selImageList.size());

Intent intent1 = new Intent(MainActivity.this, ImageGridActivity.class);

startActivityForResult(intent1, REQUEST_CODE_SELECT);

break;

default:

break;

}

}

}, names);

}

4、选择图片后的处理,onActivityResult()

@Override

protected void onActivityResult(int requestCode, int resultCode, Intent data) {

super.onActivityResult(requestCode, resultCode, data);

if (resultCode == ImagePicker.RESULT_CODE_ITEMS) {

//添加图片返回

if (data != null && requestCode == REQUEST_CODE_SELECT) {

ArrayList images = (ArrayList) data.getSerializableExtra(ImagePicker.EXTRA_RESULT_ITEMS);

if (images != null){

ImageItem imageItem = images.get(0);

String newPathHead = imageItem.path;

updateMineMessage(newPathHead);

}

}

} else if (resultCode == ImagePicker.RESULT_CODE_BACK) {

//预览图片返回

if (data != null && requestCode == REQUEST_CODE_PREVIEW) {

ArrayList images = (ArrayList) data.getSerializableExtra(ImagePicker.EXTRA_IMAGE_ITEMS);

if (images != null){

ImageItem imageItem = images.get(0);

// String newPathHead = BitmapUtils.compressImageUpload(imageItem.path);

String newPathHead = imageItem.path;

updateMineMessage(newPathHead);

}

}

}

}

二、多张图片上传,选择后可删除,这里以最多九张图片为例。步骤与选择一张图片时基本一致,图片选择器稍微不同。

1、布局中图片用RecyclerView

android:padding="5dp"

android:id="@+id/recyclerView"

android:layout_marginTop="12dp"

android:layout_width="match_parent"

android:layout_height="wrap_content"

android:choiceMode="singleChoice"

android:divider="@null"

android:fadingEdge="none"

android:listSelector="@android:color/transparent"

android:scrollbarStyle="outsideOverlay"

app:layoutManager="android.support.v7.widget.GridLayoutManager"

app:spanCount="4"

tools:listitem="@layout/item_upload_image">

2、初始化图片选择器。

private void initImagePickerMulti() {

ImagePicker imagePicker = ImagePicker.getInstance();

imagePicker.setImageLoader(new GlideImageLoader()); //设置图片加载器

imagePicker.setShowCamera(true); //显示拍照按钮

imagePicker.setCrop(false); //允许裁剪(单选才有效)

imagePicker.setSaveRectangle(true); //是否按矩形区域保存

imagePicker.setSelectLimit(maxImgCount); //选中数量限制

imagePicker.setMultiMode(true); //多选

// imagePicker.setStyle(CropImageView.Style.RECTANGLE); //裁剪框的形状

// imagePicker.setFocusWidth(800); //裁剪框的宽度。单位像素(圆形自动取宽高最小值)

// imagePicker.setFocusHeight(800); //裁剪框的高度。单位像素(圆形自动取宽高最小值)

// imagePicker.setOutPutX(1000); //保存文件的宽度。单位像素

// imagePicker.setOutPutY(1000); //保存文件的高度。单位像素

}

3、图片适配器。

public class ImagePickerAdapter extends RecyclerView.Adapter {

private int maxImgCount;

private Context mContext;

private List mData;

private LayoutInflater mInflater;

private OnRecyclerViewItemClickListener listener;

private boolean isAdded; //是否额外添加了最后一个图片

private OnItemRemoveClick onItemRemoveClick;

public boolean isAdded() {

return isAdded;

}

public void setAdded(boolean added) {

isAdded = added;

}

public void setOnItemRemoveClick(OnItemRemoveClick onItemRemoveClick) {

this.onItemRemoveClick = onItemRemoveClick;

}

public interface OnRecyclerViewItemClickListener {

void onItemClick(View view, int position);

}

public void setOnItemClickListener(OnRecyclerViewItemClickListener listener) {

this.listener = listener;

}

public void setImages(List data) {

mData = new ArrayList<>(data);

if (getItemCount() < maxImgCount) {

mData.add(new ImageItem());

isAdded = true;

} else {

isAdded = false;

}

notifyDataSetChanged();

}

public void addImg() {

if (getItemCount() < maxImgCount) {

mData.add(new ImageItem());

isAdded = true;

} else {

isAdded = false;

}

}

public List getImages() {

//由于图片未选满时,最后一张显示添加图片,因此这个方法返回真正的已选图片

if (isAdded) return new ArrayList<>(mData.subList(0, mData.size() - 1));

else return mData;

}

public ImagePickerAdapter(Context mContext, List data, int maxImgCount) {

this.mContext = mContext;

this.maxImgCount = maxImgCount;

this.mInflater = LayoutInflater.from(mContext);

setImages(data);

}

@Override

public SelectedPicViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {

return new SelectedPicViewHolder(mInflater.inflate(R.layout.item_upload_image, parent, false));

}

@Override

public void onBindViewHolder(SelectedPicViewHolder holder, int position) {

holder.bind(position);

}

@Override

public int getItemCount() {

return mData.size();

}

public class SelectedPicViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {

private RelativeLayout cancelImg;

private int clickPosition;

private ImageView iv_img;

public SelectedPicViewHolder(View itemView) {

super(itemView);

iv_img = (ImageView) itemView.findViewById(R.id.iv_img);

cancelImg = ((RelativeLayout) itemView.findViewById(R.id.item_upload_image_cancelImg));

}

public void bind(final int position) {

//设置条目的点击事件

itemView.setOnClickListener(this);

//根据条目位置设置图片

ImageItem item = mData.get(position);

if (isAdded && position == getItemCount() - 1) {

iv_img.setScaleType(ImageView.ScaleType.FIT_XY);

cancelImg.setVisibility(View.INVISIBLE);

iv_img.setImageResource(R.mipmap.img_add);

clickPosition = UploadMoreImagesActivity.IMAGE_ITEM_ADD;

} else {

iv_img.setScaleType(ImageView.ScaleType.CENTER_CROP);

cancelImg.setVisibility(View.VISIBLE);

ImagePicker.getInstance().getImageLoader().displayImage((Activity) mContext, item.path, iv_img, 0, 0);

clickPosition = position;

}

cancelImg.setOnClickListener(new View.OnClickListener() {

@Override

public void onClick(View view) {

removeItem(position);

onItemRemoveClick.onItemRemoveClick();

}

});

}

@Override

public void onClick(View v) {

if (listener != null) listener.onItemClick(v, clickPosition);

}

}

/**

* 删除某条item

* @param position

*/

public void removeItem(int position){

mData.remove(position);

// notifyItemRemoved(position);

}

public interface OnItemRemoveClick {

public void onItemRemoveClick();

}

}

4、适配器中选择图片的点击事件。adapter.setOnItemClickListener(this);

@Override

public void onItemClick(View view, int position) {

switch (position){

case IMAGE_ITEM_ADD:

//先请求权限,再进行操作

AndPermission.with(this)

.requestCode(300)

.permission(

Manifest.permission.WRITE_EXTERNAL_STORAGE,

Manifest.permission.READ_EXTERNAL_STORAGE)

.callback(this)

.start();

break;

default:

//打开预览

Intent intentPreview = new Intent(this, ImagePreviewDelActivity.class);

intentPreview.putExtra(ImagePicker.EXTRA_IMAGE_ITEMS, (ArrayList) adapter.getImages());

intentPreview.putExtra(ImagePicker.EXTRA_SELECTED_IMAGE_POSITION, position);

intentPreview.putExtra(ImagePicker.EXTRA_FROM_ITEMS,true);

startActivityForResult(intentPreview, REQUEST_CODE_PREVIEW);

break;

}

}

5、适配器中图片删除。

adapter.setOnItemRemoveClick(new ImagePickerAdapter.OnItemRemoveClick() {

@Override

public void onItemRemoveClick() {

adapter.setImages(adapter.getImages());

adapter.notifyDataSetChanged();

selImageList.clear();

selImageList.addAll(adapter.getImages());

}

});

6、发布时需要将图片上传至服务器,这里以 严振杰的NoHttp为例。(没有实际测试)

/**

* 上传图片到服务器

*/

private void upLoadImages() {

StringRequest request = new StringRequest("rul", RequestMethod.POST);

request.addHeader("", "");

request.add("content",contentEt.getText().toString());

for (int i = 0; i < selImageList.size(); i++) {

ImageItem imageItem = selImageList.get(i);

String newPath = imageItem.path;

File oldFile = new File(newPath);

File newFile = CompressHelper.getDefault(getApplicationContext()).compressToFile(oldFile);

request.add("imgs"+(i+1),newFile);

}

requestData(request, new SimpleResponseListener() {

@Override

public void onStart(int what) {

super.onStart(what);

}

@Override

public void onSucceed(int what, Response response) {

super.onSucceed(what, response);

//上传成功

}

});

}

详细参考:

调用android的拍照或本地相册选取再实现相片上传服务器,Android调用系统相机、本地相册上传图片(头像上传(裁剪)、多张图片上传)...相关推荐

  1. Android调用系统相机和相册(更换微信头像)

    最近做了调用系统相机和相册,在其他博客中看到还有对图像进行剪切,大家都知道,我们在玩微信的时候,头像更换是方形图片,接下来我们就对这种情况具体进行描述: 必要的权限: <uses-permiss ...

  2. 调用系统相机和相册出现闪退报错No Activity found to handle Intent

    调用系统相机和相册出现闪退报错No Activity found to handle Intent : 在开发安卓项目的时候遇到了一个问题,当手机调用系统相机和相册的时候会出现闪退的现象,根据报错常常 ...

  3. php微信拍照图库js接口,微信JSSDK 实现打开摄像头拍照再将相片保存到服务器

    在微信端打开手机摄像头拍照,将拍照图片保存到服务器上需要使用到微信的JSSDK接口,主要使用到了拍照或从手机相册中选图接口(chooseImage),上传图片接口(uploadImage) 参考资料: ...

  4. android调用相机与相册的方法,手把手教你:android调用系统相机、相册功能,适配6.0权限获取以及7.0之后获取URI(兼容多版本)...

    Android中调用系统相机来拍摄照片的代码,以下:html 一.首先设置Uri获取判断以及相机请求Codejava public final int TYPE_TAKE_PHOTO = 1;//Ur ...

  5. 调用系统相机、相册、剪裁图片,适配Android 12

    第一步:FileProvider相关准备工作 在AndroidManifest.xml中增加provider节点: <providerandroid:name="androidx.co ...

  6. Android调用系统相机和相册

    拍照和相册的功能在实际开发中是最常见的功能,这里记录下. 准备工作 权限 1 2 3 4 <!-- 往SDCard写入数据权限 --> <uses-permission androi ...

  7. 调用系统相机和相册,并且裁剪成圆形图片(解决6.0,7.0,8.0版本问题)

    之前写过一篇博客,那篇博客对7.0手机裁剪图片的问题没有进行解决,现在对之前的那篇博客进行补充,解决了Android6.0,7.0,8.0版本问题,不仅可以调用相册,相机,还可以将图片保存到本地,并且 ...

  8. Android 启动系统相机,相册,裁剪图片及6.0权限管理

    在日常开发中,我们经常需要用到上传图片的 功能,这个时候通常有两种做法,第一种,从相机获取,第二种,从相册获取.今天这篇博客主要讲解利用系统的Intent怎样获取? 主要内容如下 - 怎样通过相机获取 ...

  9. android 打开相册的权限,Android 启动系统相机,相册,裁剪图片及6.0权限管理

    在日常开发中,我们经常需要用到上传图片的 功能,这个时候通常有两种做法,第一种,从相机获取,第二种,从相册获取.今天这篇博客主要讲解利用系统的Intent怎样获取? 主要内容如下 怎样通过相机获取我们 ...

最新文章

  1. R语言数据包自带数据集之mtcars数据集字段解释、数据导入实战
  2. 科大星云诗社动态20210823
  3. 10月21日下午PHP常用函数
  4. python读取yaml文件
  5. 进入顶层社会的顺序是什么?
  6. Given a list,rotate the list to right by k places, where k is nonegative.
  7. ios13.4.1续航怎么样?
  8. 字符编码转换libiconv库
  9. 传输层安全协议TLS/SSL
  10. 无线鼠标vs蓝牙鼠标
  11. WordPress插件:WP No Category Base 去除分类Category目录
  12. springboot+Thymeleaf生成PDF
  13. Guitar Pro2023中文版本下载及简谱功能详细介绍
  14. python 3 4j不是合法的_3 4j 是合法Python数字类型。
  15. grab显示连不上服务器,grab 暂时链接不到服务器
  16. 如何在 6 月 7 日观看 Apple 的 WWDC 2021 主题演讲
  17. 关于MBR和GUID分区的问题
  18. shell脚本一键安装jdk(三台)
  19. AG9310与AG9311参数对比和方案选择方法
  20. 计算机视觉在AI中的7种应用

热门文章

  1. 用html5 Canvas制作一个简单的游戏 英雄抓小怪物(上)
  2. ubuntu安装pangolin
  3. 2020年创业风口:社交电商
  4. 网文版ChatGPT来了:大模型辅助写作,澜舟和中文在线联手出品
  5. 【云和恩墨大讲堂】尹涛 - 由DRM引起的ORA-00481错误
  6. 智能流程机器人助你“聚划算”
  7. 喜欢你,三个星期了!
  8. Ubuntu18 编译和运行PL-SVO(不需要ROS)
  9. GPS,RTK,PPS及网络RTK科普
  10. python等于号怎么输入_python 中不等于怎么表示