ThinkChat2.0新版上线,更智能更精彩,支持会话、画图、阅读、搜索等,送10W Token,即刻开启你的AI之旅 广告
***** **图片上传的实现** [TOC=6] # 1. 获取图库图片 ~~~ Intent intent1 = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI); startActivityForResult(intent1, LOCAL_CROP); ~~~ # 2. 获取相机拍照图片 ~~~ Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); intent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri); startActivityForResult(intent, TAKE_PHOTO); ~~~ # 3. 图片剪裁 ~~~ Intent intent = new Intent("com.android.camera.action.CROP"); //添加这一句表示对目标应用临时授权该Uri所代表的文件 intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); //可以选择图片类型,如果是*表明所有类型的图片 intent.setDataAndType(uri, "image/*"); // 下面这个crop = true是设置在开启的Intent中设置显示的VIEW可裁剪 intent.putExtra("crop", "true"); // aspectX aspectY 是宽高的比例,这里设置的是正方形(长宽比为1:1) intent.putExtra("aspectX", 1); intent.putExtra("aspectY", 1); // outputX outputY 是裁剪图片宽高 intent.putExtra("outputX", 500); intent.putExtra("outputY", 500); intent.putExtra("outputFormat", Bitmap.CompressFormat.JPEG.toString()); //是否将数据保留在Bitmap中返回,true返回bitmap,false返回uri intent.putExtra("return-data", false); ~~~ # 4. 图片回传的实现 ~~~ @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { switch (requestCode) { case TAKE_PHOTO: // 拍照 if (resultCode == RESULT_OK) { // 创建intent用于裁剪图片 Intent intent = new Intent("com.android.camera.action.CROP"); // 设置数据为文件uri,类型为图片格式 intent.setDataAndType(imageUri, "image/*"); // 允许裁剪 intent.putExtra("scale", true); // 指定输出到文件uri中 intent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri); // 启动intent,开始裁剪 startActivityForResult(intent, CROP_PHOTO); } break; case LOCAL_CROP: // 系统相机 if (resultCode == RESULT_OK) { // 创建intent用于裁剪图片 Intent intent1 = new Intent("com.android.camera.action.CROP"); // 获取图库所选图片的uri Uri uri = data.getData(); intent1.setDataAndType(uri, "image/*"); // 设置裁剪图片的宽高 intent1.putExtra("outputX", 300); intent1.putExtra("outputY", 300); // 裁剪后返回数据 intent1.putExtra("return-data", true); // 启动intent,开始裁剪 startActivityForResult(intent1, CROP_PHOTO); } case CROP_PHOTO: // 裁剪后 if (resultCode == RESULT_OK) { try { // 展示拍照后裁剪的图片 if (imageUri != null) { // 创建BitmapFactory.Options对象 BitmapFactory.Options option = new BitmapFactory.Options(); // 属性设置,用于压缩bitmap对象 option.inSampleSize = 2; option.inPreferredConfig = Bitmap.Config.RGB_565; // 根据文件流解析生成Bitmap对象 Bitmap bitmap = BitmapFactory.decodeStream(getContentResolver().openInputStream(imageUri), null, option); // 展示图片 ivHead.setImageBitmap(bitmap); imageUri = null; return; } // 展示图库中选择裁剪后的图片 if (data != null) { // 根据返回的data,获取Bitmap对象 Bitmap bitmap = data.getExtras().getParcelable("data"); // 展示图片 ivHead.setImageBitmap(bitmap); data = null; return; } } catch (Exception e) { e.printStackTrace(); } } } } ~~~ # 5. 侧滑头像上传 关于文件上传功能,现在的移动开发中有很多好的网络框架提供这个功能。早期开发Android时网络框架少,只能靠自己手写。虽然现在不用自己手写,但是弄明白原理还是很有必要的。 ~~~ POST请求头 1. Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,\*/\*;q=0.8,application/signed-exchange;v=b3 2. Accept-Encoding: gzip, deflate, br 3. Accept-Language: zh-CN,zh;q=0.9,en;q=0.8 4. Cache-Control: max-age=0 5. Connection: keep-alive 6. Content-Length: 57451 7. Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryB94bWqqQGVspXSJd 8. Host: localhost:8080 9. Origin: http://localhost:8080 10. Referer: http://localhost:8080/ 11. Upgrade-Insecure-Requests: 1 12. User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10\_14\_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.86 Safari/537.36 ~~~ ~~~ 请求体 ------WebKitFormBoundary6TAB8KxvuJTZYfUn // 第一行,是“--”字符串(不包括引号)和请求头中的boundary拼成的字符串 Content-Disposition: form-data; name="username" // 第二行是固定的Content-Disposition: form-data;和name="请求的参数名称" 二者拼接的字符串 // 这里是空行 sdafdsa //这是请求的参数,就是username的具体值 ------WebKitFormBoundary6TAB8KxvuJTZYfUn // 和第一行一样,是“--”字符串(不包括引号)和请求头中的boundary拼成的字符串 Content-Disposition: form-data; name="f"; filename="default_launcher.conf" // 和第二行类似,但是因为是文件,所以多了一个filename参数,是指你上传的文件名 Content-Type: application/octet-stream // 文件的minetype // 这里有个空行,下面是要上传的文件内容 packageName=com.cy.chineseonline className=com.cy.chineseonline.activity.MainActivity // 这里有个空行,上面是要上传的文件内容 ------WebKitFormBoundary6TAB8KxvuJTZYfUn-- // 最后一行 --和boundary和--拼接的字符串 ~~~ ~~~ private static final String nextLine = "\r\n"; private static final String twoHyphens = "--"; //分割线 随便写一个 private static final String boundary = "wk_file_2519775"; new AsyncTask<Void, Void, String>() { @Override protected String doInBackground(Void... voids) { File file = new File(filePath); HttpURLConnection connection = null; try { URL url1 = new URL("http://169.254.78.219:8080/upload"); connection = (HttpURLConnection) url1.openConnection(); connection.setDoOutput(true); // 设置字符集 connection.setRequestProperty("Charsert", "UTF-8"); //设置接收编码 connection.setRequestProperty("Accept-Charset", "utf-8"); //开启长连接可以持续传输 connection.setRequestProperty("Connection", "keep-alive"); //设置请求参数格式以及boundary分割线 connection.setRequestProperty("Content-Type", "multipart/form-data;boundary=" + boundary); //设置接收返回值的格式 connection.setRequestProperty("Accept", "application/json"); OutputStream outputStream = new DataOutputStream(connection.getOutputStream()); //分隔符头部 String header = twoHyphens + boundary + nextLine; //分隔符参数设置 header += "Content-Disposition: form-data;name=\"file\";" + "filename=\"" + file.getName() + "\"" + nextLine + nextLine; //写入输出流 outputStream.write(header.getBytes()); //读取文件并写入 FileInputStream inputStream = new FileInputStream(file); byte[] bytes = new byte[1024]; int length; while ((length = inputStream.read(bytes)) != -1) { outputStream.write(bytes, 0, length); } //文件写入完成后加回车 outputStream.write(nextLine.getBytes()); //写入结束分隔符 String footer = nextLine + twoHyphens + boundary + twoHyphens + nextLine; outputStream.write(footer.getBytes()); outputStream.flush(); if (connection.getResponseCode() == 200) { return CharStreams.toString(new InputStreamReader(connection.getInputStream())); } } catch (MalformedURLException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } return null; } @Override protected void onPostExecute(String s) { Log.i(TAG, "" + s); } }.execute(); ~~~