2016-09-05 8 views
0

ファイルをPHPサーバーにアップロードするためのプログラムを作成します。私はAndroidのアイスクリームサンドイッチの上にそれを実行したときにそれが仕事だandroid marshmallowのファイルを選択できません

public class FilePath { 

    /** 
    * Method for return file path of Gallery image/ Document/Video/Audio 
    * 
    * @param context 
    * @param uri 
    * @return path of the selected image file from gallery 
    */ 
    @TargetApi(Build.VERSION_CODES.KITKAT) 
    public static String getPath(final Context context, final Uri uri) { 

     // check here to KITKAT or new version 
     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 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"), 
         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 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 the remote address 
      if (isGooglePhotosUri(uri)) 
       return uri.getLastPathSegment(); 

      return getDataColumn(context, uri, null, null); 
     } 
     // File 
     else if ("file".equalsIgnoreCase(uri.getScheme())) { 
      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 index = cursor.getColumnIndexOrThrow(column); 
       return cursor.getString(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()); 
    } 

    /** 
    * @param uri 
    *   The Uri to check. 
    * @return Whether the Uri authority is Google Photos. 
    */ 
    public static boolean isGooglePhotosUri(Uri uri) { 
     return "com.google.android.apps.photos.content".equals(uri 
       .getAuthority()); 
    } 
} 

public class MainActivity extends AppCompatActivity implements View.OnClickListener{ 

    private static final int PICK_FILE_REQUEST = 1; 
    private static final String TAG = MainActivity.class.getSimpleName(); 
    private String selectedFilePath; 
    private String SERVER_URL = "http://192.168.0.29/aji/AndroidFileUpload/UploadToServer.php"; 
    ImageView ivAttachment; 
    Button bUpload; 
    TextView tvFileName; 
    ProgressDialog dialog; 


    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_main); 
     ivAttachment = (ImageView) findViewById(R.id.ivAttachment); 
     bUpload = (Button) findViewById(R.id.b_upload); 
     tvFileName = (TextView) findViewById(R.id.tv_file_name); 
     ivAttachment.setOnClickListener(this); 
     bUpload.setOnClickListener(this); 
    } 

    @Override 
    public void onClick(View v) { 
     if(v== ivAttachment){ 

      //on attachment icon click 
      showFileChooser(); 
     } 
     if(v== bUpload){ 

      //on upload button Click 
      if(selectedFilePath != null){ 
       dialog = ProgressDialog.show(MainActivity.this,"","Uploading File...",true); 

       new Thread(new Runnable() { 
        @Override 
        public void run() { 
         //creating new thread to handle Http Operations 
         uploadFile(selectedFilePath); 
        } 
       }).start(); 
      }else{ 
       Toast.makeText(MainActivity.this,"Please choose a File First",Toast.LENGTH_SHORT).show(); 
      } 

     } 
    } 

    private void showFileChooser() { 
     Intent intent = new Intent(); 
     //sets the select file to all types of files 
     intent.setType("file/*"); 
     //allows to select data and return it 
     intent.setAction(Intent.ACTION_GET_CONTENT); 
     //starts new activity to select file and return data 
     startActivityForResult(Intent.createChooser(intent,"Choose File to Upload.."),PICK_FILE_REQUEST); 
    } 

    @Override 
    protected void onActivityResult(int requestCode, int resultCode, Intent data) { 
     super.onActivityResult(requestCode, resultCode, data); 
     if(resultCode == Activity.RESULT_OK){ 
      if(requestCode == PICK_FILE_REQUEST){ 
       if(data == null){ 
        //no data present 
        return; 
       } 


       Uri selectedFileUri = data.getData(); 
       selectedFilePath = FilePath.getPath(this,selectedFileUri); 
       Log.i(TAG,"Selected File Path:" + selectedFilePath); 

       if(selectedFilePath != null && !selectedFilePath.equals("")){ 
        tvFileName.setText(selectedFilePath); 
       }else{ 
        Toast.makeText(this,"Cannot upload file to server",Toast.LENGTH_SHORT).show(); 
       } 
      } 
     } 
    } 

    //android upload file to server 
    public int uploadFile(final String selectedFilePath){ 

     int serverResponseCode = 0; 

     HttpURLConnection connection; 
     DataOutputStream dataOutputStream; 
     String lineEnd = "\r\n"; 
     String twoHyphens = "--"; 
     String boundary = "*****"; 


     int bytesRead,bytesAvailable,bufferSize; 
     byte[] buffer; 
     int maxBufferSize = 1 * 1024 * 1024; 
     File selectedFile = new File(selectedFilePath); 


     String[] parts = selectedFilePath.split("/"); 
     final String fileName = parts[parts.length-1]; 

     if (!selectedFile.isFile()){ 
      dialog.dismiss(); 

      runOnUiThread(new Runnable() { 
       @Override 
       public void run() { 
        tvFileName.setText("Source File Doesn't Exist: " + selectedFilePath); 
       } 
      }); 
      return 0; 
     }else{ 
      try{ 
       FileInputStream fileInputStream = new FileInputStream(selectedFile); 
       URL url = new URL(SERVER_URL); 
       connection = (HttpURLConnection) url.openConnection(); 
       connection.setDoInput(true);//Allow Inputs 
       connection.setDoOutput(true);//Allow Outputs 
       connection.setUseCaches(false);//Don't use a cached Copy 
       connection.setRequestMethod("POST"); 
       connection.setRequestProperty("Connection", "Keep-Alive"); 
       connection.setRequestProperty("ENCTYPE", "multipart/form-data"); 
       connection.setRequestProperty("Content-Type", "multipart/form-data;boundary=" + boundary); 
       connection.setRequestProperty("uploaded_file",selectedFilePath); 

       //creating new dataoutputstream 
       dataOutputStream = new DataOutputStream(connection.getOutputStream()); 

       //writing bytes to data outputstream 
       dataOutputStream.writeBytes(twoHyphens + boundary + lineEnd); 
       dataOutputStream.writeBytes("Content-Disposition: form-data; name=\"uploaded_file\";filename=\"" 
         + selectedFilePath + "\"" + lineEnd); 

       dataOutputStream.writeBytes(lineEnd); 

       //returns no. of bytes present in fileInputStream 
       bytesAvailable = fileInputStream.available(); 
       //selecting the buffer size as minimum of available bytes or 1 MB 
       bufferSize = Math.min(bytesAvailable,maxBufferSize); 
       //setting the buffer as byte array of size of bufferSize 
       buffer = new byte[bufferSize]; 

       //reads bytes from FileInputStream(from 0th index of buffer to buffersize) 
       bytesRead = fileInputStream.read(buffer,0,bufferSize); 

       //loop repeats till bytesRead = -1, i.e., no bytes are left to read 
       while (bytesRead > 0){ 
        //write the bytes read from inputstream 
        dataOutputStream.write(buffer,0,bufferSize); 
        bytesAvailable = fileInputStream.available(); 
        bufferSize = Math.min(bytesAvailable,maxBufferSize); 
        bytesRead = fileInputStream.read(buffer,0,bufferSize); 
       } 

       dataOutputStream.writeBytes(lineEnd); 
       dataOutputStream.writeBytes(twoHyphens + boundary + twoHyphens + lineEnd); 

       serverResponseCode = connection.getResponseCode(); 
       String serverResponseMessage = connection.getResponseMessage(); 

       Log.i(TAG, "Server Response is: " + serverResponseMessage + ": " + serverResponseCode); 

       //response code of 200 indicates the server status OK 
       if(serverResponseCode == 200){ 
        runOnUiThread(new Runnable() { 
         @Override 
         public void run() { 
          tvFileName.setText("File Upload completed.\n\n You can see the uploaded file here: \n\n" + "http://coderefer.com/extras/uploads/"+ fileName); 
         } 
        }); 
       } 

       //closing the input and output streams 
       fileInputStream.close(); 
       dataOutputStream.flush(); 
       dataOutputStream.close(); 



      } catch (FileNotFoundException e) { 
       e.printStackTrace(); 
       runOnUiThread(new Runnable() { 
        @Override 
        public void run() { 
         Toast.makeText(MainActivity.this,"File Not Found",Toast.LENGTH_SHORT).show(); 
        } 
       }); 
      } catch (MalformedURLException e) { 
       e.printStackTrace(); 
       Toast.makeText(MainActivity.this, "URL error!", Toast.LENGTH_SHORT).show(); 

      } catch (IOException e) { 
       e.printStackTrace(); 
       Toast.makeText(MainActivity.this, "Cannot Read/Write File!", Toast.LENGTH_SHORT).show(); 
      } 
      dialog.dismiss(); 
      return serverResponseCode; 
     } 

    } 
} 

そして、ファイルパスのために: それは次のようになります。 しかし、Android marshmallowで実行すると、ファイルをクリックできません。

それは次のようになります:

Cannot be clicked

+0

はuがすでに許可を有効にする必要がありあなたのアプリのために?時々、Android M OSを使用するデバイスで手動で有効にする必要があります – faruk

+1

@AlZillはい、私はそれを有効にしました。しかし、それは動作しません。 –

+0

'getPath'メソッド**はすべてのファイル**に対して決して機能しないことに注意してください。 **すべての** URIに対応する[ContentResolver.openInputStream()](https://developer.android.com/reference/android/content/ContentResolver.html#openInputStream(android.net.Uri))を使用する必要がありますあなたは受け取る。その方法全体をスキップするだけです。 – ianhanniballake

答えて

7

file/*は有効なMIMEタイプではありません。任意の種類のファイルをサポートする場合は、*/*を使用する必要があります。表示されるファイルは、正しいMIMEタイプではないため選択できません。 virtual files in Android 7.0(バイトストリームを持っていないので、直接アップロードすることができないファイル)の導入により

、あなたは最も確実ご意向にCATEGORY_OPENABLEを追加する必要があります

private void showFileChooser() { 
    Intent intent = new Intent(Intent.ACTION_GET_CONTENT); 
    //sets the select file to all types of files 
    intent.setType("*/*"); 
    // Only get openable files 
    intent.addCategory(Intent.CATEGORY_OPENABLE); 
    //starts new activity to select file and return data 
    startActivityForResult(Intent.createChooser(intent, 
     "Choose File to Upload.."),PICK_FILE_REQUEST); 
} 
+0

あなたの答えをありがとう。 –

+0

このカテゴリは 'ACTION_PICK'でも必要でしょうか? –

+0

@GrzegorzAdamHankiewicz - [ACTION_PICKのドキュメント](https://developer.android.com/reference/android/content/Intent.html#ACTION_PICK)によれば、 'ACTION_PICK'を' vnd.android.cursor 'とだけ使うべきです。 dir/* 'スタイルのMIMEタイプ([連絡先](https://developer.android.com/guide/components/intents-common.html#Contacts)など)を選択し、ファイルを選択しません。したがって 'open_putStream'を呼び出すことができる行だけを返すように' ACTION_PICK'をフィルタリングすることはあまり意味がありません。 – ianhanniballake

関連する問題