ارسال و دریافت و خواندن SMS و MMS در اندروید

شنبه 23 آبان 1394

در این مقاله قصد داریم ارسال sms و یا ارسال یک متن طولانی را که MMS می شود به یک شماره ارسال نماییم . و اینکه چگونگی خواندن و دریافت پیام را آموزش دهیم.

ارسال و دریافت و خواندن SMS و MMS در اندروید

ما می توانیم sms را به دو راه ارسال نماییم، با استفاده از Intent و بدون استفاده از Intent

در هر صورت ما باید permission های مورد نظر را به androidmanifest اضافه نماییم.

<manifest ...>
    
    <uses-sdk .../>    
    
    <uses-permission android:name="android.permission.SEND_SMS"/>

    <application
        ...>
        ...

</manifest>

ابتدا برای ارسال پیام با استفاده از Intent و بدون استفاده از Intent:

کاربر یک شماره و متن را وارد می کند و یک متن کوتاه و یک متن طولانی می تواند ارسال نماید.

کد زیر را در کلاس جاوا قرار می دهیم:

/* Phone Number is just all digits of the number (including country code)
 * "+" isn't needed, but can appear
 * For example:
 * I have Beeline Phone Number +7 (962) 000-00-00,
 * in my case, it should be 79620000000 or +79620000000 */
strPhone = "XXXXXXXXXXX";
strMessage = "Lorem\nIpsum";
            
Intent sendIntent = new Intent(Intent.ACTION_VIEW);
sendIntent.setType("vnd.android-dir/mms-sms");
sendIntent.putExtra("address", strPhone);
sendIntent.putExtra("sms_body", strMessage); 
startActivity(sendIntent);


در کد بالا شماره تلفن و متنی که می خواهید نوشته شود را قرار دادیم ، حالا Intent دوم شماره و متن مورد نظر را دریافت می کند، یا می توانید به صورت زیر آدرس را به صورت Uri دریافت نمایید.

/* Phone Number is just all digits of the number (including country code)
 * "+" isn't recommended, because there it is already included into Uri (see below)
 * For example:
 * I have Beeline Phone Number +7 (962) 000-00-00,
 * in my case, it should be 79620000000 */
strPhone = "XXXXXXXXXXX";
strMessage = "Lorem\nIpsum";
            
Uri sms_uri = Uri.parse("smsto:+" + strPhone); 
Intent sms_intent = new Intent(Intent.ACTION_SENDTO, sms_uri); 
sms_intent.putExtra("sms_body", txtMessage.getText().toString()); 
startActivity(sms_intent); 

حالا اگر بخواهید بدون استفاده از intent یک پیام ارسال نمایید، سطح دسترسی که قبلا نوشتیم را دوباره نیاز دارید.

از smsmanager استفاده نمایید ، شماره و پیام شما را دریافت خواهد کرد، و بعد از ارسال پیغام از یک Toast استفاده نمایید، اگر پیام شما طولانی بود و بیش از 160 کاراکتر بود دیگر به صورت sms ارسال نخواهد شد و این پیام ها به صورت mms ارسال خواهد شد.

در کد زیر از همان sendmanager استفاده می کنیم، ولی باید یک آرایه تعریف شود و از متد SendMultipleTextMessage استفاده نماییم، شماره تلفن و پیام را به صورت آرایه ای از رشته بگیریم و به صورت یک پیغام Toast نمایش داده شود.

کد های زیر برای این نوشته شده است که آیا پیام ما درست ارسال شده است یا نه؟که از دستور Case استفاده می شود، که هر کدام از حالت ها را چک می کند اگر هر کدام خطا داشت به صورت یک پیغام Toast نمایش داده شود.

String strPhone = "XXXXXXXXXXX";

String strMessage = "Lorem\nIpsum";
            
SmsManager sms = SmsManager.getDefault();

/* ---- Preparing Intents To Check While Sms Sent & Delivered ---- */

Context curContext = this.getApplicationContext();

PendingIntent sentPending = PendingIntent.getBroadcast(curContext,
        0, new Intent("SENT"), 0);

curContext.registerReceiver(new BroadcastReceiver() 
{
    @Override
    public void onReceive(Context arg0, Intent arg1) 
    {
        switch (getResultCode()) {
        case Activity.RESULT_OK:
            Toast.makeText(getBaseContext(), "Sent.",
                    Toast.LENGTH_LONG).show();
            break;
        case SmsManager.RESULT_ERROR_GENERIC_FAILURE:
            Toast.makeText(getBaseContext(), "Not Sent: Generic failure.",
                    Toast.LENGTH_LONG).show();
            break;
        case SmsManager.RESULT_ERROR_NO_SERVICE:
            Toast.makeText(getBaseContext(), "Not Sent: No service (possibly, no SIM-card).",
                    Toast.LENGTH_LONG).show();
            break;
        case SmsManager.RESULT_ERROR_NULL_PDU:
            Toast.makeText(getBaseContext(), "Not Sent: Null PDU.",
                    Toast.LENGTH_LONG).show();
            break;
        case SmsManager.RESULT_ERROR_RADIO_OFF:
            Toast.makeText(getBaseContext(), "Not Sent: Radio off (possibly, Airplane mode enabled in Settings).",
                    Toast.LENGTH_LONG).show();
            break;
        }
    }
}, new IntentFilter("SENT"));

PendingIntent deliveredPending = PendingIntent.getBroadcast(curContext,
        0, new Intent("DELIVERED"), 0);

curContext.registerReceiver(
        new BroadcastReceiver()
        {
            @Override
            public void onReceive(Context arg0,Intent arg1)
            {
                switch (getResultCode())
                {
                case Activity.RESULT_OK:
                    Toast.makeText(getBaseContext(), "Delivered.",
                            Toast.LENGTH_LONG).show();
                    break;
                case Activity.RESULT_CANCELED:
                    Toast.makeText(getBaseContext(), "Not Delivered: Canceled.",
                            Toast.LENGTH_LONG).show();
                    break;
                }
            }
        }, new IntentFilter("DELIVERED"));

/* --------------------------------------------------------------- */

sms.sendTextMessage(strPhone, null, strMessage,
        sentPending, deliveredPending);

در قسمت بعدی باید کدی را بنویسیم که چک کند آیا گوشی مورد نظر می تواند پیغام را ارسال کند یا نه؟

PackageManager pm = this.getPackageManager();

if (!pm.hasSystemFeature(PackageManager.FEATURE_TELEPHONY) &&
    !pm.hasSystemFeature(PackageManager.FEATURE_TELEPHONY_CDMA)) {
    Toast.makeText(this, "Sorry, your device probably can't send SMS...", Toast.LENGTH_SHORT).show();
 }

ارسال MMS

MMS یک sms است که عکس و فیلم و صدا را ارسال می کند.

برای ارسال MMS با استفاده از Intent باید از کد زیر استفاده نمایید.

برای ارسال SMs, MMS در اندورید ورژن پایین تر از 5 و در API 21 ما از متد smsmanager استفاده می کنیم.

کد ارسال mms با استفاده از intent به صورت زیر خواهد بود:

/* Phone Number is just all digits of the number (including country code)
 * "+" isn't needed, but can appear
 * For example:
 * I have Beeline Phone Number +7 (962) 000-00-00,
 * in my case, it should be 79620000000 or +79620000000 */
strPhone = "XXXXXXXXXXX";
strMessage = "Lorem\nIpsum";

/* Attach Url is local (!) URL to file which should be sent */
strAttachUrl = "file:///sdcard/Test.png";

/* Attach Type is a content type of file which should be sent */
strAttachType = "image/png";

Intent sendIntent = new Intent(Intent.ACTION_SEND);
sendIntent.setClassName("com.android.mms", "com.android.mms.ui.ComposeMessageActivity");
sendIntent.putExtra("address", strPhone);
sendIntent.putExtra("sms_body", strMessage);

/* Adding The Attach */
sendIntent.putExtra(Intent.EXTRA_STREAM, Uri.parse(strAttachUrl));
sendIntent.setType(strAttachType);

sendIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

startActivity(sendIntent);

برای دریافت sms باید داخل androidmanifest خود Permission زیر را بنویسید:

<manifest ...>
    
    <uses-sdk .../>
    
    <uses-permission android:name="android.permission.WRITE_SMS"/>
    <uses-permission android:name="android.permission.READ_SMS"/>
    <uses-permission android:name="android.permission.RECEIVE_SMS"/>

    <application
        ...>
        ...

</manifest>

حالا ارسال MMS بدون استفاده از Intent

public class SmsReceiver extends BroadcastReceiver {

    @Override
    public void onReceive(Context context, Intent intent) {
        Bundle intentExtras = intent.getExtras();
        
        if (intentExtras != null) {
            /* Get Messages */
            Object[] sms = (Object[]) intentExtras.get("pdus");
            
            for (int i = 0; i < sms.length; ++i) {
                /* Parse Each Message */
                SmsMessage smsMessage = SmsMessage.createFromPdu((byte[]) sms[i]);

                String phone = smsMessage.getOriginatingAddress();
                String message = smsMessage.getMessageBody().toString();
                
                Toast.makeText(context, phone + ": " + message, Toast.LENGTH_SHORT).show();
            }
        }
    }
}

برای خواندن SMS از history باید permission  آن را داخل androidmanifest بنویسید:

<manifest ...>
    
    <uses-sdk .../>
    
    <uses-permission android:name="android.permission.READ_SMS"/>

    <application
        ...>
        ...

</manifest>

در کد زیر اگر توجه نمایید sms هایی را که ارسال می کنیم می توانید آدرس دهی کنید مثلا برای Inbox,Drafts,sent در کد زیر به جای آدرس content://sms/ ، هر کدام از آدرس های زیر را قرار می دهید:

برای :inbox

//sms/ to content://sms/inbox

برای :sent

//sms/ to content://sms/sent

برای drafts:

//sms/ to content://sms/draft

در activity باید کد زیر را بنویسید:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:padding="3dp"
    tools:context="${relativePackage}.${activityClass}" >

    <LinearLayout
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentLeft="true"
        android:layout_alignParentTop="true"
        android:orientation="horizontal" >

        <Button
            android:id="@+id/btnAll"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="All" />

        <Button
            android:id="@+id/btnInbox"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginLeft="3dp"
            android:text="Inbox" />

        <Button
            android:id="@+id/btnSent"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginLeft="3dp"
            android:text="Sent" />

        <Button
            android:id="@+id/btnDraft"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginLeft="3dp"
            android:text="Draft" />

    </LinearLayout>

    <ScrollView
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:layout_marginTop="3dp"
        android:scrollbars="vertical" >
    
        <HorizontalScrollView
            android:layout_width="fill_parent"
            android:layout_height="fill_parent"
            android:scrollbars="horizontal" >
        
            <TableLayout
                android:id="@+id/tblMain"
                android:layout_width="fill_parent"
                android:layout_height="fill_parent">
        
            </TableLayout>
        
        </HorizontalScrollView>
    
    </ScrollView>

</LinearLayout>

کل کد جاوا به صورت زیر خواهد بود:

import android.app.Activity;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.view.Gravity;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TableLayout;
import android.widget.TableRow;
import android.widget.TextView;
import android.widget.Toast;

public class MainActivity extends Activity
    implements OnClickListener {

    Button btnAll;
    Button btnInbox;
    Button btnSent;
    Button btnDraft;
    TableLayout tblMain;
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        
        try {
            /*
             * Initializing Widgets
             */

            btnAll = (Button) findViewById(R.id.btnAll);
            btnAll.setOnClickListener(this);
            
            btnInbox = (Button) findViewById(R.id.btnInbox);
            btnInbox.setOnClickListener(this);
            
            btnSent = (Button) findViewById(R.id.btnSent);
            btnSent.setOnClickListener(this);
            
            btnDraft = (Button) findViewById(R.id.btnDraft);
            btnDraft.setOnClickListener(this);
            
            tblMain = (TableLayout) findViewById(R.id.tblMain);
            
        } catch (Exception ex) {
            Toast.makeText(this,
                    "Error in MainActivity.onCreate: " + ex.getMessage(),
                    Toast.LENGTH_SHORT).show();
        }
    }

    @Override
    public void onClick(View v) {
        Uri smsUri = Uri.parse("content://sms/");
        
        switch (v.getId()) {
        case R.id.btnInbox:
            smsUri = Uri.parse("content://sms/inbox");
            break;
        case R.id.btnSent:
            smsUri = Uri.parse("content://sms/sent");
            break;
        case R.id.btnDraft:
            smsUri = Uri.parse("content://sms/draft");
            break;
        }
        
        Cursor cursor = getContentResolver().query(smsUri, null, null, null, null);

        Cursor2TableLayout(cursor, tblMain);
    }
    
    public void Cursor2TableLayout(Cursor cur, TableLayout tblLayout) {
        
        /* Clearing Table If Contains Any Rows/Headers */
        tblLayout.removeAllViews();
        
        /* Moving To First */
        if (!cur.moveToFirst()) { /* false = cursor is empty */
            return;
        }

        /* Column Headers */
        
        TableRow headersRow = new TableRow(this);
        
        for (int j = 0; j < cur.getColumnCount(); j++) {
            TextView textView = new TextView(this);

            textView.setGravity(Gravity.CENTER_HORIZONTAL);
            
            textView.setText(cur.getColumnName(j));

            textView.setPadding(0, 0, 5, 0);
            
            textView.setAlpha(0.8f);
        
            headersRow.addView(textView);
        }

        headersRow.setPadding(10, 10, 10, 10);

        tblLayout.addView(headersRow);
        
        /* Rows */
    
        for (int i = 0; i < cur.getCount(); i++) {

            TableRow tableRow = new TableRow(this);

            for (int j = 0; j < cur.getColumnCount(); j++) {
                    TextView textView = new TextView(this);

                    textView.setGravity(Gravity.CENTER_HORIZONTAL);

                    textView.setText(cur.getString(j));

                    textView.setPadding(0, 0, 5, 0);
                
                    tableRow.addView(textView);
            }

            tableRow.setPadding(10, 10, 10, 10);

            tblLayout.addView(tableRow);
            cur.moveToNext();
        }

        cur.close();
    }
}

در واقع شما وقتی برنامه را اجرا می گیرید پیام هایی که در پوشه ی draft قرار دارد و پیام هایی که در inbox قرار دارد , و همین طور پیام های که ارسال شده هست خواهید دید .

زمانی که sms را ارسال نمایید خروجی به صورت زیر است:

اگر از Intent استفاده نمایید به صورت زیر خواهد بود:

فایل های ضمیمه

برنامه نویسان

نویسنده 3355 مقاله در برنامه نویسان

کاربرانی که از نویسنده این مقاله تشکر کرده اند

در صورتی که در رابطه با این مقاله سوالی دارید، در تاپیک های انجمن مطرح کنید