思路:首先,我們需要知道短信收發短信的存儲過程,收到短信先存儲到數據庫中,然後再顯示到界面上。然後短信也是可以通過ContentProvider進行共享的,所以我們需要找到com.android.providers.telephony這個程序中在寫繼承自ContentProvider的類時,在清單文件中所聲明的authorities,然後就可以拿到Uri,就可對短信進行監聽。我們查看源代碼得知其聲明的authorities爲sms,所以我們在訪問時的uri爲content://sms,之後由於這個uri路徑下存在多個表,並且每個表的列名我們也不知道,所以我們先查詢之後,打印輸出列名。新建項目,在佈局文件中加一個ListView用來將實時收發的信息顯示出來
之後:
一、創建監聽,註冊,當發送或者接受短信時,打印輸出列名
MainActivity中的onCreate()中:
uri = Uri.parse("content://sms");
//監聽短信
getContentResolver().registerContentObserver(uri,true,new SmsObserver(new Handler()));
繼承自ContentObserver的類爲SmsObsever:
private class SmsObserver extends ContentObserver{
public SmsObserver(Handler handler) {
super(handler);
}
@Override
public void onChange(boolean selfChange) {
super.onChange(selfChange);
Cursor c = getContentResolver().query(uri,null,null,null,null);
c.moveToNext();
String[] names = c.getColumnNames();//得到所有列名
for(String name : names){
System.out.println(name);//輸出查看列名
}
}
此時,收發擔心,都會輸出結果,列名我們需要的有address(電話號碼),body(短信內容),type(1代表收到短信,2代表發出短信),暫時就取出着三個值進行監聽吧
二、監聽短信的收發,並且實時顯示到ListView中
public class MainActivity extends ActionBarActivity {
Uri uri;
ListView listView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//短信的provider接口
uri = Uri.parse("content://sms");
//監聽短信
getContentResolver().registerContentObserver(uri,true,new SmsObserver(new Handler()));
listView = (ListView)findViewById(R.id.listView);
}
private class SmsObserver extends ContentObserver{
public SmsObserver(Handler handler) {
super(handler);
}
@Override
public void onChange(boolean selfChange) {
super.onChange(selfChange);
//只取最後一個
Cursor c = getContentResolver().query(uri,null,null,null,"_id DESC LIMIT 1");
List<String> data= new ArrayList<String>();
c.moveToNext();
String[] names = c.getColumnNames();//得到所有列名
for(String name : names){
System.out.println(name);//輸出查看列名
}
while (c.moveToNext()){
String address = c.getString(c.getColumnIndex("address"));
String body= c.getString(c.getColumnIndex("body"));
// String name = c.getString(c.getColumnIndex("name"));
int type = c.getInt(c.getColumnIndex("type"));
String tranType = type==1?"received":"sent";
data.add(tranType + " " + body + "The number is: " + address);
}
ArrayAdapter<String> adapter = new ArrayAdapter<String>(MainActivity.this,android.R.layout.simple_list_item_1,data);
listView.setAdapter(adapter);
//輸出查看data的值
for(String d :data){
System.out.println(d);
}
}
}
至此,實時監聽短信已經告一段落,可以將監聽到的短信數據存到本地數據庫或者傳到服務器上,或者轉發給自己。只是在做應用時收發驗證碼直接讀取出來,切勿做他用。下面,來說如何獲取聯繫人數據,不是實時監聽,就是想通過訪問C聯繫人的數據庫來讀取數據,此時還是通過ContentProvider來訪問:
首要問題,uri 和要查詢的列名如何寫,這裏我們用系統提供好的:
還是在這個程序中寫吧:
//讀取聯繫人數據的方法,獲取數據源
private void readContact(){
Cursor c =null;
c = getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI,null,null,null,null);
while(c.moveToNext()) {
String name = c.getString(c.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME));
String number = c.getString(c.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
//data.add(name + " "+number);
}
}
之後與數據源進行適配,顯示在ListView中: List<String> data= new ArrayList<String>();
ListView listView;
ArrayAdapter<String> adapter;
listView = (ListView)findViewById(R.id.listView);
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,android.R.layout.simple_list_item_1,data);
readContact();
listView.setAdapter(adapter);
這樣就可以讀取聯繫人數據