編輯:關於Android編程
android4.4對短信引入了一個全新的概念:默認短信應用。即android用戶可以在系統設置裡面選擇一個默認的短信應用,只有這個應用才能進行手機的基本短信操作。按照google自己的解釋這樣做的原因是因為很多第三方的APP使用了一些隱藏的API接口,應該是反射調用把,既然是反射調用的非常規接口,因此這些接口就並不會有兼容性即CTS測試,也就不能保證穩定可靠。個人看來,目前市場上第三方短信應用太多了,而且廠商經常把通話,聯系人,短信打包放在一起,因此手機上經常有多個短信應用,每個應用都能收短信發短信,有點混亂,尤其有的應用沒有處理好,導致收到一條短信顯示兩條。囧。因此這個默認短信的操作也就是很有必要的。
不過既然接口變了,那麼APP這邊很多東西也要改變,最典型的類似360雲盤這種能恢復短信的應用,應該怎麼恢復短信呢?這個稍後會提到google給了一個建議。這裡還是先說下接口有了哪些變化把。
google提供了:SMS_DELIVER_ACTION(sms)&& WAP_PUSH_DELIVER_ACTION(MMS)這兩個intent來給默認的短信應用,也就是說只有默認的短信應用才能收到這兩個廣播,也只有能收到這兩個廣播的應用才能對短彩信的數據庫進行寫操作。也就是說只有默認短信應用才能存儲短信。其他的非默認短信應用如果想收短信,可以監聽:
SMS_RECEIVED_ACTION 當然這些應用也只能顯示下短信,並不能存入數據庫。因此直接將4.4以前的短信應用拿過來裝到4.4上,這些應用僅能在來短信的時候進行查看閱讀,因為沒有寫數據庫的權限。google提供了一個控件接口:PackageManager.setComponentEnabledSetting(),可以對控件進行使能操作。這樣應用可以做到檢測下當前的android的平台,然後判斷是否需要關掉這個廣播。
另外在4.4之前, SMS_RECEIVED_ACTION broadcast是一個有序廣播,因此一些應用可以在監聽到這個廣播之後,進行丟棄處理,但是到了4.4之後,丟棄動作是不會生效的,這樣就可以保證所有的短信應用都能收到短信。個人認為這是非常合理的……畢竟短信嘛,不能某個應用說攔截就攔截了。
非系統的短信應用,如果想進行發短信操作的話,可以在申請了SEND_SMS權限之後,調用SmsManager接口進行短信發送操作。只有非系統短信應用在發送短信之後,framework才會將這條短信寫入數據庫,(系統短信應用會自己寫入數據庫),筆者感覺這一點非常好,再也不會有應用悄悄的在後台發送短信了……
因為一個應用如果不是默認的短信應用,其很多設計的東西都不可用的,和成為默認短信應用差別非常大,因此有必要進行一些容錯操作。首先,界面resume的時候需要檢查下是否是默認的,可以通過查詢:Telephony.Sms.getDefaultSmsPackage()來判斷自己是不是默認的短信應用。如果不是建議就disable短信發送操作,因為如果用戶發送彩信的話,系統不會幫忙寫入數據庫,應用自己又不能寫入數據庫,情況就很糟糕了……當然如果不是默認短信應用的話,也可以提示用戶選擇是否設置下,畢竟願意點擊你的應用,基本都是想用的。
sample如下:
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); } } }
怎麼樣才能讓你的應用成為成為一個合格的默認短信應用呢?首先你需要在androidmanifest.xml文件中進行一些聲明,獲取對應的權限:
1.需要在 broadcast receiver控件中,對SMS_DELIVER_ACTION廣播進行監聽,當然這個receiver也要聲明BROADCAST_SMS權限。
2.需要在 broadcast receiver控件中,對WAP_PUSH_DELIVER_ACTION廣播進行監聽,當然這個receiver也要聲明BROADCAST_WAP_PUSH權限。
3.在短信發送界面,需要監聽 ACTION_SENDTO,同時配置上sms:, smsto:, mms:, and mmsto這四個概要,這樣別的應用如果想發送短信,你的這個activity就能知道。
4.需要有一個service,能夠監聽ACTION_RESPONSE_VIA_MESSAGE,同時也要配置上sms:, smsto:, mms:, and mmsto這四個概要,並且要聲明SEND_RESPOND_VIA_MESSAGE權限。這樣用戶就能在來電的時候,用你的應用來發送拒絕短信。
sample如下:
...
沒有寫權限,備份應用應該如何寫入短信數據庫呢?google提供了這樣一個建議:
1.先查詢下並且記錄下當前的默認短信應用:
String defaultSmsApp = Telephony.Sms.getDefaultSmsPackage(context);
2.讓用戶設置你的應用成為默認短信應用,如何設置前面也有sample,成為默認短信應用之後,就可以恢復短信了:
Intent intent = new Intent(context, Sms.Intents.ACTION_CHANGE_DEFAULT); intent.putExtra(Sms.Intents.EXTRA_PACKAGE_NAME, context.getPackageName()); startActivity(intent);
3.最後恢復完成短信之後,可以在將默認短信應用還原到步驟1中記錄的短信應用:
Intent intent = new Intent(context, Sms.Intents.ACTION_CHANGE_DEFAULT); intent.putExtra(Sms.Intents.EXTRA_PACKAGE_NAME, defaultSmsApp); startActivity(intent);
最後筆者總結下:4.4上短信真的嚴格了,從此再也沒有應用能夠悄悄的發短信了,也不會有應用能夠自行攔截短信了。各種管家,安全軟件的攔截騷擾短信的功能該怎麼辦呢?
聲明:本文章取自作者對google官方博客的學習,並非直接翻譯過來。
5.0提供了兩個新的Widget,它們使用了Material Design 的style和animation: RecyclerView 一個更可插拔式的ListVie
前言 在微信剛流行的時候,在搖一搖還能用來那啥的時候,我也曾深更半夜的拿著手機晃一晃。當時想的最多的就是,我靠,為神馬搖一下需要用這麼大的力度,當時我想可能騰訊覺
Device Administration對於這個應用,市場上很多,但是看一下評論就知道效果有多差了,因為99%一鍵鎖屏應用沒辦法卸載。今天就開發一個小應用,實現輕松點擊
MVP模式 ListView中嵌入checkBox的使用本文寫的是一個小demo,如何在ListView中嵌入checkBox配合使用,本篇文章與前面的嵌入Button類