Android实现多图上传 QQ发说说图片上传 朋友圈图片上传

xiaoxiao2021-02-27  786

本demo使用七牛上传来做的图片,视频上传.

别的先不说,先上效果图 , 不想看的也可以直接拖到最下面进入我的github下载,

第一步:

build.gradle里面导入: compile ‘top.zibin:Luban:1.0.9’ //luban进行图片压缩 compile ‘com.android.support:design:25.3.1’ compile ‘com.qiniu:qiniu-android-sdk:7.2.+’//七牛 compile ‘me.iwf.photopicker:PhotoPicker:0.1.8’//图片选择 compile ‘cn.fanrunqi:waveprogress:1.0.1’//上传效果

第二步:

服务端对七牛进行集成并提供接口 如:String url = “http://112.74.28.179:8080/Chislim/Travel_notes_Servlet?dowhat=getUpLoadToken“; 代码里面对七牛上传进行初始化设置

//对七牛的初始化设置 private void initConfig() { Configuration config = new Configuration.Builder() .chunkSize(256 * 1024) //分片上传时,每片的大小。 默认256K .putThreshhold(512 * 1024) // 启用分片上传阀值。默认512K .connectTimeout(10) // 链接超时。默认10秒 .responseTimeout(60) // 服务器响应超时。默认60秒 // .recorder(recorder) // recorder分片上传时,已上传片记录器。默认null // .recorder(recorder, keyGen) // keyGen 分片上传时,生成标识符,用于片记录器区分是那个文件的上传记录 .zone(Zone.zone0) // 设置区域,指定不同区域的上传域名、备用域名、备用IP。默认 Zone.zone0 .build(); // 重用uploadManager。一般地,只需要创建一个uploadManager对象 uploadManager = new UploadManager(config); }

初始化七牛完毕后,点击按钮发送请求得到七牛的token并携带token进入发送说说的页面.

client.newCall(request).enqueue(new okhttp3.Callback() { @Override public void onResponse(okhttp3.Call call, okhttp3.Response response) throws IOException { String token = response.body().string(); Log.i("七牛", token); //第三步跳转至 发布说说页面 Intent intent = new Intent(MainActivity.this , PublishHumorActivity.class); intent.putExtra("token" , token) ; startActivityForResult(intent , GOTO_PUBLISH_HUMOR_REQUEST); } @Override public void onFailure(okhttp3.Call call, IOException e) { Log.i("七牛", e.getMessage()); } });

第三步

建立bean对象,用来接受上传的信息

public class HumorImgAndVideoBean { public String fileName =""; //文件名 public String path =""; // 本地路径 public String urlPath ="" ; //网络路径,上传时只需要上传这个给服务端存储. public String compresPath="" ; //图片压缩过后的路径 public boolean isVideo ;//判断是否为视频 public int proess = 0 ; //上传的进度 }

第四步

构建布局文件,这个部分就不代码了哈… 构建给recyclerView的adapter

public class HumorImgAndVideoAdpter extends RecyclerView.Adapter { private Context mContext ; private List<HumorImgAndVideoBean> lists ; private OnMyItemClick onMyItemClick ; public void setOnMyItemClick(OnMyItemClick onMyItemClick) { this.onMyItemClick = onMyItemClick; } //提供点击回调事件 public interface OnMyItemClick{ public void addData(); public void ImageClick(int position) ; public void VideoClick() ; public void addDataNoVideo(); public void deleteItem(int position); } public HumorImgAndVideoAdpter(Context mContext , List<HumorImgAndVideoBean> lists){ this.mContext = mContext ; this.lists = lists ; } @Override public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { View view = LayoutInflater.from(mContext).inflate(R.layout.humor_img_video_item , parent , false) ; return new ImgAndVideoHodler(view); } @Override public void onBindViewHolder(RecyclerView.ViewHolder holder, final int position) { ImgAndVideoHodler holder1 = (ImgAndVideoHodler) holder; holder1.icon_cancel.setTag(position); //当list没有数据时 if(lists == null || lists.size() == 0){ holder1.icon_cancel.setVisibility(View.GONE); holder1.waveProgressbar.setVisibility(View.GONE); Picasso.with(mContext).load(R.mipmap.btn_add).into(holder1.tu_pian); holder1.tu_pian.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { if(onMyItemClick != null){ onMyItemClick.addData(); } } }); }else { //当list有数据的时候 //1 .只有一条是视频的数据 if(lists.get(0).isVideo == true){ /*Picasso.with(mContext).load(new File(lists.get(position).path) ).resize(200 , 200).into(holder1.tu_pian);*/ holder1.waveProgressbar.setVisibility(View.VISIBLE); holder1.icon_cancel.setVisibility(View.VISIBLE); if(lists.get(0).proess != 100) { holder1.waveProgressbar.setCurrent(lists.get(0).proess, lists.get(0).proess + "%"); }else{ holder1.waveProgressbar.setVisibility(View.GONE); } Glide.with(mContext).load(new File(lists.get(position).path)).into(holder1.tu_pian); holder1.tu_pian.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { if(onMyItemClick != null){ onMyItemClick.VideoClick(); } } }); }else{ //2.全是图片的时候, if(lists.size() >= 9){ holder1.waveProgressbar.setVisibility(View.VISIBLE); holder1.icon_cancel.setVisibility(View.VISIBLE); if(lists.get(position).proess != 100) { holder1.waveProgressbar.setCurrent(lists.get(position).proess, lists.get(position).proess + "%"); }else{ holder1.waveProgressbar.setVisibility(View.GONE); } Picasso.with(mContext).load(new File(lists.get(position).path) ).resize(200 , 200).into(holder1.tu_pian); holder1.tu_pian.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { if(onMyItemClick != null){ onMyItemClick.ImageClick(position); } } }); }else{ if(position != lists.size() ){ holder1.waveProgressbar.setVisibility(View.VISIBLE); holder1.icon_cancel.setVisibility(View.VISIBLE); if(lists.get(position).proess != 100) { holder1.waveProgressbar.setCurrent(lists.get(position).proess, lists.get(position).proess + "%"); }else{ holder1.waveProgressbar.setVisibility(View.GONE); } Picasso.with(mContext).load(new File(lists.get(position).path) ).resize(200 , 200).into(holder1.tu_pian); holder1.tu_pian.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { if(onMyItemClick != null){ onMyItemClick.ImageClick(position); } } }); }else{ holder1.waveProgressbar.setVisibility(View.GONE); holder1.icon_cancel.setVisibility(View.GONE); Picasso.with(mContext).load(R.mipmap.btn_add).into(holder1.tu_pian); holder1.tu_pian.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { if(onMyItemClick != null){ onMyItemClick.addDataNoVideo(); } } }); } } } } holder1.icon_cancel.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { if(onMyItemClick != null){ onMyItemClick.deleteItem(position); } } }); } @Override public int getItemCount() { if(lists == null || lists.size() == 0 || lists.get(0).isVideo == true){ return 1 ; } if(lists.size() >= 9 ){ return 9 ; } return lists.size() + 1; } public class ImgAndVideoHodler extends RecyclerView.ViewHolder{ public ImageView tu_pian ; public ImageView icon_cancel ; public WaveProgressView waveProgressbar ; public ImgAndVideoHodler(View itemView) { super(itemView); // ButterKnife.bind(this , itemView); tu_pian = (ImageView) itemView.findViewById(R.id.tu_pian); icon_cancel = (ImageView) itemView.findViewById(R.id.delete_iv); waveProgressbar = (WaveProgressView)itemView.findViewById(R.id.waveProgressbar); waveProgressbar.setMaxProgress(100); } } }

第五步

实现Adaper里面的回调方法

adapter.setOnMyItemClick(new HumorImgAndVideoAdpter.OnMyItemClick() { @Override public void addData() { /* Toast.makeText(mActivity, "没有数据加载数据", Toast.LENGTH_SHORT).show(); PhotoPickerIntent intentPhoto = new PhotoPickerIntent(mActivity); intentPhoto.setPhotoCount(9 - lists.size()); intentPhoto.setShowCamera(true); startActivityForResult(intentPhoto,CHECK_IMAGE_REQUEST );*/ /*Intent intent = new Intent(); intent.setType("video*//*"); intent.setAction(Intent.ACTION_GET_CONTENT); startActivityForResult(intent, CHECK_VIDEO_REQUEST);*/ if (view == null) { view = LayoutInflater.from(mActivity).inflate(R.layout.layout_popupwindow , null); } TextView btnCarema = (TextView) view.findViewById(R.id.btn_camera); TextView btnPhoto = (TextView) view.findViewById(R.id.btn_photo); TextView btnCancel = (TextView) view.findViewById(R.id.btn_cancel); final PopupWindow popupWindow = new PopupWindow(view, ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT); popupWindow.setBackgroundDrawable(getResources().getDrawable(android.R.color.transparent)); popupWindow.setOutsideTouchable(true); View parent = LayoutInflater.from(mActivity).inflate(R.layout.activity_publish_humor , null); popupWindow.showAtLocation(parent, Gravity.BOTTOM, 0, 0); //popupWindow在弹窗的时候背景半透明 final WindowManager.LayoutParams params = getWindow().getAttributes(); params.alpha = 0.5f; getWindow().setAttributes(params); popupWindow.setOnDismissListener(new PopupWindow.OnDismissListener() { @Override public void onDismiss() { params.alpha = 1.0f; getWindow().setAttributes(params); } }); btnCarema.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { //跳转到调用系统相机 Intent intent = new Intent(); intent.setType("video/*"); intent.setAction(Intent.ACTION_GET_CONTENT); startActivityForResult(intent, CHECK_VIDEO_REQUEST); popupWindow.dismiss(); } }); btnPhoto.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { //跳转到调用系统图库 PhotoPickerIntent intentPhoto = new PhotoPickerIntent(mActivity); intentPhoto.setPhotoCount(9 - lists.size()); intentPhoto.setShowCamera(true); startActivityForResult(intentPhoto,CHECK_IMAGE_REQUEST ); popupWindow.dismiss(); } }); btnCancel.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { popupWindow.dismiss(); } }); } @Override public void ImageClick(int position) { Toast.makeText(mActivity, "查看大图", Toast.LENGTH_SHORT).show(); Intent intent = new Intent(mActivity , PhotoActivity.class); PhotoActivity.bitmap = lists ; intent.putExtra("ID" , position) ; startActivity(intent); } @Override public void VideoClick() { //用来播放视频 } @Override public void addDataNoVideo() { Toast.makeText(mActivity, "添加过了图像,不能添加视频了", Toast.LENGTH_SHORT).show(); PhotoPickerIntent intentPhoto = new PhotoPickerIntent(mActivity); intentPhoto.setPhotoCount(9 - lists.size()); intentPhoto.setShowCamera(true); startActivityForResult(intentPhoto,CHECK_IMAGE_REQUEST ); } @Override public void deleteItem(int position) { lists.remove(position) ; adapter.notifyDataSetChanged(); } }); }

第六步

选择图片或者视频后进行后的页面回调方法:

@Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); if(resultCode == RESULT_OK ){ switch (requestCode){ case CHECK_IMAGE_REQUEST : //选择图片后返回的路径集合 List<String> mResultsPath = data.getStringArrayListExtra(PhotoPickerActivity.KEY_SELECTED_PHOTOS); for(int i = 0 ; i < mResultsPath.size() ; i++){ final int postion = i ; final HumorImgAndVideoBean bean = new HumorImgAndVideoBean(); bean.path = mResultsPath.get(i); //命名文件的名字(按照时间进行) bean.fileName = System.currentTimeMillis()+""+i; lists.add(bean); //压缩图片 Luban.get(this) .setFilename(bean.fileName) //设置压缩完成后的文件名 .load(new File(bean.path)) //传人要压缩的图片 .putGear(Luban.THIRD_GEAR) //设定压缩档次,默认三挡 .setCompressListener(new OnCompressListener() { //设置回调 @Override public void onStart() { // TODO 压缩开始前调用,可以在方法内启动 loading UI } @Override public void onSuccess(File file) { // TODO 压缩成功后调用,返回压缩后的图片文件 //由于压缩的异步的,所以在此通过文件名进行比对 , 当图片已经过小时则不进行压缩. String name2 = file.getName().split("\\.")[0]; for (int i = 0 ; i< lists.size() ; i++){ String name1 = lists.get(i).fileName; String pa = lists.get(i).path; if(name1.equals(name2) || file.getAbsolutePath().equals(pa)){ lists.get(i).compresPath = file.getPath() ; Message message = myHandler.obtainMessage() ; message.what = YANSUO_SUCCESS ; message.arg1 = i ; myHandler.sendMessage(message) ; } } } @Override public void onError(Throwable e) { // TODO 当压缩过去出现问题时调用 Log.d("出现了问题" , e.getMessage()) ; } }).launch(); //启动压缩 adapter.notifyDataSetChanged(); } break; case CHECK_VIDEO_REQUEST : HumorImgAndVideoBean bean = new HumorImgAndVideoBean(); bean.isVideo = true ; Uri uri = data.getData(); Cursor cursor = getContentResolver().query(uri, null, null, null, null); cursor.moveToFirst(); // String imgNo = cursor.getString(0); // 图片编号 String v_path = cursor.getString(1); // 图片文件路径 bean.path = v_path ; lists.add(bean); adapter.notifyDataSetChanged(); lists.get(0).compresPath = lists.get(0).path ; getUpimg(lists.get(0)); break; } } }

在选择图片压缩时使用的是luban,并且压缩图片是异步操作所以根据在压缩时给其设置压缩文件的名字,压缩完成后与之进行比对,若相同则将压缩的路径赋予bean的compresPath属性,然后使用七牛上传,将压缩过后的图片上传给七牛的服务端.

**

第一次写博客,可能有些没有写清楚,大家可以去github上下载我的代码在运行的看看 项目地址 ,有什么问题的话可以加我QQ2372949410,大家一起共同学习一波.

**

转载请注明原文地址: https://www.6miu.com/read-403.html

最新回复(0)