Android4.4之后的短息插入方式

android4.4之前,我们可以通过下面的代码,往手机写入一条短息:

  public static void createMsg(Context context, String phone, String msg) {

     ContentResolver resolver = context.getContentResolver();
     Uri uri = Uri.parse("content://sms/");
     ContentValues values = new ContentValues();
     values.put("address", phone);
     values.put("type", "1");
     values.put("body", msg);
     values.put("date", System.currentTimeMillis());
     resolver.insert(uri, values);

   }

但是4.4及之后的版本则会写入失败,只有手机默认的消息App才能处理和短信相关的操作,而手机默认的消息App一般就是手机里自带的官方App,当然用户可以在设置里面,手动地将自己信任的消息App设置为默认App,总的来说,短信的操作控制权掌握到用户自己的手中。

那如何自己实现一个处理消息的App呢?
在项目中,新增2个BroadcastReceiver和Service,如下所示:

public class MmsReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {

    }
}
public class SmsReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {

    }
}
public class SmsSendService extends Service {
    public SmsSendService() {
    }

    @Override
    public IBinder onBind(Intent intent) {
        // TODO: Return the communication channel to the service.
        return null;
    }
}

然后,要在AndroidManifest.xml中对Receiver和Service进行注册,并声明消息相关的权限。

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

<application
    android:name=".MyApplication"
    android:allowBackup="true"
    android:icon="@mipmap/u"
    android:label="@string/app_name"
    android:roundIcon="@mipmap/ic_launcher_round"
    android:supportsRtl="true"
    android:theme="@style/AppTheme">

    <activity android:name=".MainActivity"
              android:screenOrientation="portrait">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />
            <category android:name="android.intent.category.LAUNCHER" />

            <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>

    <!--BroadcastReceiver that listens for incoming SMS messages-->
    <receiver
        android:name="sms.SmsReceiver"
        android:permission="android.permission.BROADCAST_SMS" >
        <intent-filter>
            <action android:name="android.provider.Telephony.SMS_DELIVER" />
        </intent-filter>
    </receiver>

    <!--BroadcastReceiver that listens for incoming MMS messages-->
    <receiver
        android:name="sms.MmsReceiver"
        android:permission="android.permission.BROADCAST_WAP_PUSH" >
        <intent-filter>
            <action android:name="android.provider.Telephony.WAP_PUSH_DELIVER" />
            <data android:mimeType="application/vnd.wap.mms-message" />
        </intent-filter>
    </receiver>

    <!-- Service that delivers messages from the phone "quick response"-->
    <service
        android:name=".sms.SmsSendService"
        android:exported="true"
        android:permission="android.permission.SEND_RESPOND_VIA_MESSAGE" >
        <intent-filter>
            <action android:name="android.intent.action.RESPOND_VIA_MESSAGE" />
            <category android:name="android.intent.category.DEFAULT" />
            <data android:scheme="sms" />
            <data android:scheme="smsto" />
            <data android:scheme="mms" />
            <data android:scheme="mmsto" />
        </intent-filter>
    </service>

</application>

好的,到目前为止,上面创建的3个类都不需要做任何操作了,这里提醒下,android6.0及之后的手机别忘记动态申请短息的权限,然后通过下面的代码将该App设置为默认的短息App

if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.KITKAT) {

    //查询当前默认的短信应用包名并把包名保存起来,操作完之后可以用于恢复默认短息
    String defaultSmsPkg = Telephony.Sms.getDefaultSmsPackage(this);
    String mySmsPkg = this.getPackageName();
    if (!defaultSmsPkg.equals(mySmsPkg)) {
        // 如果这个App不是默认的Sms App,则修改成默认的SMS APP
        // 因为从Android 4.4开始,只有默认的SMS APP才能对SMS数据库进行处理
        Intent intent = new Intent(Telephony.Sms.Intents.ACTION_CHANGE_DEFAULT);
        intent.putExtra(Telephony.Sms.Intents.EXTRA_PACKAGE_NAME, mySmsPkg);
        this.startActivity(intent);
    }
}

现在运行你的项目,会发现弹出下面的提示

这里写图片描述

点击更改,就可以将我们的App设置为默认的信息处理应用了.

接着,就可以通过下面的代码来写入短息

public static void createMsg(Context context, String phone, String msg) {

    if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.KITKAT) {
        if (context.getPackageName().equals(Telephony.Sms.getDefaultSmsPackage(context))) {
            // 对短信数据库进行处理
            ContentResolver resolver = context.getContentResolver();
            ContentValues values = new ContentValues();
            values.put(Telephony.Sms.ADDRESS, phone);
            values.put(Telephony.Sms.DATE, System.currentTimeMillis());
            long dateSent = System.currentTimeMillis() - 5000;
            values.put(Telephony.Sms.DATE_SENT, dateSent);
            values.put(Telephony.Sms.READ, false);
            values.put(Telephony.Sms.SEEN, false);
            values.put(Telephony.Sms.STATUS, Telephony.Sms.STATUS_COMPLETE);
            values.put(Telephony.Sms.BODY, msg);
            values.put(Telephony.Sms.TYPE, Telephony.Sms.MESSAGE_TYPE_INBOX);
            Uri uri = resolver.insert(Telephony.Sms.CONTENT_URI, values);
            if (uri != null) {
                long uriId = ContentUris.parseId(uri);
            }
        }
    } 
}

如果要恢复之前的默认短息,这就需要用到前面保存的defaultSmsPkg 来恢复了,代码如下:

// 对短信数据库处理结束后,恢复原来的默认SMS APP
if (null != defaultSmsPkg) {
    if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.KITKAT ) {
        Intent intent = new Intent(Telephony.Sms.Intents.ACTION_CHANGE_DEFAULT);
        intent.putExtra(Telephony.Sms.Intents.EXTRA_PACKAGE_NAME, defaultSmsPkg);
        startActivity(intent);
    }
}

下面给出完整的写入短息的方法

/**
 * 创建短息
 *
 * @param context
 * @param phone
 * @param msg
 */
public static void createMsg(Context context, String phone, String msg) {

    if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.KITKAT) {

        //查询当前默认的短信应用包名并把包名保存起来,操作完之后可以用于恢复默认短息
        String defaultSmsPkg = Telephony.Sms.getDefaultSmsPackage(context);
        String mySmsPkg = context.getPackageName();
        if (!defaultSmsPkg.equals(mySmsPkg)) {
            // 如果这个App不是默认的Sms App,则修改成默认的SMS APP
            // 因为从Android 4.4开始,只有默认的SMS APP才能对SMS数据库进行处理
            Intent intent = new Intent(Telephony.Sms.Intents.ACTION_CHANGE_DEFAULT);
            intent.putExtra(Telephony.Sms.Intents.EXTRA_PACKAGE_NAME, mySmsPkg);
            context.startActivity(intent);
        }
        if (mySmsPkg.equals(Telephony.Sms.getDefaultSmsPackage(context))) {
            // 对短信数据库进行处理
            ContentResolver resolver = context.getContentResolver();
            ContentValues values = new ContentValues();
            values.put(Telephony.Sms.ADDRESS, phone);
            values.put(Telephony.Sms.DATE, System.currentTimeMillis());
            long dateSent = System.currentTimeMillis() - 5000;
            values.put(Telephony.Sms.DATE_SENT, dateSent);
            values.put(Telephony.Sms.READ, false);
            values.put(Telephony.Sms.SEEN, false);
            values.put(Telephony.Sms.STATUS, Telephony.Sms.STATUS_COMPLETE);
            values.put(Telephony.Sms.BODY, msg);
            values.put(Telephony.Sms.TYPE, Telephony.Sms.MESSAGE_TYPE_INBOX);
            Uri uri = resolver.insert(Telephony.Sms.CONTENT_URI, values);
            if (uri != null) {
                long uriId = ContentUris.parseId(uri);
            }

            // 对短信数据库处理结束后,恢复原来的默认SMS APP

            Intent intent = new Intent(Telephony.Sms.Intents.ACTION_CHANGE_DEFAULT);
            intent.putExtra(Telephony.Sms.Intents.EXTRA_PACKAGE_NAME, defaultSmsPkg);
            context.startActivity(intent);

        }
    } else {
        ContentResolver resolver = context.getContentResolver();
        Uri uri = Uri.parse("content://sms/");
        ContentValues values = new ContentValues();
        values.put("address", phone);
        values.put("type", "1");
        values.put("body", msg);
        values.put("date", System.currentTimeMillis());
        resolver.insert(uri, values);
    }
}

如果安装完之后,发现桌面上并没有找到自己的App,可以将MainActivity下的这些内容单独写到一个activity中,不要写在入口的Activity中

  <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" />

猜你喜欢

转载自blog.csdn.net/mchenys/article/details/79568797