Android使用Retrofit2.0技术仿微信发说说

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

一、 首先:将photopicker到工程中

(1)、先简单讲解一下PhotoPickerIntent的用法:          

?

1

2

3

4

5

6

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方法处理选中图片和预览加载适配器

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

@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张,默认路径从集合中移除。

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

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;

 }

 }

}

三、上传管理类

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

/**

 * 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 + "]");

  }

 });

 }

四、项目代码

 

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

150

151

152

153

154

155

156

157

158

159

160

161

162

163

164

165

166

167

168

169

170

171

172

173

174

175

176

177

178

179

180

181

182

183

184

185

186

187

188

189

190

191

192

193

194

195

196

197

198

199

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

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

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";

}

 六、Struts2接收文件

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

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);

}

}

项目下载地址:https://github.com/lidong1665/Android-UploadMultipartImage

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值