当前位置:   article > 正文

Android 拍照(选择图片)并上传(包含权限动态获取)_android 拍照上传关闭页面

android 拍照上传关闭页面

作为一个Android新手,想实现手机拍照并上传的功能,经过查找资料,已实现此功能。在此记录备忘。老鸟请忽略。

一、实现思路:

1.Android手机客户端,拍照(或选择图片),然后上传到服务器。

2.服务器端接收手机端上传上来的图片。

二、实现步骤:

1.按惯例,先放效果图:

项目结构:

2.activity_main.xml

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  3. android:layout_width="match_parent"
  4. android:layout_height="match_parent"
  5. android:orientation="vertical"
  6. android:padding="5dp">
  7. <TextView
  8. android:layout_width="wrap_content"
  9. android:layout_height="wrap_content"
  10. android:text="图片预览" />
  11. <ImageView
  12. android:id="@+id/imageView"
  13. android:layout_width="match_parent"
  14. android:layout_height="400dp"
  15. android:background="#fff"
  16. android:padding="1dp"
  17. android:scaleType="fitXY" />
  18. <LinearLayout
  19. android:layout_width="wrap_content"
  20. android:layout_height="wrap_content"
  21. android:layout_gravity="center_horizontal"
  22. android:orientation="horizontal">
  23. <Button
  24. android:id="@+id/btnPhoto"
  25. android:layout_width="wrap_content"
  26. android:layout_height="wrap_content"
  27. android:text="拍照" />
  28. <Button
  29. android:id="@+id/btnSelect"
  30. android:layout_width="wrap_content"
  31. android:layout_height="wrap_content"
  32. android:text="选择" />
  33. </LinearLayout>
  34. </LinearLayout>

3.MainActivity.java

  1. package com.qingshan.note;
  2. import androidx.annotation.NonNull;
  3. import androidx.annotation.RequiresApi;
  4. import androidx.appcompat.app.AppCompatActivity;
  5. import androidx.core.app.ActivityCompat;
  6. import androidx.core.content.ContextCompat;
  7. import android.Manifest;
  8. import android.app.AlertDialog;
  9. import android.content.ContentValues;
  10. import android.content.DialogInterface;
  11. import android.content.Intent;
  12. import android.content.pm.PackageManager;
  13. import android.graphics.Bitmap;
  14. import android.graphics.BitmapFactory;
  15. import android.graphics.Matrix;
  16. import android.net.Uri;
  17. import android.os.Build;
  18. import android.os.Bundle;
  19. import android.os.Environment;
  20. import android.provider.MediaStore;
  21. import android.provider.Settings;
  22. import android.view.View;
  23. import android.widget.Button;
  24. import android.widget.ImageView;
  25. import android.widget.Toast;
  26. import java.io.BufferedReader;
  27. import java.io.DataInputStream;
  28. import java.io.DataOutputStream;
  29. import java.io.File;
  30. import java.io.FileInputStream;
  31. import java.io.FileNotFoundException;
  32. import java.io.FileOutputStream;
  33. import java.io.IOException;
  34. import java.io.InputStreamReader;
  35. import java.io.OutputStream;
  36. import java.net.HttpURLConnection;
  37. import java.net.URL;
  38. import java.text.SimpleDateFormat;
  39. import java.util.ArrayList;
  40. import java.util.Date;
  41. import java.util.HashMap;
  42. import java.util.Iterator;
  43. import java.util.List;
  44. import java.util.Map;
  45. public class MainActivity extends AppCompatActivity implements View.OnClickListener {
  46. private Button btnPhoto, btnSelect;
  47. private Intent intent;
  48. private final int CAMERA = 1;//事件枚举(可以自定义)
  49. private final int CHOOSE = 2;//事件枚举(可以自定义)
  50. private final String postUrl = "http://qingshanboke.com/Home/AndoridUploadFile";//接收上传图片的地址
  51. String photoPath = "";//要上传的图片路径
  52. private final int permissionCode = 100;//权限请求码
  53. //权限集合,对应在AndroidManifest.xml文件中添加配置
  54. // <uses-permission android:name="android.permission.CAMERA" />
  55. // <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
  56. // <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
  57. // <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
  58. // <uses-permission android:name="android.permission.INTERNET"/>
  59. String[] permissions = new String[]{
  60. Manifest.permission.CAMERA,
  61. Manifest.permission.WRITE_EXTERNAL_STORAGE,
  62. Manifest.permission.ACCESS_NETWORK_STATE,
  63. Manifest.permission.ACCESS_WIFI_STATE,
  64. Manifest.permission.INTERNET
  65. };
  66. AlertDialog alertDialog;
  67. @Override
  68. protected void onCreate(Bundle savedInstanceState) {
  69. super.onCreate(savedInstanceState);
  70. setContentView(R.layout.activity_main);
  71. //6.0才用动态权限
  72. if (Build.VERSION.SDK_INT >= 23) {
  73. checkPermission();
  74. }
  75. btnPhoto = findViewById(R.id.btnPhoto);
  76. btnSelect = findViewById(R.id.btnSelect);
  77. btnPhoto.setOnClickListener(this);
  78. btnSelect.setOnClickListener(this);
  79. }
  80. //检查权限
  81. private void checkPermission() {
  82. List<String> permissionList = new ArrayList<>();
  83. for (int i = 0; i < permissions.length; i++) {
  84. if (ContextCompat.checkSelfPermission(this, permissions[i]) != PackageManager.PERMISSION_GRANTED) {
  85. permissionList.add(permissions[i]);
  86. }
  87. }
  88. if (permissionList.size() <= 0) {
  89. //说明权限都已经通过,可以做你想做的事情去
  90. } else {
  91. //存在未允许的权限
  92. ActivityCompat.requestPermissions(this, permissions, permissionCode);
  93. }
  94. }
  95. //授权后回调函数
  96. @Override
  97. public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
  98. super.onRequestPermissionsResult(requestCode, permissions, grantResults);
  99. boolean haspermission = false;
  100. if (permissionCode == requestCode) {
  101. for (int i = 0; i < grantResults.length; i++) {
  102. if (grantResults[i] == -1) {
  103. haspermission = true;
  104. }
  105. }
  106. if (haspermission) {
  107. //跳转到系统设置权限页面,或者直接关闭页面,不让他继续访问
  108. permissionDialog();
  109. } else {
  110. //全部权限通过,可以进行下一步操作
  111. }
  112. }
  113. }
  114. //打开手动设置应用权限
  115. private void permissionDialog() {
  116. if (alertDialog == null) {
  117. alertDialog = new AlertDialog.Builder(this)
  118. .setTitle("提示信息")
  119. .setMessage("当前应用缺少必要权限,该功能暂时无法使用。如若需要,请单击【确定】按钮前往设置中心进行权限授权。")
  120. .setPositiveButton("设置", new DialogInterface.OnClickListener() {
  121. @Override
  122. public void onClick(DialogInterface dialog, int which) {
  123. cancelPermissionDialog();
  124. Uri packageURI = Uri.parse("package:" + getPackageName());
  125. Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS, packageURI);
  126. startActivity(intent);
  127. }
  128. })
  129. .setNegativeButton("取消", new DialogInterface.OnClickListener() {
  130. @Override
  131. public void onClick(DialogInterface dialog, int which) {
  132. cancelPermissionDialog();
  133. }
  134. })
  135. .create();
  136. }
  137. alertDialog.show();
  138. }
  139. //用户取消授权
  140. private void cancelPermissionDialog() {
  141. alertDialog.cancel();
  142. }
  143. @Override
  144. public void onClick(View v) {
  145. switch (v.getId()) {
  146. //拍照按钮事件
  147. case R.id.btnPhoto:
  148. //方法一:这样拍照只能取到缩略图(不清晰)
  149. //intent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
  150. //startActivityForResult(intent, CAMERA);
  151. //方法二:指定加载路径图片路径(保存原图,清晰)
  152. String SD_PATH = Environment.getExternalStorageDirectory().getPath() + "/拍照上传示例/";
  153. SimpleDateFormat format = new SimpleDateFormat("yyyyMMddHHmmss");
  154. String fileName = format.format(new Date(System.currentTimeMillis())) + ".JPEG";
  155. photoPath = SD_PATH + fileName;
  156. File file = new File(photoPath);
  157. if (!file.getParentFile().exists()) {
  158. file.getParentFile().mkdirs();
  159. }
  160. //兼容7.0以上的版本
  161. if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
  162. try {
  163. ContentValues values = new ContentValues(1);
  164. values.put(MediaStore.Images.Media.MIME_TYPE, "image/jpg");
  165. values.put(MediaStore.Images.Media.DATA, photoPath);
  166. Uri tempuri = getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);
  167. Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
  168. intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
  169. if (tempuri != null) {
  170. intent.putExtra(MediaStore.EXTRA_OUTPUT, tempuri);
  171. intent.putExtra(MediaStore.EXTRA_VIDEO_QUALITY, 1);
  172. }
  173. startActivityForResult(intent, CAMERA);
  174. } catch (Exception e) {
  175. e.printStackTrace();
  176. }
  177. } else {
  178. intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
  179. Uri uri = Uri.fromFile(file);
  180. intent.putExtra(MediaStore.EXTRA_OUTPUT, uri); //指定拍照后的存储路径,保存原图
  181. startActivityForResult(intent, CAMERA);
  182. }
  183. break;
  184. //选择按钮事件
  185. case R.id.btnSelect:
  186. intent = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
  187. startActivityForResult(intent, CHOOSE);
  188. break;
  189. }
  190. }
  191. @RequiresApi(api = Build.VERSION_CODES.O)
  192. @Override
  193. protected void onActivityResult(int requestCode, int resultCode, Intent data) {
  194. super.onActivityResult(requestCode, resultCode, data);
  195. switch (requestCode) {
  196. // 调用照相机拍照
  197. case CAMERA:
  198. if (resultCode == RESULT_OK) {
  199. //对应方法一:图片未保存,需保存文件到本地
  200. // Bundle bundle = data.getExtras();
  201. // Bitmap bitmap = (Bitmap) bundle.get("data");
  202. // String savePath;
  203. // String SD_PATH = Environment.getExternalStorageDirectory().getPath() + "/拍照上传示例/";
  204. // SimpleDateFormat format = new SimpleDateFormat("yyyyMMddHHmmss");
  205. // String fileName = format.format(new Date(System.currentTimeMillis())) + ".JPEG";
  206. // if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
  207. // savePath = SD_PATH;
  208. // } else {
  209. // Toast.makeText(MainActivity.this, "保存失败!", Toast.LENGTH_SHORT).show();
  210. // return;
  211. // }
  212. // photoPath = savePath + fileName;
  213. // File file = new File(photoPath);
  214. // try {
  215. // if (!file.exists()) {
  216. // file.getParentFile().mkdirs();
  217. // file.createNewFile();
  218. // }
  219. // FileOutputStream stream = new FileOutputStream(file);
  220. // bitmap.compress(Bitmap.CompressFormat.JPEG, 100, stream);
  221. // Toast.makeText(MainActivity.this, "保存成功,位置:" + file.getAbsolutePath(), Toast.LENGTH_SHORT).show();
  222. // } catch (IOException e) {
  223. // e.printStackTrace();
  224. // }
  225. //对应方法二:图片已保存,只需读取就行了
  226. try {
  227. FileInputStream stream = new FileInputStream(photoPath);
  228. Bitmap bitmap = BitmapFactory.decodeStream(stream);
  229. //预览图片
  230. ImageView image = findViewById(R.id.imageView);
  231. image.setImageBitmap(bitmap);
  232. //上传图片(Android 4.0 之后不能在主线程中请求HTTP请求)
  233. File file = new File(photoPath);
  234. if (file.exists()) {
  235. new Thread(new Runnable() {
  236. @Override
  237. public void run() {
  238. //文本字段(用于验证用户身份)
  239. HashMap<String, String> form = new HashMap<String, String>();
  240. form.put("username", "zhangqs");
  241. form.put("password", "123456");
  242. //图片字段
  243. HashMap<String, String> file = new HashMap<String, String>();
  244. file.put(PathHelper.getFileNameFromPath(photoPath), photoPath);
  245. formUpload(postUrl, form, file);
  246. }
  247. }).start();
  248. }
  249. } catch (FileNotFoundException e) {
  250. e.printStackTrace();
  251. }
  252. }
  253. break;
  254. // 选择图片库的图片
  255. case CHOOSE:
  256. if (resultCode == RESULT_OK) {
  257. try {
  258. Uri uri = data.getData();
  259. photoPath = PathHelper.getRealPathFromUri(MainActivity.this, uri);
  260. Bitmap bitmap = MediaStore.Images.Media.getBitmap(this.getContentResolver(), uri);
  261. //压缩图片
  262. bitmap = scaleBitmap(bitmap, (float) 0.5);
  263. //预览图片
  264. ImageView image = findViewById(R.id.imageView);
  265. image.setImageBitmap(bitmap);
  266. //上传图片(Android 4.0 之后不能在主线程中请求HTTP请求)
  267. File file = new File(photoPath);
  268. if (file.exists()) {
  269. new Thread(new Runnable() {
  270. @Override
  271. public void run() {
  272. //文本字段(用于验证用户身份)
  273. HashMap<String, String> form = new HashMap<String, String>();
  274. form.put("username", "zhangqs");
  275. form.put("password", "123456");
  276. //图片字段
  277. HashMap<String, String> file = new HashMap<String, String>();
  278. file.put(PathHelper.getFileNameFromPath(photoPath), photoPath);
  279. formUpload(postUrl, form, file);
  280. }
  281. }).start();
  282. }
  283. } catch (IOException e) {
  284. e.printStackTrace();
  285. }
  286. }
  287. break;
  288. }
  289. }
  290. //压缩图片
  291. public Bitmap scaleBitmap(Bitmap origin, float ratio) {
  292. if (origin == null) {
  293. return null;
  294. }
  295. int width = origin.getWidth();
  296. int height = origin.getHeight();
  297. Matrix matrix = new Matrix();
  298. matrix.preScale(ratio, ratio);
  299. Bitmap newBM = Bitmap.createBitmap(origin, 0, 0, width, height, matrix, false);
  300. return newBM;
  301. }
  302. //POST 表单提交
  303. @RequiresApi(api = Build.VERSION_CODES.O)
  304. public static String formUpload(String posturl, Map<String, String> textMap, Map<String, String> fileMap) {
  305. String res = "";
  306. HttpURLConnection conn = null;
  307. String BOUNDARY = "---------------------------123821742118716"; //boundary就是request头和上传文件内容的分隔符
  308. try {
  309. URL url = new URL(posturl);
  310. conn = (HttpURLConnection) url.openConnection();
  311. conn.setConnectTimeout(5000);
  312. conn.setReadTimeout(30000);
  313. conn.setDoOutput(true);
  314. conn.setDoInput(true);
  315. conn.setUseCaches(false);
  316. conn.setRequestMethod("POST");
  317. conn.setRequestProperty("Connection", "Keep-Alive");
  318. conn.setRequestProperty("User-Agent", "Mozilla/5.0 (Windows; U; Windows NT 6.1; zh-CN; rv:1.9.2.6)");
  319. conn.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + BOUNDARY);
  320. OutputStream out = new DataOutputStream(conn.getOutputStream());
  321. // text
  322. if (textMap != null) {
  323. StringBuffer buffer = new StringBuffer();
  324. Iterator iter = textMap.entrySet().iterator();
  325. while (iter.hasNext()) {
  326. Map.Entry entry = (Map.Entry) iter.next();
  327. String inputName = (String) entry.getKey();
  328. String inputValue = (String) entry.getValue();
  329. if (inputValue == null) {
  330. continue;
  331. }
  332. buffer.append("\r\n").append("--").append(BOUNDARY).append("\r\n");
  333. buffer.append("Content-Disposition: form-data; name=\"" + inputName + "\"\r\n\r\n");
  334. buffer.append(inputValue);
  335. }
  336. out.write(buffer.toString().getBytes());
  337. }
  338. // file
  339. if (fileMap != null) {
  340. Iterator iter = fileMap.entrySet().iterator();
  341. while (iter.hasNext()) {
  342. Map.Entry entry = (Map.Entry) iter.next();
  343. String inputName = (String) entry.getKey();
  344. String inputValue = (String) entry.getValue();
  345. if (inputValue == null) {
  346. continue;
  347. }
  348. File file = new File(inputValue);
  349. String filename = file.getName();
  350. String contentType = "";
  351. if (filename.endsWith(".jpg")) {
  352. contentType = "image/jpg";
  353. } else if (filename.endsWith(".png")) {
  354. contentType = "image/png";
  355. } else if (contentType == null || contentType.equals("")) {
  356. contentType = "application/octet-stream";
  357. }
  358. StringBuffer buffer = new StringBuffer();
  359. buffer.append("\r\n").append("--").append(BOUNDARY).append("\r\n");
  360. buffer.append("Content-Disposition: form-data; name=\"" + inputName + "\"; filename=\"" + filename + "\"\r\n");
  361. buffer.append("Content-Type:" + contentType + "\r\n\r\n");
  362. out.write(buffer.toString().getBytes());
  363. DataInputStream in = new DataInputStream(new FileInputStream(file));
  364. int bytes = 0;
  365. byte[] bufferOut = new byte[1024];
  366. while ((bytes = in.read(bufferOut)) != -1) {
  367. out.write(bufferOut, 0, bytes);
  368. }
  369. in.close();
  370. }
  371. }
  372. byte[] endData = ("\r\n--" + BOUNDARY + "--\r\n").getBytes();
  373. out.write(endData);
  374. out.flush();
  375. out.close();
  376. // 读取返回数据
  377. StringBuffer buffer = new StringBuffer();
  378. BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream()));
  379. String line = null;
  380. while ((line = reader.readLine()) != null) {
  381. buffer.append(line).append("\n");
  382. }
  383. res = buffer.toString();
  384. reader.close();
  385. reader = null;
  386. } catch (Exception e) {
  387. System.out.println("发送POST请求出错。" + posturl);
  388. e.printStackTrace();
  389. } finally {
  390. if (conn != null) {
  391. conn.disconnect();
  392. conn = null;
  393. }
  394. }
  395. return res;
  396. }
  397. }

4.辅助类 PathHelper.java

  1. package com.qingshan.note;
  2. import android.annotation.SuppressLint;
  3. import android.content.ContentUris;
  4. import android.content.Context;
  5. import android.database.Cursor;
  6. import android.net.Uri;
  7. import android.os.Build;
  8. import android.provider.DocumentsContract;
  9. import android.provider.MediaStore;
  10. //Android 路径辅助类
  11. public class PathHelper {
  12. //适配api19以下(不包括api19),根据uri获取图片的绝对路径
  13. public static String getRealPathFromUri(Context context, Uri uri) {
  14. int sdkVersion = Build.VERSION.SDK_INT;
  15. if (sdkVersion >= 19) { // api >= 19
  16. return getRealPathFromUriAboveApi19(context, uri);
  17. } else { // api < 19
  18. return getRealPathFromUriBelowAPI19(context, uri);
  19. }
  20. }
  21. /**
  22. * 适配api19以下(不包括api19),根据uri获取图片的绝对路径
  23. *
  24. * @param context 上下文对象
  25. * @param uri 图片的Uri
  26. * @return 如果Uri对应的图片存在, 那么返回该图片的绝对路径, 否则返回null
  27. */
  28. private static String getRealPathFromUriBelowAPI19(Context context, Uri uri) {
  29. return getDataColumn(context, uri, null, null);
  30. }
  31. /**
  32. * 适配api19及以上,根据uri获取图片的绝对路径
  33. *
  34. * @param context 上下文对象
  35. * @param uri 图片的Uri
  36. * @return 如果Uri对应的图片存在, 那么返回该图片的绝对路径, 否则返回null
  37. */
  38. @SuppressLint("NewApi")
  39. private static String getRealPathFromUriAboveApi19(Context context, Uri uri) {
  40. String filePath = null;
  41. if (DocumentsContract.isDocumentUri(context, uri)) {
  42. // 如果是document类型的 uri, 则通过document id来进行处理
  43. String documentId = DocumentsContract.getDocumentId(uri);
  44. if (isMediaDocument(uri)) { // MediaProvider
  45. // 使用':'分割
  46. String id = documentId.split(":")[1];
  47. String selection = MediaStore.Images.Media._ID + "=?";
  48. String[] selectionArgs = {id};
  49. filePath = getDataColumn(context, MediaStore.Images.Media.EXTERNAL_CONTENT_URI, selection, selectionArgs);
  50. } else if (isDownloadsDocument(uri)) { // DownloadsProvider
  51. Uri contentUri = ContentUris.withAppendedId(Uri.parse("content://downloads/public_downloads"), Long.valueOf(documentId));
  52. filePath = getDataColumn(context, contentUri, null, null);
  53. }
  54. } else if ("content".equalsIgnoreCase(uri.getScheme())) {
  55. // 如果是 content 类型的 Uri
  56. filePath = getDataColumn(context, uri, null, null);
  57. } else if ("file".equals(uri.getScheme())) {
  58. // 如果是 file 类型的 Uri,直接获取图片对应的路径
  59. filePath = uri.getPath();
  60. }
  61. return filePath;
  62. }
  63. private static String getDataColumn(Context context, Uri uri, String selection, String[] selectionArgs) {
  64. String path = null;
  65. String[] projection = new String[]{MediaStore.Images.Media.DATA};
  66. Cursor cursor = null;
  67. try {
  68. cursor = context.getContentResolver().query(uri, projection, selection, selectionArgs, null);
  69. if (cursor != null && cursor.moveToFirst()) {
  70. int columnIndex = cursor.getColumnIndexOrThrow(projection[0]);
  71. path = cursor.getString(columnIndex);
  72. }
  73. } catch (Exception e) {
  74. e.printStackTrace();
  75. } finally {
  76. if (cursor != null) {
  77. cursor.close();
  78. }
  79. }
  80. return path;
  81. }
  82. private static boolean isMediaDocument(Uri uri) {
  83. return "com.android.providers.media.documents".equals(uri.getAuthority());
  84. }
  85. private static boolean isDownloadsDocument(Uri uri) {
  86. return "com.android.providers.downloads.documents".equals(uri.getAuthority());
  87. }
  88. //从路径中提取文件名
  89. public static String getFileNameFromPath(String path) {
  90. int start = path.lastIndexOf("/");
  91. int end = path.lastIndexOf(".");
  92. if (start != -1 && end != -1) {
  93. return path.substring(start + 1, end);
  94. } else {
  95. return null;
  96. }
  97. }
  98. }

5.AndroidManifest.xml

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <manifest xmlns:android="http://schemas.android.com/apk/res/android"
  3. package="com.qingshan.note">
  4. <!-- 因为拍照需要写入文件 所以需要申请读取内存的权限 -->
  5. <uses-permission android:name="android.permission.CAMERA" />
  6. <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
  7. <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
  8. <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
  9. <uses-permission android:name="android.permission.INTERNET"/>
  10. <application
  11. android:networkSecurityConfig="@xml/network_security_config"
  12. android:allowBackup="true"
  13. android:icon="@mipmap/ic_launcher"
  14. android:label="@string/app_name"
  15. android:usesCleartextTraffic="true"
  16. android:roundIcon="@mipmap/ic_launcher_round"
  17. android:supportsRtl="true"
  18. android:theme="@style/AppTheme">
  19. <activity android:name=".MainActivity">
  20. <intent-filter>
  21. <action android:name="android.intent.action.MAIN" />
  22. <category android:name="android.intent.category.LAUNCHER" />
  23. </intent-filter>
  24. </activity>
  25. </application>
  26. </manifest>

6.\res\xml\network_security_config.xml

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <network-security-config>
  3. <base-config cleartextTrafficPermitted="true" />
  4. <domain-config cleartextTrafficPermitted="true" >
  5. <domain includeSubdomains="true">127.0.0.1</domain>
  6. <domain includeSubdomains="true">192.168.100.192</domain>
  7. <domain includeSubdomains="true">localhost</domain>
  8. <domain includeSubdomains="true">qingshanboke.com</domain>
  9. </domain-config>
  10. </network-security-config>

7.服务器端接收(asp.net mvc 接收)

  1. public ActionResult AndoridUploadFile()
  2. {
  3. var userName = Request.Params["username"];
  4. var password = Request.Params["password"];
  5. if (string.IsNullOrEmpty(userName) || string.IsNullOrEmpty(password))
  6. {
  7. return Content("抱歉,用户名和密码错误!");
  8. }
  9. //todo:身份验证
  10. var dir = PathHelper.GetMapPath("~/Uploadfiles/" + DateTime.Now.ToString("yyyy-MM"));
  11. if (!Directory.Exists(dir))
  12. {
  13. Directory.CreateDirectory(dir);
  14. }
  15. for (int i = 0; i < Request.Files.Count; i++)
  16. {
  17. var path = Path.Combine(dir, DateTime.Now.ToString("yyyyMMddHHmmss") + ".jpg");
  18. if (Request.Files[i] != null)
  19. {
  20. Request.Files[i].SaveAs(path);
  21. }
  22. }
  23. return Content("{\"isSuccess\":true}");
  24. }

三、注意事项

1.Android发起http请求时,默认请求地址需https,需要增加 network-security-config 配置来允许使用http。(详见上面6.\res\xml\network_security_config.xml)

2.发起post提交时,往往需要做接口身份识别,需要将文本字段和图片字段一起提交,构造表单时,需要 "Content-Type", "multipart/form-data; boundary..."。

3.拍照时,默认只能取到缩略图,不够清晰,若要取到原图,需要在拍照时,传入指定保存位置,在回调函数中只需读取就可以了。

声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:【wpsshop博客】
推荐阅读
相关标签
  

闽ICP备14008679号