用okhttp上传图片(java,后端netcore)

发布时间 2023-09-23 23:34:46作者: 牛腩
用okhttp上传图片(java,后端netcore)
2023年09月23日
https://github.com/square/okhttp
https://github.com/google/gson
流程:
1. 点选择按键,弹出相册,选择一张图片,图片显示到ImageView中
2.再点上传按钮,把选择的图片发送到后端上传接口,返回图片的网络地址显示在TextView中(在这里我的后端我又把图片上传到了七牛云)
3.OVER
环境:
Android Studio Giraffe 2022.3.1 Patch 1,JAVA,API33,模板用那个右下角有个小图标的,后端net7
 
先贴后端关键代码:
using Qiniu.Storage;
using Qiniu.Util; //nuget搜索:qiniu

private IHostingEnvironment hostingEnv;

/// <summary>
        /// 生成900x900的图片,上传到七牛云
        /// </summary>
        /// <returns></returns>
        [HttpPost]
        public IActionResult ImgUpload900()
        {
            var imgFile = Request.Form.Files[0];
            if (imgFile != null && !string.IsNullOrEmpty(imgFile.FileName))
            {
                long size = 0;
                var filename = ContentDispositionHeaderValue
                                .Parse(imgFile.ContentDisposition)
                                .FileName
                                .Trim().Value;
                var fileExt = filename.Substring(filename.LastIndexOf('.'), filename.Length - filename.LastIndexOf('.')); //扩展名,如.jpg

                fileExt = fileExt.Replace("\"", "");

                #region 判断后缀
                if (!fileExt.ToLower().Contains("jpg") && !fileExt.ToLower().Contains("png") && !fileExt.ToLower().Contains("gif") && !fileExt.ToLower().Contains("jpeg"))
                {
                    return Json(new { code = 1, msg = "只允许上传jpg,png,gif,jpeg格式的图片.", });
                }
                #endregion

                #region 判断大小
                long mb = imgFile.Length / 1024 / 1024; // MB
                if (mb > 20)
                {
                    return Json(new { code = 1, msg = "只允许上传小于 20MB 的图片.", });
                }
                #endregion

                string nohouzui = "niunannet_" + DateTime.Now.ToString("yyyyMMdd") + "_" + System.Guid.NewGuid().ToString().Substring(0, 6);
                String newFileName = nohouzui + fileExt;


                var path = hostingEnv.WebRootPath; //网站静态文件目录  wwwroot
                string dir = DateTime.Now.ToString("yyyyMMdd");
                //完整物理路径
                string wuli_path = path + $"{Path.DirectorySeparatorChar}upload{Path.DirectorySeparatorChar}to7niu{Path.DirectorySeparatorChar}";
                if (!System.IO.Directory.Exists(wuli_path))
                {
                    System.IO.Directory.CreateDirectory(wuli_path);
                }
                filename = wuli_path + newFileName;
                size += imgFile.Length;
                using (FileStream fs = System.IO.File.Create(filename))
                {
                    imgFile.CopyTo(fs);
                    fs.Flush();
                }

                #region 生成900x900

                string filename_upload = nohouzui + "_900x900" + fileExt;
                string tpath = wuli_path + filename_upload;
                Tool.CreateImage(wuli_path + newFileName, tpath, 900, 900);


                #endregion
                #region 传到七牛云上
                string AccessKey = "634643Z45kvT_20zbdk2O";
                string SecretKey = "4icRNJClNnu3x27nz3D";
                string Bucket = "niunan";
                Mac mac = new Mac(AccessKey, SecretKey);
                PutPolicy putPolicy = new PutPolicy();
                putPolicy.Scope = Bucket;
                putPolicy.SetExpires(3600);
                string jstr = putPolicy.ToJsonString();
                string token = Auth.CreateUploadToken(mac, jstr);
                Config config = new Config();
                config.Zone = Qiniu.Storage.Zone.ZONE_CN_South;
                config.UseHttps = false;
                config.UseCdnDomains = true;
                FormUploader fu = new FormUploader(config);
                Stream s = new System.IO.FileInfo(tpath).OpenRead();
                var result = fu.UploadStream(s, filename_upload, token, null);
                //  log.Info($"上传图片到七牛云,文件名【{filename1}】,上传结果\r\n{result.ToString()}\r\n\r\n\r\n");

                string endfilepath = "http://image.niunan.net/" + filename_upload;
                #endregion

                return Json(new { code = 0, msg = "上传成功", data = new { src = endfilepath, title = filename_upload } });
            }
            return Json(new { code = 1, msg = "上传失败", });
        }
选择按钮,弹出相册,选择图片,显示到ImageView上
public static final int PHOTO_PICKER_REQUEST_CODE = 1;
private Uri imageUri;

//选择图片
binding.btnSelPic.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View view) {
       Intent intent = new Intent(Intent.ACTION_PICK);//MediaStore.ACTION_PICK_IMAGES 用这个也行,没前面的方便
        intent.setType("image/*");
        startActivityForResult(intent, PHOTO_PICKER_REQUEST_CODE);

    }
});

//2023年09月23日做的时候发现有横线了,应该是该方法快废弃了吧
@Override
public void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    if (resultCode != RESULT_OK) {
        // Handle error
        return;
    }

    switch (requestCode) {
        case PHOTO_PICKER_REQUEST_CODE:
            // Get photo picker response for single select.
            imageUri = data.getData();
            Bitmap bitmap = null;
            try {
                bitmap = BitmapFactory.decodeStream(SecondFragment.this.getActivity().getContentResolver().openInputStream(imageUri));
                binding.imageView1.setImageBitmap(bitmap);


            } catch (FileNotFoundException e) {
                e.printStackTrace();
            }

            return;

    }
}
点上传按钮,把选择的图片发给后端接口,后端处理好了再返回图片网络地址,用到okhttp来POST提交,还用到了gson来解析后端返回来的JSON字符串, 根据JSON自己定义了对应的模型 ApiResult和ApiResultInner
//Androidmainfast.xml里先加上网络权限
....
</application>
<uses-permission android:name="android.permission.INTERNET" />


//app下的build.gradle.kts里加入okhttp和gson
implementation ("com.google.code.gson:gson:2.10.1")
implementation("com.squareup.okhttp3:okhttp:4.11.0")

private static final MediaType MEDIA_TYPE_PNG = MediaType.parse("image/png");

//上传图片
binding.btnUpload.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View view) {
        new Thread(new Runnable() {
            @Override
            public void run() {
                //1.创建OKHTTP
                OkHttpClient client = new OkHttpClient();
                File file = uri2File(imageUri);  //网上找的uri2File方法,用于把Uri转为File
                //2.创建RequestBody
                RequestBody fileBody = RequestBody.create(MEDIA_TYPE_PNG, file);

                //3.构建MultipartBody
                RequestBody requestBody = new MultipartBody.Builder()
                        .setType(MultipartBody.FORM)
                        .addFormDataPart("file", "testImage.png", fileBody)
                        .build();

                //4.构建请求
                Request request = new Request.Builder()
                        .url("http://www.abc.net/api/imgupload")
                        .post(requestBody)
                        .build();

                //5.发送请求
                try {
                    Response response = client.newCall(request).execute();
                    String retstr = response.body().string();
                    Log.i(TAG, "上传图片接口返回:" + retstr);
                    SecondFragment.this.getActivity().runOnUiThread(new Runnable() {
                        @Override
                        public void run() {
                            Gson gson = new Gson();
                            ApiResult retm = gson.fromJson(retstr, ApiResult.class);
                            if (retm.getCode() == 0) {
                                binding.tvres.setText(retm.getData().getSrc());
                            } else {
                                binding.tvres.setText(retm.getMsg());
                            }
                        }
                    });
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
        }).start();
    }
});


//把Uri转为File
private File uri2File(Uri uri) {
    String img_path;
    String[] proj = {MediaStore.Images.Media.DATA};
    Cursor actualimagecursor = SecondFragment.this.getActivity().managedQuery(uri, proj, null,
            null, null);
    if (actualimagecursor == null) {
        img_path = uri.getPath();
    } else {
        int actual_image_column_index = actualimagecursor
                .getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
        actualimagecursor.moveToFirst();
        img_path = actualimagecursor
                .getString(actual_image_column_index);
    }
    File file = new File(img_path);
    return file;