Android应用中拍照后获取照片路径并上传的实例分享

时间:2021-09-28 06:18:43

activity 中的代码,我只贴出重要的事件部分代码

?
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
public void dophoto(view view)
{
  destorybimap();
  string state = environment.getexternalstoragestate();
  if (state.equals(environment.media_mounted)) {
    intent intent = new intent("android.media.action.image_capture");
    startactivityforresult(intent, 1);
  } else {
    toast.maketext(mainactivity.this, "没有sd卡", toast.length_long).show();
  }
}
 
@override
protected void onactivityresult(int requestcode, int resultcode, intent data)
{
  uri uri = data.getdata();
  if (uri != null) {
    this.photo = bitmapfactory.decodefile(uri.getpath());
  }
  if (this.photo == null) {
    bundle bundle = data.getextras();
    if (bundle != null) {
      this.photo = (bitmap) bundle.get("data");
    } else {
      toast.maketext(mainactivity.this, "拍照失败", toast.length_long).show();
      return;
    }
  }
 
  fileoutputstream fileoutputstream = null;
  try {
    // 获取 sd 卡根目录
    string savedir = environment.getexternalstoragedirectory() + "/meitian_photos";
    // 新建目录
    file dir = new file(savedir);
    if (! dir.exists()) dir.mkdir();
    // 生成文件名
    simpledateformat t = new simpledateformat("yyyymmddsssss");
    string filename = "mt" + (t.format(new date())) + ".jpg";
    // 新建文件
    file file = new file(savedir, filename);
    // 打开文件输出流
    fileoutputstream = new fileoutputstream(file);
    // 生成图片文件
    this.photo.compress(bitmap.compressformat.jpeg, 100, fileoutputstream);
    // 相片的完整路径
    this.picpath = file.getpath();
    imageview imageview = (imageview) findviewbyid(r.id.showphoto);
    imageview.setimagebitmap(this.photo);
  } catch (exception e) {
    e.printstacktrace();
  } finally {
    if (fileoutputstream != null) {
      try {
        fileoutputstream.close();
      } catch (exception e) {
        e.printstacktrace();
      }
    }
  }
}
 
/**
 * 销毁图片文件
 */
private void destorybimap()
{
  if (photo != null && ! photo.isrecycled()) {
    photo.recycle();
    photo = null;
  }
}

layout 布局页面

?
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
<linearlayout xmlns:android="http://schemas.android.com/apk/res/android"
  android:layout_width="fill_parent"
  android:layout_height="fill_parent"
  android:orientation="vertical"
  >
  <scrollview
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    >
    <linearlayout
      android:layout_width="fill_parent"
      android:layout_height="fill_parent"
      android:orientation="vertical"
      >
      <button
        android:id="@+id/dophoto"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:padding="10dp"
        android:layout_marginbottom="10dp"
        android:text="拍照"
        android:onclick="dophoto"
        />
      <textview
        android:id="@+id/showcontent"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_marginbottom="10dp"
        />
      <imageview
        android:id="@+id/showphoto"
        android:layout_width="fill_parent"
        android:layout_height="250dp"
        android:scaletype="centercrop"
        android:src="@drawable/add"
        android:layout_marginbottom="10dp"
        />
    </linearlayout>
  </scrollview>
</linearlayout>

其中的上传工具类我们下面一起来看:
android 发送http get post 请求以及通过 multipartentitybuilder 上传文件

全部使用新的方式 multipartentitybuilder 来处理了。
httpmime-4.3.2.jar   
httpcore-4.3.1.jar  

下载地址:http://hc.apache.org/downloads.cgi
有些镜像貌似打不开,页面上可以可以选择国内的 .cn 后缀的域名镜像服务器来下载

直接上代码了:
zhttprequset.java

?
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
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
package com.ai9475.util;
 
import org.apache.http.httpentity;
import org.apache.http.httpresponse;
import org.apache.http.httpstatus;
import org.apache.http.client.httpclient;
import org.apache.http.client.methods.httpget;
import org.apache.http.client.methods.httppost;
import org.apache.http.client.methods.httprequestbase;
import org.apache.http.entity.mime.httpmultipartmode;
import org.apache.http.entity.mime.multipartentitybuilder;
import org.apache.http.impl.client.defaulthttpclient;
import org.apache.http.params.basichttpparams;
import org.apache.http.params.httpconnectionparams;
import org.apache.http.params.httpparams;
import org.apache.http.protocol.http;
 
import java.io.bytearrayoutputstream;
import java.io.ioexception;
import java.io.inputstream;
import java.nio.charset.charset;
 
/**
 * created by zhouz on 14-2-3.
 */
public class zhttprequest
{
  public final string http_get = "get";
 
  public final string http_post = "post";
 
  /**
   * 当前请求的 url
   */
  protected string url = "";
 
  /**
   * http 请求的类型
   */
  protected string requsettype = http_get;
 
  /**
   * 连接请求的超时时间
   */
  protected int connectiontimeout = 5000;
 
  /**
   * 读取远程数据的超时时间
   */
  protected int sotimeout = 10000;
 
  /**
   * 服务端返回的状态码
   */
  protected int statuscode = -1;
 
  /**
   * 当前链接的字符编码
   */
  protected string charset = http.utf_8;
 
  /**
   * http get 请求管理器
   */
  protected httprequestbase httprequest= null;
 
  /**
   * http 请求的配置参数
   */
  protected httpparams httpparameters= null;
 
  /**
   * http 请求响应
   */
  protected httpresponse httpresponse= null;
 
  /**
   * http 客户端连接管理器
   */
  protected httpclient httpclient= null;
 
  /**
   * http post 方式发送多段数据管理器
   */
  protected multipartentitybuilder multipartentitybuilder= null;
 
  /**
   * 绑定 http 请求的事件监听器
   */
  protected onhttprequestlistener onhttprequestlistener = null;
 
  public zhttprequest(){}
 
  public zhttprequest(onhttprequestlistener listener) {
    this.setonhttprequestlistener(listener);
  }
 
  /**
   * 设置当前请求的链接
   *
   * @param url
   * @return
   */
  public zhttprequest seturl(string url)
  {
    this.url = url;
    return this;
  }
 
  /**
   * 设置连接超时时间
   *
   * @param timeout 单位(毫秒),默认 5000
   * @return
   */
  public zhttprequest setconnectiontimeout(int timeout)
  {
    this.connectiontimeout = timeout;
    return this;
  }
 
  /**
   * 设置 socket 读取超时时间
   *
   * @param timeout 单位(毫秒),默认 10000
   * @return
   */
  public zhttprequest setsotimeout(int timeout)
  {
    this.sotimeout = timeout;
    return this;
  }
 
  /**
   * 设置获取内容的编码格式
   *
   * @param charset 默认为 utf-8
   * @return
   */
  public zhttprequest setcharset(string charset)
  {
    this.charset = charset;
    return this;
  }
 
  /**
   * 获取当前 http 请求的类型
   *
   * @return
   */
  public string getrequesttype()
  {
    return this.requsettype;
  }
 
  /**
   * 判断当前是否 http get 请求
   *
   * @return
   */
  public boolean isget()
  {
    return this.requsettype == http_get;
  }
 
  /**
   * 判断当前是否 http post 请求
   *
   * @return
   */
  public boolean ispost()
  {
    return this.requsettype == http_post;
  }
 
  /**
   * 获取 http 请求响应信息
   *
   * @return
   */
  public httpresponse gethttpresponse()
  {
    return this.httpresponse;
  }
 
  /**
   * 获取 http 客户端连接管理器
   *
   * @return
   */
  public httpclient gethttpclient()
  {
    return this.httpclient;
  }
 
  /**
   * 添加一条 http 请求的 header 信息
   *
   * @param name
   * @param value
   * @return
   */
  public zhttprequest addheader(string name, string value)
  {
    this.httprequest.addheader(name, value);
    return this;
  }
 
  /**
   * 获取 http get 控制器
   *
   * @return
   */
  public httpget gethttpget()
  {
    return (httpget) this.httprequest;
  }
 
  /**
   * 获取 http post 控制器
   *
   * @return
   */
  public httppost gethttppost()
  {
    return (httppost) this.httprequest;
  }
 
  /**
   * 获取请求的状态码
   *
   * @return
   */
  public int getstatuscode()
  {
    return this.statuscode;
  }
 
  /**
   * 通过 get 方式请求数据
   *
   * @param url
   * @return
   * @throws ioexception
   */
  public string get(string url) throws exception
  {
    this.requsettype = http_get;
    // 设置当前请求的链接
    this.seturl(url);
    // 新建 http get 请求
    this.httprequest = new httpget(this.url);
    // 执行客户端请求
    this.httpclientexecute();
    // 监听服务端响应事件并返回服务端内容
    return this.checkstatus();
  }
 
  /**
   * 获取 http post 多段数据提交管理器
   *
   * @return
   */
  public multipartentitybuilder getmultipartentitybuilder()
  {
    if (this.multipartentitybuilder == null) {
      this.multipartentitybuilder = multipartentitybuilder.create();
      // 设置为浏览器兼容模式
      multipartentitybuilder.setmode(httpmultipartmode.browser_compatible);
      // 设置请求的编码格式
      multipartentitybuilder.setcharset(charset.forname(this.charset));
    }
    return this.multipartentitybuilder;
  }
 
  /**
   * 配置完要 post 提交的数据后, 执行该方法生成数据实体等待发送
   */
  public void buildpostentity()
  {
    // 生成 http post 实体
    httpentity httpentity = this.multipartentitybuilder.build();
    this.gethttppost().setentity(httpentity);
  }
 
  /**
   * 发送 post 请求
   *
   * @param url
   * @return
   * @throws exception
   */
  public string post(string url) throws exception
  {
    this.requsettype = http_post;
    // 设置当前请求的链接
    this.seturl(url);
    // 新建 http post 请求
    this.httprequest = new httppost(this.url);
    // 执行客户端请求
    this.httpclientexecute();
    // 监听服务端响应事件并返回服务端内容
    return this.checkstatus();
  }
 
  /**
   * 执行 http 请求
   *
   * @throws exception
   */
  protected void httpclientexecute() throws exception
  {
    // 配置 http 请求参数
    this.httpparameters = new basichttpparams();
    this.httpparameters.setparameter("charset", this.charset);
    // 设置 连接请求超时时间
    httpconnectionparams.setconnectiontimeout(this.httpparameters, this.connectiontimeout);
    // 设置 socket 读取超时时间
    httpconnectionparams.setsotimeout(this.httpparameters, this.sotimeout);
    // 开启一个客户端 http 请求
    this.httpclient = new defaulthttpclient(this.httpparameters);
    // 启动 http post 请求执行前的事件监听回调操作(如: 自定义提交的数据字段或上传的文件等)
    this.getonhttprequestlistener().onrequest(this);
    // 发送 http 请求并获取服务端响应状态
    this.httpresponse = this.httpclient.execute(this.httprequest);
    // 获取请求返回的状态码
    this.statuscode = this.httpresponse.getstatusline().getstatuscode();
  }
 
  /**
   * 读取服务端返回的输入流并转换成字符串返回
   *
   * @throws exception
   */
  public string getinputstream() throws exception
  {
    // 接收远程输入流
    inputstream instream = this.httpresponse.getentity().getcontent();
    // 分段读取输入流数据
    bytearrayoutputstream baos = new bytearrayoutputstream();
    byte[] buf = new byte[1024];
    int len = -1;
    while ((len = instream.read(buf)) != -1) {
      baos.write(buf, 0, len);
    }
    // 数据接收完毕退出
    instream.close();
    // 将数据转换为字符串保存
    return new string(baos.tobytearray(), this.charset);
  }
 
  /**
   * 关闭连接管理器释放资源
   */
  protected void shutdownhttpclient()
  {
    if (this.httpclient != null && this.httpclient.getconnectionmanager() != null) {
      this.httpclient.getconnectionmanager().shutdown();
    }
  }
 
  /**
   * 监听服务端响应事件并返回服务端内容
   *
   * @return
   * @throws exception
   */
  protected string checkstatus() throws exception
  {
    onhttprequestlistener listener = this.getonhttprequestlistener();
    string content;
    if (this.statuscode == httpstatus.sc_ok) {
      // 请求成功, 回调监听事件
      content = listener.onsucceed(this.statuscode, this);
    } else {
      // 请求失败或其他, 回调监听事件
      content = listener.onfailed(this.statuscode, this);
    }
    // 关闭连接管理器释放资源
    this.shutdownhttpclient();
    return content;
  }
 
  /**
   * http 请求操作时的事件监听接口
   */
  public interface onhttprequestlistener
  {
    /**
     * 初始化 http get 或 post 请求之前的 header 信息配置 或 其他数据配置等操作
     *
     * @param request
     * @throws exception
     */
    public void onrequest(zhttprequest request) throws exception;
 
    /**
     * 当 http 请求响应成功时的回调方法
     *
     * @param statuscode 当前状态码
     * @param request
     * @return 返回请求获得的字符串内容
     * @throws exception
     */
    public string onsucceed(int statuscode, zhttprequest request) throws exception;
 
    /**
     * 当 http 请求响应失败时的回调方法
     *
     * @param statuscode 当前状态码
     * @param request
     * @return 返回请求失败的提示内容
     * @throws exception
     */
    public string onfailed(int statuscode, zhttprequest request) throws exception;
  }
 
  /**
   * 绑定 http 请求的监听事件
   *
   * @param listener
   * @return
   */
  public zhttprequest setonhttprequestlistener(onhttprequestlistener listener)
  {
    this.onhttprequestlistener = listener;
    return this;
  }
 
  /**
   * 获取已绑定过的 http 请求监听事件
   *
   * @return
   */
  public onhttprequestlistener getonhttprequestlistener()
  {
    return this.onhttprequestlistener;
  }
}

在 activity 中的使用方法(这里我还是只写主体部分代码):
mainactivity.java

?
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
public void doclick(view view)
{
  zhttprequest get = new zhttprequest();
  get
      .setcharset(http.utf_8)
      .setconnectiontimeout(5000)
      .setsotimeout(5000);
  get.setonhttprequestlistener(new zhttprequest.onhttprequestlistener() {
    @override
    public void onrequest(zhttprequest request) throws exception {
 
    }
 
    @override
    public string onsucceed(int statuscode, zhttprequest request) throws exception {
      return request.getinputstream();
    }
 
    @override
    public string onfailed(int statuscode, zhttprequest request) throws exception {
      return "get 请求失败:statuscode "+ statuscode;
    }
  });
 
  zhttprequest post = new zhttprequest();
  post
      .setcharset(http.utf_8)
      .setconnectiontimeout(5000)
      .setsotimeout(10000);
  post.setonhttprequestlistener(new zhttprequest.onhttprequestlistener() {
    private string charset = http.utf_8;
    private contenttype text_plain = contenttype.create("text/plain", charset.forname(charset));
 
    @override
    public void onrequest(zhttprequest request) throws exception {
      // 设置发送请求的 header 信息
      request.addheader("cookie", "abc=123;456=爱就是幸福;");
      // 配置要 post 的数据
      multipartentitybuilder builder = request.getmultipartentitybuilder();
      builder.addtextbody("p1", "abc");
      builder.addtextbody("p2", "中文", text_plain);
      builder.addtextbody("p3", "abc中文cba", text_plain);
      if (picpath != null && ! "".equals(picpath)) {
        builder.addtextbody("pic", picpath);
        builder.addbinarybody("file", new file(picpath));
      }
      request.buildpostentity();
    }
 
    @override
    public string onsucceed(int statuscode, zhttprequest request) throws exception {
      return request.getinputstream();
    }
 
    @override
    public string onfailed(int statuscode, zhttprequest request) throws exception {
      return "post 请求失败:statuscode "+ statuscode;
    }
  });
 
  textview textview = (textview) findviewbyid(r.id.showcontent);
  string content = "初始内容";
  try {
    if (view.getid() == r.id.doget) {
      content = get.get("http://www.baidu.com");
      content = "get数据:isget: " + (get.isget() ? "yes" : "no") + " =>" + content;
    } else {
      content = post.post("http://192.168.1.6/test.php");
      content = "post数据:ispost" + (post.ispost() ? "yes" : "no") + " =>" + content;
    }
 
  } catch (ioexception e) {
    content = "io异常:" + e.getmessage();
  } catch (exception e) {
    content = "异常:" + e.getmessage();
  }
  textview.settext(content);
}

其中 picpath 为 sd 卡中的图片路径 string 类型,我是直接拍照后进行上传用的
布局页面
activity_main.xml

?
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
<linearlayout xmlns:android="http://schemas.android.com/apk/res/android"
  android:layout_width="fill_parent"
  android:layout_height="fill_parent"
  android:orientation="vertical"
  >
  <scrollview
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    >
    <linearlayout
      android:layout_width="fill_parent"
      android:layout_height="fill_parent"
      android:orientation="vertical"
      >
      <button
        android:id="@+id/doget"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:padding="10dp"
        android:layout_marginbottom="10dp"
        android:text="get请求"
        android:onclick="doclick"
        />
      <button
        android:id="@+id/dopost"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:padding="10dp"
        android:layout_marginbottom="10dp"
        android:text="post请求"
        android:onclick="doclick"
        />
      <button
        android:id="@+id/dophoto"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:padding="10dp"
        android:layout_marginbottom="10dp"
        android:text="拍照"
        android:onclick="dophoto"
        />
      <textview
        android:id="@+id/showcontent"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_marginbottom="10dp"
        />
      <imageview
        android:id="@+id/showphoto"
        android:layout_width="fill_parent"
        android:layout_height="250dp"
        android:scaletype="centercrop"
        android:src="@drawable/add"
        android:layout_marginbottom="10dp"
        />
    </linearlayout>
  </scrollview>
</linearlayout>

至于服务端我用的 php ,只是简单的输出获取到的数据而已

?
1
2
3
4
5
6
7
8
9
10
11
<?php
echo 'get:<br>'. "\n";
//print_r(array_map('urldecode', $_get));
print_r($_get);
echo '<br>'. "\n". 'post:<br>'. "\n";
//print_r(array_map('urldecode', $_post));
print_r($_post);
echo '<br>'. "\n". 'files:<br>'. "\n";
print_r($_files);
echo '<br>'. "\n". 'cookies:<br>'. "\n";
print_r($_cookie);