android实现选择图片并压缩上传的功能

1.先请求是否有读写权限

  /**
     * 检测需要的权限
     * 打电话、拍照、存储、读取联系人、短信手机、日历、位置、传感器、麦克风
     **/
    public boolean checkPermissions(String[] permissions) {
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
            return true;
        }
        for (String permission : permissions) {
            if (ContextCompat.checkSelfPermission(this, permission) != PackageManager.PERMISSION_GRANTED) {
                return false;
            }
        }
        return true;
    }

2.如果没有读写权限需要请求该权限

public static final int SELECT_PIC_BY_PICK_PHOTO = 1; 
boolean isHavePermission1 = this.checkPermissions(new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE});
                if (isHavePermission1) {
                    Intent intent = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
                    intent.setDataAndType(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, "image/*");
                    startActivityForResult(intent, SELECT_PIC_BY_PICK_PHOTO);
                } else {
                    this.requestPermission(new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 1);
                }

3.请求存储权限

/**
     * 请求需要的权限
     */
    public void requestPermission(String[] permissions, int requestCode) {
            List<String> needPermissions = getDeniedPermissions(permissions);
            ActivityCompat.requestPermissions(this, needPermissions.toArray(new String[needPermissions.size()]), REQUEST_CODE_PERMISSION);
        
    }

/**
     * 获取权限集中需要申请权限的列表
     *
     * @param permissions
     * @return
     */
    private List<String> getDeniedPermissions(String[] permissions) {
        List<String> needRequestPermissionList = new ArrayList<>();
        for (String permission : permissions) {
            if (ContextCompat.checkSelfPermission(this, permission) !=
                    PackageManager.PERMISSION_GRANTED ||
                    ActivityCompat.shouldShowRequestPermissionRationale(this, permission)) {
                needRequestPermissionList.add(permission);
            }
        }
        return needRequestPermissionList;
    }

4.处理用户选择之后的图片

 @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (requestCode == SELECT_PIC_BY_PICK_PHOTO && resultCode == Activity.RESULT_OK){
            if (data != null) {
                String filePath = getRealFilePath(MyUserInfoActivity.this, data.getData());
            }
        }
}

/**
*兼容android7.0以上的系统
*/
public static String getRealFilePath(Activity activity, final Uri uri) {//通过uri获取文件的绝对路径
        if (null == uri) return null;
        final String scheme = uri.getScheme();
        String data = null;
        if (scheme == null)
            data = uri.getPath();
        else if (ContentResolver.SCHEME_FILE.equals(scheme)) {
            data = uri.getPath();
        } else if (ContentResolver.SCHEME_CONTENT.equals(scheme)) {
            Cursor cursor = activity.getContentResolver().query(uri, new String[]{MediaStore.Images.ImageColumns.DATA}, null, null, null);
            if (null != cursor) {
                if (cursor.moveToFirst()) {
                    int index = cursor.getColumnIndex(MediaStore.Images.ImageColumns.DATA);
                    if (index > -1) {
                        data = cursor.getString(index);
                    }
                }
                cursor.close();
            }
        }
        return data;
    }

5.获取到文件路径就可以上传图片啦,使用retrofit2+rxjava

5.1先压缩该文件

public MultipartBody filesToMultipartBody(String filePath) {
        filePath = PhotoUtils.compressImage(filePath);
        File file = new File(filePath);
        RequestBody requestBody = RequestBody.create(MediaType.parse("application/octet-stream"), file);
        return new MultipartBody.Builder().addFormDataPart("file", file.getName(), requestBody).setType(MultipartBody.FORM).build();
    }
public class PhotoUtils {
    public static String compressImage(String filePath) {
        //先获取图片被旋转的角度
        int angle = readPictureDegree(filePath);
        //获取一定尺寸的图片
        Bitmap bm = getSmallBitmap(filePath);
        //修复图片被旋转的角度
        bm = rotatingImageView(angle, bm);
        File outputFile = new File(Environment.getExternalStorageDirectory(), System.currentTimeMillis() + ".png");
        try {
            if (!outputFile.exists()) {
                outputFile.getParentFile().mkdirs();
            } else {
                outputFile.delete();
            }
            FileOutputStream out = new FileOutputStream(outputFile);
            bm.compress(Bitmap.CompressFormat.JPEG, 100, out);
        } catch (Exception e) {
        }
        return outputFile.getPath();
    }

    /**
     * 根据路径获得图片信息并按比例压缩,返回bitmap
     */
    public static Bitmap getSmallBitmap(String filePath) {
        final BitmapFactory.Options options = new BitmapFactory.Options();
        options.inJustDecodeBounds = true;//只解析图片边沿,获取宽高
        BitmapFactory.decodeFile(filePath, options);
        // 计算缩放比
        options.inSampleSize = calculateInSampleSize(options, 480, 800);
        // 完整解析图片返回bitmap
        options.inJustDecodeBounds = false;
        return BitmapFactory.decodeFile(filePath, options);
    }

    public static int calculateInSampleSize(BitmapFactory.Options options,
                                            int reqWidth, int reqHeight) {
        final int height = options.outHeight;
        final int width = options.outWidth;
        int inSampleSize = 1;
        if (height > reqHeight || width > reqWidth) {
            final int heightRatio = Math.round((float) height / (float) reqHeight);
            final int widthRatio = Math.round((float) width / (float) reqWidth);
            inSampleSize = heightRatio < widthRatio ? heightRatio : widthRatio;
        }
        return inSampleSize;
    }

    /**
     * 读取照片旋转角度
     *
     * @param path 照片路径
     * @return 角度
     */
    public static int readPictureDegree(String path) {
        int degree = 0;
        try {
            ExifInterface exifInterface = new ExifInterface(path);
            int orientation = exifInterface.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL);
            switch (orientation) {
                case ExifInterface.ORIENTATION_ROTATE_90:
                    degree = 90;
                    break;
                case ExifInterface.ORIENTATION_ROTATE_180:
                    degree = 180;
                    break;
                case ExifInterface.ORIENTATION_ROTATE_270:
                    degree = 270;
                    break;
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return degree;
    }

    /**
     * 旋转图片
     *
     * @param angle  被旋转角度
     * @param bitmap 图片对象
     * @return 旋转后的图片
     */
    public static Bitmap rotatingImageView(int angle, Bitmap bitmap) {
        Bitmap returnBm = null;
        // 根据旋转角度,生成旋转矩阵
        Matrix matrix = new Matrix();
        matrix.postRotate(angle);
        try {
            // 将原始图片按照旋转矩阵进行旋转,并得到新的图片
            returnBm = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);
        } catch (OutOfMemoryError e) {
        }
        if (returnBm == null) {
            returnBm = bitmap;
        }
        if (bitmap != returnBm) {
            bitmap.recycle();
        }
        return returnBm;
    }
}

5.2可以上传啦

public static Retrofit setURLRetrofit(String url) {
        return new Retrofit.Builder()
                .addConverterFactory(GsonConverterFactory.create())
                .client(genericClient())
                .baseUrl(url)
                .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
                .build();
    }

    public static OkHttpClient genericClient() {
        return new OkHttpClient.Builder()
                .readTimeout(20, TimeUnit.SECONDS)
                .writeTimeout(20, TimeUnit.SECONDS)
                .connectTimeout(20, TimeUnit.SECONDS)
                .addInterceptor(new Interceptor() {
                    @Override
                    public Response intercept(Chain chain) throws IOException {
                        Request request = chain.request()
                                .newBuilder()
                                .header("token", UIUtils.getToken())
                                .build();
                        return chain.proceed(request);
                    }
                })
                .build();
    }
 private BaseUrlService baseUrlService=setURLRetrofit(HttpUrlUtils.BASE_URL).create(BaseUrlService.class);
//TODO 上传用户文件
    public static Observable<Result<BaseBean>> uploadFile(MultipartBody multipartBody) {
        return baseUrlService.uploadFile(multipartBody).subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread());
    }

 @POST("file/upload")
 Observable<Result<BaseBean>> uploadFile(@Body MultipartBody multipartBody);

 

展开阅读全文

没有更多推荐了,返回首页