【问题标题】:Implementing a File Picker in Android and copying the selected file to another location在 Android 中实现文件选择器并将所选文件复制到另一个位置
【发布时间】:2015-06-11 18:53:17
【问题描述】:

我正在尝试在我的 Android 项目中实现文件选择器。到目前为止我能做的是:

Intent chooseFile;
Intent intent;
chooseFile = new Intent(Intent.ACTION_GET_CONTENT);
chooseFile.setType("*/*");
intent = Intent.createChooser(chooseFile, "Choose a file");
startActivityForResult(intent, PICKFILE_RESULT_CODE);

然后在我的onActivityResult()

switch(requestCode){
 case PICKFILE_RESULT_CODE:
   if(resultCode==-1){
      Uri uri = data.getData();
      String filePath = uri.getPath();
      Toast.makeText(getActivity(), filePath,
                        Toast.LENGTH_LONG).show();
    }
 break;
}

这是打开一个文件选择器,但它不是我想要的。例如,我想选择一个文件(.txt),然后得到那个File 然后使用它。有了这段代码,我想我会得到完整路径,但它没有发生;例如我得到:/document/5318/。但是使用此路径我无法获取文件。我创建了一个名为 PathToFile() 的方法,它返回一个 File

 private File PathToFile(String path) {
    File tempFileToUpload;
    tempFileToUpload = new File(path);
    return tempFileToUpload;
}

我想做的是让用户从任何地方选择一个File,这意味着DropBoxDriveSDCardMega,等等......我找不到路为了正确地做到这一点,我尝试获取Path 然后通过Path 获取File... 但它不起作用,所以我认为最好获取File 本身,然后使用这个File 以编程方式我Copy 这个或Delete

编辑(当前代码)

我的Intent

 Intent chooseFile = new Intent(Intent.ACTION_GET_CONTENT);
 chooseFile.addCategory(Intent.CATEGORY_OPENABLE);
 chooseFile.setType("text/plain");
 startActivityForResult(
      Intent.createChooser(chooseFile, "Choose a file"),
      PICKFILE_RESULT_CODE
 );

我有一个问题,因为我不知道text/plain 支持什么,但我会对此进行调查,但目前无所谓。

在我的onActivityResult() 上,我使用了与@Lukas Knuth answer 相同的功能,但我不知道是否可以通过它将Copy 这个File 从我的SDcard 转移到另一部分我正在等待他的回答。

@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    if (requestCode == PICKFILE_RESULT_CODE && resultCode == Activity.RESULT_OK){
        Uri content_describer = data.getData();
        //get the path 
        Log.d("Path???", content_describer.getPath());
        BufferedReader reader = null;
        try {
            // open the user-picked file for reading:
            InputStream in = getActivity().getContentResolver().openInputStream(content_describer);
            // now read the content:
            reader = new BufferedReader(new InputStreamReader(in));
            String line;
            StringBuilder builder = new StringBuilder();

            while ((line = reader.readLine()) != null){
                builder.append(line);
            }
            // Do something with the content in
            text.setText(builder.toString());



        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (reader != null) {
                try {
                    reader.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

getPath() 来自@Y.S.

我正在这样做:

    String[] projection = { MediaStore.Files.FileColumns.DATA };
            Cursor cursor = getActivity().getContentResolver().query(content_describer, projection, null, null, null);
int column_index = cursor.getColumnIndexOrThrow(projection[0]);
cursor.moveToFirst();
cursor.close();
Log.d( "PATH-->",cursor.getString(column_index));

收到NullPointerException

java.lang.RuntimeException: 传递结果 ResultInfo{who=null, request=131073, result=-1, data=Intent { dat=file:///path typ=text/plain flg=0x3 }} 失败活动 {info.androidhive.tabsswipe/info.androidhive.tabsswipe.MainActivity2}:java.lang.NullPointerException

借助@Y.S.@Lukas Knuth@CommonsWare 编辑代码。

这是Intent,我只接受文件text/plain

Intent chooseFile = new Intent(Intent.ACTION_GET_CONTENT);
chooseFile.addCategory(Intent.CATEGORY_OPENABLE);
chooseFile.setType("text/plain");
startActivityForResult(
    Intent.createChooser(chooseFile, "Choose a file"),
    PICKFILE_RESULT_CODE
);

在我的onActivityResult() 上,我创建了一个URI,在其中获取Intent 的数据,我创建了一个File,在其中保存绝对路径 执行content_describer.getPath();,并且然后我将路径的名称保留在TextViewcontent_describer.getLastPathSegment(); 中使用它(这太棒了@YS 不知道该功能),然后我创建了第二个File,我称之为destination 和我发送AbsolutePath 可以创建这个File

@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    if (requestCode == PICKFILE_RESULT_CODE && resultCode == Activity.RESULT_OK){
        Uri content_describer = data.getData();
        String src = content_describer.getPath();
        source = new File(src);
        Log.d("src is ", source.toString());
        String filename = content_describer.getLastPathSegment();
        text.setText(filename);
        Log.d("FileName is ",filename);
        destination = new File(Environment.getExternalStorageDirectory().getAbsolutePath() + "/Test/TestTest/" + filename);
        Log.d("Destination is ", destination.toString());
        SetToFolder.setEnabled(true);
    }
}

我还创建了一个函数,您必须发送我们之前创建的 source filedestination file 才能将其复制到新文件夹。

private void copy(File source, File destination) throws IOException {

    FileChannel in = new FileInputStream(source).getChannel();
    FileChannel out = new FileOutputStream(destination).getChannel();

    try {
        in.transferTo(0, in.size(), out);
    } catch(Exception e){
        Log.d("Exception", e.toString());
    } finally {
        if (in != null)
            in.close();
        if (out != null)
            out.close();
    }
}

我还创建了一个函数,告诉我这个文件夹是否存在(我必须发送destination file,如果它不存在我创建这个文件夹,如果它不存在我什么也不做.

private void DirectoryExist (File destination) {

    if(!destination.isDirectory()) {
        if(destination.mkdirs()){
            Log.d("Carpeta creada","....");
        }else{
            Log.d("Carpeta no creada","....");
        }
    }

再次感谢您的帮助,希望您喜欢与大家一起制作的这段代码 :)

【问题讨论】:

    标签: android android-intent android-file android-fileprovider android-implicit-intent


    【解决方案1】:

    第 1 步 - 使用隐式 Intent

    要从设备中选择文件,您应该使用隐式Intent

    Intent chooseFile = new Intent(Intent.ACTION_GET_CONTENT);
    chooseFile.setType("*/*");
    chooseFile = Intent.createChooser(chooseFile, "Choose a file");
    startActivityForResult(chooseFile, PICKFILE_RESULT_CODE);
    

    第 2 步 - 获取绝对文件路径:

    要从Uri 获取文件路径,首先尝试使用

    Uri uri = data.getData();
    String src = uri.getPath();
    

    其中data 是在onActivityResult() 中返回的Intent

    如果不行,请使用以下方法:

    public String getPath(Uri uri) {
    
        String path = null;
        String[] projection = { MediaStore.Files.FileColumns.DATA };
        Cursor cursor = getContentResolver().query(uri, projection, null, null, null);
    
        if(cursor == null){
            path = uri.getPath()
        }
        else{
            cursor.moveToFirst();
            int column_index = cursor.getColumnIndexOrThrow(projection[0]);
            path = cursor.getString(column_index);
            cursor.close();
        }
    
        return ((path == null || path.isEmpty()) ? (uri.getPath()) : path);
    }
    

    这两种方法中的至少一种应该可以为您提供正确的完整路径。

    第 3 步 - 复​​制文件:

    我相信你想要的是将文件从一个位置复制到另一个位置。

    为此,必须拥有源位置和目标位置的绝对文件路径

    首先,使用我的getPath()方法或uri.getPath()获取绝对文件路径:

    String src = getPath(uri);    /* Method defined above. */
    

    Uri uri = data.getData();
    String src = uri.getPath();
    

    然后,如下创建两个File对象:

    File source = new File(src);
    String filename = uri.getLastPathSegment();
    File destination = new File(Environment.getExternalStorageDirectory().getAbsolutePath() + "/CustomFolder/" + filename);
    

    其中CustomFolder 是您要将文件复制到的外部驱动器上的目录。

    然后使用以下方法将文件从一个地方复制到另一个地方:

    private void copy(File source, File destination) {
    
       FileChannel in = new FileInputStream(source).getChannel();
       FileChannel out = new FileOutputStream(destination).getChannel();
    
       try {
          in.transferTo(0, in.size(), out);
       } catch(Exception){
          // post to log
       } finally {
          if (in != null)
             in.close();
          if (out != null)
             out.close();
       }
    }
    

    试试这个。这应该可以。

    注意: Vis-a-vis Lukas 的回答 - 他所做的是使用一种名为 openInputStream() 的方法,该方法返回 Uri内容Uri 代表文件还是 URL。

    另一种有前途的方法 - FileProvider

    还有另一种方法可以从另一个应用程序获取文件。如果一个应用通过FileProvider 共享它的文件,那么就有可能获得一个FileDescriptor 对象,该对象包含该文件的特定信息。

    为此,请使用以下Intent

    Intent mRequestFileIntent = new Intent(Intent.ACTION_GET_CONTENT);
    mRequestFileIntent.setType("*/*");
    startActivityForResult(mRequestFileIntent, 0);
    

    在你的onActivityResult():

    @Override
    public void onActivityResult(int requestCode, int resultCode,
            Intent returnIntent) {
        // If the selection didn't work
        if (resultCode != RESULT_OK) {
            // Exit without doing anything else
            return;
        } else {
            // Get the file's content URI from the incoming Intent
            Uri returnUri = returnIntent.getData();
            /*
             * Try to open the file for "read" access using the
             * returned URI. If the file isn't found, write to the
             * error log and return.
             */
            try {
                /*
                 * Get the content resolver instance for this context, and use it
                 * to get a ParcelFileDescriptor for the file.
                 */
                mInputPFD = getContentResolver().openFileDescriptor(returnUri, "r");
            } catch (FileNotFoundException e) {
                e.printStackTrace();
                Log.e("MainActivity", "File not found.");
                return;
            }
            // Get a regular file descriptor for the file
            FileDescriptor fd = mInputPFD.getFileDescriptor();
            ...
        }
    }
    

    其中mInputPFDParcelFileDescriptor

    参考资料:

    1. Common Intents - File Storage.

    2. FileChannel.

    3. FileProvider.

    4. Requesting a Shared File.

    【讨论】:

    • 评论不用于扩展讨论;这个对话是moved to chat
    • @tohidmahmoudvand:它对我和其他人都有效;请创建一个新问题并提供详细信息,说明究竟是什么不起作用。
    • @Y.S.你能帮忙解决这个question吗?
    【解决方案2】:

    正如@CommonsWare 已经指出的,Android 会返回一个Uri,这是一个比文件路径更抽象的概念。

    它也可以描述一个简单的文件路径,但它也可以描述一个通过应用程序访问的资源(例如content://media/external/audio/media/710)。

    如果您希望您的用户从手机中选择任何文件以从您的应用程序中读取它,您可以通过询问该文件(如您所做的正确)然后使用ContentResolver 来获取InputStream对于选择器返回的Uri

    这是一个例子:

    Intent chooseFile = new Intent(Intent.ACTION_GET_CONTENT);
    // Ask specifically for something that can be opened:
    chooseFile.addCategory(Intent.CATEGORY_OPENABLE);
    chooseFile.setType("*/*");
    startActivityForResult(
            Intent.createChooser(chooseFile, "Choose a file"),
            PICKFILE_REQUEST_CODE
    );
    
    // And then somewhere, in your activity:
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (requestCode == PICKFILE_REQUEST_CODE && resultCode == RESULT_OK){
            Uri content_describer = data.getData();
            BufferedReader reader = null;
            try {
                // open the user-picked file for reading:
                InputStream in = getContentResolver().openInputStream(content_describer);
                // now read the content:
                reader = new BufferedReader(new InputStreamReader(in));
                String line;
                StringBuilder builder = new StringBuilder();
                while ((line = reader.readLine()) != null){
                    builder.append(line);
                }
                // Do something with the content in
                some_view.setText(builder.toString());
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                if (reader != null) {
                    try {
                        reader.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    }
    

    重要提示:一些提供商(如 Dropbox)将其数据存储/缓存在外部存储中。您需要在清单中声明android.permission.READ_EXTERNAL_STORAGE-permission,否则您将获得FileNotFoundException,即使文件在那里。


    更新:是的,您可以通过从一个流中读取文件并将其写入另一个流来复制文件:

    // Error handling is omitted for shorter code!
    Uri content_describer = data.getData();
    InputStream in = null;
    OutputStream out = null;
    try {
        // open the user-picked file for reading:
        in = getContentResolver().openInputStream(content_describer);
        // open the output-file:
        out = new FileOutputStream(new File("some/path/to/a/writable/file"));
        // copy the content:
        byte[] buffer = new byte[1024];
        int len;
        while ((len = in.read(buffer)) != -1) {
            out.write(buffer, 0, len);
        }
        // Contents are copied!
    } finally {
        if (in != null) {
            in.close();
        }
        if (out != null){
            out.close();
        }
    }
    

    删除该文件可能是不可能的,因为该文件不属于您,它属于与您共享它的应用程序。因此,拥有的应用程序负责删除该文件。

    【讨论】:

    • 谢谢,但是我可以使用这个文件吗?意味着我可以复制到另一个文件夹,或者只是删除它等?我可以用这个文件做点什么吗?
    • 我用复制代码和一些关于删除文件的解释更新了我的答案。如果这还不够,请准确告诉我您要归档的内容。
    • 我尝试了您的代码,但我必须使用您的第一个代码将其写入字符串,然后使用新的代码来编写它还是什么?你知道为什么我要在我的 SD 卡上创建一个新文件,但它在我的电脑上不可见吗?意味着我可以浏览它我只能在我的设备上使用我的 FileExplorer 时才能做到这一点
    • 如何确定远程图像的文件类型或扩展名 ex.如果图像是从谷歌驱动器中提取的
    • @RaghavSatyadev 有 ContentResolver.getType(Uri) 方法,它为您提供了 content-uri 的 MIME 类型。
    【解决方案3】:

    我做了同样的事情让用户从一个文件夹中选择一个图像:

    1)有一个按钮OPEN:

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
        case R.id.btn_open:
            myOpenImagePicker();
            break;
        }
    }
    

    2)打开图片文件夹功能:

    @SuppressLint("InlinedApi")
    public void myOpenImagePicker() {
    
        if (Build.VERSION.SDK_INT < 19) {
            Intent intent = new Intent();
            intent.setType("image/*");
            intent.setAction(Intent.ACTION_GET_CONTENT);
            startActivityForResult(
                    Intent.createChooser(intent, "Select Picture"),
                    SELECT_FOLDER);
    
        } else {
            Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
            intent.addCategory(Intent.CATEGORY_OPENABLE);
            intent.setType("image/*");
            startActivityForResult(intent, SELECT_FOLDER);
        }
    }
    

    3) 我获取图像文件路径并使用图像路径做任何我想做的事情的活动结果:

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        switch (requestCode) {
        case SELECT_FOLDER:
            if (resultCode == RESULT_OK && data != null) {
    
                Uri originalUri = data.getData();
                String id01 = W_ImgFilePathUtil.getPath(
                        getApplicationContext(), originalUri);
                Bitmap unscaledBitmap = W_ImgScalingUtil.decodeResource(id01,
                        xdrawing.getViewWidth(), xdrawing.getViewHeight(),
                        ScalingLogic.FIT);
                if (unscaledBitmap == null) {
                    zprefsutil.ShowToast("IMAGE ERROR", 1);
                } else {
                    setExternalScaledBitmap(W_ImgScalingUtil
                            .createScaledBitmap(unscaledBitmap,
                                    xdrawing.getViewWidth(),
                                    xdrawing.getViewHeight(), ScalingLogic.FIT));
                    unscaledBitmap.recycle();
                    xdrawing.invalidate();
                }
    
            }
            break;
        default:
            break;
        }
    }
    

    4) 现在是最重要的部分,W_ImgFilePathUtil 类,代码不是来自我,但它允许您检索任何选定文件的完整路径,无论是在 sd 卡、谷歌驱动器... :

    public class W_ImgFilePathUtil {
    
        /**
         * Method for return file path of Gallery image
         * 
         * @param context
         * @param uri
         * @return path of the selected image file from gallery
         */
        @SuppressLint("NewApi")
        public static String getPath(final Context context, final Uri uri) {
    
            // check here to KITKAT or new version
            final boolean isKitKatorUp = Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT;
    
            // DocumentProvider
            if (isKitKatorUp && 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());
        }
    }
    

    结论:代码适用于图像路径,但确实适用于任何类型的文件。

    希望这有助于解决您的问题。

    和平。

    【讨论】:

      【解决方案4】:

      A Uri is not a fileUri 更接近 Web 服务器 URL。它是一个不透明的地址,只对“服务器”(或者在本例中为ContentProvider)有意义。

      正如您使用InputStream 读取由Web URL 表示的字节一样,您使用InputStream 读取由Uri 表示的字节。您可以通过在 ContentResolver 上调用 openInputStream() 来获得这样的流。

      【讨论】:

      • 我也使用了String FilePath = data.getData().getPath();,但没有给我正确的路径......我在哪里可以找到一个例子你想向我解释什么?你明白我要做什么了吗?
      【解决方案5】:

      ActivityResultLauncher 的工作方式类似:

      ActivityResultLauncher<Intent> startActivityForResult = requireActivity().registerForActivityResult(new ActivityResultContracts.StartActivityForResult(), result -> {
          if (result.getResultCode() == Activity.RESULT_OK) {
              Intent data = result.getData();
              Uri contentUri = data.getData();
              ...
          }
      });
      

      使用示例:

      Intent data = new Intent(Intent.ACTION_GET_CONTENT);
      data.addCategory(Intent.CATEGORY_OPENABLE);
      data.setType("*/*");
      Intent intent = Intent.createChooser(data, "Choose a file");
      startActivityForResult.launch(intent);
      

      需要以下依赖项(有或没有-ktx):

      implementation "androidx.activity:activity:1.2.3"
      

      【讨论】:

        【解决方案6】:

        以下是如何实现文件选择器并将所选文件移动到另一个位置(例如图片)。

        首先,在您的代码中添加一个带有点击侦听器按钮的文件选择器,如下所示:

        选择文件的按钮:

        @Override
        public void onClick(View v) {
            switch (v.getId()) {
            case R.id.btn_choose_file:
                showFileChooser();
                break;
            }
        }
        
        private String filePath = null;
        private File sourceFile;
        
        private static final int FILE_SELECT_CODE = 0;
        
            private void showFileChooser() {
                Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
                intent.setType("*/*");
                intent.addCategory(Intent.CATEGORY_OPENABLE);
        
                try {
                    startActivityForResult(
                            Intent.createChooser(intent, "Select a File to Copy"),
                            FILE_SELECT_CODE);
                } catch (android.content.ActivityNotFoundException ex) {
                    Toast.makeText(this, "Please install a File Manager.",
                            Toast.LENGTH_SHORT).show();
                }
            }
        

        然后像这样处理onActivityResult:

            @Override
            protected void onActivityResult(int requestCode, int resultCode, Intent data) {
                switch (requestCode) {
                    case FILE_SELECT_CODE:
                        if (resultCode == RESULT_OK) {
                            // Get the Uri of the selected file
                            Uri uri = data.getData();
        
                            File   file = new File(getCacheDir(), getFileName(uri));
        
                            int maxBufferSize = 1 * 1024 * 1024;
        
                            try {
                                InputStream inputStream = getContentResolver().openInputStream(uri);
                                Log.e("InputStream Size","Size " + inputStream);
                                int  bytesAvailable = inputStream.available();
                                int bufferSize = Math.min(bytesAvailable, maxBufferSize);
                                final byte[] buffers = new byte[bufferSize];
        
                                FileOutputStream outputStream = new FileOutputStream(file);
                                int read = 0;
                                while ((read = inputStream.read(buffers)) != -1) {
                                    outputStream.write(buffers, 0, read);
                                }
                                Log.e("File Size","Size " + file.length());
                                inputStream.close();
                                outputStream.close();
        
                                file.getPath();
                                Log.e("File Path","Path " + file.getPath());
                                file.length();
                                Log.e("File Size","Size " + file.length());
        
                                if(file.length() > 0){
        
                                    sourceFile = file;
                                   saveFile(sourceFile);
                                }
        
        
                            } catch (FileNotFoundException e) {
                                e.printStackTrace();
                            } catch (IOException e) {
                                e.printStackTrace();
                            } catch (OutOfMemoryError e) {
                                e.printStackTrace();
                            }
        
        
        
                        } else {
        
        
                        }
        
                        break;
                }
                super.onActivityResult(requestCode, resultCode, data);
            }
        
        
        
        
        
            private void saveFile (File sourceFile) {
        
        
                        try {
        
                        File currentFile = sourceFile;
        
                        Bitmap myBitmap = BitmapFactory.decodeFile(currentFile.getAbsolutePath());
        
        
                        String path = currentFile.getAbsolutePath();
                        String idStr = path.substring(path.lastIndexOf('/') + 1);
                        File filepath = Environment.getExternalStorageDirectory();
                        File dir = new File(filepath.getAbsolutePath() + "/" + "yourFolderName" + "/");
                        if (!dir.exists()) {
                            dir.mkdirs();
                        }
                        String fileName = currentFile.getName();
                        file = new File(dir, fileName);
                        if (file.exists()) file.delete();
                        FileOutputStream fos = new FileOutputStream(file);
                        myBitmap.compress(CompressFormat.JPEG, 65, fos);
                        fos.flush();
                        fos.close();
        
        
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
        
            }
        

        注意:不要忘记将此权限添加到清单文件中。

            <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
            <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
        

        希望这会有所帮助。

        【讨论】:

          【解决方案7】:

          在该方法中传递onActivityResult中返回的URI

          private String getPath(Uri contentURI) {
          
              String result;
              Cursor cursor = getActivity().getContentResolver().query(contentURI,
                      null, null, null, null);
          
              if (cursor == null) {
                  result = contentURI.getPath();
              } else {
                  cursor.moveToFirst();
                  int idx = cursor
                          .getColumnIndex(MediaStore.Images.ImageColumns.DATA);
                  result = cursor.getString(idx);
                  cursor.close();
              }
              return result;
          }
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2021-07-30
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多