1

I've got a class to open a blank character sheet (for a LARP) stored in my raw resources and then add some values to the empty fields using iText. The PDF is getting stored in /data/data/package/files just fine, but when I try to use the OpenPDF method, I get an EACCES (permission denied) error. If I try to use adb to export it to my computer, I can open it in PDF viewers/editors with no problems.

Still fairly new to android development, so I have no idea why I'm getting Permission Denied.

imports...

/**
 * Created by Matt on 10/15/2014.
 */
public class SheetBuilder {

    private final String LOGTAG = getClass().getName();

    private Context context;
    private InputStream inputStream;
    private OutputStream outputStream = null;
    private PdfReader reader = null;
    private Document document;
    private PdfWriter writer = null;
    private String outputFileName;
    private PdfContentByte canvas;

    private int alignment = Element.ALIGN_LEFT;

    public SheetBuilder(Context context, int sourceFile, String outputFileName) {
        this.outputFileName = outputFileName.replace(".pdf", "") + ".pdf";
        this.context = context;

        inputStream = context.getResources().openRawResource(sourceFile);
        try {
            reader = new PdfReader(inputStream);
        } catch (IOException e) {
            e.printStackTrace();
        }

        try {
            outputStream = context.openFileOutput(this.outputFileName, context.MODE_PRIVATE);
        } catch (Exception e) {
            e.printStackTrace();
        }

        document = new Document(reader.getPageSize(1));
        try {
            writer = PdfWriter.getInstance(document, outputStream);
        } catch (DocumentException e) {
            e.printStackTrace();
        }
        document.open();
        canvas = writer.getDirectContent();
    }

    public void OpenPDF() {
        ContextWrapper cw = new ContextWrapper(context);
        File path = cw.getFilesDir();
        File pdfFile = new File(path + "/" + outputFileName);
        if(pdfFile.exists())
        {
            Log.i(LOGTAG, "Found " + outputFileName);

            Uri uriPath = Uri.fromFile(pdfFile);
            Intent pdfIntent = new Intent(Intent.ACTION_VIEW);
            pdfIntent.setDataAndType(uriPath, "application/pdf");
            pdfIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);

            try {
                context.startActivity(pdfIntent);
            } catch (ActivityNotFoundException e) {
                Toast.makeText(context, "No application available to view PDF", Toast.LENGTH_LONG).show();
            }
        }
    }

    public void ImportPage(int PageNumber) {
        if(PageNumber == 0) PageNumber = 1;
        PdfImportedPage page = writer.getImportedPage(reader, PageNumber);
        document.newPage();
        canvas.addTemplate(page, 0, 0);
    }

    public void setAlignment(int Alignment) {
        this.alignment = Alignment;
    }

    public void setAlignment() {
        this.alignment = Element.ALIGN_LEFT;
    }

    public void AddBasicPhrase(String phrase, float x, float y, float rotation) {
        Phrase p = new Phrase(phrase);
        ColumnText.showTextAligned(canvas, alignment, p, x, y, rotation);
    }

    public void AddBasicPhrase(String phrase, float x, float y) {
        AddBasicPhrase(phrase, x, y, 0);
    }

    public void Close() {
        document.close();

        if (outputStream != null) {
            try {
                outputStream.flush();
                outputStream.close();
                inputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

}
Alexis Pigeon
  • 7,423
  • 11
  • 39
  • 44
Matt DeKok
  • 197
  • 1
  • 8
  • I'm sure it has been answered before, but when I was searching for it I kept getting things that didn't answer my question and I didn't see the one posted above. And the ones that seemed like they would answer my question kept giving me other errors until I figured out how to make it work. – Matt DeKok Oct 16 '14 at 14:07

1 Answers1

1

Found my own solution. Changes marked with comments below. Correct me if I'm doing something I shouldn't. Discovered "External vs Internal" file storing was my issue.

/**
 * Created by Matt on 10/15/2014.
 */
public class SheetBuilder {

    private final String LOGTAG = getClass().getName();

    private Context context;
    private InputStream inputStream;
    private OutputStream outputStream = null;
    private PdfReader reader = null;
    private Document document;
    private PdfWriter writer = null;
    private String outputFileName;
    private PdfContentByte canvas;

    private int alignment = Element.ALIGN_LEFT;

    public SheetBuilder(Context context, int sourceFile, String outputFileName) {
        this.outputFileName = outputFileName.replace(".pdf", "") + ".pdf";
        this.context = context;

        inputStream = context.getResources().openRawResource(sourceFile);
        try {
            reader = new PdfReader(inputStream);
        } catch (IOException e) {
            e.printStackTrace();
        }

        /* Changes From Here */    
        try {
            File path = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOCUMENTS);
            File file = new File(path, this.outputFileName);
            Log.i("ExternalStorage", file.getAbsolutePath());
            path.mkdirs();
            outputStream = new FileOutputStream(file);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
        /* To Here */

        document = new Document(reader.getPageSize(1));
        try {
            writer = PdfWriter.getInstance(document, outputStream);
        } catch (DocumentException e) {
            Log.e("ErrorsAllAround", "Nope!");
            e.printStackTrace();
        }
        document.open();
        canvas = writer.getDirectContent();
    }

    public void OpenPDF() {
        /* Changes From Here */
        File pdfFile = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOCUMENTS), outputFileName);
        /* To Here */
        if(pdfFile.exists())
        {
            Log.i(LOGTAG, "Found " + pdfFile.getAbsolutePath());

            Uri uriPath = Uri.fromFile(pdfFile);
            Intent pdfIntent = new Intent(Intent.ACTION_VIEW);
            pdfIntent.setDataAndType(uriPath, "application/pdf");
            pdfIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);

            try {
                context.startActivity(pdfIntent);
            } catch (ActivityNotFoundException e) {
                Toast.makeText(context, "No application available to view PDF", Toast.LENGTH_LONG).show();
            }
        }
        else
        {
            Log.i(LOGTAG, "File Not Found: " + pdfFile.getAbsolutePath());
            Toast.makeText(context, "File Not Found: " + pdfFile.getAbsolutePath(), Toast.LENGTH_LONG).show();
        }
    }

    public void ImportPage(int PageNumber) {
        if(PageNumber == 0) PageNumber = 1;
        PdfImportedPage page = writer.getImportedPage(reader, PageNumber);
        document.newPage();
        canvas.addTemplate(page, 0, 0);
    }

    public void setAlignment(int Alignment) {
        this.alignment = Alignment;
    }

    public void setAlignment() {
        this.alignment = Element.ALIGN_LEFT;
    }

    public void AddBasicPhrase(String phrase, float x, float y, float rotation) {
        Phrase p = new Phrase(phrase);
        ColumnText.showTextAligned(canvas, alignment, p, x, y, rotation);
    }

    public void AddBasicPhrase(String phrase, float x, float y) {
        AddBasicPhrase(phrase, x, y, 0);
    }

    public void Close() {
        document.close();

        if (outputStream != null) {
            try {
                outputStream.flush();
                outputStream.close();
                inputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

}
Matt DeKok
  • 197
  • 1
  • 8