Android 에서 이미지 압축 방안 상세 설명 및 원본 다운로드

23483 단어 Android그림 압축
Android 에서 이미지 압축 방안 상세 설명 및 원본 다운로드
사진 의 전 시 는 우리 의 어떤 응용 프로그램 에서 도 피 할 수 없다 고 할 수 있 지만 대량의 사진 에 많은 문제 가 발생 할 수 있다.예 를 들 어 큰 그림 을 불 러 오 거나 여러 그림 을 불 러 올 때의 OOM 문 제 는Android 고 효율 로드 맵 및 다 중 맵 피 프로그램 OOM로 옮 길 수 있다.또 하나의 문 제 는 바로 사진 의 업로드 와 다운로드 문제 이다.흔히 우 리 는 사진 이 명확 하면 서도 차지 하 는 메모리 가 작은 것 을 좋아한다.즉,가능 한 한 우리 의 데 이 터 를 적 게 소모 하 는 것 이다.이것 이 바로 내 가 오늘 말 하고 자 하 는 문제 이다.그림 의 압축 방안 에 대한 상세 한 설명 이다.
1.품질 압축 법
bitmap options 속성 을 설정 하여 그림 의 질 을 낮 추고 픽 셀 이 감소 하지 않 습 니 다.
첫 번 째 매개 변 수 는 압축 이 필요 한 bitmap 그림 대상 이 고 두 번 째 매개 변 수 는 압축 후 그림 이 저 장 된 위치 입 니 다.
options 속성 0-100 을 설정 하여 압축 을 실현 합 니 다.

private Bitmap compressImage(Bitmap image) { 
 ByteArrayOutputStream baos = new ByteArrayOutputStream(); 
 image.compress(Bitmap.CompressFormat.JPEG, 100, baos);//      ,  100     ,          baos  
 int options = 100; 
 while ( baos.toByteArray().length / 1024>100) { //               100kb,       
 baos.reset();//  baos   baos 
 image.compress(Bitmap.CompressFormat.JPEG, options, baos);//    options%,          baos  
 options -= 10;//     10 
 } 
 ByteArrayInputStream isBm = new ByteArrayInputStream(baos.toByteArray());//       baos   ByteArrayInputStream  
 Bitmap bitmap = BitmapFactory.decodeStream(isBm, null, null);// ByteArrayInputStream       
 return bitmap; 
 }
질량 압축 은 그림 의 픽 셀 을 줄 이지 않 는 다.이것 은 픽 셀 이 변 하지 않 는 전제 에서 그림 의 깊이 와 투명 도 를 바 꾸 어 그림 을 압축 하 는 목적 을 달성 하 는 것 이다.압축 된 그림 파일 의 크기 가 바 뀌 지만 bitmap 로 가 져 온 후 차지 하 는 메모 리 는 변 하지 않 습 니 다.픽 셀 이 변 하지 않 기 때문에 무한 압축 이 불가능 하고 한 값 에 도달 하면 계속 작 아 지지 않 습 니 다.분명히 이 방법 은 미리 보기 그림 에 적용 되 지 않 고 압축 그림 을 통 해 메모리 의 적용 을 줄 이려 는 경우 에 도 적용 되 지 않 으 며 그림 의 질 을 확보 하 는 동시에 파일 크기 를 줄 이려 는 경우 에 만 적용 된다.
2.샘플링 압축 법

private Bitmap getimage(String srcPath) { 
 BitmapFactory.Options newOpts = new BitmapFactory.Options(); 
 //      ,   options.inJustDecodeBounds   true  
 newOpts.inJustDecodeBounds = true; 
 Bitmap bitmap = BitmapFactory.decodeFile(srcPath,newOpts);//    bm   
 newOpts.inJustDecodeBounds = false; 
 int w = newOpts.outWidth; 
 int h = newOpts.outHeight; 
 //          1280*720   ,           
 float hh = 1280f;//       1280f 
 float ww = 720f;//       720f 
 //   。         ,                   
 int be = 1;//be=1      
 if (w > h && w > ww) {//                  
 be = (int) (newOpts.outWidth / ww); 
 } else if (w < h && h > hh) {//                  
 be = (int) (newOpts.outHeight / hh); 
 } 
 if (be <= 0) 
 be = 1; 
 newOpts.inSampleSize = be;//       
 //      ,       options.inJustDecodeBounds   false  
 bitmap = BitmapFactory.decodeFile(srcPath, newOpts); 
 return compressImage(bitmap);//                
 }
이 방법의 장점 은 메모리 사용 을 크게 줄 였 다 는 것 이다.메모리 에 있 는 그림 을 읽 을 때 고 화질 효과 가 필요 하지 않 으 면 먼저 그림 의 가장자리 만 읽 고 너비 와 높이 를 통 해 샘플링 율 을 설정 한 후에 그림 을 불 러 올 수 있다.그러면 메모 리 를 너무 많이 차지 하지 않 을 것 이다.
3.확대
그림 픽 셀 크기 를 조정 하여 그림 의 메모리 크기 를 줄 입 니 다.
방식 1

public static void compressBitmapToFile(Bitmap bmp, File file){
 //       ,   ,      
 int ratio = 2;
 //   Bitmap     
 Bitmap result = Bitmap.createBitmap(bmp.getWidth() / ratio, bmp.getHeight() / ratio, Config.ARGB_8888);
 Canvas canvas = new Canvas(result);
 Rect rect = new Rect(0, 0, bmp.getWidth() / ratio, bmp.getHeight() / ratio);
 canvas.drawBitmap(bmp, null, rect, null);

 ByteArrayOutputStream baos = new ByteArrayOutputStream();
 //           baos 
 result.compress(Bitmap.CompressFormat.JPEG, 100 ,baos);
 try { 
 FileOutputStream fos = new FileOutputStream(file); 
 fos.write(baos.toByteArray()); 
 fos.flush(); 
 fos.close(); 
 } catch (Exception e) { 
 e.printStackTrace(); 
 } 
}

방식 2

ByteArrayOutputStream out = new ByteArrayOutputStream(); 
image.compress(Bitmap.CompressFormat.JPEG, 85, out); 
float zoom = (float)Math.sqrt(size * 1024 / (float)out.toByteArray().length); 

Matrix matrix = new Matrix(); 
matrix.setScale(zoom, zoom); 

Bitmap result = Bitmap.createBitmap(image, 0, 0, image.getWidth(), image.getHeight(), matrix, true); 

out.reset(); 
result.compress(Bitmap.CompressFormat.JPEG, 85, out); 
while(out.toByteArray().length > size * 1024){ 
 System.out.println(out.toByteArray().length); 
 matrix.setScale(0.9f, 0.9f); 
 result = Bitmap.createBitmap(result, 0, 0, result.getWidth(), result.getHeight(), matrix, true); 
 out.reset(); 
 result.compress(Bitmap.CompressFormat.JPEG, 85, out); 
}

크기 조정 법 은 간단 합 니 다.matrix 를 설정 하고 createBitmap 에 있 으 면 됩 니 다.그러나 우 리 는 크기 조정 비율 을 모 르 고 그림 의 최종 크기 를 요구 했다.직접 크기 의 비율 로 하면 문제 가 있 을 것 이다.크기 의 비율 로 하 는 것 이 비슷 하지만 차이 가 있다.하지만 조금 만 더 미세 조정 하면 될 것 같 습 니 다.미세 조정 하면 수 정 된 그림 의 크기 가 최종 크기 보다 크 면 0.8 의 압축 을 하고 크기 가 적당 할 때 까지 순환 합 니 다.이렇게 하면 적당 한 크기 의 그림 을 얻 을 수 있 고 품질 도 비교적 보장 할 수 있다.
4.JNI 호출 libjpeg 라 이브 러 리 압축
JNI 정적 호출 bitherlibjni.c 의 방법 으로 압축 자바net_bither_util_NativeUtil_compressBitmap
net_bither_util 은 패키지 이름,NativeUtil 은 클래스 이름,copressBitmap 는 native 방법 이름 입 니 다.저 희 는 saveBitmap()방법 만 호출 하면 됩 니 다.bmp 는 압축 된 Bitmap 대상,quality 압축 품질 0-100,fileName 압축 후 저장 할 파일 주 소 를 사용 하고 optimize 는 하 프 만 표 데이터 로 품질 차 이 를 5-10 배 계산 합 니까?

jstring Java_net_bither_util_NativeUtil_compressBitmap(JNIEnv* env,
 jobject thiz, jobject bitmapcolor, int w, int h, int quality,
 jbyteArray fileNameStr, jboolean optimize) {

 AndroidBitmapInfo infocolor;
 BYTE* pixelscolor;
 int ret;
 BYTE * data;
 BYTE *tmpdata;
 char * fileName = jstrinTostring(env, fileNameStr);
 if ((ret = AndroidBitmap_getInfo(env, bitmapcolor, &infocolor)) < 0) {
 LOGE("AndroidBitmap_getInfo() failed ! error=%d", ret);
 return (*env)->NewStringUTF(env, "0");;
 }
 if ((ret = AndroidBitmap_lockPixels(env, bitmapcolor, &pixelscolor)) < 0) {
 LOGE("AndroidBitmap_lockPixels() failed ! error=%d", ret);
 }

 BYTE r, g, b;
 data = NULL;
 data = malloc(w * h * 3);
 tmpdata = data;
 int j = 0, i = 0;
 int color;
 for (i = 0; i < h; i++) {
 for (j = 0; j < w; j++) {
 color = *((int *) pixelscolor);
 r = ((color & 0x00FF0000) >> 16);
 g = ((color & 0x0000FF00) >> 8);
 b = color & 0x000000FF;
 *data = b;
 *(data + 1) = g;
 *(data + 2) = r;
 data = data + 3;
 pixelscolor += 4;

 }

 }
 AndroidBitmap_unlockPixels(env, bitmapcolor);
 int resultCode= generateJPEG(tmpdata, w, h, quality, fileName, optimize);
 free(tmpdata);
 if(resultCode==0){
 jstring result=(*env)->NewStringUTF(env, error);
 error=NULL;
 return result;
 }
 return (*env)->NewStringUTF(env, "1"); //success
}

5.품질 압축+샘플링 압축+JNI 호출 libjpeg 라 이브 러 리 압축 결합 사용
먼저 사이즈 압축 을 통 해 핸드폰 에서 자주 사용 하 는 해상도(1280*960 위 챗 은 이 해상도 로 압축 된 것 같다)로 압축 한 다음 에 우 리 는 그림 을 일정한 크기 이내(예 를 들 어 200 k)로 압축 한 다음 에 순환 을 통 해 품질 압축 을 해서 options 가 얼마나 설정 해 야 하 는 지 계산 하고 마지막 에 JNI 압축 을 호출 해 야 한다.
크기 조정 비 계산

/**
 *      
 * @param bitWidth       
 * @param bitHeight       
 * @return int    
 */
 public static int getRatioSize(int bitWidth, int bitHeight) {
 //        
 int imageHeight = 1280;
 int imageWidth = 960;
 //    
 int ratio = 1;
 //    ,         ,                  
 if (bitWidth > bitHeight && bitWidth > imageWidth) {
 //           ,      
 ratio = bitWidth / imageWidth;
 } else if (bitWidth < bitHeight && bitHeight > imageHeight) {
 //           ,      
 ratio = bitHeight / imageHeight;
 }
 //      1
 if (ratio <= 0)
 ratio = 1;
 return ratio;
 }
질량 압축+JNI 압축

/**
 * @Description:   JNI     Bitmap       
 * @param curFilePath
 *         
 * @param targetFilePath
 *           
 */
 public static void compressBitmap(String curFilePath, String targetFilePath) {
 //        500KB
 int maxSize = 500;
 //      bitmap
 Bitmap result = getBitmapFromFile(curFilePath);
 ByteArrayOutputStream baos = new ByteArrayOutputStream();
 //       ,  100     ,          baos 
 int quality = 100;
 result.compress(Bitmap.CompressFormat.JPEG, quality, baos);
 //                500kb,      
 while (baos.toByteArray().length / 1024 > maxSize) {
 //   baos   baos
 baos.reset();
 //      10
 quality -= 10;
 //     quality,          baos 
 result.compress(Bitmap.CompressFormat.JPEG, quality, baos);
 }
 // JNI     SD      
 NativeUtil.saveBitmap(result, quality, targetFilePath, true);
 //   Bitmap
 if (!result.isRecycled()) {
 result.recycle();
 }
 }

JNI 그림 압축 도구 클래스

package net.bither.util;
import android.graphics.Bitmap;
import android.graphics.Bitmap.Config;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Matrix;
import android.graphics.Rect;
import android.media.ExifInterface;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
/**
* JNI       
*
* @Description TODO
* @Package net.bither.util
* @Class NativeUtil
*/
public class NativeUtil {

 private static int DEFAULT_QUALITY = 95;

 /**
 * @Description: JNI    
 * @param bit
 * bitmap  
 * @param fileName
 *        
 * @param optimize
 *                  5-10 
 */
 public static void compressBitmap(Bitmap bit, String fileName, boolean optimize) {
 saveBitmap(bit, DEFAULT_QUALITY, fileName, optimize);
 }

 /**
 * @Description:   JNI     Bitmap       
 * @param image
 * bitmap  
 * @param filePath
 *         
 */
 public static void compressBitmap(Bitmap image, String filePath) {
 //        150KB
 int maxSize = 150;
 //         
 int ratio = NativeUtil.getRatioSize(image.getWidth(),image.getHeight());
 //   Bitmap     
 Bitmap result = Bitmap.createBitmap(image.getWidth() / ratio,image.getHeight() / ratio, Config.ARGB_8888);
 Canvas canvas = new Canvas(result);
 Rect rect = new Rect(0, 0, image.getWidth() / ratio, image.getHeight() / ratio);
 canvas.drawBitmap(image,null,rect,null);
 ByteArrayOutputStream baos = new ByteArrayOutputStream();
 //       ,  100     ,          baos 
 int options = 100;
 result.compress(Bitmap.CompressFormat.JPEG, options, baos);
 //                100kb,      
 while (baos.toByteArray().length / 1024 > maxSize) {
 //   baos   baos
 baos.reset();
 //      10
 options -= 10;
 //     options%,          baos 
 result.compress(Bitmap.CompressFormat.JPEG, options, baos);
 }
 // JNI     SD      
 NativeUtil.saveBitmap(result, options, filePath, true);
 //   Bitmap
 if (!result.isRecycled()) {
 result.recycle();
 }
 }

 /**
 * @Description:   JNI     Bitmap       
 * @param curFilePath
 *         
 * @param targetFilePath
 *           
 */
 public static void compressBitmap(String curFilePath, String targetFilePath) {
 //        500KB
 int maxSize = 500;
 //      bitmap
 Bitmap result = getBitmapFromFile(curFilePath);
 ByteArrayOutputStream baos = new ByteArrayOutputStream();
 //       ,  100     ,          baos 
 int quality = 100;
 result.compress(Bitmap.CompressFormat.JPEG, quality, baos);
 //                500kb,      
 while (baos.toByteArray().length / 1024 > maxSize) {
 //   baos   baos
 baos.reset();
 //      10
 quality -= 10;
 //     quality,          baos 
 result.compress(Bitmap.CompressFormat.JPEG, quality, baos);
 }
 // JNI     SD      
 NativeUtil.saveBitmap(result, quality, targetFilePath, true);
 //   Bitmap
 if (!result.isRecycled()) {
 result.recycle();
 }

 }

 /**
 *      
 * @param bitWidth       
 * @param bitHeight       
 * @return int    
 */
 public static int getRatioSize(int bitWidth, int bitHeight) {
 //        
 int imageHeight = 1280;
 int imageWidth = 960;
 //    
 int ratio = 1;
 //    ,         ,                  
 if (bitWidth > bitHeight && bitWidth > imageWidth) {
 //           ,      
 ratio = bitWidth / imageWidth;
 } else if (bitWidth < bitHeight && bitHeight > imageHeight) {
 //           ,      
 ratio = bitHeight / imageHeight;
 }
 //      1
 if (ratio <= 0)
 ratio = 1;
 return ratio;
 }

 /**
 *          Bitmap  OOM          
 * @param filePath
 * @return
 */
 public static Bitmap getBitmapFromFile(String filePath){
 BitmapFactory.Options newOpts = new BitmapFactory.Options();
 newOpts.inJustDecodeBounds = true;//   ,     
 BitmapFactory.decodeFile(filePath, newOpts);
 int w = newOpts.outWidth;
 int h = newOpts.outHeight;
 //         
 newOpts.inSampleSize = NativeUtil.getRatioSize(w,h);
 newOpts.inJustDecodeBounds = false;//      
 newOpts.inDither = false;
 newOpts.inPurgeable=true;
 newOpts.inInputShareable=true;
 newOpts.inTempStorage = new byte[32 * 1024];
 Bitmap bitmap = null;
 File file = new File(filePath);
 FileInputStream fs = null;
 try {
 fs = new FileInputStream(file);
 } catch (FileNotFoundException e) {
 e.printStackTrace();
 }
 try {
 if(fs!=null){
 bitmap = BitmapFactory.decodeFileDescriptor(fs.getFD(),null,newOpts);
 //    
 int photoDegree = readPictureDegree(filePath);
 if(photoDegree != 0){
  Matrix matrix = new Matrix();
  matrix.postRotate(photoDegree);
  //       
  bitmap = Bitmap.createBitmap(bitmap, 0, 0,
  bitmap.getWidth(), bitmap.getHeight(), matrix, true);
 }
 }
 } catch (IOException e) {
 e.printStackTrace();
 } finally{
 if(fs!=null) {
 try {
  fs.close();
 } catch (IOException e) {
  e.printStackTrace();
 }
 }
 }
 return bitmap;
 }

 /**
 *
 *       :     
 * @param path       
 * @return degree     
 */

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

 /**
 *   native  
 * @Description:    
 * @param bit
 * @param quality
 * @param fileName
 * @param optimize
 */
 private static void saveBitmap(Bitmap bit, int quality, String fileName, boolean optimize) {
 compressBitmap(bit, bit.getWidth(), bit.getHeight(), quality, fileName.getBytes(), optimize);
 }

 /**
 *      bitherlibjni.c    
 * @Description:    
 * @param bit
 * @param w
 * @param h
 * @param quality
 * @param fileNameBytes
 * @param optimize
 * @return
 */
 private static native String compressBitmap(Bitmap bit, int w, int h, int quality, byte[] fileNameBytes,
   boolean optimize);
 /**
 *   lib   so  
 */
 static {
 System.loadLibrary("jpegbither");
 System.loadLibrary("bitherjni");
 }
}

그림 압축 처리 중 발생 할 수 있 는 문제:
시스템 앨범 요청 세 가지 Action 이 있 습 니 다.
메모:갤러리(미리 보기 그림)와 그림(원본 그림)
ACTION_OPEN_DOCUMENT 는 4.4 이상 만 기본 값 으로 원본 그림 을 엽 니 다.
그림 에서 가 져 온 uri 형식 은:content://com.android.providers.media.documents/document/image%666>>>
ACTION_GET_CONTENT 4.4 이하 기본 값 으로 미리 보기 그림 을 엽 니 다.이상 은 파일 관리 자 를 열 어 선택 할 수 있 습 니 다.갤러리 를 미리 보기 그림 페이지 로 열 고 그림 을 선택 하여 원본 그림 탐색 으로 열 수 있 습 니 다.
갤러리 에서 가 져 온 uri 형식 은:content://media/external/images/media/666666
ACTION_PICK 을 모두 사용 할 수 있 습 니 다.기본 값 은 미리 보기 그림 인터페이스 이 고 좀 더 열 어 봐 야 합 니 다.
참조 코드:

public void pickFromGallery() {
 if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) {
 startActivityForResult(new Intent(Intent.ACTION_GET_CONTENT).setType("image/*"),
 REQUEST_PICK_IMAGE);
 } else {
 Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
 intent.addCategory(Intent.CATEGORY_OPENABLE);
 intent.setType("image/*");
 startActivityForResult(intent, REQUEST_KITKAT_PICK_IMAGE);
 }
}
URI 에 따 른 파일 경로 가 져 오기
우리 가 갤러리 에서 그림 을 선택 한 후에 우리 에 게 되 돌려 준 data.getData()는 URI 일 수 있 습 니 다.우 리 는 평소에 파일 에 대한 작업 은 기본적으로 경 로 를 바탕 으로 여러 가지 조작 과 전환 을 합 니 다.지금 우 리 는 URI 에 대응 하 는 파일 경 로 를 찾 아야 합 니 다.구체 적 인 참고 코드 는 다음 과 같 습 니 다.

public static String getPathByUri(Context context, Uri data){
 if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) {
 return getPathByUri4BeforeKitkat(context, data);
 }else {
 return getPathByUri4AfterKitkat(context, data);
 }
 }
 //4.4    Uri    :data Uri,filename   String    ,      
 public static String getPathByUri4BeforeKitkat(Context context, Uri data) {
 String filename=null;
 if (data.getScheme().toString().compareTo("content") == 0) {
 Cursor cursor = context.getContentResolver().query(data, new String[] { "_data" }, null, null, null);
 if (cursor.moveToFirst()) {
 filename = cursor.getString(0);
 }
 } else if (data.getScheme().toString().compareTo("file") == 0) {// file:///   uri
 filename = data.toString().replace("file://", "");//   file://
 if (!filename.startsWith("/mnt")) {//   "/mnt" 
 filename += "/mnt";
 }
 }
 return filename;
 }
 //4.4    Uri    :
 @SuppressLint("NewApi")
 public static String getPathByUri4AfterKitkat(final Context context, final Uri uri) {
 final boolean isKitKat = Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT;
 // DocumentProvider
 if (isKitKat && DocumentsContract.isDocumentUri(context, uri)) {
 if (isExternalStorageDocument(uri)) {// ExternalStorageProvider
 final String docId = DocumentsContract.getDocumentId(uri);
 final String[] split = docId.split(":");
 final String type = split[0];
 if ("primary".equalsIgnoreCase(type)) {
  return Environment.getExternalStorageDirectory() + "/" + split[1];
 }
 } else if (isDownloadsDocument(uri)) {// DownloadsProvider
 final String id = DocumentsContract.getDocumentId(uri);
 final Uri contentUri = ContentUris.withAppendedId(Uri.parse("content://downloads/public_downloads"),
  Long.valueOf(id));
 return getDataColumn(context, contentUri, null, null);
 } else if (isMediaDocument(uri)) {// MediaProvider
 final String docId = DocumentsContract.getDocumentId(uri);
 final String[] split = docId.split(":");
 final String type = split[0];
 Uri contentUri = null;
 if ("image".equals(type)) {
  contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
 } else if ("video".equals(type)) {
  contentUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI;
 } else if ("audio".equals(type)) {
  contentUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
 }
 final String selection = "_id=?";
 final String[] selectionArgs = new String[] { split[1] };
 return getDataColumn(context, contentUri, selection, selectionArgs);
 }
 } else if ("content".equalsIgnoreCase(uri.getScheme())) {// MediaStore
 // (and
 // general)
 return getDataColumn(context, uri, null, null);
 } else if ("file".equalsIgnoreCase(uri.getScheme())) {// File
 return uri.getPath();
 }
 return null;
 }

 /**
 * Get the value of the data column for this Uri. This is useful for
 * MediaStore Uris, and other file-based ContentProviders.
 *
 * @param context
 * The context.
 * @param uri
 * The Uri to query.
 * @param selection
 * (Optional) Filter used in the query.
 * @param selectionArgs
 * (Optional) Selection arguments used in the query.
 * @return The value of the _data column, which is typically a file path.
 */
 public static String getDataColumn(Context context, Uri uri, String selection, String[] selectionArgs) {
 Cursor cursor = null;
 final String column = "_data";
 final String[] projection = { column };
 try {
 cursor = context.getContentResolver().query(uri, projection, selection, selectionArgs, null);
 if (cursor != null && cursor.moveToFirst()) {
 final int column_index = cursor.getColumnIndexOrThrow(column);
 return cursor.getString(column_index);
 }
 } finally {
 if (cursor != null)
 cursor.close();
 }
 return null;
 }

 /**
 * @param uri
 * The Uri to check.
 * @return Whether the Uri authority is ExternalStorageProvider.
 */
 public static boolean isExternalStorageDocument(Uri uri) {
 return "com.android.externalstorage.documents".equals(uri.getAuthority());
 }

 /**
 * @param uri
 * The Uri to check.
 * @return Whether the Uri authority is DownloadsProvider.
 */
 public static boolean isDownloadsDocument(Uri uri) {
 return "com.android.providers.downloads.documents".equals(uri.getAuthority());
 }

 /**
 * @param uri
 * The Uri to check.
 * @return Whether the Uri authority is MediaProvider.
 */
 public static boolean isMediaDocument(Uri uri) {
 return "com.android.providers.media.documents".equals(uri.getAuthority());
 }

원본 코드 를 동봉 합 니 다.자체 참고:원본 코드 다운로드

좋은 웹페이지 즐겨찾기