Currently in android from KITKAT sending SMS/MMS can be sent only by
default SMS app. You have to make your app as default SMS app before
sending sms/mms from your app (later we will discuss about this).
Newly from 5.x android has removed “Enable/Disable” of mobile data
programmatically, so in this case you have to manually enable your
mobile data from settings.
Here i am gonna use a library called “Android SMS/MMS/Google Voice Sending Library” which is created by Jacob Klinker.
GitHub link: Android SMS/MMS/Google Voice Sending Library
To check whether app is default sms app or not add this in:
AndroidManifest.xml.
AndroidManifest.xml.
<!-- Activity that allows the user to send new SMS/MMS messages --> <activity android:name=".ComposeSmsActivity" > <intent-filter> <action android:name="android.intent.action.SEND" /> <action android:name="android.intent.action.SENDTO" /> <category android:name="android.intent.category.DEFAULT" /> <category android:name="android.intent.category.BROWSABLE" /> <data android:scheme="sms" /> <data android:scheme="smsto" /> <data android:scheme="mms" /> <data android:scheme="mmsto" /> </intent-filter> </activity> //add permission <uses-permission android:name="android.permission.SEND_SMS" /> <uses-permission android:name="android.permission.READ_SMS" /> <uses-permission android:name="android.permission.WRITE_SMS" /> <uses-permission android:name="android.permission.RECEIVE_SMS" /> <uses-permission android:name="android.permission.RECEIVE_MMS" /> <uses-permission android:name="android.permission.READ_PHONE_STATE" /> <uses-permission android:name="android.provider.Telephony.SMS_RECEIVED" /> <uses-permission android:name="android.permission.WAKE_LOCK" /> <uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" /> <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" /> <uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" /> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.WRITE_SETTINGS"/>
Create a activity called ComposeSmsActivity to make your app default sms app:
public class ComposeSmsActivity extends Activity { @Override protected void onResume() { super.onResume(); final String myPackageName = getPackageName(); if (!Telephony.Sms.getDefaultSmsPackage(this).equals(myPackageName)) { // App is not default. // Show the "not currently set as the default SMS app" interface View viewGroup = findViewById(R.id.not_default_app); viewGroup.setVisibility(View.VISIBLE); // Set up a button that allows the user to change the default SMS app Button button = (Button) findViewById(R.id.change_default_app); button.setOnClickListener(new View.OnClickListener() { public void onClick(View v) { Intent intent = new Intent(Telephony.Sms.Intents.ACTION_CHANGE_DEFAULT); intent.putExtra(Telephony.Sms.Intents.EXTRA_PACKAGE_NAME, myPackageName); startActivity(intent); } }); } else { // App is the default. // Hide the "not currently set as the default SMS app" interface View viewGroup = findViewById(R.id.not_default_app); viewGroup.setVisibility(View.GONE); } } }
Create a AsyncTask for sending sms/mms in background.
AsyncTask enables proper and easy use of the UI thread. This class
allows to perform background operations and publish results on the UI
thread without having to manipulate threads and/or handlers.
AsyncTask is designed to be a helper class around
Thread
and Handler
and does not constitute a generic threading framework. AsyncTasks
should ideally be used for short operations (a few seconds at the most.)
If you need to keep threads running for long periods of time, it is
highly recommended you use the various APIs provided by the java.util.concurrent
package such as Executor
, ThreadPoolExecutor
and FutureTask
.
An asynchronous task is defined by a computation that runs on a
background thread and whose result is published on the UI thread. An
asynchronous task is defined by 3 generic types, called
Params
, Progress
and Result
, and 4 steps, called onPreExecute
, doInBackground
, onProgressUpdate
and onPostExecute
.
AsyncTask must be subclassed to be used. The subclass will override at least one method (
doInBackground(Params...)
), and most often will override a second one (onPostExecute(Result)
.)SMS/MMS AsyncTask.java:
public class SMSMMS_AsyncTask extends AsyncTask<String, Integer, String> { private Settings settings; Context mContext; public static String filePath; String TYPE = ""; private static final int EOF = -1; String[] SendTo={"mobilenumber1","mobilenumber2"}; String text = ""; public SMSMMS_AsyncTask(Context context, String file_path, String Type, String text) { this.mContext = context; this.filePath=file_path; this.TYPE = Type; this.text = text; if (PreferenceManager.getDefaultSharedPreferences(mContext) .getBoolean("request_permissions", true) && Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { mContext.startActivity(new Intent(mContext, PermissionActivity.class)); Log.e("SMSMMS_AsyncTask", "error starting permission intent"); return; } initSettings(); }
//onPreExecute() check setting to send the sms/mms:
@Override protected void onPreExecute() { super.onPreExecute(); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && !android.provider.Settings.System.canWrite(mContext)) { Intent intent = new Intent(android.provider.Settings.ACTION_MANAGE_WRITE_SETTINGS); intent.setData(Uri.parse("packagemContext.getPackageName())); intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); try { mContext.startActivity(intent); } catch (Exception e) { Log.e("SMSMMS_AsyncTask", "error starting permission intent", e); } } } //In doInBackground() send the sms/mms: @Override protected String doInBackground(String... params) { com.klinker.android.send_message.Settings sendSettings = new com.klinker.android.send_message.Settings(); sendSettings.setMmsc(settings.getMmsc()); sendSettings.setProxy(settings.getMmsProxy()); sendSettings.setPort(settings.getMmsPort()); Transaction transaction = new Transaction(mContext, sendSettings); Message message = new Message("MMS message", SendTo); if (MMSTYPE.equals("IMAGE")) { message.setType(Message.TYPE_SMSMMS); BitmapFactory.Options bmOptions = new BitmapFactory.Options(); message.setImage(BitmapFactory.decodeFile(filePath, bmOptions)); } else if (MMSTYPE.equals("AUDIO")) { message.setType(Message.TYPE_VOICE); byte[] data = null; InputStream is = null; File file = new File(filePath); try { is = openInputStream(file); data = toByteArray(is, file.length()); } catch (IOException e) { e.printStackTrace(); } message.addAudio(data); } else if (MMSTYPE.equals("TEXT")) { message.setType(Message.TYPE_SMSMMS); message.setText(text); } transaction.sendNewMessage(message, Transaction.NO_THREAD_ID); return null; } @Override protected void onPostExecute(String s) { super.onPostExecute(s); } //Init the Apns setting: private void initSettings() { settings = Settings.get(mContext); if (TextUtils.isEmpty(settings.getMmsc())) { initApns(); } } private void initApns() { ApnUtils.initDefaultApns(mContext, new ApnUtils.OnApnFinishedListener() { @Override public void onFinished() { settings = Settings.get(mContext, true); } }); }
Methods for converting audio file to ByteArray[] format:
public static FileInputStream openInputStream(File file) throws IOException {
if (file.exists()) {
if (file.isDirectory()) {
throw new IOException("File '" + file + "' exists but is a directory");
}
if (file.canRead() == false) {
throw new IOException("File '" + file + "' cannot be read");
}
} else {
throw new FileNotFoundException("File '" + file + "' does not exist");
}
return new FileInputStream(file);
}
public static byte[] toByteArray(InputStream input, int size) throws IOException {
if (size < 0) {
throw new IllegalArgumentException("Size must be equal or greater than zero: " + size);
}
if (size == 0) {
return new byte[0];
}
byte[] data = new byte[size];
int offset = 0;
int readed;
while (offset < size && (readed = input.read(data, offset, size - offset)) != EOF) {
offset += readed;
}
if (offset != size) {
throw new IOException("Unexpected readed size. current: " + offset + ", excepted: " + size);
}
return data;
}
public static byte[] toByteArray(InputStream input, long size) throws IOException {
if (size > Integer.MAX_VALUE) {
throw new IllegalArgumentException("Size cannot be greater than Integer max value: " + size);
}
return toByteArray(input, (int) size);
}
}
For more clarification try android sms/mms library sample.
Comments
Post a Comment