在Android中处理来自uri的外部数据的简便方法

时间:2016-02-26 16:34:25

标签: android android-intent uri android-contentprovider

有没有简单的方法来处理android中的内容提供程序。我的应用程序必须处理文本,图像和文档,但在添加对Google Drive内容提供商,Google相册,媒体等的支持后...... 现在,当我的应用程序与图像和文本共享Google Keep note时,我的应用程序崩溃了。

这是我现在如何使用它的片段:

public class IntentUtils {
public static String handlePDFIntent(Context context, Intent intent) {
    Uri uri = intent.getParcelableExtra(Intent.EXTRA_STREAM);
    if (uri != null) {
        return getPath(context, uri);
    }
    return "";
}

public static String handleTextIntent(Intent intent) {
    String sharedText = intent.getStringExtra(Intent.EXTRA_TEXT);
    if (sharedText != null) {
        return sharedText;
    }
    return "";
}

public static String handleImageIntent(Context context, Intent intent) {
    Uri imageUri = intent.getParcelableExtra(Intent.EXTRA_STREAM);
    if (imageUri != null) {
        return getPath(context, imageUri);
    }

    return "";
}

public static boolean isExternalStorageRemovable() {
    return Build.VERSION.SDK_INT < Build.VERSION_CODES.GINGERBREAD || Environment.isExternalStorageRemovable();
}

public static File getExternalCacheDir(Context context) {
    if (hasExternalCacheDir()) {
        return context.getExternalCacheDir();
    }

    // Before Froyo we need to construct the external cache dir ourselves
    final String cacheDir = "/Android/data/" + context.getPackageName() + "/cache/";
    return new File(Environment.getExternalStorageDirectory().getPath() + cacheDir);
}

public static boolean hasExternalCacheDir() {
    return Build.VERSION.SDK_INT >= Build.VERSION_CODES.FROYO;
}

@TargetApi(Build.VERSION_CODES.KITKAT)
public static String getPath(final Context context, final Uri uri) {
    final boolean isKitKat = Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT;

    // DocumentProvider
    if (isKitKat && DocumentsContract.isDocumentUri(context, uri)) {
        // ExternalStorageProvider
        if (isExternalStorageDocument(uri)) {
            final String docId = DocumentsContract.getDocumentId(uri);
            final String[] split = docId.split(":");
            final String format = split[0];

            if ("primary".equalsIgnoreCase(format)) {
                return Environment.getExternalStorageDirectory() + "/" + split[1];
            }

            // TODO handle non-primary volumes
        }
        // DownloadsProvider
        else if (isDownloadsDocument(uri)) {

            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);
        }
        // MediaProvider
        else if (isMediaDocument(uri)) {
            final String docId = DocumentsContract.getDocumentId(uri);
            final String[] split = docId.split(":");
            final String format = split[0];

            Uri contentUri = null;
            switch (format) {
                case "image":
                    contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
                    break;
                case "video":
                    contentUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI;
                    break;
                case "audio":
                    contentUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
                    break;
            }

            final String selection = "_id=?";
            final String[] selectionArgs = new String[]{
                    split[1]
            };

            return getDataColumn(context, contentUri, selection, selectionArgs);
        }
    }
    // MediaStore (and general)
    else if ("content".equalsIgnoreCase(uri.getScheme())) {
        if (isDriveStorageDocument(uri) || isPlusPhotosDocument(uri) || Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
            try {
                ParcelFileDescriptor parcel = context.getContentResolver().openFileDescriptor(uri, "r");
                final InputStream is = new FileInputStream(parcel.getFileDescriptor());
                final File cacheDir;

                if (externalMemoryAvailable()) {
                    cacheDir = context.getExternalCacheDir();
                } else {
                    cacheDir = context.getCacheDir();
                }

                final String type = context.getContentResolver().getType(uri);
                String ext = "pdf";

                if (type.startsWith("image")) {
                    if (type.toLowerCase().contains("jpg") || type.toLowerCase().contains("jpeg")) {
                        ext = "jpg";
                    } else if (type.toLowerCase().contains("png")) {
                        ext = "png";
                    }
                }

                cacheDir.mkdirs();
                File out = new File(cacheDir, "tmp_" + System.currentTimeMillis() + "." + ext);

                FileUtils.copyInputStreamToFile(is, out);
                is.close();
                parcel.close();

                System.out.println(Uri.fromFile(out).getPath());

                return Uri.fromFile(out).getPath();

            } catch (IOException e) {
                e.printStackTrace();
            }
        } else {
            return getDataColumn(context, uri, null, null);
        }
    }
    // File
    else if ("file".equalsIgnoreCase(uri.getScheme())) {
        return uri.getPath();
    } else {
        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());
}

public static boolean isDriveStorageDocument(Uri uri) {
    return uri.getAuthority().startsWith("com.google.android.apps.docs.storage");
}

public static boolean isKeepNote(Uri uri) {
    return uri.getAuthority().startsWith("com.google.android.keep");
}

public static boolean isPlusPhotosDocument(Uri uri) {
    return uri.getAuthority().startsWith("content://com.google.android.apps.photos.content");
}

/**
 * @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());
}

public static boolean isPackageInstalled(String packagename, Context context) {
    PackageManager pm = context.getPackageManager();
    try {
        pm.getPackageInfo(packagename, PackageManager.GET_ACTIVITIES);
        return true;
    } catch (PackageManager.NameNotFoundException e) {
        return false;
    }
}

public static boolean isDebuggable(Context ctx) {
    boolean debuggable = false;

    PackageManager pm = ctx.getPackageManager();
    try {
        final ApplicationInfo appinfo = pm.getApplicationInfo(ctx.getPackageName(), 0);
        debuggable = (0 != (appinfo.flags & ApplicationInfo.FLAG_DEBUGGABLE));
    } catch (NameNotFoundException e) {/*debuggable variable will remain false*/}

    return debuggable;
}

public static boolean externalMemoryAvailable() {
    return Environment.getExternalStorageState().equals(
            Environment.MEDIA_MOUNTED);
}

}

更新1: 谷歌似乎继续使用剪贴板数据和一些blob,但我正在寻找更通用的方法来处理外部内容提供商。有什么帮助吗?

0 个答案:

没有答案
相关问题