I thought I'd share a snippet of the code on my blog as it could be useful for some. Feel free to ask any questions about the inner workings of it, otherwise I'll leave it up to you to read and understand. Please be aware I stripped some code out so I haven't actually ran the exact code below on my phone.
public void startDefaultAppOrPromptUserForSelection() { String action = Intent.ACTION_SEND; // Get list of handler apps that can send Intent intent = new Intent(action); intent.setType("image/jpeg"); PackageManager pm = getPackageManager(); List<ResolveInfo> resInfos = pm.queryIntentActivities(intent, 0); boolean useDefaultSendApplication = sPrefs.getBoolean("useDefaultSendApplication", false); if (!useDefaultSendApplication) { // Referenced http://stackoverflow.com/questions/3920640/how-to-add-icon-in-alert-dialog-before-each-item // Class for a singular activity item on the list of apps to send to class ListItem { public final String name; public final Drawable icon; public final String context; public final String packageClassName; public ListItem(String text, Drawable icon, String context, String packageClassName) { this.name = text; this.icon = icon; this.context = context; this.packageClassName = packageClassName; } @Override public String toString() { return name; } } // Form those activities into an array for the list adapter final ListItem[] items = new ListItem[resInfos.size()]; int i = 0; for (ResolveInfo resInfo : resInfos) { String context = resInfo.activityInfo.packageName; String packageClassName = resInfo.activityInfo.name; CharSequence label = resInfo.loadLabel(pm); Drawable icon = resInfo.loadIcon(pm); items[i] = new ListItem(label.toString(), icon, context, packageClassName); i ; } ListAdapter adapter = new ArrayAdapter<ListItem>( this, android.R.layout.select_dialog_item, android.R.id.text1, items){ public View getView(int position, View convertView, ViewGroup parent) { // User super class to create the View View v = super.getView(position, convertView, parent); TextView tv = (TextView)v.findViewById(android.R.id.text1); // Put the icon drawable on the TextView (support various screen densities) int dpS = (int) (32 * getResources().getDisplayMetrics().density 0.5f); items[position].icon.setBounds(0, 0, dpS, dpS); tv.setCompoundDrawables(items[position].icon, null, null, null); // Add margin between image and name (support various screen densities) int dp5 = (int) (5 * getResources().getDisplayMetrics().density 0.5f); tv.setCompoundDrawablePadding(dp5); return v; } }; // Build the list of send applications AlertDialog.Builder builder = new AlertDialog.Builder(this); builder.setTitle("Choose your app:"); builder.setIcon(R.drawable.dialog_icon); CheckBox checkbox = new CheckBox(getApplicationContext()); checkbox.setText(getString(R.string.enable_default_send_application)); checkbox.setOnCheckedChangeListener(new OnCheckedChangeListener() { // Save user preference of whether to use default send application @Override public void onCheckedChanged(CompoundButton paramCompoundButton, boolean paramBoolean) { SharedPreferences.Editor editor = sPrefs.edit(); editor.putBoolean("useDefaultSendApplication", paramBoolean); editor.commit(); } }); builder.setView(checkbox); builder.setOnCancelListener(new OnCancelListener() { @Override public void onCancel(DialogInterface paramDialogInterface) { // do something } }); // Set the adapter of items in the list builder.setAdapter(adapter, new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { SharedPreferences.Editor editor = sPrefs.edit(); editor.putString("defaultSendApplicationName", items[which].name); editor.putString("defaultSendApplicationPackageContext", items[which].context); editor.putString("defaultSendApplicationPackageClassName", items[which].packageClassName); editor.commit(); dialog.dismiss(); // Start the selected activity sending it the URLs of the resized images Intent intent; intent = new Intent(Intent.ACTION_SEND); intent.setType("image/jpeg"); intent.setClassName(items[which].context, items[which].packageClassName); startActivity(intent); finish(); } }); AlertDialog dialog = builder.create(); dialog.show(); } else { // Start the default send application // Get default app name saved in preferences String defaultSendApplicationName = sPrefs.getString("defaultSendApplicationName", "<null>"); String defaultSendApplicationPackageContext = sPrefs.getString("defaultSendApplicationPackageContext", "<null>"); String defaultSendApplicationPackageClassName = sPrefs.getString("defaultSendApplicationPackageClassName", "<null>"); if (defaultSendApplicationPackageContext == "<null>" || defaultSendApplicationPackageClassName == "<null>") { Toast.makeText(getApplicationContext(), "Can't find app: " defaultSendApplicationName " (" defaultSendApplicationPackageClassName ")", Toast.LENGTH_LONG).show(); // don't have default application details in prefs file so set use default app to null and rerun this method SharedPreferences.Editor editor = sPrefs.edit(); editor.putBoolean("useDefaultSendApplication", false); editor.commit(); startDefaultAppOrPromptUserForSelection(); return; } // Check app is still installed try { ApplicationInfo info = getPackageManager().getApplicationInfo(defaultSendApplicationPackageContext, 0); } catch (PackageManager.NameNotFoundException e){ Toast.makeText(getApplicationContext(), "Can't find app: " defaultSendApplicationName " (" defaultSendApplicationPackageClassName ")", Toast.LENGTH_LONG).show(); // don't have default application installed so set use default app to null and rerun this method SharedPreferences.Editor editor = sPrefs.edit(); editor.putBoolean("useDefaultSendApplication", false); editor.commit(); startDefaultAppOrPromptUserForSelection(); return; } // Start the selected activity intent = new Intent(Intent.ACTION_SEND); intent.setType("image/jpeg"); intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); intent.setClassName(defaultSendApplicationPackageContext, defaultSendApplicationPackageClassName); startActivity(intent); finish(); return; } }
Excellent, thanks a lot for this
ReplyDeleteNice tutorial, very very useful to me. Many thanks!
ReplyDeletecould be please share this particular project? i mean only the 'set this as default application' working project?
ReplyDeleteSorry I don't have a project just for that and cannot share any of the other source code. If you have any questions please ask here and I'll try and help.
DeletesPrefs? What is this adressed for, getting error on some places after importing everything fine?
ReplyDeleteand density is given in 0.5f, it showing error too.
please make this tutorial more understandable by adding a share button implementation to it.
ReplyDeletei am getting error at this line in log:
boolean useDefaultSendApplication = sPrefs.getBoolean("useDefaultSendApplication", false);
trying to solve it but it still giving errors.
a little help will be appreciated.
Thanks in advance.
Thanks a lot, i found this article really useful
ReplyDeletei copied the code and it was working but now the checkbox no longef shows. might therd be a verson dependency?
ReplyDelete