I have a requirement to send a apk file through share Intent and I have also implemented without any hassle. But the problem arises only while sending apk via GMail, I am getting permission denied while i try to attach. I really dont know what is happening with GMail. Kindly help me through your answers and solutions. Any Small hint and tips would also be useful for me. Thanks in advance
I am using following code to send APK using shared intents:
public static void appSend(ArrayList<File> files,Context context){
Intent shareIntent = new Intent(Intent.ACTION_SEND_MULTIPLE);
shareIntent.setType("application/vnd.android.package-archive");
shareIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);
ArrayList<Uri> uriFiles = new ArrayList<Uri> ();
for(File file: files) {
uriFiles.add (Uri.fromFile (file));
}
shareIntent.putParcelableArrayListExtra (Intent.EXTRA_STREAM, uriFiles);
try {
context.startActivity (Intent.createChooser (shareIntent, "Share via"));
} catch (android.content.ActivityNotFoundException ex) {
Toast.makeText (context, "There are no share applications installed.", Toast.LENGTH_SHORT).show();
}
}
Androidmanifest.xml:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.sample.share"
android:versionCode="2"
android:versionName="1.1">
<uses-permission android:name="android.permission.WRITE_INTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="ANDROID.PERMISSION.READ_EXTERNAL_STORAGE"/>
<uses-feature
android:glEsVersion="0x00020000"
android:required="true" />
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name">
<activity
android:name="com.sample.share.SplashActivity"
android:label="@string/app_name"
android:theme="@style/Theme.AppCompat.Light.NoActionBar.FullScreen">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name="com.sample.share.LandingScreenActivity"
android:label="@string/app_name"
android:theme="@style/Theme.AppCompat.Light.NoActionBar.FullScreen"/>
<activity
android:name="com.sample.share.MainActivity"
android:label="@string/app_name"
android:theme="@style/ShareToolbar"/>
</application>
</manifest>
Adapter class to fetch the list of apps present in the device
ShowAppsAdapter.java
public class ShowAppsAdapter extends RecyclerView.Adapter<ShowAppsAdapter.ViewHolder> implements Filterable{
private Context context;
private static List pkgAppsList;
private List pkgAppsListOriginal;
private int mLayout;
private ArrayList<File> mFileList;
static OnItemClickListener mItemClickListener;
private ItemFilter filter = new ItemFilter();
private HashMap<String,Boolean> itemChecked = new HashMap<String,Boolean>();
private Typeface tf;
public ShowAppsAdapter(Context context, List pkgAppsList, int layout, Typeface tf) {
this.context = context;
this.pkgAppsList = pkgAppsList;
this.pkgAppsListOriginal = pkgAppsList;
this.mLayout = layout;
this.mFileList = new ArrayList<File> ();
this.tf = tf;
for (int i = 0; i < this.getItemCount (); i++) {
itemChecked.put ((String) ((ResolveInfo) pkgAppsList.get (i)).loadLabel (context.getPackageManager ()), false); // initializes all items value with false
}
}
@Override
public ViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
View v = LayoutInflater.from(viewGroup.getContext()).inflate(mLayout, viewGroup, false);
return new ViewHolder(v);
}
@Override
public void onBindViewHolder(final ViewHolder holder, final int position) {
final ResolveInfo info = (ResolveInfo) pkgAppsList.get(position);
final File file = new File(info.activityInfo.applicationInfo.publicSourceDir);
String appSize= (Utils.getFileSize(context, info.activityInfo.applicationInfo.sourceDir));
holder.txtAppName.setText(info.loadLabel(context.getPackageManager()));
holder.txtAppSize.setText(/*info.activityInfo.packageName*/""+appSize);
holder.txtAppName.setTypeface(tf);
holder.txtAppSize.setTypeface(tf);
holder.txtAppIcon.setImageDrawable(info.loadIcon(context.getPackageManager()));
holder.chkTick.setChecked(itemChecked.get(info.loadLabel (context.getPackageManager ())));
holder.chkTick.setOnClickListener (new View.OnClickListener () {
@Override
public void onClick (View view) {
toggleSelected((String) info.loadLabel (context.getPackageManager ()), holder.chkTick.isChecked(), file);
}
});
}
private void toggleSelected (String name, boolean b, File file) {
itemChecked.put (name,b);
if(b){
addAppList(file);
}else{
removeAppList(file);
}
}
private void addAppList (File file) {
mFileList.add (file);
}
private void removeAppList (File file) {
mFileList.remove (file);
}
public ArrayList<File> getAppList(){
return mFileList;
}
@Override
public int getItemCount() {
return pkgAppsList == null ? 0 : pkgAppsList.size();
}
@Override
public Filter getFilter () {
return filter;
}
public static class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
TextView txtAppName;
TextView txtAppSize;
ImageView txtAppIcon;
CheckBox chkTick;
public ViewHolder(View itemView) {
super(itemView);
txtAppName = (TextView)itemView.findViewById(R.id.text_app_name);
txtAppSize = (TextView)itemView.findViewById(R.id.txt_app_size);
txtAppIcon = (ImageView)itemView.findViewById(R.id.img_app_icon);
chkTick = (CheckBox)itemView.findViewById (R.id.chk_tick);
itemView.setOnClickListener(this);
}
@Override
public void onClick(View v) {
mItemClickListener.onItemClick(v, getAdapterPosition (),((ResolveInfo)pkgAppsList.get (getAdapterPosition ()))); //OnItemClickListener mItemClickListener;
}
}
public interface OnItemClickListener {
public void onItemClick (View view, int position, ResolveInfo o);
}
public void SetOnItemClickListener(final OnItemClickListener mItemClickListener) {
this.mItemClickListener = mItemClickListener;
}
@Override
public long getItemId(int i) {
return i;
}
private class ItemFilter extends Filter{
@Override
protected FilterResults performFiltering (CharSequence charSequence) {
String searchString = charSequence.toString ().toLowerCase ();
FilterResults results = new FilterResults();
final List list = pkgAppsListOriginal;
int count = list.size();
final List nlist = new ArrayList<ResolveInfo>(count);
String filterableString ;
for (int i = 0; i < count; i++) {
final ResolveInfo info = (ResolveInfo) pkgAppsListOriginal.get(i);
filterableString = (String) info.loadLabel (context.getPackageManager ());
if (filterableString.toLowerCase().contains(searchString)) {
nlist.add(pkgAppsListOriginal.get (i));
}
}
results.values = nlist;
results.count = nlist.size();
return results;
}
@Override
protected void publishResults (CharSequence charSequence, FilterResults filterResults) {
pkgAppsList = (List) filterResults.values;
notifyDataSetChanged ();
}
}
}