Как экспортировать файл CSV Android Studio - PullRequest
0 голосов
/ 17 апреля 2020

Я пытаюсь создать приложение, которое создает файл CSV, а затем экспортирует этот файл CSV, прикрепив его к электронному письму или загрузив на диск Google. Я смотрел это видео: https://www.youtube.com/watch?v=VDAwbgHoYEA, и код почти работает. Тем не менее, у меня возникает проблема с разрешением, когда я пытаюсь его экспортировать: 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()

Я знаю, что это довольно часто задаваемый вопрос, но я не смог найти онлайн-решение, которое, кажется, работает с новейшая Android сборка. Мне было интересно, если кто-то может помочь мне понять, как решить проблему, которая у меня возникла? В функции экспорта я пытаюсь отправить текстовый файл.

Ниже приведены мои основные действия и android файл манифеста ниже. Заранее благодарим за любую помощь!

Основная деятельность

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 Манифест

<?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>
...