Skip to content

Instantly share code, notes, and snippets.

@metalwihen
Last active November 21, 2019 10:43
Show Gist options
  • Save metalwihen/8ff306fc0332ac19529ffd2bc259ab84 to your computer and use it in GitHub Desktop.
Save metalwihen/8ff306fc0332ac19529ffd2bc259ab84 to your computer and use it in GitHub Desktop.
Android N Changes - FileProvider

Changes to be made in AndroidManifest.xml

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<provider
    android:name="android.support.v4.content.FileProvider"
    android:authorities="${applicationId}.provider"
    android:exported="false"
    android:grantUriPermissions="true">
    <meta-data
        android:name="android.support.FILE_PROVIDER_PATHS"
        android:resource="@xml/provider_paths" />
</provider>

Changes to be made in /res/xml/

Add xml file, provider_paths.xml

<?xml version="1.0" encoding="utf-8"?>
<paths>
    <external-path
        name="downloads"
        path="/Download" />
    <cache-path
        name="cache"
        path="/" />
    <files-path
        name="files"
        path="/" />
</paths>

Check if suitable permissions allowed

if (isPermitted()) {
    // save attachment
} else {
    Toast.makeText(getActivity(), R.string.msg_allow_permission_to_download_attachments, Toast.LENGTH_SHORT).show();
}
private static final int REQUEST_ATTACH_FILE = 201;

private boolean isPermitted() {
    // Here, thisActivity is the current activity
    if (ContextCompat.checkSelfPermission(getActivity(), Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
        // Permission is not granted
        // Should we show an explanation?
        if (!ActivityCompat.shouldShowRequestPermissionRationale(getActivity(), Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
            // No explanation needed; request the permission
            ActivityCompat.requestPermissions(getActivity(), new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, REQUEST_ATTACH_FILE);
        }

        return false;
    } else {
        // Permission has already been granted
        return true;
    }
}

@Override
public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
    switch (requestCode) {
        case REQUEST_ATTACH_FILE: {
            // If request is cancelled, the result arrays are empty.
            if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                Toast.makeText(getActivity(), R.string.msg_permission_granted, Toast.LENGTH_SHORT).show();
            } else {
                Toast.makeText(getActivity(), R.string.msg_allow_permission_to_download_attachments, Toast.LENGTH_SHORT).show();
            }
            return;
        }
    }
}

Open file picker to attach file

public void onMenuAttach() {
    if (FileUtils.isPermitted(this)) {
        Intent intentBrowseFiles = new Intent(Intent.ACTION_GET_CONTENT);
        intentBrowseFiles.setType("*/*");
        intentBrowseFiles.addCategory(Intent.CATEGORY_OPENABLE);
        startActivityForResult(intentBrowseFiles, REQUEST_SELECT_FILE);
    } else {
        Toast.makeText(this, R.string.msg_allow_permission_to_download_attachments, Toast.LENGTH_SHORT).show();
    }
}

Save new file (to be opened later)

public static File getNewCacheFile(Context context, String name) throws IOException {
  String state = Environment.getExternalStorageState();
  if (Environment.MEDIA_MOUNTED.equals(state)) {
    File cacheDir = new File(Environment.getExternalStorageDirectory(), "Download");
    cacheDir.mkdirs();
    File file = new File(cacheDir, name);
    return file;
  } else {
    // Functionality changed. Should not be called now.
    return new File(context.getCacheDir(), name);
  }
}

Open attachment in external App

    private void viewAttachment(File file, String type, int attachmentId) {
        Uri photoURI = FileProvider.getUriForFile(getActivity(), BuildConfig.APPLICATION_ID + ".provider", file);

        Intent intent = new Intent();
        intent.setAction(Intent.ACTION_VIEW);
        intent.setDataAndType(photoURI, type);
        intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_ACTIVITY_NEW_TASK);

        try {
            getActivity().startActivity(intent);
        } catch (ActivityNotFoundException e) {
            AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
            builder.setMessage(R.string.dlg_open_attachment_error);
            builder.setNeutralButton(R.string.btn_ok, new DialogInterface.OnClickListener() {
                public void onClick(DialogInterface dialog, int which) {
                    dialog.dismiss();
                }
            });
            builder.show();
        }
    }

References

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment