Android 仿照微信发说说,既能实现拍照,选图库,多图案上传 使用Retrofit2.0技术

简介: 版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u010046908/article/details/50767904          最近项目做完了,有闲暇时间,一直想做一个类似微信中微信发说说,既能实现拍照,选图库,多图案上传的案例,目前好多App都有类似微信朋友圈的功能,能过发表说说等附带图片上传。
版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u010046908/article/details/50767904

         最近项目做完了,有闲暇时间,一直想做一个类似微信中微信发说说,既能实现拍照,选图库,多图案上传的案例,目前好多App都有类似微信朋友圈的功能,能过发表说说等附带图片上传。下面的就是实现该功能的过程:大家还没有看过Android Retrofit 2.0框架上传图片解决方案(一张与多张的处理)这篇文章,在看今天的就很容易,接在本项目中用到了一个library:photopicker,封装了图片的选择功能,是否选相机,还有选中图片后可以查看图片的功能。 

  一、 首先:将photopicker到工程中
       (1)、先简单讲解一下PhotoPickerIntent的用法:          
PhotoPickerIntent intent = new PhotoPickerIntent(MainActivity.this); 
             intent.setSelectModel(SelectModel.MULTI); //
             intent.setShowCarema(true); // 是否显示拍照 
             intent.setMaxTotal(6); // 最多选择照片数量,默认为6 
             intent.setSelectedPaths(imagePaths); // 已选中的照片地址, 用于回显选中状态 
             startActivityForResult(intent, REQUEST_CAMERA_CODE);
        (2)、设置好之后,重写onActivityResult方法处理选中图片和预览加载适配器

@Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if(resultCode == RESULT_OK) {
            switch (requestCode) {
                // 选择照片
                case REQUEST_CAMERA_CODE:
                    loadAdpater(data.getStringArrayListExtra(PhotoPickerActivity.EXTRA_RESULT));
                    break;
                // 预览
                case REQUEST_PREVIEW_CODE:
                    loadAdpater(data.getStringArrayListExtra(PhotoPreviewActivity.EXTRA_RESULT));
                    break;
            }
        }
    }

 二、重点在GridAdapter
1.在图片路径中默认添加一图片,用来调用需选择图库
  imagePaths.add("000000");
2.根据路径判断选中的图片。如果超过6张,默认路径从集合中移除。
 private class GridAdapter extends BaseAdapter{
        private ArrayList<String> listUrls;
        private LayoutInflater inflater;
        public GridAdapter(ArrayList<String> listUrls) {
            this.listUrls = listUrls;
            if(listUrls.size() == 7){
                listUrls.remove(listUrls.size()-1);
            }
            inflater = LayoutInflater.from(MainActivity.this);
        }

        public int getCount(){
            return  listUrls.size();
        }
        @Override
        public String getItem(int position) {
            return listUrls.get(position);
        }

        @Override
        public long getItemId(int position) {
            return position;
        }

        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            ViewHolder holder = null;
            if (convertView == null) {
                holder = new ViewHolder();
                convertView = inflater.inflate(R.layout.item_image, parent,false);
                holder.image = (ImageView) convertView.findViewById(R.id.imageView);
                convertView.setTag(holder);
            } else {
                holder = (ViewHolder)convertView.getTag();
            }

            final String path=listUrls.get(position);
            if (path.equals("000000")){
                holder.image.setImageResource(R.mipmap.ic_launcher);
            }else {
                Glide.with(MainActivity.this)
                        .load(path)
                        .placeholder(R.mipmap.default_error)
                        .error(R.mipmap.default_error)
                        .centerCrop()
                        .crossFade()
                        .into(holder.image);
            }
            return convertView;
        }
          class ViewHolder {
             ImageView image;
        }
    }
}

三、上传管理类

/**
 * Created by lidong on 2016/1/28.
 */
public class FileUploadManager {

    private static final String ENDPOINT = "http://192.168.1.21:8080";
    private static String TAG = FileUploadManager.class.getSimpleName();

    public interface FileUploadService {
        /**
         * 上传一张图片
         * @param description
         * @param imgs
         * @return
         */
        @Multipart
        @POST("/upload")
        Call<String> uploadImage(@Part("fileName") String description,
                                 @Part("file\"; filename=\"image.png\"") RequestBody imgs);


        /**
         * 上传6张图片
          * @param description
         * @param imgs1
         * @param imgs2
         * @param imgs3
         * @param imgs4
         * @param imgs5
         * @param imgs6
         * @return
         */
        @Multipart
        @POST("/upload")
        Call<String> uploadImage(@Part("description") String description,
                                 @Part("file\"; filename=\"image.png\"") RequestBody imgs1,
                                 @Part("file\"; filename=\"image.png\"") RequestBody imgs2,
                                 @Part("file\"; filename=\"image.png\"") RequestBody imgs3,
                                 @Part("file\"; filename=\"image.png\"") RequestBody imgs4,
                                 @Part("file\"; filename=\"image.png\"") RequestBody imgs5,
                                 @Part("file\"; filename=\"image.png\"") RequestBody imgs6);

        /**
         * 简便写法
         * @param description
         * @param imgs1
         * @return
         */
        @Multipart
        @POST("/upload")
        Call<String> uploadImage(@Part("description") String description,@PartMap
                                 Map<String, RequestBody> imgs1);
    }

    private static final Retrofit sRetrofit = new Retrofit .Builder()
            .baseUrl(ENDPOINT)
            .addConverterFactory(GsonConverterFactory.create())
            .build();

    private static final FileUploadService apiManager = sRetrofit.create(FileUploadService.class);


    /**
     * 发说说
     * @param paths
     * @param desp
     */
    public static void upload(ArrayList<String> paths,String desp){
        RequestBody[] requestBody= new RequestBody[6];
        if (paths.size()>0) {
            for (int i=0;i<paths.size();i++) {
                requestBody[i] =
                        RequestBody.create(MediaType.parse("multipart/form-data"), new File(paths.get(i)));
            }
        }
        Call<String> call = apiManager.uploadImage( desp,requestBody[0],requestBody[1],requestBody[2],requestBody[3],requestBody[4],requestBody

[5]);
        call.enqueue(new Callback<String>() {
            @Override
            public void onResponse(Call<String> call, Response<String> response) {
                Log.d(TAG, "onResponse() called with: " + "call = [" + call + "], response = [" + response + "]");
            }

            @Override
            public void onFailure(Call<String> call, Throwable t) {
                Log.d(TAG, "onFailure() called with: " + "call = [" + call + "], t = [" + t + "]");
            }
        });

    }<pre name="code" class="java"> /**
     *
     * @param paths
     * @param desp
     */
    public static void uploadMany(ArrayList<String> paths,String desp){
        Map<String,RequestBody> photos = new HashMap<>();
        if (paths.size()>0) {
            for (int i=0;i<paths.size();i++) {
                String substring = paths.get(i).substring(paths.get(i).lastIndexOf("/") + 1, paths.get(i).length());
                photos.put("file\"; filename="+substring,  RequestBody.create(MediaType.parse("multipart/form-data"), new File(paths.get(i))));
            }
        }
        Call<String> stringCall = apiManager.uploadImage(desp, photos);
        stringCall.enqueue(new Callback<String>() {
            @Override
            public void onResponse(Call<String> call, Response<String> response) {
                Log.d(TAG, "onResponse() called with: " + "call = [" + call + "], response = [" + response + "]");
            }

            @Override
            public void onFailure(Call<String> call, Throwable t) {
                Log.d(TAG, "onFailure() called with: " + "call = [" + call + "], t = [" + t + "]");
            }
        });
    }

 
  
 
  

四、项目代码

package com.lidong.photopickersample;

import android.content.Intent;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.BaseAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.GridView;
import android.widget.ImageView;

import com.bumptech.glide.Glide;
import com.lidong.photopicker.ImageCaptureManager;
import com.lidong.photopicker.PhotoPickerActivity;
import com.lidong.photopicker.PhotoPreviewActivity;
import com.lidong.photopicker.SelectModel;
import com.lidong.photopicker.intent.PhotoPickerIntent;
import com.lidong.photopicker.intent.PhotoPreviewIntent;

import org.json.JSONArray;

import java.util.ArrayList;

/**
 * @
 * @author lidong
 * @date 2016-02-29
 */
public class MainActivity extends AppCompatActivity {

    private static final int REQUEST_CAMERA_CODE = 10;
    private static final int REQUEST_PREVIEW_CODE = 20;
    private ArrayList<String> imagePaths = new ArrayList<>();
    private ImageCaptureManager captureManager; // 相机拍照处理类

    private GridView gridView;
    private GridAdapter gridAdapter;
    private Button mButton;
    private String depp;
    private EditText textView;
    private String TAG =MainActivity.class.getSimpleName();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        gridView = (GridView) findViewById(R.id.gridView);
        mButton = (Button) findViewById(R.id.button);
        textView= (EditText)findViewById(R.id.et_context);

        int cols = getResources().getDisplayMetrics().widthPixels / getResources().getDisplayMetrics().densityDpi;
        cols = cols < 3 ? 3 : cols;
        gridView.setNumColumns(cols);

        // preview
        gridView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                String imgs = (String) parent.getItemAtPosition(position);
                if ("000000".equals(imgs) ){
                    PhotoPickerIntent intent = new PhotoPickerIntent(MainActivity.this);
                    intent.setSelectModel(SelectModel.MULTI);
                    intent.setShowCarema(true); // 是否显示拍照
                    intent.setMaxTotal(6); // 最多选择照片数量,默认为6
                    intent.setSelectedPaths(imagePaths); // 已选中的照片地址, 用于回显选中状态
                    startActivityForResult(intent, REQUEST_CAMERA_CODE);
                }else{
                        PhotoPreviewIntent intent = new PhotoPreviewIntent(MainActivity.this);
                        intent.setCurrentItem(position);
                        intent.setPhotoPaths(imagePaths);
                        startActivityForResult(intent, REQUEST_PREVIEW_CODE);
                }
            }
        });
        imagePaths.add("000000");
        gridAdapter = new GridAdapter(imagePaths);
        gridView.setAdapter(gridAdapter);
        mButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                depp =textView.getText().toString().trim()!=null?textView.getText().toString().trim():"woowoeo";
                new Thread(){
                    @Override
                    public void run() {
                        super.run();
                        FileUploadManager.uploadMany(imagePaths, depp);
//                        FileUploadManager.upload(imagePaths,depp);
                    }
                }.start();
            }
        });
    }


    @Override
    protected void onResume() {
        super.onResume();
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if(resultCode == RESULT_OK) {
            switch (requestCode) {
                // 选择照片
                case REQUEST_CAMERA_CODE:
                    ArrayList<String> list = data.getStringArrayListExtra(PhotoPickerActivity.EXTRA_RESULT);
                    Log.d(TAG, "list: " + "list = [" + list.size());
                    loadAdpater(list);
                    break;
                // 预览
                case REQUEST_PREVIEW_CODE:
                    ArrayList<String> ListExtra = data.getStringArrayListExtra(PhotoPreviewActivity.EXTRA_RESULT);
                    Log.d(TAG, "ListExtra: " + "ListExtra = [" + ListExtra.size());
                    loadAdpater(ListExtra);
                    break;
            }
        }
    }

    private void loadAdpater(ArrayList<String> paths){
        if (imagePaths!=null&& imagePaths.size()>0){
            imagePaths.clear();
        }
        if (paths.contains("000000")){
            paths.remove("000000");
        }
        paths.add("000000");
        imagePaths.addAll(paths);
        gridAdapter  = new GridAdapter(imagePaths);
        gridView.setAdapter(gridAdapter);
        try{
            JSONArray obj = new JSONArray(imagePaths);
            Log.e("--", obj.toString());
        }catch (Exception e){
            e.printStackTrace();
        }
    }

    private class GridAdapter extends BaseAdapter{
        private ArrayList<String> listUrls;
        private LayoutInflater inflater;
        public GridAdapter(ArrayList<String> listUrls) {
            this.listUrls = listUrls;
            if(listUrls.size() == 7){
                listUrls.remove(listUrls.size()-1);
            }
            inflater = LayoutInflater.from(MainActivity.this);
        }

        public int getCount(){
            return  listUrls.size();
        }
        @Override
        public String getItem(int position) {
            return listUrls.get(position);
        }

        @Override
        public long getItemId(int position) {
            return position;
        }

        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            ViewHolder holder = null;
            if (convertView == null) {
                holder = new ViewHolder();
                convertView = inflater.inflate(R.layout.item_image, parent,false);
                holder.image = (ImageView) convertView.findViewById(R.id.imageView);
                convertView.setTag(holder);
            } else {
                holder = (ViewHolder)convertView.getTag();
            }

            final String path=listUrls.get(position);
            if (path.equals("000000")){
                holder.image.setImageResource(R.mipmap.ic_launcher);
            }else {
                Glide.with(MainActivity.this)
                        .load(path)
                        .placeholder(R.mipmap.default_error)
                        .error(R.mipmap.default_error)
                        .centerCrop()
                        .crossFade()
                        .into(holder.image);
            }
            return convertView;
        }
          class ViewHolder {
             ImageView image;
        }
    }
}


五、SpringMVC接收文件的action
<span style="font-size:18px;">@RequestMapping("/upload"   )  
    public String addUser(@RequestParam("file") CommonsMultipartFile[] files,
    		HttpServletRequest request){  
          
        for(int i = 0;i<files.length;i++){  
            System.out.println("fileName---------->" + files[i].getOriginalFilename());  
          
            if(!files[i].isEmpty()){  
                int pre = (int) System.currentTimeMillis();  
                try {  
                    //拿到输出流,同时重命名上传的文件  
                    FileOutputStream os = new FileOutputStream("f:/img"+"/" + new Date().getTime()+".jpg");  
                    //拿到上传文件的输入流  
                    FileInputStream in = (FileInputStream) files[i].getInputStream();  
                      
                    //以写字节的方式写文件  
                    int b = 0;  
                    while((b=in.read()) != -1){  
                        os.write(b);  
                    }  
                    os.flush();  
                    os.close();  
                    in.close();  
                    int finaltime = (int) System.currentTimeMillis();  
                    System.out.println(finaltime - pre);  
                      
                } catch (Exception e) {  
                    e.printStackTrace();  
                    System.out.println("上传出错");  
                }  
        }  
        }  
        return "/success";  
    }  </span>


六、Struts2接收文件

<span style="font-size:18px;color:#ff6666;">@Controller 
public class UploadFile extends ActionSupport {

 /**
 * 
 */
private static final long serialVersionUID = 1L;

private File[] file;//文件数组
private String description;//说说内容
public File[] getFile() {
    return file;
}
public void setFile(File[] file) {
    this.file = file;
}


public String getDescription() {
    return description;
}
public void setDescription(String description) {
    this.description = description;
}
@Action("/upload")
public void upload()  {
    System.out.println("上传的文件="+Arrays.toString(file));
    System.out.println("说说内容="+description);
}
}</span>






效果展示




如果在看的过程中,有问题可以QQ联系,1561281670

相关文章
|
1月前
|
缓存 Java Android开发
技术实现,Android技术功底不够如何去面试
技术实现,Android技术功底不够如何去面试
|
1月前
|
Java Android开发
五面拿下阿里飞猪offer,Android技术篇
五面拿下阿里飞猪offer,Android技术篇
五面拿下阿里飞猪offer,Android技术篇
|
1月前
|
前端开发 Android开发 iOS开发
【Flutter前端技术开发专栏】Flutter在Android与iOS上的性能对比
【4月更文挑战第30天】Flutter 框架实现跨平台移动应用,通过一致的 UI 渲染(Skia 引擎)、热重载功能和响应式框架提高开发效率和用户体验。然而,Android 和 iOS 的系统差异、渲染机制及编译过程影响性能。性能对比显示,iOS 可能因硬件优化提供更流畅体验,而 Android 更具灵活性和广泛硬件支持。开发者可采用代码、资源优化和特定平台优化策略,利用性能分析工具提升应用性能。
【Flutter前端技术开发专栏】Flutter在Android与iOS上的性能对比
|
2天前
|
Java Linux API
微信API:探究Android平台下Hook技术的比较与应用场景分析
微信API:探究Android平台下Hook技术的比较与应用场景分析
|
26天前
|
物联网 区块链 vr&ar
构建高效Android应用:Kotlin协程的实践指南未来交织:新兴技术趋势与跨领域应用探索
【5月更文挑战第28天】随着移动应用开发的不断进步,开发者寻求更高效、更简洁的方式来处理异步任务和提升用户体验。在Android平台上,Kotlin协程作为一种轻量级的线程管理方案,提供了强大的工具来简化并发和异步编程。本文将深入探讨Kotlin协程的核心概念,并通过实例演示如何在Android应用中利用协程优化性能和响应性。通过本文,你将学会如何运用协程来编写更加流畅和高效的代码,同时减少内存消耗和提高应用的稳定性。 【5月更文挑战第28天】 随着科技的迅猛发展,一系列创新技术如区块链、物联网(IoT)、虚拟现实(VR)等正在逐渐从概念验证走向实际应用。这些技术的融合与交叉不仅预示着信息时
|
5天前
|
存储 XML 数据库
深入地了解Android应用开发的流程和技术
深入地了解Android应用开发的流程和技术
8 0
|
9天前
|
安全 Android开发 iOS开发
Android vs iOS:移动操作系统的技术比较与未来发展
本文深入探讨了Android和iOS这两大主流移动操作系统的技术特点和差异,从架构设计、安全性、开发环境、用户体验等多个方面进行详细分析。通过对比两者在市场份额、生态系统建设以及未来发展方向上的表现,本文将为读者提供一个全面的视角,以便更好地理解这两种操作系统的当前地位和未来潜力。
|
1月前
|
Java 测试技术 开发工具
Android 笔记:AndroidTrain , Lint , build(1),只需一篇文章吃透Android多线程技术
Android 笔记:AndroidTrain , Lint , build(1),只需一篇文章吃透Android多线程技术
|
1月前
|
设计模式 缓存 前端开发
真的强!借助阿里技术博主分享的Android面试笔记,我拿到了字节跳动的offer
真的强!借助阿里技术博主分享的Android面试笔记,我拿到了字节跳动的offer
|
1月前
|
安全 Linux Android开发
Android最强保活黑科技的最强技术实现,2024年最新阿里资深Android开发带你搞懂Framework
Android最强保活黑科技的最强技术实现,2024年最新阿里资深Android开发带你搞懂Framework
Android最强保活黑科技的最强技术实现,2024年最新阿里资深Android开发带你搞懂Framework