欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Android7.0以上Uri轉(zhuǎn)路徑的方法實(shí)現(xiàn)(已驗(yàn)證)

 更新時間:2020年03月06日 09:20:37   作者:dx林i  
這篇文章主要介紹了Android7.0以上Uri轉(zhuǎn)路徑的方法實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧

網(wǎng)絡(luò)上看到過很多種Uri轉(zhuǎn)路徑的方法,可基本上都只適用于很少的Uri值,可能沒有結(jié)果(例如,對于由MediaStore索引的非本地文件),也可能沒有可用的結(jié)果(例如,對于可移動存儲上的文件)。

解決方法

使用ContentResolver和openInputStream()在Uri標(biāo)識的內(nèi)容上獲取InputStream。在控制的文件上使用InputStream和FileOutputStream復(fù)制內(nèi)容,然后使用該文件。

代碼如下:

private static String getFilePathForN(Context context, Uri uri) {
  try {
    Cursor returnCursor = context.getContentResolver().query(uri, null, null, null, null);
    int nameIndex = returnCursor.getColumnIndex(OpenableColumns.DISPLAY_NAME);
    returnCursor.moveToFirst();
    String name = (returnCursor.getString(nameIndex));
    File file = new File(context.getFilesDir(), name);
    InputStream inputStream = context.getContentResolver().openInputStream(uri);
    FileOutputStream outputStream = new FileOutputStream(file);
    int read = 0;
    int maxBufferSize = 1 * 1024 * 1024;
    int bytesAvailable = inputStream.available();
    int bufferSize = Math.min(bytesAvailable, maxBufferSize);
    final byte[] buffers = new byte[bufferSize];
    while ((read = inputStream.read(buffers)) != -1) {
      outputStream.write(buffers, 0, read);
    }
    returnCursor.close();
    inputStream.close();
    outputStream.close();
    return file.getPath();
  } catch (Exception e) {
    e.printStackTrace();
  }
  return null;
}

附上全系統(tǒng)的代碼:

/**
 * 文件Uri轉(zhuǎn)路徑(兼容各品牌手機(jī))
 */
public class PathUtils {
  /**
   * android7.0以上處理方法
   */
  private static String getFilePathForN(Context context, Uri uri) {
    try {
      Cursor returnCursor = context.getContentResolver().query(uri, null, null, null, null);
      int nameIndex = returnCursor.getColumnIndex(OpenableColumns.DISPLAY_NAME);
      returnCursor.moveToFirst();
      String name = (returnCursor.getString(nameIndex));
      File file = new File(context.getFilesDir(), name);
      InputStream inputStream = context.getContentResolver().openInputStream(uri);
      FileOutputStream outputStream = new FileOutputStream(file);
      int read = 0;
      int maxBufferSize = 1 * 1024 * 1024;
      int bytesAvailable = inputStream.available();

      int bufferSize = Math.min(bytesAvailable, maxBufferSize);

      final byte[] buffers = new byte[bufferSize];
      while ((read = inputStream.read(buffers)) != -1) {
        outputStream.write(buffers, 0, read);
      }
      returnCursor.close();
      inputStream.close();
      outputStream.close();
      return file.getPath();
    } catch (Exception e) {
      e.printStackTrace();
    }
    return null;
  }

  /**
   * 全平臺處理方法
   */
  public static String getPath(final Context context, final Uri uri) throws Exception {

    final boolean isKitKat = Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT;
    final boolean isN = Build.VERSION.SDK_INT >= Build.VERSION_CODES.N;

    if (isN) {
      return getFilePathForN(context, uri);
    }

    // DocumentProvider
    if (isKitKat && DocumentsContract.isDocumentUri(context, uri)) {
      // ExternalStorageProvider
      if (isExternalStorageDocument(uri)) {
        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];
        }

      }
      // DownloadsProvider
      else if (isDownloadsDocument(uri)) {

        final String id = DocumentsContract.getDocumentId(uri);
        final Uri contentUri = ContentUris.withAppendedId(
            Uri.parse("content://downloads/public_downloads"), StringUtils.toLong(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 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);
      }
    }
    // MediaStore (and general)
    else if ("content".equalsIgnoreCase(uri.getScheme())) {
      return getDataColumn(context, uri, null, null);
    }
    // File
    else if ("file".equalsIgnoreCase(uri.getScheme())) {
      return uri.getPath();
    }

    return null;
  }

  /**
   * 獲取此Uri的數(shù)據(jù)列的值。這對于MediaStore uri和其他基于文件的內(nèi)容提供程序非常有用。
   */
  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);
      }
    } catch (IllegalArgumentException e){
      //do nothing
    } finally {
      if (cursor != null)
        cursor.close();
    }
    return null;
  }

  public static boolean isExternalStorageDocument(Uri uri) {
    return "com.android.externalstorage.documents".equals(uri.getAuthority());
  }

  public static boolean isDownloadsDocument(Uri uri) {
    return "com.android.providers.downloads.documents".equals(uri.getAuthority());
  }

  public static boolean isMediaDocument(Uri uri) {
    return "com.android.providers.media.documents".equals(uri.getAuthority());
  }
}

參考資料:https://stackoverflow.com/questions/42508383/illegalargumentexception-column-data-does-not-exist

另發(fā)現(xiàn)一篇,親測,Android 4.4到Android 10可用,測試的系統(tǒng)有VIVO、OPPO、MIUI、EMUI...

解決的國內(nèi)產(chǎn)商問題:華為的黃色圖標(biāo)管理器,他返回了4.4的標(biāo)準(zhǔn)的Uri了,不是4.4以上的標(biāo)準(zhǔn)的Uri,導(dǎo)致解析的時候,判斷到版本 > 4.4,然后用了4.4以上的標(biāo)準(zhǔn)的解析,然后失敗了,并非不回調(diào)。 

直接可用的代碼片段:

public class FileUtils {
 
  private Context context;
 
  public FileUtils(Context context) {
    this.context = context;
  }
 
  public String getFilePathByUri(Uri uri) {
    // 以 file:// 開頭的
    if (ContentResolver.SCHEME_FILE.equals(uri.getScheme())) {
      return uri.getPath();
    }
    // 以/storage開頭的也直接返回
    if (isOtherDocument(uri)) {
      return uri.getPath();
    }
    // 版本兼容的獲??!
    String path = getFilePathByUri_BELOWAPI11(uri);
    if (path != null) {
      LogUtils.d("getFilePathByUri_BELOWAPI11獲取到的路徑為:" + path);
      return path;
    }
    path = getFilePathByUri_API11to18(uri);
    if (path != null) {
      LogUtils.d("getFilePathByUri_API11to18獲取到的路徑為:" + path);
      return path;
    }
    path = getFilePathByUri_API19(uri);
    LogUtils.d("getFilePathByUri_API19獲取到的路徑為:" + path);
    return path;
  }
 
  private String getFilePathByUri_BELOWAPI11(Uri uri) {
    // 以 content:// 開頭的,比如 content://media/extenral/images/media/17766
    if (ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())) {
      String path = null;
      String[] projection = new String[]{MediaStore.Images.Media.DATA};
      Cursor cursor = context.getContentResolver().query(uri, projection, null, null, null);
      if (cursor != null) {
        if (cursor.moveToFirst()) {
          int columnIndex = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
          if (columnIndex > -1) {
            path = cursor.getString(columnIndex);
          }
        }
        cursor.close();
      }
      return path;
    }
    return null;
  }
 
  private String getFilePathByUri_API11to18(Uri contentUri) {
    String[] projection = {MediaStore.Images.Media.DATA};
    String result = null;
    CursorLoader cursorLoader = new CursorLoader(context, contentUri, projection, null, null, null);
    Cursor cursor = cursorLoader.loadInBackground();
    if (cursor != null) {
      int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
      cursor.moveToFirst();
      result = cursor.getString(column_index);
      cursor.close();
    }
    return result;
  }
 
  private String getFilePathByUri_API19(Uri uri) {
    // 4.4及之后的 是以 content:// 開頭的,比如 content://com.android.providers.media.documents/document/image%3A235700
    if (ContentResolver.SCHEME_CONTENT.equals(uri.getScheme()) && Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
      if (DocumentsContract.isDocumentUri(context, uri)) {
        if (isExternalStorageDocument(uri)) {
          // ExternalStorageProvider
          String docId = DocumentsContract.getDocumentId(uri);
          String[] split = docId.split(":");
          String type = split[0];
          if ("primary".equalsIgnoreCase(type)) {
            if (split.length > 1) {
              return Environment.getExternalStorageDirectory() + "/" + split[1];
            } else {
              return Environment.getExternalStorageDirectory() + "/";
            }
            // This is for checking SD Card
          }
        } else if (isDownloadsDocument(uri)) {
          //下載內(nèi)容提供者時應(yīng)當(dāng)判斷下載管理器是否被禁用
          int stateCode = context.getPackageManager().getApplicationEnabledSetting("com.android.providers.downloads");
          if (stateCode != 0 && stateCode != 1) {
            return null;
          }
          String id = DocumentsContract.getDocumentId(uri);
          // 如果出現(xiàn)這個RAW地址,我們則可以直接返回!
          if (id.startsWith("raw:")) {
            return id.replaceFirst("raw:", "");
          }
          if (id.contains(":")) {
            String[] tmp = id.split(":");
            if (tmp.length > 1) {
              id = tmp[1];
            }
          }
          Uri contentUri = Uri.parse("content://downloads/public_downloads");
          LogUtils.d("測試打印Uri: " + uri);
          try {
            contentUri = ContentUris.withAppendedId(contentUri, Long.parseLong(id));
          } catch (Exception e) {
            e.printStackTrace();
          }
          String path = getDataColumn(contentUri, null, null);
          if (path != null) return path;
          // 兼容某些特殊情況下的文件管理器!
          String fileName = getFileNameByUri(uri);
          if (fileName != null) {
            path = Environment.getExternalStorageDirectory().toString() + "/Download/" + fileName;
            return path;
          }
        } else if (isMediaDocument(uri)) {
          // MediaProvider
          String docId = DocumentsContract.getDocumentId(uri);
          String[] split = docId.split(":");
          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;
          }
          String selection = "_id=?";
          String[] selectionArgs = new String[]{split[1]};
          return getDataColumn(contentUri, selection, selectionArgs);
        }
      }
    }
    return null;
  }
 
  private String getFileNameByUri(Uri uri) {
    String relativePath = getFileRelativePathByUri_API18(uri);
    if (relativePath == null) relativePath = "";
    final String[] projection = {
        MediaStore.MediaColumns.DISPLAY_NAME
    };
    try (Cursor cursor = context.getContentResolver().query(uri, projection, null, null, null)) {
      if (cursor != null && cursor.moveToFirst()) {
        int index = cursor.getColumnIndexOrThrow(MediaStore.MediaColumns.DISPLAY_NAME);
        return relativePath + cursor.getString(index);
      }
    }
    return null;
  }
 
  private String getFileRelativePathByUri_API18(Uri uri) {
    final String[] projection;
    if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.Q) {
      projection = new String[]{
          MediaStore.MediaColumns.RELATIVE_PATH
      };
      try (Cursor cursor = context.getContentResolver().query(uri, projection, null, null, null)) {
        if (cursor != null && cursor.moveToFirst()) {
          int index = cursor.getColumnIndexOrThrow(MediaStore.MediaColumns.RELATIVE_PATH);
          return cursor.getString(index);
        }
      }
    }
    return null;
  }
 
  private String getDataColumn(Uri uri, String selection, String[] selectionArgs) {
    final String column = MediaStore.Images.Media.DATA;
    final String[] projection = {column};
    try (Cursor 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);
      }
    } catch (IllegalArgumentException iae) {
      iae.printStackTrace();
    }
    return null;
  }
 
  private boolean isExternalStorageDocument(Uri uri) {
    return "com.android.externalstorage.documents".equals(uri.getAuthority());
  }
 
  private boolean isOtherDocument(Uri uri) {
    // 以/storage開頭的也直接返回
    if (uri != null && uri.getPath() != null) {
      String path = uri.getPath();
      if (path.startsWith("/storage")) {
        return true;
      }
      if (path.startsWith("/external_files")) {
        return true;
      }
    }
    return false;
  }
 
  private boolean isDownloadsDocument(Uri uri) {
    return "com.android.providers.downloads.documents".equals(uri.getAuthority());
  }
 
  private boolean isMediaDocument(Uri uri) {
    return "com.android.providers.media.documents".equals(uri.getAuthority());
  }
}

調(diào)用 getFilePathByUri(Uri uri) 即可獲得最終的路徑。 

到此這篇關(guān)于Android7.0以上Uri轉(zhuǎn)路徑的方法實(shí)現(xiàn)(已驗(yàn)證)的文章就介紹到這了,更多相關(guān)Android7 Uri轉(zhuǎn)路徑內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Kotlin中的擴(kuò)展函數(shù)與屬性示例詳解

    Kotlin中的擴(kuò)展函數(shù)與屬性示例詳解

    理論上來說,擴(kuò)展函數(shù)很簡單,它就是一個類的成員函數(shù),不過定義在類的外面。下面這篇文章主要給大家介紹了關(guān)于Kotlin中擴(kuò)展函數(shù)與屬性的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2018-06-06
  • 完美解決Android Studio集成crashlytics后無法編譯的問題

    完美解決Android Studio集成crashlytics后無法編譯的問題

    下面小編就為大家?guī)硪黄昝澜鉀QAndroid Studio集成crashlytics后無法編譯的問題。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-05-05
  • Android自定義View繪圖實(shí)現(xiàn)拖影動畫

    Android自定義View繪圖實(shí)現(xiàn)拖影動畫

    這篇文章主要介紹了Android自定義View繪圖實(shí)現(xiàn)拖影動畫,,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2016-09-09
  • 基于Android studio3.6的JNI教程之ncnn之語義分割ENet

    基于Android studio3.6的JNI教程之ncnn之語義分割ENet

    這篇文章主要介紹了基于Android studio3.6的JNI教程之ncnn之語義分割ENet的相關(guān)知識,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值 ,需要的朋友可以參考下
    2020-03-03
  • Kotlin Jetpack組件ViewModel使用詳解

    Kotlin Jetpack組件ViewModel使用詳解

    作為Jetpack組件之一的ViewModel,也是框架MVVM中的一部分,其功能主要用于屏幕反轉(zhuǎn)后的數(shù)據(jù)保存;因?yàn)锳ctivity翻轉(zhuǎn)屏幕后或?qū)崿F(xiàn)onCreat()方法,也就是說會重新創(chuàng)建頁面,之前頁面的臨時數(shù)據(jù)都會清除
    2022-12-12
  • Android編程向服務(wù)器發(fā)送請求時出現(xiàn)中文亂碼問題的解決方法

    Android編程向服務(wù)器發(fā)送請求時出現(xiàn)中文亂碼問題的解決方法

    這篇文章主要介紹了Android編程向服務(wù)器發(fā)送請求時出現(xiàn)中文亂碼問題的解決方法,實(shí)例分析了Android參數(shù)傳遞過程中中文亂碼的解決技巧,具有一定參考借鑒價值,需要的朋友可以參考下
    2015-11-11
  • Android實(shí)現(xiàn)探探圖片滑動效果

    Android實(shí)現(xiàn)探探圖片滑動效果

    這篇文章主要為大家詳細(xì)介紹了Android實(shí)現(xiàn)探探圖片滑動效果,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-06-06
  • RxJava 1升級到RxJava 2過程中踩過的一些“坑”

    RxJava 1升級到RxJava 2過程中踩過的一些“坑”

    RxJava2相比RxJava1,它的改動還是很大的,那么下面這篇文章主要給大家總結(jié)了在RxJava 1升級到RxJava 2過程中踩過的一些“坑”,文中介紹的非常詳細(xì),對大家具有一定的參考學(xué)習(xí)價值,需要的朋友們下來要一起看看吧。
    2017-05-05
  • Android使用Kotlin和RxJava 2.×實(shí)現(xiàn)短信驗(yàn)證碼倒計時效果

    Android使用Kotlin和RxJava 2.×實(shí)現(xiàn)短信驗(yàn)證碼倒計時效果

    本篇文章主要介紹了Android使用Kotlin和RxJava 2.×實(shí)現(xiàn)短信驗(yàn)證碼倒計時效果,非常具有實(shí)用價值,需要的朋友可以參考下
    2017-12-12
  • android使用handlerthread創(chuàng)建線程示例

    android使用handlerthread創(chuàng)建線程示例

    這篇文章主要介紹了android使用handlerthread創(chuàng)建線程,講解了這種方式的好處及為什么不使用Thread類的原因
    2014-01-01

最新評論