0

I am trying to create an app that builds a CSV file, then exports that CSV file via attaching to an email, or uploading to google drive. I watched this video: https://www.youtube.com/watch?v=VDAwbgHoYEA and have the code almost working. However, I have this permission issue when I try to export it: java.lang.SecurityException: Permission Denial: reading androidx.core.content.FileProvider uri content://com.example.CalendarTracker.fileprovider/data/data.csv from pid=22257, uid=1000 requires the provider be exported, or grantUriPermission()

I know that this is a fairly frequently asked question, but I have not been able to find an online solution that seems to work with the newest Android builds. I was wondering if someone could help me figure out how to solve the issue that I'm having? The export function is where I am trying to send out the text file.

Below are my main activity and android manifest file below. Thanks in advance for any help!

Main Activity

package com.example.calendartracker;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.graphics.Color;
import android.net.Uri;
import android.os.Bundle;

import androidx.appcompat.app.AppCompatActivity;
import androidx.core.content.FileProvider;

import android.os.CountDownTimer;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;

import java.io.File;
import java.io.FileOutputStream;
import java.net.URI;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.List;

public class MainActivity extends AppCompatActivity {
    private static final long START_TIME_IN_MILLIS = 900000000;
    private TextView mResultsString;
    private TextView mStatusString;
    private Button mResetButton;
    private Button mStopButton;
    private CountDownTimer mCountdownTimer;



    private boolean mTimerRunning;
    private long mTimeLeftInMillis = START_TIME_IN_MILLIS;
    private int count = 0;


    StringBuilder calendarData = new StringBuilder();

    Calendar calendar = Calendar.getInstance();


    @Override
    protected void onCreate(Bundle savedInstanceState){
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        mResultsString = findViewById(R.id.resultsString);
        mStatusString = findViewById(R.id.status_TextView);
        mResetButton = findViewById(R.id.reset_button);
        mStopButton = findViewById(R.id.stopButton);

        mResetButton.setEnabled(false);

        mStatusString.setText("Collection Running");
        mStatusString.setTextColor(Color.rgb(0,255,0));
        startTimer();
        mResetButton.setOnClickListener(new View.OnClickListener(){
            @Override
            public void onClick(View v){
                resetTimer();
            }
        });

        mStopButton.setOnClickListener(new View.OnClickListener(){
            @Override
            public void onClick(View v){
                stopTimer();
            }
        });

        updateUI();
    }




    private void startTimer(){
        mCountdownTimer = new CountDownTimer(mTimeLeftInMillis, 1000){
            @Override
            public void onTick(long millisUntilFinshed){
                calendar = Calendar.getInstance();
                updateUI();
            }
            @Override
            public void onFinish(){
                mTimerRunning = false;
            }

        }.start();
        mTimerRunning = true;
    }


    private void resetTimer(){
        mStatusString.setText("Collection Running");
        mStatusString.setTextColor(Color.rgb(0,255,0));
        mResetButton.setEnabled(false);
        mStopButton.setEnabled(true);
        mTimeLeftInMillis = START_TIME_IN_MILLIS;
        startTimer();
        updateUI();
    }

    private void stopTimer(){
        mCountdownTimer.cancel();
        mTimerRunning = false;
        mResetButton.setEnabled(true);
        mStopButton.setEnabled(false);
        mStatusString.setText("Stopped");
        mStatusString.setTextColor(Color.rgb(255,0,0));
        export();
    }

    private void updateUI(){
        SimpleDateFormat formatter = new SimpleDateFormat("MM/dd/yyyy hh:mm:ss");
        String currentTime = formatter.format(calendar.getTime());
        mResultsString.setText(currentTime);
        calendarData.append(currentTime);
    }

    public void export() {
        Context context = getApplicationContext();
        File fileLocation = new File(getFilesDir(), "data.csv");
        Uri path = FileProvider.getUriForFile(context, "com.example.CalendarTracker.fileprovider", fileLocation);

        //writing the data to a CSV file
        try {
            FileOutputStream output = openFileOutput("data.csv", Context.MODE_PRIVATE);
            output.write((calendarData.toString().getBytes()));
            output.close();

            //exporting

            Intent fileIntent = new Intent(Intent.ACTION_SEND);
            fileIntent.setType("*/*");
            fileIntent.putExtra(Intent.EXTRA_SUBJECT, "Calendar Data");
            fileIntent.putExtra(Intent.EXTRA_STREAM, path);
            fileIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION |Intent.FLAG_GRANT_WRITE_URI_PERMISSION);

            startActivity(Intent.createChooser(fileIntent, "Send mail"));
        } catch (Exception e) {
            System.out.println(e);
        }
    }


}

Android Manifest

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.calendartracker">
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.READ_INTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />

    <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">

        <activity
            android:name=".MainActivity"
            android:label="@string/app_name"
            android:theme="@style/AppTheme.NoActionBar">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

        <provider
            android:name="androidx.core.content.FileProvider"
            android:authorities="com.example.CalendarTracker.fileprovider"
            android:grantUriPermissions="true"
            android:exported="false">
            <meta-data
                android:name="android.support.FILE_PROVIDER_PATHS"
                android:resource="@xml/provider_paths"/>

        </provider>


    </application>

</manifest>
  • 1
    see this question you will get the answer here https://stackoverflow.com/questions/24467696/android-file-provider-permission-denial – Black4Guy Apr 17 '20 at 19:32
  • https://stackoverflow.com/questions/57689792/permission-denial-while-sharing-file-with-fileprovider this will help you. – Android_id Apr 18 '20 at 07:10
  • Check your provider_paths.xml file. I think you are providing the wrong path for granting Uri permissions there. – Satyam Kamboj Jun 08 '21 at 05:23

0 Answers0