3

I am creating a button which will, Fetch database, create .xls file in documents folder and send it as an attachment in email or whatsapp. However, I am getting mailjava.io.FileNotFoundException error even after adding permissions to Manifest file. I know its something small I am missing, but can't figure out.

  1. I have tried creating file in Internal Cache directory, where file is created successfully but cannot be fetched as attachment to email or whatsapp.
  2. I don't have any problem where the file should be saved, because I am deleting it anyway after sending as attachment.
  3. In Email Intent, I have played with Uri as Uri.parse("content://", file.getAbsolutePath()) file.toUri(); Uri uri = Uri.fromFile(file); All have same results showing this error. Parent class has all defined variables

        imbtnMail.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
              try {
    
                Cursor cursor = dbManager.fetch(DatabaseHelper.TICKET_TABLE);
    
                String filename = "Report-" + DateUtil.timeMilisToString(System.currentTimeMillis(), "ddMMyy");
                String xlsfile = filename + ".xlx";
                file = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOCUMENTS), xlsfile);
                Log.i("File written at:",file.getAbsolutePath());
    
                //file path
                WorkbookSettings wbSettings = new WorkbookSettings();
                wbSettings.setLocale(new Locale("en", "EN"));
                WritableWorkbook workbook;
                workbook = Workbook.createWorkbook(file, wbSettings);
                //Excel sheet name. 0 represents first sheet
                WritableSheet sheet = workbook.createSheet("Daily Report", 0);
    
                // column and row
                sheet.addCell(new Label(0, 0, "Pass Report"));
                sheet.addCell(new Label(1, 0, "User"));
    
                if (cursor.moveToFirst()) {
                    do {
                        String Rno = cursor.getString(cursor.getColumnIndex(DatabaseHelper.TICKET_RECEIPT));
                        String vno = cursor.getString(cursor.getColumnIndex(DatabaseHelper.TICKET_V_NO));
                        String vtype = cursor.getString(cursor.getColumnIndex(DatabaseHelper.TICKET_V_TYPE));
                        String vin = cursor.getString(cursor.getColumnIndex(DatabaseHelper.TICKET_V_IN_TIME));
                        String vout = cursor.getString(cursor.getColumnIndex(DatabaseHelper.TICKET_V_OUT_TIME));
                        int i = cursor.getPosition() + 1;
                        sheet.addCell(new Label(0, i, Rno));
                        sheet.addCell(new Label(1, i, vno));
                        sheet.addCell(new Label(2, i, vtype));
                        sheet.addCell(new Label(3, i, vin));
                        sheet.addCell(new Label(4, i, vout));
                    } while (cursor.moveToNext());
                }
    
                //closing cursor
                cursor.close();
                workbook.write();
                workbook.close();
    
                Intent intent = new Intent(Intent.ACTION_SEND);
                intent.setType("*/*");
                intent.putExtra(Intent.EXTRA_EMAIL, new String[]{"email@example.com"});
                intent.putExtra(Intent.EXTRA_SUBJECT, "subject here");
                intent.putExtra(Intent.EXTRA_TEXT, "body text");
                if (!file.exists() || !file.canRead()) {
                    Toast.makeText(ViewLog.this, "Attachment Error", Toast.LENGTH_SHORT).show();
                    return;
                }
                Uri uri = Uri.fromFile(file);
    
                intent.putExtra(Intent.EXTRA_STREAM, uri);
                startActivityForResult(Intent.createChooser(intent, "Send email..."),ViewLog.REQUEST_WRITE_STORAGE);
            } catch (Exception e) {
                System.out.println("is exception raises during sending mail" + e);
            }
        }
    });
    

And this is the error which I am catching after clicking this button

I/System.out: is exception raises during sending mailjava.io.FileNotFoundException: /storage/emulated/0/Documents/Report-020219.xlx (No such file or directory)

Manifest.xml

    <?xml version="1.0" encoding="utf-8"?>
    <manifest xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    package="mypackagename">
    <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
    <uses-permission android:name="android.permission.GET_ACCOUNTS" />
    <uses-permission android:name="android.permission.READ_PROFILE" />
    <uses-permission android:name="android.permission.READ_CONTACTS" />
    <uses-permission android:name="android.permission.BLUETOOTH" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.INTERNET" />
<application
    android:allowBackup="true"
    android:icon="@mipmap/ic_launcher"
    android:label="@string/app_name"
    android:roundIcon="@mipmap/ic_launcher_round"
    android:supportsRtl="true"
    android:theme="@style/AppTheme"
    tools:ignore="GoogleAppIndexingWarning">
    <activity android:name=".VehicleSetup"></activity>
    <activity android:name=".About" />
    <activity android:name=".Parked" />
    <activity android:name=".AppSetup" />
    <activity android:name=".ViewLog" />
    <activity android:name=".LoginActivity" />
    <activity android:name=".Main" />
    <activity android:name=".Splashscreen">
      <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

I want this file written at any location but should be taken as attachment in any email client or whatsapp

Sushant
  • 165
  • 7

1 Answers1

0

I just found out the error responsible for mailjava.io.FileNotFoundException as only instance was created and not the actual file.

Basically, there were two errors responsible for this.

  1. I declared File instance (file) in class itself(not in onClick method). Since it was declared in a class variable, it throws FileUriExposedException which indeed exposed the URI which caught in catch block.
  2. I was trying to fetch that file from internal cached directory, which is not permitted in GMail 5.0 according to this issue

Solution

  1. Declare file instance in onClick method itself so that URI is not exposed.
  2. Create file in ExternalSD because it is world accessible and accepted by GMail 5.0
imbtnMail.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                try {
                    Cursor cursor = dbManager.fetch(DatabaseHelper.TICKET_TABLE);
                    File file = new File(Environment.getExternalStorageDirectory(),"Report-"+DateUtil.timeMilisToString(System.currentTimeMillis(),"hh-MM-yy")+".xls");
                    Toast.makeText(getApplicationContext(),"File saved",Toast.LENGTH_LONG).show();

                    WorkbookSettings wbSettings = new WorkbookSettings();
                    wbSettings.setLocale(new Locale("en", "EN"));
                    WritableWorkbook workbook;
                    workbook = Workbook.createWorkbook(file, wbSettings);
                    WritableSheet sheet = workbook.createSheet("Daily Report", 0);

                    // column and row
                    sheet.addCell(new Label(0, 0, "Pass Report"));
                    sheet.addCell(new Label(1, 0, "User"));

                    if (cursor.moveToFirst()) {
                        do {
                            String Rno = cursor.getString(cursor.getColumnIndex(DatabaseHelper.TICKET_RECEIPT));
                            String vno = cursor.getString(cursor.getColumnIndex(DatabaseHelper.TICKET_V_NO));
                            String vtype = cursor.getString(cursor.getColumnIndex(DatabaseHelper.TICKET_V_TYPE));
                            String vin = cursor.getString(cursor.getColumnIndex(DatabaseHelper.TICKET_V_IN_TIME));
                            String vout = cursor.getString(cursor.getColumnIndex(DatabaseHelper.TICKET_V_OUT_TIME));
                            int i = cursor.getPosition() + 1;
                            sheet.addCell(new Label(0, i, Rno));
                            sheet.addCell(new Label(1, i, vno));
                            sheet.addCell(new Label(2, i, vtype));
                            sheet.addCell(new Label(3, i, vin));
                            sheet.addCell(new Label(4, i, vout));
                        } while (cursor.moveToNext());
                    }

                    //closing cursor
                    cursor.close();
                    workbook.write();
                    workbook.close();

                    Intent intent = new Intent(Intent.ACTION_SEND);
                    intent.setType("text/plain");
                    intent.putExtra(Intent.EXTRA_EMAIL, new String[] {"email@example.com"});
                    intent.putExtra(Intent.EXTRA_SUBJECT, "subject here");
                    intent.putExtra(Intent.EXTRA_TEXT, "body text");
                    if (!file.exists() || !file.canRead()) {
                        Toast.makeText(getApplicationContext(), "Attachment Error", Toast.LENGTH_SHORT).show();
                        return;
                    }
                    Uri uri = Uri.fromFile(file);
                    intent.putExtra(Intent.EXTRA_STREAM, uri);
                    startActivity(Intent.createChooser(intent, "Send email..."));
                }
                catch (Exception e){e.printStackTrace();}
            }
        });
Community
  • 1
  • 1
Sushant
  • 165
  • 7