在外部存储中保存文件时权限被拒绝

时间:2014-11-23 15:15:08

标签: java android android-external-storage

我的目标是将图像文件从内部存储(data / data / myproject / ...)复制到外部存储(图库)。我只列出一个代码示例:

public class MainActivity extends ActionBarActivity {
    private static final int REQUEST_CODE = 1;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();
        if (id == R.id.action_settings) {
            return true;
        }
        return super.onOptionsItemSelected(item);
    }


    public void openActivity(View view){
        Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
        intent.setType("image/jpeg");
        startActivityForResult(Intent.createChooser(intent,"Select iamge"), REQUEST_CODE);
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        if (requestCode == REQUEST_CODE && resultCode == Activity.RESULT_OK){
            String image_path = getRealPathFromUri(this, data.getData());
            File externalInput = new File(image_path);
            File internalCopy = new File(getFilesDir(), temp_image.replace(".jpg", ".OUT.jpg"));
            File externalCopy = new File(image_path.replace(".jpg", ".OUT.jpg"));

            try {
                copyFile(new FileInputStream(externalInput),new FileOutputStream(internalCopy));
                System.out.println("Copied into internal Storage OK");
            } catch (FileNotFoundException e) {
                // TODO Auto-generated catch block
                System.out.println("NOT Copied into internal Storage ERR");
                e.printStackTrace();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }


            /* here some image manipulation are performed */



            if(!externalCopy.getParentFile().exists()){
                externalCopy.getParentFile().mkdirs();
                System.out.println("Created directories ...");
            }else{
                System.out.println("Directories already OK");
            }

            try {
                copyFile(new FileInputStream(internalCopy),new FileOutputStream(externalCopy));
                System.out.println("Copied into external Storage OK");
            } catch (FileNotFoundException e) {
                // TODO Auto-generated catch block
                System.out.println("NOT Copied into external Storage ERR");
                e.printStackTrace();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
                System.out.println("NOT Copied into external Storage ERR");
            }
        }

        super.onActivityResult(requestCode, resultCode, data);
    }

    public void quitActivity(View view){
        android.os.Process.killProcess(android.os.Process.myPid());
        System.exit(1);     
    }

     public static String getRealPathFromUri(Context context, Uri contentUri) {
            Cursor cursor = null;
            try {
                String[] proj = { MediaStore.Images.Media.DATA };
                cursor = context.getContentResolver().query(contentUri, proj, null, null, null);
                int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
                cursor.moveToFirst();
                return cursor.getString(column_index);
            } finally {
                if (cursor != null) {
                    cursor.close();
                }
            }
     }

     public void copyFile(InputStream in, OutputStream out) throws IOException {
         byte[] buffer = new byte[1024];
         int read;
         while((read = in.read(buffer)) != -1){
           out.write(buffer, 0, read);
         }
     }

}

这样就不会复制复制文件以拒绝被许可人!如果我尝试使用externalCopy.getParentFile()。canWrite(),结果为false。

请查看以下LogCat输出:

12-01 22:02:02.271: D/ActivityThread(22255): setTargetHeapUtilization:0.25
12-01 22:02:02.271: D/ActivityThread(22255): setTargetHeapIdealFree:8388608
12-01 22:02:02.271: D/ActivityThread(22255): setTargetHeapConcurrentStart:2097152
12-01 22:02:02.601: I/dalvikvm(22255): Could not find method android.view.ViewGroup.onNestedScrollAccepted, referenced from method android.support.v7.internal.widget.ActionBarOverlayLayout.onNestedScrollAccepted
12-01 22:02:02.601: W/dalvikvm(22255): VFY: unable to resolve virtual method 11385: Landroid/view/ViewGroup;.onNestedScrollAccepted (Landroid/view/View;Landroid/view/View;I)V
12-01 22:02:02.601: D/dalvikvm(22255): VFY: replacing opcode 0x6f at 0x0000
12-01 22:02:02.601: I/dalvikvm(22255): Could not find method android.view.ViewGroup.onStopNestedScroll, referenced from method android.support.v7.internal.widget.ActionBarOverlayLayout.onStopNestedScroll
12-01 22:02:02.601: W/dalvikvm(22255): VFY: unable to resolve virtual method 11391: Landroid/view/ViewGroup;.onStopNestedScroll (Landroid/view/View;)V
12-01 22:02:02.601: D/dalvikvm(22255): VFY: replacing opcode 0x6f at 0x0000
12-01 22:02:02.621: I/dalvikvm(22255): Could not find method android.support.v7.internal.widget.ActionBarOverlayLayout.stopNestedScroll, referenced from method android.support.v7.internal.widget.ActionBarOverlayLayout.setHideOnContentScrollEnabled
12-01 22:02:02.621: W/dalvikvm(22255): VFY: unable to resolve virtual method 8963: Landroid/support/v7/internal/widget/ActionBarOverlayLayout;.stopNestedScroll ()V
12-01 22:02:02.621: D/dalvikvm(22255): VFY: replacing opcode 0x6e at 0x000e
12-01 22:02:02.661: I/dalvikvm(22255): Could not find method android.view.ViewGroup.onRtlPropertiesChanged, referenced from method android.support.v7.widget.Toolbar.onRtlPropertiesChanged
12-01 22:02:02.661: W/dalvikvm(22255): VFY: unable to resolve virtual method 11388: Landroid/view/ViewGroup;.onRtlPropertiesChanged (I)V
12-01 22:02:02.661: D/dalvikvm(22255): VFY: replacing opcode 0x6f at 0x0007
12-01 22:02:02.671: I/dalvikvm(22255): Could not find method android.content.res.TypedArray.getChangingConfigurations, referenced from method android.support.v7.internal.widget.TintTypedArray.getChangingConfigurations
12-01 22:02:02.671: W/dalvikvm(22255): VFY: unable to resolve virtual method 366: Landroid/content/res/TypedArray;.getChangingConfigurations ()I
12-01 22:02:02.671: D/dalvikvm(22255): VFY: replacing opcode 0x6e at 0x0002
12-01 22:02:02.671: I/dalvikvm(22255): Could not find method android.content.res.TypedArray.getType, referenced from method android.support.v7.internal.widget.TintTypedArray.getType
12-01 22:02:02.671: W/dalvikvm(22255): VFY: unable to resolve virtual method 388: Landroid/content/res/TypedArray;.getType (I)I
12-01 22:02:02.671: D/dalvikvm(22255): VFY: replacing opcode 0x6e at 0x0002
12-01 22:02:02.901: D/libEGL(22255): loaded /system/lib/egl/libEGL_adreno200.so
12-01 22:02:02.941: D/libEGL(22255): loaded /system/lib/egl/libGLESv1_CM_adreno200.so
12-01 22:02:02.941: D/libEGL(22255): loaded /system/lib/egl/libGLESv2_adreno200.so
12-01 22:02:02.941: I/Adreno200-EGL(22255): <qeglDrvAPI_eglInitialize:299>: EGL 1.4 QUALCOMM build: AU_LINUX_ANDROID_JB_REL_2.0.3.04.01.02.21.107_msm8625_JB_REL_2.0.3_CL3357771_release_AU (CL3357771)
12-01 22:02:02.941: I/Adreno200-EGL(22255): Build Date: 02/25/13 Mon
12-01 22:02:02.941: I/Adreno200-EGL(22255): Local Branch: 
12-01 22:02:02.941: I/Adreno200-EGL(22255): Remote Branch: quic/jb_rel_2.0.3
12-01 22:02:02.941: I/Adreno200-EGL(22255): Local Patches: NONE
12-01 22:02:02.941: I/Adreno200-EGL(22255): Reconstruct Branch: AU_LINUX_ANDROID_JB_REL_2.0.3.04.01.02.21.107 +  NOTHING
12-01 22:02:03.041: D/OpenGLRenderer(22255): Enabling debug mode 0
12-01 22:02:11.861: D/AbsListView(22255): Get MotionRecognitionManager
12-01 22:02:17.711: I/System.out(22255): Copied into internal Storage OK
12-01 22:02:17.711: I/System.out(22255): Directories already OK
12-01 22:02:17.721: I/System.out(22255): NOT Copied into external Storage ERR
12-01 22:02:17.731: W/System.err(22255): java.io.FileNotFoundException: /storage/sdcard0/DCIM/Camera/20141201_185225.OUT.jpg: open failed: EACCES (Permission denied)
12-01 22:02:17.761: W/System.err(22255):    at libcore.io.IoBridge.open(IoBridge.java:416)
12-01 22:02:17.761: W/System.err(22255):    at java.io.FileOutputStream.<init>(FileOutputStream.java:88)
12-01 22:02:17.761: W/System.err(22255):    at java.io.FileOutputStream.<init>(FileOutputStream.java:73)
12-01 22:02:17.761: W/System.err(22255):    at it.pittuzzo.fucre.MainActivity.onActivityResult(MainActivity.java:91)
12-01 22:02:17.761: W/System.err(22255):    at android.app.Activity.dispatchActivityResult(Activity.java:5387)
12-01 22:02:17.761: W/System.err(22255):    at android.app.ActivityThread.deliverResults(ActivityThread.java:3205)
12-01 22:02:17.771: W/System.err(22255):    at android.app.ActivityThread.handleSendResult(ActivityThread.java:3252)
12-01 22:02:17.771: W/System.err(22255):    at android.app.ActivityThread.access$1200(ActivityThread.java:143)
12-01 22:02:17.771: W/System.err(22255):    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1289)
12-01 22:02:17.771: W/System.err(22255):    at android.os.Handler.dispatchMessage(Handler.java:99)
12-01 22:02:17.771: W/System.err(22255):    at android.os.Looper.loop(Looper.java:137)
12-01 22:02:17.771: W/System.err(22255):    at android.app.ActivityThread.main(ActivityThread.java:4960)
12-01 22:02:17.781: W/System.err(22255):    at java.lang.reflect.Method.invokeNative(Native Method)
12-01 22:02:17.781: W/System.err(22255):    at java.lang.reflect.Method.invoke(Method.java:511)
12-01 22:02:17.781: W/System.err(22255):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1038)
12-01 22:02:17.781: W/System.err(22255):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:805)
12-01 22:02:17.781: W/System.err(22255):    at dalvik.system.NativeStart.main(Native Method)
12-01 22:02:17.781: W/System.err(22255): Caused by: libcore.io.ErrnoException: open failed: EACCES (Permission denied)
12-01 22:02:17.781: W/System.err(22255):    at libcore.io.Posix.open(Native Method)
12-01 22:02:17.781: W/System.err(22255):    at libcore.io.BlockGuardOs.open(BlockGuardOs.java:110)
12-01 22:02:17.781: W/System.err(22255):    at libcore.io.IoBridge.open(IoBridge.java:400)
12-01 22:02:17.791: W/System.err(22255):    ... 16 more
12-01 22:02:19.761: I/Process(22255): Sending signal. PID: 22255 SIG: 9

关注我的ManifestActivity.xml的第一行

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="it.pittuzzo.fucre"
    android:versionCode="1"
    android:versionName="1.0" >
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

    <uses-sdk
        android:minSdkVersion="14"
        android:targetSdkVersion="21" />

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name=".MainActivity"

我在真实设备上工作:移动三星酷睿与Android 4.1.2和平板电脑三星Note 2014 Andorid 4.3。 它似乎与代码无关,因为我复制/粘贴网上找到的许多例子,结果仍然相同(有人可以尝试我的代码以检查是否面临相同的结果?)。

我真的无法弄明白......

1 个答案:

答案 0 :(得分:0)

您只能将openFileOutput()用于实习内存中的相对路径。对于外部存储器使用new FileOutputStream(..absolute..path..)