推广

超级完整版android 图片上传,包括客户端和后台服务器

iseeyu2年前 (2024-02-22)推广127

第一个是图片选择框架

第二个是图片加载工具

需要引用jitpack的库

具体使用我就不多讲了,gIthub地址—>https://github.com/LuckSiege/PictureSelector

需要注意的是要用到gitbub  demo包里的一个工具类

所以建议你把demo项目下载,里面的具体调用方法和注释写的很详细

但我们不要繁杂的写在一个Activity里,所以我们自己封装,上代码

这是调用相册的方法,具体其他api可以自己依照我的方法往下加方法即可

package com.xqb.photography_app.tool;

import android.app.Activity;

import android.util.Log;

import androidx.core.content.ContextCompat;

import com.luck.picture.lib.PictureSelector;

import com.luck.picture.lib.config.PictureConfig;

import com.luck.picture.lib.config.PictureMimeType;

import com.luck.picture.lib.entity.LocalMedia;

import com.luck.picture.lib.listener.OnResultCallbackListener;

import com.luck.picture.lib.style.PictureWindowAnimationStyle;

import com.xqb.photography_app.R;

import java.util.List;

/*

*create by xqb on 2020/9/8

*/

public class MyPictureSelector{

private static MyPictureSelectormyPictureSelector;

    private MyPictureSelector() {

}

//实现单例

    public static MyPictureSelectorgetInstance() {

if (myPictureSelector ==null) {

synchronized (MyPictureSelector.class) {

if (myPictureSelector ==null) {

return myPictureSelector =new MyPictureSelector();

                }

}

}

return myPictureSelector;

    }

//启动推出动画,demo包里也有具体说明

    private PictureWindowAnimationStylepictureWindowAnimationStyle;

    //具体调用方法

    public void openAlbum(Activity activity,int maxSelectNum,boolean isOneSelect,boolean isCrop,boolean isCircleCrop,boolean isCropBorder,final OnSelectorResult onSelectorResult){

pictureWindowAnimationStyle =new PictureWindowAnimationStyle();

        pictureWindowAnimationStyle.ofAllAnimation(R.anim.picture_anim_up_in, R.anim.picture_anim_down_out);

        int selectionMode;

        if (isOneSelect){

selectionMode=PictureConfig.SINGLE;

        }else{

selectionMode=PictureConfig.MULTIPLE;

        }

PictureSelector.create(activity)

.openGallery(PictureMimeType.ofImage())

.imageEngine(GlideEngine.createGlideEngine())//这是需要用到demo包里的一个工具类

                .theme(R.style.picture_white_style)//style配置demo包里也有

                .maxSelectNum(maxSelectNum)

.selectionMode(selectionMode)//单选 PictureConfig.SINGLE

                .isSingleDirectReturn(true)// 单选模式下是否直接返回,PictureConfig.SINGLE模式下有效

                .isCamera(false)//是否使用相机

                .setPictureWindowAnimationStyle(pictureWindowAnimationStyle)// 自定义相册启动退出动画

                .circleDimmedLayer(isCircleCrop)// 是否圆形裁剪

                .isEnableCrop(isCrop)// 是否裁剪

                .showCropFrame(isCropBorder)// 是否显示裁剪矩形边框 圆形裁剪时建议设为false

                .isCompress(true)// 是否压缩

                .compressQuality(100)// 图片压缩后输出质量 0~ 100

                .synOrAsy(false)//同步true或异步false 压缩 默认同步

//                        .compressSavePath(getPath())//压缩图片保存地址

                .setCropDimmedColor(ContextCompat.getColor(activity, R.color.black80Color))// 设置裁剪背景色值

                .withAspectRatio(1, 1)// 裁剪比例 如16:9 3:2 3:4 1:1 可自定义

//                .renameCompressFile(“icon-” + PrefTool.getString(activity, “userPhone”, “”) + “.jpg”)// 重命名压缩文件名、 如果是多张压缩则内部会自动拼上当前时间戳防止重复

                .forResult(new MyResultCallback(onSelectorResult));//自定义回调接口

    }

//因为这里把调用方法写出来了,所以在activity里的OnActivityResult方法里是监听不到的

//这是后需要自己实现回调接口

    public interface OnSelectorResult{

void onResult(List result);

    }

//这是demo里自定义的回调类,我稍作了修改,让它变成具体调用方法的实现回调监听接口

    private static class MyResultCallbackimplements OnResultCallbackListener{

private OnSelectorResultonSelectorResult;

        public MyResultCallback(OnSelectorResult onSelectorResult) {

super();

            this.onSelectorResult=onSelectorResult;

        }

@Override

        public void onResult(List result) {

onSelectorResult.onResult(result);

        }

@Override

        public void onCancel() {

Log.d(“—–>图片选择”, “onCancel: 退出了”);

        }

}

}

调用方法

比起demo里的调用方法整洁了不少,看着舒服,尤其是哪个回调接口的实现,我瞬间有自豪的感觉了,哈哈哈哈

result里就是装的图片信息了,如何获取,demo包里也写的清楚,具体我不多说了

最重要的一部要来了,如何上传,因为图片可选一张可选多张,还需携带用户字符信息,上代码

这里的okhttp也是封装了的,带我的大佬写的,感觉还蛮实用,我在他的基础上改成了图片上传请求

public void doGetForPic(String url,JSONObject object, final OkCallback okCallback) {

Log.i(“TAG”, “” + object.toString());

        final MultipartBody.Builder builder =new MultipartBody.Builder();

        try {

builder.addFormDataPart(“data”,object.getString(“data”));

            JSONArray array=object.getJSONArray(“pic”);

            for (int i=0;i

JSONObject object1=array.getJSONObject(i);

                //文件路径中文转码,否者会报错

//                StringBuffer stringBuffer = new StringBuffer();

//                for (int j = 0, length = object1.getString(“picPath”).length(); j < length; j++) {

//                    char c = object1.getString(“picPath”).charAt(i);

//                    if (c <= ‘\u001f’ || c >= ‘\u007f’) {

//                        stringBuffer.append(String.format(“\\u%04x”, (int) c));

//                    } else {

//                        stringBuffer.append(c);

//                    }

//                }

                builder.addFormDataPart(“img[]”,object1.getString(“picName”), RequestBody.create(MediaType.parse(“image/jpeg”), new File(object1.getString(“picPath”))));

            }

}catch (JSONException e) {

e.printStackTrace();

            Log.e(“——>图片上传异常”,e+””);

        }

RequestBody requestBody = builder.build();

        Request.Builder reqBuilder =new Request.Builder();

        Request request =reqBuilder

.post(requestBody)

.url(url)

.build();

        final Call call =mOkHttpClien.newCall(request);

        call.enqueue(new Callback() {

@Override

            public void onFailure(Call call, final IOException e) {

if (okCallback !=null) {

//切换到主线程

                    mHandler.post(new Runnable() {

@Override

                        public void run() {

okCallback.onFailure(e);

                        }

});

                }

}

@Override

            public void onResponse(Call call, final Response response)throws IOException {

try {

if (response !=null && response.isSuccessful()) {

final String json = response.body().string();

                        if (okCallback !=null) {

Log.i(TAG, “onResponse: ” + Thread.currentThread().getName());

                            mHandler.post(new Runnable() {

@Override

                                public void run() {

Log.i(TAG, “onResponse: ” + Thread.currentThread().getName());

                                    okCallback.onResponse(json);

                                }

});

return;

                        }

}

}catch (IOException e) {

e.printStackTrace();

                }

if (okCallback !=null) {

mHandler.post(new Runnable() {

@Override

                        public void run() {

okCallback.onFailure(new Exception(“请求失败”));

                        }

});

                }

}

});

    }

是不是有点看不懂,其实很好理解,除了上传的参数解析外,其余的操作就是让请求跑在子线程上,请求完成让它回到当前主UI线程

请求调用

private void uploadUserIcon(List result) {

JSONObject object =new JSONObject();

    JSONArray array =new JSONArray();

    try {

for (LocalMedia media : result) {

JSONObject object1 =new JSONObject();

            object1.put(“picName”, media.getFileName()).put(“picPath”, media.getCompressPath());

            array.put(object1);

        }

object.put(“pic”, array);

        object.put(“data”, new JSONObject()

.put(“userPhone”, PrefTool.getString(context, “userPhone”, “”))

.put(“picType”, “icon”)

.put(“userId”, PrefTool.getInt(context, “userId”, 0)));

    }catch (Exception e) {

e.printStackTrace();

    }

OkhttpUtil.getInstance().doGetForPic(IP.requestPicUrl, object, new OkhttpUtil.OkCallback() {

@Override

        public void onFailure(Exception e) {

e.printStackTrace();

            MyToast.toast(context, ToastTextHelper.okhttpOnFailText);

        }

@Override

        public void onResponse(String json) {

try {

Log.e(TAG, “onResponse: ” + json);

                JSONObject responseJson =new JSONObject(json);

                if (responseJson.getBoolean(“status”)) {

PrefTool.setString(context, “userIcon”,responseJson.getString(“data”));

                    Picasso.get().load(IP.requestImgUrl + PrefTool.getString(context, “userIcon”, “”)).transform(new CircleTransform()).into(myInfoIcon);

                }else {

MyToast.toast(context, responseJson.getString(“message”));

                }

}catch (JSONException e) {

e.printStackTrace();

                Log.e(TAG, ToastTextHelper.okhttpOnResponseErrText);

            }

}

});

}

后台服务器解析

添加依赖包

然后以下这是写在service层具体实现的代码

@Override

public MapuploadUserIcon(HttpServletRequest request) {

MultipartRequest multipartRequest = (MultipartRequest) request;

    List list = multipartRequest.getFiles(“img[]”);

    JSONObject requestJson =new JSONObject(request.getParameter(“data”));

    System.out.println(“图片参数”+requestJson);

    switch (requestJson.getString(“picType”)) {

case “icon”:

MultipartFile file = list.get(0);

            if (file ==null || file.getSize() ==0) {

map.put(“status”,false);

                map.put(“message”,”文件损坏”);

            }else{

String fileName=”icon-“+requestJson.getString(“userPhone”)+”.jpg”;

                String filePath=iconSavePath+fileName;

                try {

file.transferTo(new File(filePath));

                    UserTb userId=new UserTb();

                    userId.setUserId(requestJson.getInt(“userId”));

                    userId.setUserIcon(“/myInfoImg/”+fileName);

                    int update =userTbMapper.updateByPrimaryKeySelective(userId);

                    if (update>0){

userTb=userTbMapper.selectByPrimaryKey(requestJson.getInt(“userId”));

                        map.put(“status”,true);

                        map.put(“message”,”图片上传成功”);

                        map.put(“data”,userTb.getUserIcon());

                    }else{

map.put(“status”,false);

                        map.put(“message”,”图片上传失败”);

                    }

}catch (IOException e) {

e.printStackTrace();

                    map.put(“status”,false);

                    map.put(“message”,”图片上传失败”);

                }

}

break;

        case “photo”:

break;

    }

return map;

}

基本上就完成了,我因为之前写过一个类似的版本,写起现在这个来就很容易了,所以没有写很多注释,但是代码并不难,所以仔细看,不懂的可以再找我要demo,到时候要的多,我写个demo放github,到此结束

扫描二维码推送至手机访问。

版权声明:本文由西安泽虎代运营发布,如需转载请注明出处。

转载请注明出处https://www.0291.com.cn/post/55820.html

相关文章

渠道运营丨想成为推广高手,你需要组合出奇招

渠道运营丨想成为推广高手,你需要组合出奇招

做推广时都有“渠道为王”的说法,尤其是在创业公司,leader总希望负责推广的同学能尝试更多免费,或所谓性价比高的渠道,以期获得意外的收获。 在“指令”的驱动下,推广同学吭哧吭哧研究好几天,最后发现有逾越不了的困难,比如成本、技术屏蔽等,然后放弃。又或者是推广后发现外部数据不错,但用户怎...

OCPC医疗账户搭建及优化的实操案例

OCPC医疗账户搭建及优化的实操案例

  现在很多的朋友都用上了OCPC投放模式,不管是之前发过关于OCPC的文章还是今天发的,虽然有很多不同的因素,但是一些优化的思路和策略相信对朋友们还是有一定的借鉴意义。 关于ocpc和ecpc的原理和运用大家都会,今天和大家说一下以我的实战经验如何做到更细致,更省钱,...

分享互联网时代如何让网站建设更出色。

分享互联网时代如何让网站建设更出色。

随着时代的到来,也变得越来越重要,而站长的压力也越来越大。那么怎样建设网站才可以让自己的网站在众多的网站中脱颖而出呢?网站建设的方式都是类似的,网站的内容、结构、布局等等都相似。建站过程中,细节是决定成败的关键。下面我们就来和武汉建站公司讨论一下: 第一、网站的结构和布局。...

淘宝直播超级推荐推广怎么操作,淘宝推广怎么做(淘宝店铺超级推荐怎么用)

淘宝直播超级推荐推广怎么操作,淘宝推广怎么做(淘宝店铺超级推荐怎么用)

直播推广是超级推荐的一项功能,通过直播推广,可以将淘宝直播间推送到猜你喜欢、微淘、直播广场等三大资源位场景。...

拼多多怎么下载不了?别急,原因解析与解决方法都在这里!

拼多多怎么下载不了?别急,原因解析与解决方法都在这里!

相信很多小伙伴们在用拼多多购物的时候,都遇到过“拼多多怎么下载不了”的困扰。别急,今天我将为你揭秘这个问题的原因,并提供解决方法。关键词:拼多多怎么下载不了。 我们要了解为什么拼多多会在某些情况下无法下载。一般来说,这可能有以下几个原因1. 网络环境问题:如果你所处的网络环境不稳定,...

极速推在哪里展现,极速推广99元有用吗?(极速推的曝光位置是在哪里)

极速推在哪里展现,极速推广99元有用吗?(极速推的曝光位置是在哪里)

系统会根据您设置的订单条件,比如定向人群,快速智能地帮助您的宝贝投放给更多高价值活跃的消费者人群链路上,目前以淘内推荐流量为主要渠道。...

现在,非常期待与您的又一次邂逅

我们努力让每一部企业宣传片和抖音短视频成为商业大片