create a share intent with respect to sms messages - android

background
it's very common to share content by using intents:
final Intent shareIntent = new Intent(Intent.ACTION_SEND);
shareIntent.setType("text/plain");
shareIntent.putExtra(Intent.EXTRA_TEXT, "msg");
shareIntent.putExtra(Intent.EXTRA_SUBJECT, "subject");
final Intent chooserIntent = Intent.createChooser(shareIntent, "Share using...");
startActivity(chooserIntent);
it's even possible to add receipients to the same sharing intent :
shareIntent.putExtra(Intent.EXTRA_EMAIL, new String[] { email });
shareIntent.putExtra(Intent.EXTRA_PHONE_NUMBER, new String[] { phoneNumber });
problem
the problem is the content of the message itself. on SMS, messages can cost money, so it's important to keep them short in order to send only a single message instead of multiple messages.
so you might say , just keep the message short, but i would like to be able to do both - create a fancy message for all apps (maybe add embed images and links), except that if it's for SMS, make it short.
what i've done is to create a dialog with the intents to be used, while for sms i simply set the message to be shorter.
question
how can i do it?
i've tried the next code , but it for some reason it doesn't show the phone number for sms sending.
here's the code:
create and show the dialog:
final String phoneNumber = "12346556", email = "test#gmail.com";
final String smsMessage="sms", message="message", title="title";
final PackageManager pm = getPackageManager();
//
final Uri uri = Uri.parse("smsto:" + phoneNumber);
final Intent smsIntent = new Intent(Intent.ACTION_SENDTO, uri);
smsIntent.setType("vnd.android-dir/mms-sms");
smsIntent.putExtra("sms_body", smsMessage);
smsIntent.putExtra("address", new String[] { phoneNumber });
final List<ResolveInfo> smsResInfo = pm.queryIntentActivities(smsIntent, 0);
final Set<String> smsPackages = new HashSet<String>();
for (final ResolveInfo ri : smsResInfo)
smsPackages.add(ri.activityInfo.packageName + ri.activityInfo.name);
//
final Intent shareIntent = new Intent(Intent.ACTION_SEND);
shareIntent.setType("text/plain");
shareIntent.putExtra(Intent.EXTRA_SUBJECT, title);
shareIntent.putExtra(Intent.EXTRA_TEXT, message);
shareIntent.putExtra(Intent.EXTRA_EMAIL, new String[] { email });
shareIntent.putExtra(Intent.EXTRA_PHONE_NUMBER, new String[] { phoneNumber });
final List<ResolveInfo> shareResInfo = pm.queryIntentActivities(shareIntent, 0);
//
final List<ResolveInfo> mergedResInfo = new ArrayList<ResolveInfo>(smsResInfo);
for (final ResolveInfo resolveInfo : shareResInfo) {
if (smsPackages.contains(resolveInfo.activityInfo.packageName + resolveInfo.activityInfo.name))
continue;
mergedResInfo.add(resolveInfo);
}
//
final AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this);
final String[] items = new String[mergedResInfo.size()];
for (int i = 0; i < mergedResInfo.size(); i++) {
final ResolveInfo resolveInfo = mergedResInfo.get(i);
items[i] = resolveInfo.loadLabel(pm).toString();
}
//
final ListAdapter adapter = new ArrayAdapterWithIcon(MainActivity.this, items, mergedResInfo);
builder.setTitle("Select app").setAdapter(adapter, new DialogInterface.OnClickListener() {
#Override
public void onClick(final DialogInterface dialog, final int item) {
final ResolveInfo resolveInfo = mergedResInfo.get(item);
Intent intent;
if (smsPackages.contains(resolveInfo.activityInfo.packageName + resolveInfo.activityInfo.name))
intent = smsIntent;
else
intent = shareIntent;
intent.setClassName(resolveInfo.activityInfo.packageName, resolveInfo.activityInfo.name);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_NO_HISTORY
| Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);
startActivity(intent);
}
}).show();
ArrayAdapterWithIcon class:
public class ArrayAdapterWithIcon extends ArrayAdapter<String> {
private final List<ResolveInfo> mMergedResInfo;
public ArrayAdapterWithIcon(final MainActivity context, final String[] items,
final List<ResolveInfo> mergedResInfo) {
super(context, android.R.layout.select_dialog_item, items);
this.mMergedResInfo = mergedResInfo;
}
#Override
public View getView(final int position, final View convertView, final ViewGroup parent) {
final View view = super.getView(position, convertView, parent);
final TextView textView = (TextView) view.findViewById(android.R.id.text1);
final Drawable icon = mMergedResInfo.get(position).loadIcon(getPackageManager());
textView.setCompoundDrawablesWithIntrinsicBounds(icon, null, null, null);
textView.setCompoundDrawablePadding((int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 12,
getContext().getResources().getDisplayMetrics()));
return view;
}
}
what can i do in order to fix this code?

ok ,the problem is with those lines:
final Intent smsIntent = new Intent(Intent.ACTION_SENDTO, uri);
smsIntent.putExtra("address", new String[] { phoneNumber });
should be:
final Intent smsIntent = new Intent(Intent.ACTION_VIEW);
smsIntent.putExtra("address", phoneNumber);
if you need to send to more numbers, just add "," between them.
i also think the part with the EXTRA_PHONE_NUMBER isn't needed.

Related

Android share image and text on twitter wall using Intent

I have used following code for sharing image and text both on twitter wall. Please help me why following code is not working in my application? Launcher activity opens but it display only text and not showing image. And also share text only instead of both image and text.
Intent share = new Intent(Intent.ACTION_SEND);
share.setType("image/*");
final PackageManager pm = mainActivity.getPackageManager();
#SuppressWarnings("rawtypes")
final List activityList = pm.queryIntentActivities(share, 0);
int len = activityList.size();
for (int i = 0; i < len; i++)
{
final ResolveInfo app = (ResolveInfo) activityList.get(i);
Log.print("Packages", app.activityInfo.name);
if (app.activityInfo.packageName.startsWith("com.twitter.android"))
{
Log.print(":::: Twitter Share Name Activity ::: " + (app.activityInfo.name).toString());
try
{
final ActivityInfo activity = app.activityInfo;
final ComponentName name = new ComponentName(activity.applicationInfo.packageName, activity.name);
share.addCategory(Intent.CATEGORY_LAUNCHER);
share.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);
share.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
share.setComponent(name);
share.putExtra(Intent.EXTRA_TEXT, Pref.getValue(mainActivity, Labels.TITLE, ""));
share.putExtra(Intent.EXTRA_STREAM, new URI(new URL(imgUrl).toString()));
startActivity(share);
}
catch (Exception e)
{
e.printStackTrace();
Log.error(":::: Twitter image path Exception::::", e.toString());
}
break;
}
}

Share image to only twitter by intent.action_send error

I use code as follow to share image to twitter but when display screen of twitter app to input text and image,it only display text ,image don't display.
public void shareImageByTwitter(Context mContext, String path) {
File myFile = new File(path);
final String[] twitterApps = {
// package // name - nb installs (thousands)
"com.twitter.android", "com.twidroid",
"com.handmark.tweetcaster", "com.thedeck.android" };
Intent tweetIntent = new Intent();
tweetIntent.setType("image/jpeg");
tweetIntent.putExtra(Intent.EXTRA_STREAM, Uri.fromFile(myFile));
final PackageManager packageManager = mContext.getPackageManager();
List<ResolveInfo> list = packageManager.queryIntentActivities(
tweetIntent,0);
for (int i = 0; i < twitterApps.length; i++) {
for (ResolveInfo resolveInfo : list) {
String p = resolveInfo.activityInfo.packageName;
if (p != null && p.startsWith(twitterApps[i])) {
tweetIntent.setPackage(p);
}
}
}
mContext.startActivity(tweetIntent);
}
How must I do.

Styling the Share Action Provider in Android

Here is how I share the content through Share Action Provider:
Intent sendIntent = new Intent();
sendIntent.setAction(Intent.ACTION_SEND);
sendIntent.putExtra(Intent.EXTRA_TEXT,
"Check the Link : " + url);
sendIntent.setType("text/plain");
startActivity(Intent.createChooser(sendIntent, "Share with"));
I want to style the share with window. I want to change the text color and highlighter line color from default blue color to my custom color. I am using Holo light theme. I don't know how to style those elements. Can anyone point out a reference to do that?
Is there a way to access attributes of android.widget.ShareActionProvider through styling?
I don't know how to style the dialog, i have seen different layouts in different devices. But you can use PackageManager.queryIntentActivities(Intent intent, int flag) to get all activities that could handle this intent. And use the list data to create your own chooser.
EDIT: a demo
final Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setData(Uri.parse("http://www.google.com"));
PackageManager pm = getPackageManager();
final List<ResolveInfo> infos = pm.queryIntentActivities(intent,
PackageManager.MATCH_DEFAULT_ONLY);
CharSequence[] names = new CharSequence[infos.size()];
for (int i = 0; i < infos.size(); i++) {
names[i] = infos.get(i).loadLabel(pm);
}
new AlertDialog.Builder(this).setItems(names,
new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
ResolveInfo info = infos.get(which);
intent.setClassName(info.activityInfo.packageName,
info.activityInfo.name);
startActivity(intent);
}
}).show();
As far as I know, you cannot style the chooser dialog. It is a system-level actvity, and uses the default system theme.
You can also use like this
final Intent intent = new Intent(Intent.ACTION_SEND);
intent.setType("text/plain");
intent.putExtra(android.content.Intent.EXTRA_SUBJECT,getString(R.string.app_name));
intent.putExtra(android.content.Intent.EXTRA_TEXT,getString(R.string.tell_your_frnd));
PackageManager pm = getPackageManager();
final List<ResolveInfo> infos = pm.queryIntentActivities(intent,
PackageManager.MATCH_DEFAULT_ONLY);
name = new String[infos.size()];
image=new Drawable[infos.size()];
for (int i = 0; i < infos.size(); i++)
{
name[i] = (String) infos.get(i).loadLabel(pm);
image[i]=infos.get(i).loadIcon(pm);
}
CustomGrid adapter = new CustomGrid(ShareActivity.this,name,image);
mGridView.setAdapter(adapter);
mGridView.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view,int position, long id)
{
ResolveInfo info = infos.get(position);
intent.setClassName(info.activityInfo.packageName,
info.activityInfo.name);
startActivity(intent);
}
});

Send attachment with SMS [duplicate]

I am working on a multimedia application. I am capturing one image through the camera and want to send that image with a text to some other number. But I am not getting how to send the image via the MMS.
MMS is just a htttp-post request. You should perform the request using extra network feature :
final ConnectivityManager connMgr = (ConnectivityManager)context.getSystemService(Context.CONNECTIVITY_SERVICE);
final int result = connMgr.startUsingNetworkFeature( ConnectivityManager.TYPE_MOBILE, Phone.FEATURE_ENABLE_MMS);
If you get result with Phone.APN_REQUEST_STARTED value, you have to wait for proper state. Register BroadCastReciver and wait until Phone.APN_ALREADY_ACTIVE appears:
final IntentFilter filter = new IntentFilter();
filter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
context.registerReceiver(reciver, filter);
If connection background is ready, build content and perform request. If you want to do that using android's internal code, please use this:
final SendReq sendRequest = new SendReq();
final EncodedStringValue[] sub = EncodedStringValue.extract(subject);
if (sub != null && sub.length > 0) {
sendRequest.setSubject(sub[0]);
}
final EncodedStringValue[] phoneNumbers = EncodedStringValue
.extract(recipient);
if (phoneNumbers != null && phoneNumbers.length > 0) {
sendRequest.addTo(phoneNumbers[0]);
}
final PduBody pduBody = new PduBody();
if (parts != null) {
for (MMSPart part : parts) {
final PduPart partPdu = new PduPart();
partPdu.setName(part.Name.getBytes());
partPdu.setContentType(part.MimeType.getBytes());
partPdu.setData(part.Data);
pduBody.addPart(partPdu);
}
}
sendRequest.setBody(pduBody);
final PduComposer composer = new PduComposer(this.context, sendRequest);
final byte[] bytesToSend = composer.make();
HttpUtils.httpConnection(context, 4444L, MMSCenterUrl,
bytesToSendFromPDU, HttpUtils.HTTP_POST_METHOD, !TextUtils
.isEmpty(MMSProxy), MMSProxy, port);
MMSCenterUrl: url from MMS-APNs, MMSProxy: proxy from MMS-APNs, port: port from MMS-APNs
Note that some classes are from internal packages. Download from android git is required.
The request should be done with url from user's apn-space...code..:
public class APNHelper {
public class APN {
public String MMSCenterUrl = "";
public String MMSPort = "";
public String MMSProxy = "";
}
public APNHelper(final Context context) {
this.context = context;
}
public List<APN> getMMSApns() {
final Cursor apnCursor = this.context.getContentResolver().query(Uri.withAppendedPath(Telephony.Carriers.CONTENT_URI, "current"), null, null, null, null);
if ( apnCursor == null ) {
return Collections.EMPTY_LIST;
} else {
final List<APN> results = new ArrayList<APN>();
if ( apnCursor.moveToFirst() ) {
do {
final String type = apnCursor.getString(apnCursor.getColumnIndex(Telephony.Carriers.TYPE));
if ( !TextUtils.isEmpty(type) && ( type.equalsIgnoreCase(Phone.APN_TYPE_ALL) || type.equalsIgnoreCase(Phone.APN_TYPE_MMS) ) ) {
final String mmsc = apnCursor.getString(apnCursor.getColumnIndex(Telephony.Carriers.MMSC));
final String mmsProxy = apnCursor.getString(apnCursor.getColumnIndex(Telephony.Carriers.MMSPROXY));
final String port = apnCursor.getString(apnCursor.getColumnIndex(Telephony.Carriers.MMSPORT));
final APN apn = new APN();
apn.MMSCenterUrl = mmsc;
apn.MMSProxy = mmsProxy;
apn.MMSPort = port;
results.add(apn);
}
} while ( apnCursor.moveToNext() );
}
apnCursor.close();
return results;
}
}
private Context context;
}
This seems to be answered in the post: Sending MMS with Android
Key lines of code being:
Intent sendIntent = new Intent(Intent.ACTION_SEND);
sendIntent.putExtra("sms_body", "some text");
sendIntent.putExtra(Intent.EXTRA_STREAM, Uri.parse(url));
sendIntent.setType("image/png");
If you have to send MMS with any Image using Intent then use this code.
Intent sendIntent = new Intent(Intent.ACTION_SEND);
sendIntent.setClassName("com.android.mms", "com.android.mms.ui.ComposeMessageActivity");
sendIntent.putExtra("sms_body", "some text");
sendIntent.putExtra(Intent.EXTRA_STREAM, Uri.parse("file:///sdcard/image_4.png"));
sendIntent.setType("image/png");
startActivity(sendIntent);;
OR
If you have to send MMS with Audio or Video file using Intent then use this.
Intent sendIntent = new Intent(Intent.ACTION_SEND);
sendIntent.setClassName("com.android.mms", "com.android.mms.ui.ComposeMessageActivity");
sendIntent.putExtra("address", "1213123123");
sendIntent.putExtra("sms_body", "if you are sending text");
final File file1 = new File(mFileName);
if(file1.exists()){
System.out.println("file is exist");
}
Uri uri = Uri.fromFile(file1);
sendIntent.putExtra(Intent.EXTRA_STREAM, uri);
sendIntent.setType("video/*");
startActivity(sendIntent);
let me know if this help you.
The answer with the APN helper will not work after android 4.0. To get mms apn settings on Android 4.0 and above view this answer: View mms apn

How to send image via MMS in Android?

I am working on a multimedia application. I am capturing one image through the camera and want to send that image with a text to some other number. But I am not getting how to send the image via the MMS.
MMS is just a htttp-post request. You should perform the request using extra network feature :
final ConnectivityManager connMgr = (ConnectivityManager)context.getSystemService(Context.CONNECTIVITY_SERVICE);
final int result = connMgr.startUsingNetworkFeature( ConnectivityManager.TYPE_MOBILE, Phone.FEATURE_ENABLE_MMS);
If you get result with Phone.APN_REQUEST_STARTED value, you have to wait for proper state. Register BroadCastReciver and wait until Phone.APN_ALREADY_ACTIVE appears:
final IntentFilter filter = new IntentFilter();
filter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
context.registerReceiver(reciver, filter);
If connection background is ready, build content and perform request. If you want to do that using android's internal code, please use this:
final SendReq sendRequest = new SendReq();
final EncodedStringValue[] sub = EncodedStringValue.extract(subject);
if (sub != null && sub.length > 0) {
sendRequest.setSubject(sub[0]);
}
final EncodedStringValue[] phoneNumbers = EncodedStringValue
.extract(recipient);
if (phoneNumbers != null && phoneNumbers.length > 0) {
sendRequest.addTo(phoneNumbers[0]);
}
final PduBody pduBody = new PduBody();
if (parts != null) {
for (MMSPart part : parts) {
final PduPart partPdu = new PduPart();
partPdu.setName(part.Name.getBytes());
partPdu.setContentType(part.MimeType.getBytes());
partPdu.setData(part.Data);
pduBody.addPart(partPdu);
}
}
sendRequest.setBody(pduBody);
final PduComposer composer = new PduComposer(this.context, sendRequest);
final byte[] bytesToSend = composer.make();
HttpUtils.httpConnection(context, 4444L, MMSCenterUrl,
bytesToSendFromPDU, HttpUtils.HTTP_POST_METHOD, !TextUtils
.isEmpty(MMSProxy), MMSProxy, port);
MMSCenterUrl: url from MMS-APNs, MMSProxy: proxy from MMS-APNs, port: port from MMS-APNs
Note that some classes are from internal packages. Download from android git is required.
The request should be done with url from user's apn-space...code..:
public class APNHelper {
public class APN {
public String MMSCenterUrl = "";
public String MMSPort = "";
public String MMSProxy = "";
}
public APNHelper(final Context context) {
this.context = context;
}
public List<APN> getMMSApns() {
final Cursor apnCursor = this.context.getContentResolver().query(Uri.withAppendedPath(Telephony.Carriers.CONTENT_URI, "current"), null, null, null, null);
if ( apnCursor == null ) {
return Collections.EMPTY_LIST;
} else {
final List<APN> results = new ArrayList<APN>();
if ( apnCursor.moveToFirst() ) {
do {
final String type = apnCursor.getString(apnCursor.getColumnIndex(Telephony.Carriers.TYPE));
if ( !TextUtils.isEmpty(type) && ( type.equalsIgnoreCase(Phone.APN_TYPE_ALL) || type.equalsIgnoreCase(Phone.APN_TYPE_MMS) ) ) {
final String mmsc = apnCursor.getString(apnCursor.getColumnIndex(Telephony.Carriers.MMSC));
final String mmsProxy = apnCursor.getString(apnCursor.getColumnIndex(Telephony.Carriers.MMSPROXY));
final String port = apnCursor.getString(apnCursor.getColumnIndex(Telephony.Carriers.MMSPORT));
final APN apn = new APN();
apn.MMSCenterUrl = mmsc;
apn.MMSProxy = mmsProxy;
apn.MMSPort = port;
results.add(apn);
}
} while ( apnCursor.moveToNext() );
}
apnCursor.close();
return results;
}
}
private Context context;
}
This seems to be answered in the post: Sending MMS with Android
Key lines of code being:
Intent sendIntent = new Intent(Intent.ACTION_SEND);
sendIntent.putExtra("sms_body", "some text");
sendIntent.putExtra(Intent.EXTRA_STREAM, Uri.parse(url));
sendIntent.setType("image/png");
If you have to send MMS with any Image using Intent then use this code.
Intent sendIntent = new Intent(Intent.ACTION_SEND);
sendIntent.setClassName("com.android.mms", "com.android.mms.ui.ComposeMessageActivity");
sendIntent.putExtra("sms_body", "some text");
sendIntent.putExtra(Intent.EXTRA_STREAM, Uri.parse("file:///sdcard/image_4.png"));
sendIntent.setType("image/png");
startActivity(sendIntent);;
OR
If you have to send MMS with Audio or Video file using Intent then use this.
Intent sendIntent = new Intent(Intent.ACTION_SEND);
sendIntent.setClassName("com.android.mms", "com.android.mms.ui.ComposeMessageActivity");
sendIntent.putExtra("address", "1213123123");
sendIntent.putExtra("sms_body", "if you are sending text");
final File file1 = new File(mFileName);
if(file1.exists()){
System.out.println("file is exist");
}
Uri uri = Uri.fromFile(file1);
sendIntent.putExtra(Intent.EXTRA_STREAM, uri);
sendIntent.setType("video/*");
startActivity(sendIntent);
let me know if this help you.
The answer with the APN helper will not work after android 4.0. To get mms apn settings on Android 4.0 and above view this answer: View mms apn

Categories

Resources