(一)上传图片到服务器一 ---------------------------------AndroID代码
(二)上传图片到服务器二---------------------------------AndroID 系统7.0以上调用相机兼容问题
(三)上传图片到服务器三 -----------------------------------后台服务器代码
一、相关知识
①AndroID权限申请
②网络访问框架OKhttp
③内存溢出问题:图片压缩
④AndroID 系统7.0以上调用系统相机无效
⑤有关图片上传过程中遇到的内存溢出问题
二、效果展示
二、代码①HTML
1 <linearLayout 2 androID:layout_wIDth="match_parent" 3 androID:layout_height="wrap_content" 4 androID:orIEntation="vertical" 5 androID:background="@color/white" 6 > 7 androID.support.v7.Widget.RecyclerVIEw 8 androID:ID="@+ID/rvPic" 9 androID:layout_wIDth10 androID:layout_height11 androID:layout_gravity="center_horizontal"12 13 </androID.support.v7.Widget.RecyclerVIEw14 15 TextVIEw16 ="@+ID/tvNum"17 18 19 androID:text="0/8"20 androID:textcolor="#666666"21 ="right|bottom"22 androID:paddingRight="@dimen/dp_10"/>23 24 25 linearLayout26 button27 28 ="@+ID/btn_Enter"29 androID:layout_wIDth30 androID:layout_height="@dimen/dp_45"31 androID:layout_alignParentBottom="true"32 androID:background="@drawable/selecter_button"33 androID:text="确认上传"34 androID:textcolor="@color/inbuttonText"35 androID:textSize="@dimen/dp_18" />
②Java代码
<基本功能>
实体类
1 public class LoadfileVo { 2 3 file file; 4 5 int pg; //图片下方的进度条 6 7 boolean isupload = false; 标识该文件是否上传 8 9 Bitmap bitmap;10 11 public Bitmap getBitmap() {12 return bitmap;13 }15 voID setBitmap(Bitmap bitmap) {16 this.bitmap =17 18 19 boolean isupload() {20 isupload;21 22 23 voID setUpload( upload) {24 isupload = upload;25 26 27 LoadfileVo() {28 29 30 public LoadfileVo(file file,int pg) {31 this.file = file;32 this.pg = pg;33 34 35 boolean isupload,1)"> pg,Bitmap bitmap) {36 37 38 this.isupload =39 40 41 42 file getfile() {43 44 45 46 setfile(file file) {47 48 49 50 getPg() {51 52 53 54 voID setPg(55 56 57 }
适配器
1 /* 2 *Create By 小群子 2018/12/10 3 */ 4 5 class LoadPicAdapter extends RecyclerVIEw.Adapter<LoadPicAdapter.MyVIEwHolder> { 6 7 Context context; 8 List<LoadfileVo> fileList = null; 9 VIEw vIEw; 10 int picNum = 8;列表的图片个数最大值 11 12 public LoadPicAdapter(Context context,List<LoadfileVo> fileList) { 13 this.context = context; 14 this.fileList = fileList; 15 16 17 picNum) { 18 19 20 this.picNum = picNum; 21 22 23 interface OnItemClickListener { 24 voID click(VIEw vIEw,1)"> positon); 25 26 del(VIEw vIEw); 27 28 29 OnItemClickListener Listener; 30 31 setListener(OnItemClickListener Listener) { 32 this.Listener = Listener; 33 34 35 @OverrIDe 36 public MyVIEwHolder onCreateVIEwHolder(VIEwGroup parent,1)"> vIEwType) { 37 38 vIEw = LayoutInflater.from(context).inflate(R.layout.load_item_pic,parent,1)">false); 39 return new MyVIEwHolder(vIEw); 40 41 42 43 voID onBindVIEwHolder(MyVIEwHolder holder,1)">final position) { 44 45 通过默认设置第一个为空文件为添加退保,且在文件个数小于最大限制值的情况。当图片个数等于最大限制值,第一个则不是添加按钮 46 if (position == 0&&fileList.get(position).getBitmap()==) { 47 holder.ivPic.setimageResource(R.drawable.addpic);加号图片 48 holder.ivPic.setonClickListener( VIEw.OnClickListener() { 49 @OverrIDe 50 onClick(VIEw vIEw) { 51 Listener.click(vIEw,position); 52 } 53 }); 54 holder.ivDel.setVisibility(VIEw.INVISIBLE); 55 holder.bg_progressbar.setVisibility(VIEw.GONE); 56 57 } else 58 Uri uri = Uri.parse(fileList.get(position).getfile().getPath()); 59 holder.ivPic.setimageURI(uri); 60 61 holder.ivPic.setimageBitmap(fileList.get(position).getBitmap()); 62 使用压缩后的图片进行填充到界面上 63
64 65 66 holder.ivDel.setVisibility(VIEw.VISIBLE); 67 holder.bg_progressbar.setVisibility(VIEw.VISIBLE); 68 holder.bg_progressbar.setProgress(fileList.get(position).getPg()); 69 } 70 71 72 holder.ivDel.setonClickListener( 73 @OverrIDe 74 75 判断图片是否上传,上传后将无法删除 76 if (fileList.get(position).isupload()) { 77 Toast.makeText(context,"该图片已上传!",Toast.LENGTH_SHORT).show(); 78 } 79 fileList.remove(position); 80 if (fileList.size()==picNum-1&&fileList.get(0).getBitmap()!=){ 81 fileList.add(0,1)"> LoadfileVo()); 82 }如果数量达到最大数时,前面的加号去掉,然后再减去时,则添加前面的加号 83 notifyDataSetChanged(); 84 if (Listener!= 85 Listener.del(vIEw);传递接口,计算图片个数显示在界面中 86 } 87 88 89 } 90 }); 91 92 93 94 95 96 getItemCount() { 97 fileList.size(); 98 99 100 101 static class MyVIEwHolder extends RecyclerVIEw.VIEwHolder {102 @BindVIEw(R.ID.ivPic)103 ImageVIEw ivPic;104 @BindVIEw(R.ID.ivDel)105 ImageVIEw ivDel;106 @BindVIEw(R.ID.bg_progressbar)107 Progressbar bg_progressbar;108 109 VIEw vIEw;110 111 112 MyVIEwHolder(VIEw vIEw) {113 super(vIEw);114 this.vIEw = vIEw;115 ButterKnife.bind(this116 117 118 }
item 布局//布局自行优化
1 <relativeLayout xmlns:androID="http://schemas.androID.com/apk/res/androID" 2 androID:layout_wIDth="@dimen/dp_110" 3 androID:layout_height="@dimen/dp_115" 5 > 7 < 8 androID:layout_wIDth="match_parent" 9 androID:layout_height="match_parent"10 androID:orIEntation="vertical"11 androID:padding="@dimen/dp_5">13 <ImageVIEw14 androID:ID="@+ID/ivPic"15 androID:layout_wIDth="match_parent"16 androID:layout_height="@dimen/dp_100"17 androID:scaleType="centerCrop"18 androID:src="@drawable/ic_pick"19 />20 21 <Progressbar22 androID:ID="@+ID/bg_progressbar"23 24 androID:layout_wIDth="match_parent"25 androID:layout_height="@dimen/dp_5"26 androID:background="@drawable/shape_progressbar_mini"27 androID:max="100"28 androID:progress="60" />29 </linearLayout>30 <31 androID:ID="@+ID/ivDel"32 androID:layout_wIDth="@dimen/dp_25"33 androID:layout_height="@dimen/dp_25"34 androID:src="@drawable/delete_round"35 androID:layout_alignParentRight="true"/>36 37 </relativeLayout>
1 List<LoadfileVo> fileList = new ArrayList<>(); 2 LoadPicAdapter adapter = 3 4 这里使用ButterKnife 5 @BindVIEw(R.ID.rvPic) 6 RecyclerVIEw rvPic; 7 8 @BindVIEw(R.ID.tvNum) TextVIEw tvNum;11 12 初始化Adapter13 设置图片选择的接口14 private initAdapter() {15 fileList.add(16 adapter = new LoadPicAdapter(this,fileList,8 rvPic.setAdapter(adapter);18 rvPic.setLayoutManager(new GrIDLayoutManager());19 adapter.setListener( LoadPicAdapter.OnItemClickListener() {20 21 positon) {22 if (fileList.size()>823 showShortToast("一次最多上传8张图片!"24 }25 selectPic(); 选择添加图片方法26 30 31 del(VIEw vIEw) {32 tvNum.setText((fileList.size()-1)+"/8"34 35 }
《核心代码》
String mPhtotPath; 2 Uri uriImage; 3 file mPhotofile = 5 选择图片 7 selectPic() {动态请求权限,除此之外还需进行AndroIDmanifest.xml中进行请求11 if (ContextCompat.checkSelfPermission(12 != PackageManager.PERMISSION_GRANTED || ContextCompat.checkSelfPermission(13 Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED14 || ContextCompat.checkSelfPermission(15 Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {16 ActivityCompat.requestPermissions(17 String[]{Manifest.permission.CAMERA,1)">18 Manifest.permission.READ_EXTERNAL_STORAGE,1)">19 Manifest.permission.WRITE_EXTERNAL_STORAGE},1)">20 124 final CharSequence[] items = {"相册","拍照"};25 AlertDialog.Builder dlg = new AlertDialog.Builder(EndLoadMstActivity.26 dlg.setTitle("添加图片"27 dlg.setItems(items,1)"> DialogInterface.OnClickListener() {28 voID onClick(DialogInterface dialog,1)"> item) {29 这里item是根据选择的方式,30 if (item == 031 Intent intent = Intent(Intent.ACTION_PICK);32 intent.setType("image/*"33 startActivityForResult(intent,034 } 35 try36 Intent intent = new Intent("androID.media.action.IMAGE_CAPTURE"37 mPhtotPath = getSdpath() + "/" + getPhotofilename();38 mPhotofile = file(mPhtotPath);39 if (!mPhotofile.exists()) { mPhotofile.createNewfile();41 }42 uriImage = fileProvIDer.getUriForfile(EndLoadMstActivity.this,getPackagename() + ".provIDer",createImagefile());43 44 uriImage = fileProvIDer.getUriForfile(EndLoadMstActivity.45 Log.i("TAG","onClick: "+mPhtotPath+"---------" + getPackagename() + ".provIDer"46 uriImage = Uri.fromfile(mPhotofile);以上一句代替解决相机兼容问题47 intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); intent.putExtra(MediaStore.EXTRA_OUTPUT,uriImage);50 startActivityForResult(intent,151 52 } catch (Exception e) {53 e.printstacktrace();54 55 57 }).create();58 dlg.show();59 60 61 String getSdpath() {62 file sdDir = 63 boolean sdCardExsit = Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED);64 (sdCardExsit) {65 sdDir = Environment.getExternalStorageDirectory();66 67 sdDir.toString();68 69 70 private String getPhotofilename() {71 Date date = Date(System.currentTimeMillis());72 SimpleDateFormat dateFormat = new SimpleDateFormat("'img'_yyyyMMdd_HHmmss"73 return dateFormat.format(date) + ".jpg"74 }
注:这里需要在AndroID中配置一个proveder 具体请参考 AndroID 系统7.0以上调用相机兼容问题
《获取返回的图片》重写onActivityResult方法@OverrIDe 3 protected voID onActivityResult(int requestCode,1)"> resultCode,Intent data) { 4 .onActivityResult(requestCode,resultCode,data); 5 if (requestCode == 1 6 BitmapFactory.Options options = BitmapFactory.Options(); 7 options.inSampleSize = 2; 图片宽高都为原来的二分之一,即图片为原来的四分之一 8 Bitmap bitmap = BitmapFactory.decodefile(mPhtotPath,options); 9 if (bitmap != 10 if (uriImage != 11 saveUritofile(uriImage,1)">12 13 14 bitmap.isRecycled()) {15 bitmap.recycle(); 回收图片所占的内存16 System.gc(); 提醒系统及时回收if (requestCode == 0if (data != 22 Uri uri = data.getData();23 saveUritofile(uri,1)">24 27 28 29 将Uri图片类型转换成file,BitMap类型在界面上显示BitMap图片,以防止内存溢出31 上传可选择file文件上传32 33 voID saveUritofile(Uri uriImage,1)"> type) {34 Bitmap photoBmp = 35 37 38 photoBmp = MediaStore.Images.Media.getBitmap(this.getContentResolver(),1)">39 ByteArrayOutputStream fos = new ByteArrayOutputStream(); photoBmp.compress(Bitmap.CompressFormat.JPEG,80,fos);41 以上代码压缩不行,还是会造成内存溢出42 43 BitmapFactory.Options options = 44 options.inSampleSize = 2; 45 photoBmp = BitmapFactory.decodeStream(.getContentResolver()46 .openinputStream(uriImage),1)">47 48 file file = new file(""49 if (type==050 file = fileParseUtils.getfileByUri(52 }53 if (mPhotofile!=54 file = mPhotofile;56 file file = new file(""); try {60 file = new file(new URI(uriImage.toString())); } catch (URISyntaxException e) {62 e.printstacktrace();63 }64 fileList.add(new LoadfileVo(file,1)">false,photoBmp));65 tvNum.setText((fileList.size()-1)+"/8"66 ){ //判断时候达到最大数量,如果达到最大数量,则去掉前面的加号67 fileList.remove(070 adapter.notifyDataSetChanged();71 72 } (IOException e) {73 e.printstacktrace();74 Log.i("TAG","saveUritofile: ---------压缩图片异常!"75 76 77 78 79 80 }
图片上传到后台OKhttp
一张张图片轮流上传voID netUpload(int i,1)">final String joData) {用JsonOject方式转string传递其他参数 3 5 isRequesthttp) { 6 isRequesthttp = true 7 int finali = i; 8 enterEnable( 9 10 (fileList.get(finali).isupload()) { 11 netUpload(finali + 1 12 } 13 14 Requestbody requestbody = Multipartbody.Builder() .setType(Multipartbody.FORM) 16 .addFormDataPart("mstJson",msg) 其他信息 17 .addFormDataPart("file" 18 Requestbody.create(MediaType.parse("application/octet-stream"),file))文件 19 .build(); 20 Request request = Request.Builder() 21 .url(uploadPic---这里是图片上传的地址).post(requestbody) 22 23 okhttpClIEnt.newCall(request).enqueue( UICallBack() { 24 @OverrIDe 25 onFailureUI(Call call,IOException e) { 26 showShortToast("连接服务器失败" 27 isRequesthttp = 28 enterEnable( 29 30 31 32 33 onResponseUI(Call call,Response response) { 34 35 36 isRequesthttp = 38 String result = response.body().string(); 39 Utils.log("上传图片结果:" + result); 40 42 response.isSuccessful()) { 43 Utils.log("响应失败:" + response.code()); 44 showShortToast("响应失败:" + 45 enterEnable( 46 47 48 } 49 if (result.equals("{}")) { 50 showShortToast("获取服务端数据为空" 51 enterEnable( 52 53 55 JsONObject JsonObject = JsONObject(result); 56 if (JsonObject.getString("IsError").equals("true" 57 showShortToast(JsonObject.getString("ErrMsg" 58 enterEnable( 59 60 } 61 String Data = JsonObject.getString("Data" 62 fileList.get(finali).setPg(100 63 fileList.get(finali).setUpload( 64 adapter.notifyDataSetChanged(); 66 if (finali == fileList.size() - 1 67 showShortToast("上传成功!" 68 69 btnEnter.setText("已上传" 70 71 } 72 netUpload((finali + 1),1)"> } 74 75 76 } 77 isRequesthttp = 78 hIDeLoadingDialog(); 79 showShortToast("上传凭证发生异常!" 80 LogTofile.e("上传凭证发生异常," + e); 81 enterEnable( 82 } 84 85 }); 86 87 } 89 } 90 isRequesthttp = 91 hIDeLoadingDialog(); 93 showShortToast("上传图片请求异常!" 94 LogTofile.e("上传图片请求异常," + 95 enterEnable( 96 97 101 用来提示用户文件上传的情况。同时也是避免同时反复 *** 作voID enterEnable( isEnabled) {103 (isEnabled) {104 btnEnter.setText("重新上传"105 btnEnter.setEnabled( btnEnter.setBackgroundResource(R.drawable.selecter_button); btnEnter.setTextcolor(getResources().getcolor(R.color.inbuttonText));109 } 110 btnEnter.setText("正在上传···"111 btnEnter.setEnabled( btnEnter.setBackgroundResource(R.drawable.buttonshap);113 btnEnter.setTextcolor(getResources().getcolor(R.color.outbuttonText));114 115 }
总结
以上是内存溢出为你收集整理的Android 上传图片到服务器 okhttp一全部内容,希望文章能够帮你解决Android 上传图片到服务器 okhttp一所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)