Android проблема с совместным использованием временного файла - PullRequest
0 голосов
/ 02 июля 2019

Я пытаюсь создать временный файл и поделиться им.Поэтому я создал этот класс:

public class GenerateFile {

    public static File writeToFile(Context mcoContext, String sBody) {

        String fileName = "LOG FILE_" + String.valueOf(System.currentTimeMillis()) +".txt";
        File file = new File(mcoContext.getCacheDir(), fileName);

        try{
            FileWriter writer = new FileWriter(file);
            writer.append(sBody);
            writer.flush();
            writer.close();
            return  file;

        }catch (Exception e){
            Toast.makeText(mcoContext, "File write failed: " + e.toString(), Toast.LENGTH_LONG).show();
        }
        return null;
    }
}

, чтобы сгенерировать файл, который после того, как я поделюсь здесь:

String logContent = "123";
File filePath = new File(file.getAbsolutePath(), "external_files");
filePath.mkdir();
Uri uri = FileProvider.getUriForFile(StatusActivity.this, getPackageName(), filePath);

Intent intent = ShareCompat.IntentBuilder.from(StatusActivity.this)
       .setStream(uri) // uri from FileProvider
        .setType("text/html")
        .getIntent()
        .setAction(Intent.ACTION_VIEW) //Change if needed
        .setDataAndType(uri, "text/*")
        .addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
startActivity(intent);

И в манифесте уже есть это разрешение:

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="com.sec.android.provider.badge.permission.WRITE"/>
<uses-permission android:name="com.sec.android.provider.badge.permission.READ"/>

и объявление провайдера

 <provider
    android:name="android.support.v4.content.FileProvider"
    android:authorities="android.getqardio.com.gmslocationtest"
    android:exported="false"
    android:grantUriPermissions="true">
    <meta-data
        android:name="android.support.FILE_PROVIDER_PATHS"
        android:resource="@xml/provider_paths"/>
</provider>

Класс provider_paths определяется следующим образом:

<?xml version="1.0" encoding="utf-8"?>
<paths>
    <files-path
        name="share"
        path="external_files"/>
</paths>

Но он генерирует сообщение, когда я пытаюсь поделиться им по почте илителеграмма "Невозможно прикрепить файл" или "Неподдерживаемое вложение".Также мне кажется, что файл не создан.

Ответы [ 3 ]

2 голосов
/ 02 июля 2019

Другие приложения не имеют доступа к getCacheDir() вашего приложения. FLAG_GRANT_READ_URI_PERMISSION и FLAG_GRANT_WRITE_URI_PERMISSION предназначены для значений content Uri, а не file Uri. И на устройствах Android 7.0+ ваш код должен вылетать с FileUriExposedException.

Используйте FileProvider, чтобы сделать ваш контент доступным для других приложений, и используйте FileProvider.getUriForFile(), чтобы Uri вставил Intent.

1 голос
/ 02 июля 2019

Вы специально спрашивали у пользователя эти разрешения? Недостаточно просто поместить разрешения в манифесте для целевых sdks ниже 28. Кроме того, в Android Q вам придется вообще обходить разрешения для внешнего хранилища, поскольку это запрещено.

0 голосов
/ 03 июля 2019

Так что я следую предложению @CommonsWare и отредактировал свой код. Это конечный результат:

public class GenerateFile {

    public static Uri getFileURI(Context context, String nameFile, String content, String fileExtension) {
        DateFormat dateFormat = new SimpleDateFormat("yyyy_MM_dd");
        Date date = new Date();
        String fileName = dateFormat.format(date)+nameFile+fileExtension;
        File file = new File(context.getCacheDir(), fileName);

        try{
            FileWriter writer = new FileWriter(file);
            writer.append(content);
            writer.flush();
            writer.close();
            //Toast.makeText(context, "Writing to the file completed successfully", Toast.LENGTH_LONG).show();
        }catch (Exception e){
            Toast.makeText(context, "File writing failed: " + e.toString(), Toast.LENGTH_LONG).show();
        }

        File filePath = new File(context.getCacheDir(), "");
        File newFile = new File(filePath, fileName);
        return FileProvider.getUriForFile(context, "MYPACKAGE.fileprovider", newFile);
    }
}

и в другом классе:

private void sendFile(String nameFile, String logContent,  String fileExtension) {
        Uri contentUri = GenerateFile.getFileURI(getApplicationContext(), nameFile, logContent, fileExtension);

        Intent intent = ShareCompat.IntentBuilder.from(StatusActivity.this)
                .setStream(contentUri) // uri from FileProvider
                .setType("text/plain")
                .getIntent()
                .addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
        startActivity(Intent.createChooser(intent, "send"));
}

чтобы отправить файл. Я также удалил разрешение (ранее упомянутое) в манифесте, потому что оно мне больше не нужно.

И я также отредактировал файл провайдера и файла provider_path так:

<provider
   android:name="android.support.v4.content.FileProvider"
   android:authorities="MYPACKAGE.fileprovider"
   android:exported="false"
   android:grantUriPermissions="true">
   <meta-data
            android:name="android.support.FILE_PROVIDER_PATHS"
            android:resource="@xml/provider_paths" />
 </provider>

<?xml version="1.0" encoding="utf-8"?>
<cache-path
    name="my_files"
    path=""
/>

Теперь это работает! Спасибо большое ребята за помощь!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...