Прикрепление файла к электронной почте с помощью ContentProvider не работает - PullRequest
0 голосов
/ 06 мая 2019

Я хочу прикрепить файл, который я генерирую во время выполнения.

Поток времени выполнения:

  1. Создать намерение
  2. Создать файл в cacheDir
  3. Добавить файл как content:// дополнительно к цели
  4. Запустите chooser и выберите Gmail
  5. ожидайте, что будет вызван openFile(), и разрешите доступ
  6. Gmail открывается без вложений

Однако openFile() не вызывается.

Вот соответствующий код:

Создать намерение и добавить дополнения:

public static void contact(Activity activity, String message) {
    Intent emailIntent = new Intent(Intent.ACTION_SEND);
    emailIntent.setType("text/plain");

    String version = Version.appVersion(activity);
    emailIntent.putExtra(Intent.EXTRA_EMAIL, new String[]{activity.getString(R.string.contact_email)});
    emailIntent.putExtra(Intent.EXTRA_SUBJECT, activity.getString(R.string.app_name)+" ("+version+")");
    emailIntent.putExtra(Intent.EXTRA_TEXT, message);

    addInfoAttachment(emailIntent, activity);

    String title = activity.getString(R.string.string_select_email_app);
    activity.startActivity(Intent.createChooser(emailIntent, title));
}

Создать кешированный файл:

public static void createCachedFile(Context context, String fileName,
                                    String content) throws IOException 
{
    File cacheFile = new File(context.getCacheDir() + File.separator
            + fileName);
    cacheFile.delete();
    cacheFile.createNewFile();

    FileOutputStream fos = new FileOutputStream(cacheFile);
    OutputStreamWriter osw = new OutputStreamWriter(fos, "UTF8");
    PrintWriter pw = new PrintWriter(osw);
    pw.println(content);
    pw.flush();
    pw.close();
}

Добавить файл в намерение:

emailIntent.putExtra(Intent.EXTRA_STREAM, Uri.parse("content://" + AUTHORITY + File.separator + REPORT_INFO_FILE_NAME));

Переопределение ContentProvider: (не вызывается)

public class LogFileProvider extends ContentProvider {

    private static final String TAG = "LogFileProvider";

    public static final String AUTHORITY = "com.domain.appName.LogFileProvider";

    private UriMatcher uriMatcher;

    @Override
    public boolean onCreate() {
        uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
        uriMatcher.addURI(AUTHORITY, "*", 1);
        return true;
    }

    @Override
    public ParcelFileDescriptor openFile(@NonNull Uri uri, @NonNull String mode) throws FileNotFoundException {

        Log.v(TAG, "openFile Called with uri: '" + uri + "'." + uri.getLastPathSegment());

        // Check incoming Uri against the matcher
        switch (uriMatcher.match(uri)) {

            // If it returns 1 - then it matches the Uri defined in onCreate
            case 1:
                String fileLocation = getContext().getCacheDir() + File.separator
                        + uri.getLastPathSegment();
                return ParcelFileDescriptor.open(new File(
                        fileLocation), ParcelFileDescriptor.MODE_READ_ONLY);

            default:
                Log.v(TAG, "Unsupported uri: '" + uri + "'.");
                throw new FileNotFoundException("Unsupported uri: "
                        + uri.toString());
        }
    }

    // //////////////////////////////////////////////////////////////
    // Not supported / used / required for this example
    // //////////////////////////////////////////////////////////////

    @Override
    public int update(@NonNull Uri uri, ContentValues contentvalues, String s,
                      String[] as) {
        return 0;
    }

    @Override
    public int delete(@NonNull Uri uri, String s, String[] as) {
        return 0;
    }

    @Override
    public Uri insert(@NonNull Uri uri, ContentValues contentvalues) {
        return null;
    }

    @Override
    public String getType(@NonNull Uri uri) {
        return null;
    }

    @Override
    public Cursor query(@NonNull Uri uri, String[] projection, String s, String[] as1,
                        String s1) {
        return null;
    }
}

В манифесте:

<provider
    android:name=".LogFileProvider"
    android:authorities="com.domain.appName.LogFileProvider"
    android:enabled="true"
    android:exported="false"
    android:grantUriPermissions="true"/>

1 Ответ

1 голос
/ 06 мая 2019

Вам необходимо добавить FLAG_GRANT_READ_URI_PERMISSION к Intent.В нынешнем виде получатель не имеет прав на доступ к этому контенту.

Вы можете рассмотреть возможность использования FileProvider вместо того, чтобы беспокоиться о своем собственном.Некоторые клиенты ожидают, что провайдер будет делать больше, чем у вас (например, ответить на query() для OpenableColumns, ответить на getType() с фактическим типом MIME).

...