I have an application that I want to export the current SQLite database to the Internal storage Downloads folder of the device. I am getting the below error.
java.io.FileNotFoundException: /storage/emulated/0/Download/Pipe_Tally: open failed: EACCES (Permission denied)
I have what I think are the correct permissions included in the AndroidManifest.xml file for reading and writing to storage.
Here is the AndroidManifest.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="com.example.bigdaddy.pipelinepipetally">
    <uses-feature android:name="android.hardware.camera2"
                  android:required="true"/>
    <uses-permission android:name="android.permission.READ_CONTACTS"/>
    <uses-permission android:name="android.permission.INTERNET"/>
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"
        android:maxSdkVersion="18"/>
    <uses-permission android:name="android.permission.CAMERA"/>
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
    <uses-permission android:name="android.permission.ACCESS_LOCATION_EXTRA_COMMANDS"/>
    <application
        android:allowBackup="true"
        android:debuggable="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:supportsRtl="true"
        android:theme="@style/AppTheme"
        tools:ignore="HardcodedDebugMode">
        <activity
            android:name=".MainActivity"
            android:windowSoftInputMode="adjustResize">
            <intent-filter>
                <action android:name="android.intent.action.MAIN"/>
                <category android:name="android.intent.category.LAUNCHER"/>
            </intent-filter>
        </activity>
        <activity
            android:name=".TallyActivity2"
            android:windowSoftInputMode="adjustResize">
        </activity>
        <activity
            android:name=".JobAndDbActivity"
            android:windowSoftInputMode="adjustResize">
        </activity>
        <activity
            android:name=".ExistingTallyActivity"
            android:windowSoftInputMode="adjustResize">
        </activity>
        <activity android:name=".ImageToFullscreen"
            android:windowSoftInputMode="adjustResize">
        </activity>
        <provider
            android:name="android.support.v4.content.FileProvider"
            android:authorities="com.example.bigdaddy.pipelinepipetally.fileprovider"
            android:exported="false"
            android:grantUriPermissions="true">
            <meta-data
                android:name="android.support.FILE_PROVIDER_PATHS"
                android:resource="@xml/file_paths">
            </meta-data>
        </provider>
    </application>
</manifest>
Here is the method I am trying to use to create the file for the /Downloads/ folder within the internal device storage:
public void backUpDatabase() {
    /* Open your local db as the input stream */
    DBHelper anotherDbHelper = null;
    try {
        try {
            anotherDbHelper = new DBHelper(ExistingTallyActivity.this);
        } catch (NoSuchFieldException e) {
            e.printStackTrace();
        }
    } catch (ClassNotFoundException e) {
        e.printStackTrace();
    }
    String path = null;
    if (anotherDbHelper != null) {
        path = String.valueOf(getApplicationContext().getDatabasePath(anotherDbHelper.getDatabaseName()));
        Log.i(TAG, "backUpDatabase: 1" +path);
    }
    File dbFile = null;
    if (path != null) {
        dbFile = new File(path);
        Log.i(TAG, "backUpDatabase: 2" + String.valueOf(dbFile));
    }
    FileInputStream fis = null;
    try {
        if (dbFile != null) {
            fis = new FileInputStream(dbFile);
            Log.i(TAG, "backUpDatabase: 3" + String.valueOf(dbFile));
        }
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    }
    String outFileName = (Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS).getAbsolutePath()+ "/Pipe_Tally/");
    Log.i(TAG, "backUpDatabase: 4"+ outFileName);
    // Open the empty db as the output stream
    OutputStream outputStream = null;
    //FileOutputStream outputStream = null;
    try {
         outputStream = new FileOutputStream(outFileName);
        Log.i(TAG, "backUpDatabase: 5"+ outFileName);
        Log.i(TAG, "backUpDatabase: 6"+ String.valueOf(outputStream));
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    }
    // Transfer bytes from the input-file to the output-file
    byte[] buffer = new byte[1024];
    int length;
    try {
        if (fis != null) {
            while ((length = fis.read(buffer)) > 0) {
                try {
                    if (outputStream != null) {
                        outputStream.write(buffer, 0, length);
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    } catch (IOException e) {
        e.printStackTrace();
    }
    //Close the streams
    try {
        if (outputStream != null) {
            outputStream.flush();
            outputStream.close();
        }
    } catch (IOException e) {
        e.printStackTrace();
    }
    try {
        if (fis != null) {
            fis.close();
        }
    } catch (IOException e) {
        e.printStackTrace();
    }
}
Here is the method I am using to check for the correct permissions at Runtime:
private boolean checkSdCardPermissions() {
    /* Checking here if we already have permissions*/
    if (ActivityCompat.checkSelfPermission(ExistingTallyActivity.this,
            Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED
            && ActivityCompat.checkSelfPermission(ExistingTallyActivity.this,
            Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) { /* Added this for Write External Storage permissions */
        /* Checking to see if we are equal to or at a higher version than Marshmallow */
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            /* System default popup box here to ask for permissions. */
            ActivityCompat.requestPermissions(ExistingTallyActivity.this,
                    new String[]{Manifest.permission.READ_EXTERNAL_STORAGE},
                    MY_PERMISSION_READ_EXTERNAL_STORAGE);
            /* Added this today for trying to prompt for writing external storage*/
            ActivityCompat.requestPermissions(ExistingTallyActivity.this,
                    new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},
                    MY_PERMISSION_WRITE_EXTERNAL_STORAGE);
        }
        return true;
    } else {
        return false;
    }
}
This is the onOptionsItemSelected() method that has the switch in it to handle the menu and what is selected. The case:R.id.menu_save_and_export:
is where I am checking if checkSdCardPermissions() method is true, then calling the backUpDatabase() method.
 @Override
    public boolean onOptionsItemSelected(MenuItem menuItem) {
        switch (menuItem.getItemId()) {
            /*
            When Tally New Pipe is selected from the Menu, it sends the user to the TallyActivity
            page, all encapsulated in a runnable and passed to thread below.
            */
            case R.id.menu_new_pipe:
                class ToTallyActivityManager implements Runnable {
                    @Override
                    public void run() {
                        Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
                        Intent intentToTallyActivity =
                                new Intent(ExistingTallyActivity.this, TallyActivity2.class);
                        startActivity(intentToTallyActivity); /* Heading to TallyActivity.*/
                    } /* run method ends here. */
                } /* Runnable ends here. */
                /* This thread takes care of the call to go to TallyActivity page from here.*/
                mThreadToTallyActivity = new Thread(new ToTallyActivityManager());
                mThreadToTallyActivity.start();
                break;
            /* When selected, sends the user to the MainActivity page. */
            case R.id.menu_to_main:
                Intent intentToMainActivity =
                        new Intent(ExistingTallyActivity.this, MainActivity.class);
                startActivity(intentToMainActivity); // Heading to MainActivity
                break;
            /* When chosen allows the option to save and export the current DB.*/
            case R.id.menu_save_and_export:
                if (checkSdCardPermissions()) {
                    try {
                        backUpDatabase();
                    } catch (/*IOException*/ SQLException e) {
                        e.printStackTrace();
                    }
                }
                break;
            /* When chosen from the menu, this kills the app completely. Has popup embedded.*/
            default:
                AlertHelperDialog.displayExitAlertDialog(ExistingTallyActivity.this);
        } /* switch/case ends here */
        return super.onOptionsItemSelected(menuItem);
    } /* onOptionsItemSelected method ends here. */
I really appreciate any help or advice with fixing this issue. Thank you.