我尝试从原始存储器复制到外部存储器,但它不起作用

I try to copy from raw to external memory but it does not work

很好,

我正在尝试open a pdf文档from my raw folder,但是我听说它不能直接从原始文件夹打开,所以我正在将它复制到外部存储器。

问题是我 not copy the file to external memory 为了打开它。

这是我的代码:

public class OpenPdf {

private static final String TAG = "Open pdf";

public OpenPdf(Context ctx) {
if (checkMemory()){
    Toast.makeText(ctx, "There is access to the SD and you can write", Toast.LENGTH_SHORT).show();
    openPDF(ctx);
}else {
    Toast.makeText(ctx, "No access to SD or can not write", Toast.LENGTH_SHORT).show();
}
}

private boolean checkMemory(){
boolean sdAvailable = false;
boolean sdAccessWriter = false;
boolean value = false;
String state = Environment.getExternalStorageState();

if(state.equals(Environment.MEDIA_MOUNTED)){
    sdAvailable = true;
    sdAccessWriter = true;
}else if (state.equals(Environment.MEDIA_MOUNTED_READ_ONLY)){
    sdAvailable = true;
    sdAccessWriter = false;
}

if(sdAvailable && sdAccessWriter){
    value = true;
}
return value;
}

public void openPDF(Context ctx){

try {
    copyFile(ctx.getResources().openRawResource(R.raw.avisolegal), new FileOutputStream(new File(ctx.getFilesDir(), "Documents/avisolegal.pdf")));
} catch (IOException e) {
    e.printStackTrace();
}

try {
    File pdfFile = new File(ctx.getFilesDir(), "Documents/avisolegal.pdf");
    Uri path = Uri.fromFile(pdfFile);
    Intent intent = new Intent(Intent.ACTION_VIEW);
    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    intent.setDataAndType(path, "application/pdf");
    ctx.startActivity(intent);
} catch (Exception e){
    Toast.makeText(ctx, "Fail to open file.", Toast.LENGTH_SHORT).show();
    Log.i(TAG, "Fail to open file" + e);
}

}

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

这些是 AndroidManifest 上的权限:

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

如何复制文件以打开它?

这是错误日志:

03-15 12:53:26.976 5267-5267/radio.ecca.gesenecca W/System.err: java.io.FileNotFoundException: /data/user/0/radio.ecca.gesenecca/files/Documents/avisolegal.pdf: open failed: ENOENT (No such file or directory)
03-15 12:53:26.979 5267-5267/radio.ecca.gesenecca W/System.err:     at libcore.io.IoBridge.open(IoBridge.java:452)
03-15 12:53:26.979 5267-5267/radio.ecca.gesenecca W/System.err:     at java.io.FileOutputStream.<init>(FileOutputStream.java:87)
03-15 12:53:26.979 5267-5267/radio.ecca.gesenecca W/System.err:     at java.io.FileOutputStream.<init>(FileOutputStream.java:72)
03-15 12:53:26.979 5267-5267/radio.ecca.gesenecca W/System.err:     at radio.ecca.gesenecca.Recursos.OpenPdf.openPDF(OpenPdf.java:59)
03-15 12:53:26.979 5267-5267/radio.ecca.gesenecca W/System.err:     at radio.ecca.gesenecca.Recursos.OpenPdf.<init>(OpenPdf.java:30)
03-15 12:53:26.979 5267-5267/radio.ecca.gesenecca W/System.err:     at radio.ecca.gesenecca.MainActivity.onNavigationItemSelected(MainActivity.java:89)
03-15 12:53:26.979 5267-5267/radio.ecca.gesenecca W/System.err:     at android.support.design.widget.NavigationView.onMenuItemSelected(NavigationView.java:151)
03-15 12:53:26.979 5267-5267/radio.ecca.gesenecca W/System.err:     at android.support.v7.view.menu.MenuBuilder.dispatchMenuItemSelected(MenuBuilder.java:811)
03-15 12:53:26.979 5267-5267/radio.ecca.gesenecca W/System.err:     at android.support.v7.view.menu.MenuItemImpl.invoke(MenuItemImpl.java:152)
03-15 12:53:26.979 5267-5267/radio.ecca.gesenecca W/System.err:     at android.support.v7.view.menu.MenuBuilder.performItemAction(MenuBuilder.java:958)
03-15 12:53:26.979 5267-5267/radio.ecca.gesenecca W/System.err:     at android.support.design.internal.NavigationMenuPresenter.onClick(NavigationMenuPresenter.java:318)
03-15 12:53:26.979 5267-5267/radio.ecca.gesenecca W/System.err:     at android.view.View.performClick(View.java:5280)
03-15 12:53:26.979 5267-5267/radio.ecca.gesenecca W/System.err:     at android.view.View$PerformClick.run(View.java:21239)
03-15 12:53:26.979 5267-5267/radio.ecca.gesenecca W/System.err:     at android.os.Handler.handleCallback(Handler.java:739)
03-15 12:53:26.979 5267-5267/radio.ecca.gesenecca W/System.err:     at android.os.Handler.dispatchMessage(Handler.java:95)
03-15 12:53:26.979 5267-5267/radio.ecca.gesenecca W/System.err:     at android.os.Looper.loop(Looper.java:234)
03-15 12:53:26.979 5267-5267/radio.ecca.gesenecca W/System.err:     at android.app.ActivityThread.main(ActivityThread.java:5526)
03-15 12:53:26.979 5267-5267/radio.ecca.gesenecca W/System.err:     at java.lang.reflect.Method.invoke(Native Method)
03-15 12:53:26.980 5267-5267/radio.ecca.gesenecca W/System.err:     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
03-15 12:53:26.980 5267-5267/radio.ecca.gesenecca W/System.err:     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
03-15 12:53:26.980 5267-5267/radio.ecca.gesenecca W/System.err: Caused by: android.system.ErrnoException: open failed: ENOENT (No such file or directory)
03-15 12:53:26.980 5267-5267/radio.ecca.gesenecca W/System.err:     at libcore.io.Posix.open(Native Method)
03-15 12:53:26.980 5267-5267/radio.ecca.gesenecca W/System.err:     at libcore.io.BlockGuardOs.open(BlockGuardOs.java:186)
03-15 12:53:26.980 5267-5267/radio.ecca.gesenecca W/System.err:     at libcore.io.IoBridge.open(IoBridge.java:438)
03-15 12:53:26.980 5267-5267/radio.ecca.gesenecca W/System.err:     ... 19 more
03-15 12:53:27.139 5267-5566/radio.ecca.gesenecca V/RenderScript: 0x9d2a3000 Launching thread(s), CPUs 4
03-15 12:53:44.030 5267-5267/radio.ecca.gesenecca I/Timeline: Timeline: Activity_idle id: android.os.BinderProxy@73b6028 time:138471792

非常感谢你,感谢这个社区,我学到了很多东西。

对不起,我不小心把问题删了

编辑 1:

如果我用“/avisolegal.pdf”改变路线。它不显示错误,但不将文件复制到该路径。

我已经解决了我的问题,我把它留在这里让他们看到,我可以帮助他们

我做的第一件事就是要求用户对外部存储器的写入权限。

static final Integer WRITE_EXST = 0x3;

askForPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE,WRITE_EXST);


   private void askForPermission(String permission, Integer requestCode) {
    if (ContextCompat.checkSelfPermission(MainActivity.this, permission) != PackageManager.PERMISSION_GRANTED) {

        // Should we show an explanation?
        if (ActivityCompat.shouldShowRequestPermissionRationale(MainActivity.this, permission)) {

            //This is called if user has denied the permission before
            //In this case I am just asking the permission again
            ActivityCompat.requestPermissions(MainActivity.this, new String[]{permission}, requestCode);

        } else {

            ActivityCompat.requestPermissions(MainActivity.this, new String[]{permission}, requestCode);
        }
    } else {
        //Toast.makeText(this, "" + permission + " ya han sido consedidos.", Toast.LENGTH_SHORT).show();
        OpenPdf openPdf = new OpenPdf(getApplicationContext());
    }
}

@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
    super.onRequestPermissionsResult(requestCode, permissions, grantResults);
    if(ActivityCompat.checkSelfPermission(this, permissions[0]) == PackageManager.PERMISSION_GRANTED){
        Toast.makeText(this, "Permisos consedidos", Toast.LENGTH_SHORT).show();
        OpenPdf openPdf = new OpenPdf(getApplicationContext());
    }else{
        Toast.makeText(this, "Permisos denegados", Toast.LENGTH_SHORT).show();}
}

这是我的 class 将原始文件复制到外部存储器然后打开它。

public class OpenPdf {

private static final String TAG = "Copiar fichero" ;

public OpenPdf(Context ctx) {

    if (checkMemory()){
        //Toast.makeText(ctx, "Hay acceso a la SD y se puede escribir", Toast.LENGTH_SHORT).show();
        try
        {
            File ruta_sd = Environment.getExternalStorageDirectory();
            openPDF(ctx,ruta_sd);
        }
        catch (Exception ex)
        {
            Log.e("Ficheros", "Error al escribir el fichero en la tarjeta SD " + ex);
        }
    }else {
        Toast.makeText(ctx, "No hay acceso a la SD o no se puede escribir", Toast.LENGTH_SHORT).show();
    }
}

private boolean checkMemory(){
    boolean sdAvailable = false;
    boolean sdAccessWriter = false;
    boolean value = false;
    String state = Environment.getExternalStorageState();

    if(state.equals(Environment.MEDIA_MOUNTED)){
        sdAvailable = true;
        sdAccessWriter = true;
    }else if (state.equals(Environment.MEDIA_MOUNTED_READ_ONLY)){
        sdAvailable = true;
        sdAccessWriter = false;
    }

    if(sdAvailable && sdAccessWriter){
        value = true;
    }
    return value;
}

public void openPDF(Context ctx, File ruta){

    try {
        copyFile(ctx.getResources().openRawResource(R.raw.avisolegal), new FileOutputStream(new File(ruta, "avisolegal.pdf")));
    } catch (IOException e) {
        e.printStackTrace();
    }

   try {
        File pdfFile = new File(ruta, "avisolegal.pdf");
        Uri path = Uri.fromFile(pdfFile);
        Intent intent = new Intent(Intent.ACTION_VIEW);
        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        intent.setDataAndType(path, "application/pdf");
        ctx.startActivity(intent);
    } catch (Exception e){
        Toast.makeText(ctx, "Error al abrir el archivo.\nDebe tener un visor de archivos PDF", Toast.LENGTH_SHORT).show();
        Log.i(TAG, "Error al abrir el archivo" + e);
    }

}

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

问题出在新版本 android 的权限和我用来复制文件的路径上。

问候,非常感谢您的帮助