This is a continuation of my
previous post
in which I explained in detail on how to share a Text (corresponding raw data) from RecyclerView to other application using share Intent . In this project we can extend the same concept to share the image from RecyclerView to other application using a FileProvider class.
This was the design of the page which we used in the previous post:
A FileProvider is a subclass of Content Provider..File Provider is used specifically for sharing the app’s internal Files ,While Content Provider is a component that enables you to securely share any type of data by providing third party apps access to the content that’s stored as file in internal storage space.
So Let’s see how to use this FileProvider to share data from RecyclerView.
In order to use FileProvider in Project :
1. Define the FileProvider in your AndroidManifest file
2. Create an XML file that contains all paths that the FileProvider will share with other applications
Define the FileProvider in your AndroidManifest file:
The first step is to include the File Provider in Android manifest file as shown in Figure:
It is just like a unique identifier , Basically Android System keeps a list of Providers and the Authority attribute helps to distinguish these providers
. You can either use your package name as this attribute or set the value as ${applicationId}. If you are using ${applicationId} then it automatically set project package name: ${applicationId}.myfileprovider as attribute value.
2.
android:exported
This is the attribute which defines whether any other application can access the content provider or not. The default value for this attribute is TRUE. in order to control the access you have to set the attribute value as FALSE.
3.android:grantUriPermissions:
This attribute allows you to securely share your app’s internal storage to other applications,
I.e This attribute defines a permission that controls
both read and write access to the whole of the Content provider(storage space)
.
Here we are specifying the permissions (read/write) that we enables to other applications .
After that define a meta-data tag which define the path to the XML file ( xml file that we are going to create in the next step ) which contains all data paths that the FileProvider can share with external apps.
Create an XML file that contains all paths that the FileProvider will share with other applications:
First Create XML Directory in res as shown in the Figure: res >New >Android Directory
Then select Resource Type as xml . After that create xml file inside the directory XML > NEW > Resource XML file:
Screen Shots Below,
This code , allows the FileProvider to share all files that are inside the app’s internal cache and files directory.
After including the File Provider in project next we can use this to share data to other applications.In this project I will show you how to share image using FileProvider.As already explained in the
previous post
, in order to share data, you need to add a share intent function. For that inside onBindViewHolder method make the share button clickable by using Android SetOnClickListener method.
image_share.java
@Override
public void onBindViewHolder(@NonNull final MyViewHolder holder, final int position) {
final HashMap < String, String > Details = dataSet.get(position);
holder.share.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// create file from drawable image
Bitmap bm = BitmapFactory.decodeResource(context.getResources(), Integer.parseInt(Details.get("Bimage")));
File filesDir = context.getApplicationContext().getFilesDir();
File imageFile = new File(filesDir, "birdimg.png");
OutputStream os;
try {
os = new FileOutputStream(imageFile);
bm.compress(Bitmap.CompressFormat.PNG, 100, os);
os.flush();
os.close();
} catch (Exception e) {
Log.e(getClass().getSimpleName(), "Error writing bitmap", e);
Intent intent = new Intent();
intent.setAction(Intent.ACTION_SEND);
intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
Uri imageUri = FileProvider.getUriForFile(context, BuildConfig.APPLICATION_ID, imageFile);
intent.putExtra(Intent.EXTRA_STREAM, imageUri);
intent.setType("image/png");
context.startActivity(intent);
Since we saved our image as a drawable, we need to create a bitmap (
Details.get(“Bimage”)
is HashMap that hold current position of the image.) and compress the image as PNG and save to the app’s cache.
Specify the intent type that is Intent.ACTION_SEND type used to share data. then set flag to give temporary permission to external app to use your FileProvider and using the method
FileProvider.getUriForFile
we can
generate a secure URI
(therefore a unique identifier) pointing to our file.
we use PUTEXTRA method to pass data which we want to share (In this case image data ) & set the share type specifying the type of data we share ( Image/png )
Finally start the activity with Intent. createchooser which is used to get the list of installed application which you can use to share the data
complete code for
DataAdapter.java
package com.xxxxxxxxxxxxxxxxxxx.recyclerviewimageshare;
import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.core.content.FileProvider;
import androidx.recyclerview.widget.RecyclerView;
import java.io.File;
import java.io.FileOutputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.HashMap;
public class mDataAdapter extends RecyclerView.Adapter < mDataAdapter.MyViewHolder > {
private ArrayList < HashMap < String,
String >> dataSet;
Context context;
public mDataAdapter(Context context, ArrayList < HashMap < String, String >> dataSet) {
this.dataSet = dataSet;
this.context = context;
@NonNull
@Override
public MyViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext())
.inflate(R.layout.recycler_data, parent, false);
return new MyViewHolder(v);
@Override
public void onBindViewHolder(@NonNull final MyViewHolder holder, final int position) {
final HashMap < String, String > Details = dataSet.get(position);
holder.bName.setText(Details.get("Bname"));
holder.bImage.setImageResource(Integer.parseInt((Details.get("Bimage"))));
holder.visit.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
final String website = Details.get("Burl");
Intent browserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(website));
context.startActivity(browserIntent);
holder.share.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// create file from drawable image
Bitmap bm = BitmapFactory.decodeResource(context.getResources(), Integer.parseInt(Details.get("Bimage")));
File filesDir = context.getApplicationContext().getFilesDir();
File imageFile = new File(filesDir, "birds.png");
OutputStream os;
try {
os = new FileOutputStream(imageFile);
bm.compress(Bitmap.CompressFormat.PNG, 100, os); // 100% quality
os.flush();
os.close();
} catch (Exception e) {
Log.e(getClass().getSimpleName(), "Error writing bitmap", e);
Intent intent = new Intent();
intent.setAction(Intent.ACTION_SEND);
intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
Uri imageUri = FileProvider.getUriForFile(context, BuildConfig.APPLICATION_ID, imageFile);
intent.putExtra(Intent.EXTRA_STREAM, imageUri);
intent.setType("image/*");
context.startActivity(intent);
@Override
public int getItemCount() {
return (dataSet == null) ? 0 : dataSet.size();
public class MyViewHolder extends RecyclerView.ViewHolder {
TextView bName;
ImageView bImage;
Button visit;
Button share;
MyViewHolder(@NonNull View itemView) {
super(itemView);
bName = (TextView) itemView.findViewById(R.id.bName);
bImage = (ImageView) itemView.findViewById(R.id.bImage);
visit = (Button) itemView.findViewById(R.id.website);
share = (Button) itemView.findViewById(R.id.share);
Complete code for this project is available
here
.
Happy Coding
Preethi
I have had multiple incarnations. I worked as a Researcher, Lecturer and as a Developer, but one thing has always been a constant, my passion for Computer Science. This is my first attempt at writing a blog, I believe I can do Justice to this endeavor as well as I was able to contribute to all my previous incarnations and would be able to call myself in future as a Blogger and someone who helps in someway to make technology more accessible and interesting to learn.
View Archive
→
Privacy & Cookies: This site uses cookies. By continuing to use this website, you agree to their use.
To find out more, including how to control cookies, see here:
Cookie Policy