2017-02-08 2 views
3

의 내부 저장소가 아닌 의 sdcard에있는 파일을 선택하고 서버를 업로드하지만 크기를 가져올 수없는 경로를 가져올 수 없습니다. 사용자가 sdcard에 (이동식)에서 모든 파일을 선택하지 않으면 내가 this answer하고 작업을 사용하고 파일에 경로를 얻기 위해sdcard에서 파일의 URI에서 실제 경로 얻기

intent = new Intent(Intent.ACTION_OPEN_DOCUMENT); 
intent.addCategory(Intent.CATEGORY_OPENABLE); 
intent.setType("*/*"); 
String[] mimetypes = {"application/*"}; 
intent.putExtra(Intent.EXTRA_MIME_TYPES, mimetypes); 
startActivityForResult(
     Intent.createChooser(intent, "Select a File to Upload"), FILE_SELECT_CODE); 

: 코드 아래 사용하여 파일을 선택하기위한 I는 의도를 시작합니다. 내가 유형이 아니라는 코드를 디버깅 및 발견했을 때 이 때문에이 조건 내에서 이동하지 않습니다

그래서 내 질문에 뜻이 다른 사람의 될 것입니다
if("primary".equalsIgnoreCase(type)){ 
    return Environment.getExternalStorageDirectory() + "/" + split[1]; 
} 

? 즉 유형이 기본이 아닌 경우 어떻게 우리가 파일에 대한 경로를 얻을 수 있습니까? 나는 많은 질문과 자습서를 가지고 있는데 그 중 아무 것도 없다. 또한 this answer의 다른 부분을 시도했지만 그는 "EXTERNAL_STORAGE"를 "SECONDARY_STORAGE"와 sdcard에에 대한 System.getenv() 반환 때문에 작동하지 않습니다.

if ("primary".equalsIgnoreCase(type)) { 
    return Environment.getExternalStorageDirectory() + "/" + split[1]; 
}else{ 
    return System.getenv("EXTERNAL_STORAGE") + "/" + split[1]; 
} 

열린 우리당과 파일에 대한 문서 ID가 같은 모양 :

열린 : 내용 : //com.android.externalstorage.documents/document/을 내가하려고 할 때 찾을 수 없습니다 예외 파일을 얻을 0EF9-3110 %의 3Adevice-2016-12-02-130553.png

DOCID : 0EF9-3110 : 장치 2016-12-02-130553.png을

어떤 도움 ??

+0

문제점은 여러 번보고되었습니다. 매주 내가 생각하는 지난 달. 따라서이 사이트를 읽으십시오. 또한 파일 경로가 필요한 이유를 설명해야합니다. 당신은 대부분 당신이 가진 콘텐츠 구성표로 동일하게 할 수 있습니다. – greenapps

+0

@greenapps 이미 링크를 검색하고 링크를 게시했습니다. 내 질문과 관련된 링크가있는 경우 –

+0

'내 질문은 무엇입니까? '. '타입'이란 뜻이야? 그럼 당신은 말할 수 있습니다! – greenapps

답변

3

Android 기기 관리자에 시간을 소비 한 후, 여기있다 : 문서 유형 ID가 차없는

경우, 내가 사용하는 경로를 만들 :

filePath = "/storage/" + type + "/" + split[1]; 

편집 : 경우

public static String getRealPathFromURI_API19(Context context, Uri uri) { 
    String filePath = ""; 

    // 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]; 
     } else { 

      if (Build.VERSION.SDK_INT > 20) { 
        //getExternalMediaDirs() added in API 21 
        File extenal[] = context.getExternalMediaDirs(); 
        if (extenal.length > 1) { 
         filePath = extenal[1].getAbsolutePath(); 
         filePath = filePath.substring(0, filePath.indexOf("Android")) + split[1]; 
        } 
      }else{ 
        filePath = "/storage/" + type + "/" + split[1]; 
      } 
      return filePath; 
     } 

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

     Cursor cursor = null; 
     final String column = "_data"; 
     final String[] projection = {column}; 

     try { 
      cursor = context.getContentResolver().query(uri, projection, null, null, null); 
      if (cursor != null && cursor.moveToFirst()) { 
       final int index = cursor.getColumnIndexOrThrow(column); 
       String result = cursor.getString(index); 
       cursor.close(); 
       return result; 
      } 
     } finally { 
      if (cursor != null) 
       cursor.close(); 
     } 
    } else if (DocumentsContract.isDocumentUri(context, uri)) { 
     // MediaProvider 
     String wholeID = DocumentsContract.getDocumentId(uri); 

     // Split at colon, use second item in the array 
     String[] ids = wholeID.split(":"); 
     String id; 
     String type; 
     if (ids.length > 1) { 
      id = ids[1]; 
      type = ids[0]; 
     } else { 
      id = ids[0]; 
      type = ids[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[]{id}; 
     final String column = "_data"; 
     final String[] projection = {column}; 
     Cursor cursor = context.getContentResolver().query(contentUri, 
      projection, selection, selectionArgs, null); 

     if (cursor != null) { 
      int columnIndex = cursor.getColumnIndex(column); 

      if (cursor.moveToFirst()) { 
       filePath = cursor.getString(columnIndex); 
      } 
      cursor.close(); 
     } 
     return filePath; 
    } else { 
     String[] proj = {MediaStore.Audio.Media.DATA}; 
     Cursor cursor = context.getContentResolver().query(uri, proj, null, null, null); 
     if (cursor != null) { 
      int column_index = cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.DATA); 
      if (cursor.moveToFirst()) 
       filePath = cursor.getString(column_index); 
      cursor.close(); 
     } 


     return filePath; 
    } 
    return null; 
} 
: DocumentUri의 파일 형식 여기

의 기준으로 contentUri을 선택이 완료 기능입니다

+0

"isExternalStorageDocument"및 "isDownloadsDocument"메서드에 대해 어떻게해야합니까? –

+1

여기에서 이러한 기능을 찾을 수 있습니다. https://stackoverflow.com/questions/33295300/how-to-get-absolute-path-in-android-for-file/33298265#33298265 –

-1

응용 프로그램에 FileProvider를 구현하는 것은 매우 쉽습니다.

<?xml version="1.0" encoding="utf-8"?> 
<manifest xmlns:android="http://schemas.android.com/apk/res/android" 
    ... 
    <application 
     ... 
     <provider 
      android:name="android.support.v4.content.FileProvider" 
      android:authorities="${applicationId}.provider" 
      android:exported="false" 
      android:grantUriPermissions="true"> 
      <meta-data 
       android:name="android.support.FILE_PROVIDER_PATHS" 
       android:resource="@xml/provider_paths"/> 
     </provider> 
    </application> 
</manifest> 

의 AndroidManifest.xml을 그리고 고해상도 폴더 아래에 XML 폴더에 provider_paths.xml 파일을 생성 : 먼저 다음과 같은 태그 아래의 AndroidManifest.xml에 FileProvider 태그를 추가해야합니다. 존재하지 않을 경우 폴더를 만들어야 할 수 있습니다.

고해상도/XML/provider_paths.xml는

<?xml version="1.0" encoding="utf-8"?> 
<paths xmlns:android="http://schemas.android.com/apk/res/android"> 
    <external-path name="external_files" path="."/> 
</paths> 

을 완료! FileProvider가 이제 선언되어 사용할 준비가되었습니다.

마지막 단계는 MainActivity.java

Uri photoURI = Uri.fromFile(createImageFile()); 
to 



Uri photoURI = FileProvider.getUriForFile(MainActivity.this, 
      BuildConfig.APPLICATION_ID + ".provider", 
      createImageFile()); 

그리고 .... 일에 아래 코드의 라인을 변경하는 것입니다! Android Nougat을 포함한 모든 Android 버전에서 애플리케이션이 완벽하게 작동해야합니다. 예!

+0

과 같은 유형일 수 있습니다. 왜 내 AndroidManifest에이 FileProvider를 추가해야합니까 ?? –

+1

이 답변에주의하십시오. 여기서 말도 안돼. 파일 제공자를 잘 사용하는 방법을 가르치는 것과 마찬가지로 대답은 다른 게시물에 속한다고 생각합니다. – greenapps

+0

누가 잘못 했나요? nougat에 대해 – g7pro

3

업로드 코드를 변경하십시오.어딘가에 당신은

InputStream is = getContentResolver().openInputStream(uri); 

그래서 직접 URI를 사용

FileInputStream fis = new FileInputStream(path); 

변경

해야합니다. 파일 경로가 필요 없습니다. 나는 해결책을 발견