0

I have a button in my app, which when clicked on will open a PDF (the "Open with" prompt will show). The PDF file is in my assets folder of the app. I have written the code such that an AsyncTask carries out the operation of copying from the assets folder to external storage and then opening it. On running however, none of the methods of AsyncTask class execute as I can see from Logcat. I have seen other similar questions and tried their different answers:

  1. .executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR) instead of .execute()
  2. .executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, (Void[])null);
  3. adding onPreExecute()

The error I get is NullPointerException in the onPostExecute(File file) method, i.e. file is not found. None of the logged statements in the three methods are in logcat.

I call this execute method below:

public void execute() {

    Context context = contextWeakReference.get();
    if (context != null) {
        new CopyFileAsyncTask().executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, (Void[])null);
    }

}


private class CopyFileAsyncTask extends AsyncTask<Void, Void, File> {


    final String appDirectoryName = BuildConfig.APPLICATION_ID;
    final File fileRoot = new File(Environment.getExternalStoragePublicDirectory(
            Environment.DIRECTORY_DOCUMENTS), appDirectoryName);

    @Override
    protected void onPreExecute() {
        super.onPreExecute();
        Log.e("AsyncTask", "onPreExecute");
    }

    @Override
    protected File doInBackground(Void... params) {

        Context context = contextWeakReference.get();

        AssetManager assetManager = context.getAssets();

        File file = new File(fileRoot, fileName);

        InputStream in = null;
        OutputStream out = null;
        try {

            file.mkdirs();

            if (file.exists()) {
                file.delete();
            }

            file.createNewFile();


            in = assetManager.open(fileName);
            Log.d(TAG, "In");

            out = new FileOutputStream(file);
            Log.d(TAG, "Out");

            Log.d(TAG, "Copy file");
            copyFile(in, out);

            Log.d(TAG, "Close");
            in.close();

            out.flush();
            out.close();

            return file;
        } catch (Exception e)
        {
            Log.e(TAG, e.getMessage());
        }

        return null;
    }

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

    @Override
    protected void onPostExecute(File file) {
        super.onPostExecute(file);

        Context context = contextWeakReference.get();


        Intent intent = new Intent(Intent.ACTION_VIEW);
        intent.setDataAndType(
                Uri.fromFile(file),
                "application/pdf");

        context.startActivity(intent);

    }
}
Nikhil_10
  • 133
  • 3
  • 10

2 Answers2

1

You Always return null in doInBackground

so

protected void onPostExecute(File file) {
    super.onPostExecute(file);

    Context context = contextWeakReference.get();


    Intent intent = new Intent(Intent.ACTION_VIEW);
    intent.setDataAndType(
            Uri.fromFile(file),
            "application/pdf");

    context.startActivity(intent);

}

File is Always Null

try to edit this

  @Override
    protected File doInBackground(Void... params) {

        Context context = contextWeakReference.get();

        AssetManager assetManager = context.getAssets();

        File file = new File(fileRoot, fileName);

        InputStream in = null;
        OutputStream out = null;
        try {

            file.mkdirs();

            if (file.exists()) {
                file.delete();
            }

            file.createNewFile();


            in = assetManager.open(fileName);
            Log.d(TAG, "In");

            out = new FileOutputStream(file);
            Log.d(TAG, "Out");

            Log.d(TAG, "Copy file");
            copyFile(in, out);

            Log.d(TAG, "Close");
            in.close();

            out.flush();
            out.close();

        } catch (Exception e)
        {
            Log.e(TAG, e.getMessage());
        }
            return file;

     }
Elsunhoty
  • 1,609
  • 14
  • 27
  • Thanks a lot!! The application runs and the "Open with" dialog appears as well. The adobe reader flash screen appears but then I get a toast message: "This file could not be accessed. Check the location or the network and try again". Could you help me with this? – Nikhil_10 Apr 08 '17 at 16:01
  • Another point: I used other apps and they cannot open it either. It seems as if the file is not in that directory. – Nikhil_10 Apr 08 '17 at 16:03
  • Also! I checked the log again: onPreExecute is encountered but not the other two methods! Maybe this is why the file does not exist where it is supposed to – Nikhil_10 Apr 08 '17 at 16:13
  • and Is my Answers didn`t satisfy You – Elsunhoty Apr 08 '17 at 17:30
  • My question is why is the onPreExecute method is getting executed but not the other two – Nikhil_10 Apr 08 '17 at 17:38
0

Problem solved!! Apparently Marshmallow does some secret behind the scenes work like not asking for permissions (while installing using android studio). I found that the answer here android mkdirs not working worked for me. You have to go to Settings > Apps > Your app > Turn on Storage permissions. It took me three days to solve this!

Community
  • 1
  • 1
Nikhil_10
  • 133
  • 3
  • 10