用okhttp上传图片(java,后端netcore)
用okhttp上传图片(java,后端netcore)
2023年09月23日
流程:
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;
撸码:复制、粘贴,拿起键盘就是“干”!!!
分类:
Android
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具