下面通過短信攔截器來介紹短信中的廣播
布局文件
在布局文件中可以設置需要攔截的號碼
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:textStyle="bold" android:textSize="25sp" android:text="需要攔截的號碼"/> <EditText android:id="@+id/phoneNum" android:layout_width="match_parent" android:layout_height="wrap_content" /> <Button android:id="@+id/sure" android:layout_width="wrap_content" android:layout_height="wrap_content" android:textSize="18sp" android:text="確認"/> </LinearLayout>
Activity
在Activity中獲取數據並保存到本地的xml數據庫中
package xidian.dy.com.chujia; import android.content.Context; import android.content.SharedPreferences; import android.os.Bundle; import android.support.v7.app.AppCompatActivity; import android.view.View; import android.widget.Button; import android.widget.EditText; import android.widget.Toast; public class MainActivity extends AppCompatActivity { SharedPreferences sp; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); sp = getSharedPreferences("hate", Context.MODE_PRIVATE); Button button = (Button) findViewById(R.id.sure); if(button != null) button.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { EditText et = (EditText) findViewById(R.id.phoneNum); if(et != null){ sp.getString("num", et.getText().toString()); Toast.makeText(MainActivity.this, "保存成功", Toast.LENGTH_SHORT).show(); } } }); } }
短信攔截器
package xidian.dy.com.chujia; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.os.Build; import android.os.Bundle; import android.provider.Telephony; import android.telephony.SmsMessage; import android.util.Log; /** * Created by dy on 2016/7/11. */ public class SmsReciever extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { //短信的信息封裝在Intent中 Bundle bundle = intent.getExtras(); Object[] objects = (Object[]) bundle.get("pdus"); SmsMessage sms; int currentApiVversion = Build.VERSION.SDK_INT; //拿到廣播中的所有短信(有可能短信太長在發送時被拆分成多條進行發送) for (Object obj : objects) { if(currentApiVversion >= Build.VERSION_CODES.LOLLIPOP) sms = SmsMessage.createFromPdu((byte[])obj, Telephony.Sms.Intents.SMS_RECEIVED_ACTION); else sms = SmsMessage.createFromPdu((byte[])obj); Log.i(this.getClass().getName(), sms.getOriginatingAddress()); Log.i(this.getClass().getName(), sms.getMessageBody()); //廣播攔截 //來自1243的短信將會被攔截掉 if(sms.getOriginatingAddress().equals("1243")){ abortBroadcast(); } } } }
短信的格式比較復雜(號碼+信息),所以被存儲在intent對象中。由於考慮的API level的問題這里需要做版本判斷。調用abortBroadcast后廣播將直接被銷毀。
清單文件
在清單文件中需要開啟短信接受權限,因為廣播接受者也有優先級問題(-1000~1000),所以我們應該將我們的攔截器優先級設置為最高(1000)
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="xidian.dy.com.chujia"> <uses-permission android:name="android.permission.RECEIVE_SMS"/> <application android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:supportsRtl="true" android:theme="@style/AppTheme"> <activity android:name=".MainActivity" android:label="主界面"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <receiver android:name=".SmsReciever"> <intent-filter android:priority="1000"> <action android:name="android.provider.Telephony_SMS_RECIEVED"/> </intent-filter> </receiver> </application> </manifest>
注意
在Android4.0之后如果APP被安裝了但從來沒被用戶啟動過,或者是用戶自己手動殺死APP進程,則系統不會去主動啟動APP中的廣播接受者來接受廣播。