Good,
I am trying to open a pdf
document from my raw folder
, but I have read that it can not be opened directly from the raw folder, so I am copying it to external memory.
The problem is that I do not copy the file to external memory
in order to open it.
This is my code:
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);
}
}
And these are the permissions on the AndroidManifest:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
How can I have the file copied to open it?
This is the error log:
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$1.onNavigationItemSelected(MainActivity.java:89)
03-15 12:53:26.979 5267-5267/radio.ecca.gesenecca W/System.err: at android.support.design.widget.NavigationView$1.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$1.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
Thank you very much in advance, I am learning a lot thanks to this community.
I'm sorry, I accidentally deleted the question.
EDIT 1:
If I change the route by "/avisolegal.pdf". It does not display the error, but does not copy the file to that path.
I have already solved my problem, I leave it here so that they can see it and I can help them
The first thing I did, was to ask the user to write permissions to the external memory.
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();}
}
And this is my class that copies the raw file to the external memory and then opens it.
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);
}
}
The problem was in the permissions for the new versions of android and the route I was using to copy the file.
A greeting and thank you very much for the help