android 学习receiver和发送广播,其中监听其他activity的启动demo;给activity加自定义权限只有指定有权限的app可以监听到
1、如果不创建activity只静态注册一个receiver,receiver不在运行,即无法监听!为了解决这个问题花了好长时间才查资料得: 一个APK包中如果没有actvity,只有Receiver,即使安装了Receiver不会启动,收不到广播。
在后面的学习中发现servicce是可以独自存在,但需要别的应用程序的activity启动服务service。http://www.cnblogs.com/bokeofzp/p/4733722.html
2、创建activity后静态注册了receiver后可以接收到短信广播,但将应用的优先级调到最高,调用abortBroadcast()后仍然可以收到短信,在写下面的代码期间发生了一个小插曲。就是SmsMessage 被弃用,后来才发现是导错了包,有一个相同名的包废弃了。
package com.example.smsreceiver; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.os.Bundle; import android.telephony.SmsMessage; public class Smsreceiver222 extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { // TODO Auto-generated method stub Bundle bundle= intent.getExtras(); Object[] ob=(Object[]) bundle.get("pdus"); // Object[] ob=(Object[]) intent.getExtras().get("pdus"); for(Object obj:ob) { SmsMessage sm=SmsMessage.createFromPdu((byte[])obj); System.out.println(sm.getMessageBody()+"来源:"+sm.getOriginatingAddress()); } abortBroadcast(); System.out.println("拦截"); } }
根据上面android 4的更新我查了下资料,并觉得一篇文章讲的不错http://blog.csdn.net/maybe_windleave/article/details/17740345,原来android4.4后,短信的功能有了很大的转变,只有指定的默认的短信应用才有写SMS_DELIVER_ACTION(sms)&& WAP_PUSH_DELIVER_ACTION(MMS)这两个intent来给默认的短信应用,也就是说只有默认的短信应用才能收到这两个广播,也只有能收到这两个广播的应用才能对短彩信的数据库进行写操作。也就是说只有默认短信应用才能存储短信。其他的非默认短信应用如果想收短信,可以监听:SMS_RECEIVED_ACTION 当然这些应用也只能显示下短信,并不能存入数据库。非系统的短信应用,如果想进行发短信操作的话,可以在申请了SEND_SMS权限之后,调用SmsManager接口进行短信发送操作。只有非系统短信应用在发送短信之后,framework才会将这条短信写入数据库,(系统短信应用会自己写入数据库)。
因为一个应用如果不是默认的短信应用,其很多设计的东西都不可用的,和成为默认短信应用差别非常大,因此有必要进行一些容错操作。首先,界面resume的时候需要检查下是否是默认的,可以通过查询:Telephony.Sms.getDefaultSmsPackage()来判断自己是不是默认的短信应用。如果不是建议就disable短信发送操作,因为如果用户发送彩信的话,系统不会帮忙写入数据库,应用自己又不能写入数据库,情况就很糟糕了……当然如果不是默认短信应用的话,也可以提示用户选择是否设置下,毕竟愿意点击你的应用,基本都是想用的。
(1)静态注册的xml文件,
android:priority="1000" >是接收有序广播的优先级,范围是[-1000,1000],接收到广播的顺序是由高到低的,相同级别的接受者接收广播的顺序是随机的。
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.smsreceiver" android:versionCode="1" android:versionName="1.0" > <uses-sdk android:minSdkVersion="8" android:targetSdkVersion="19" />
<uses-permission android:name="android.permission.RECEIVE_SMS"/> <application android:allowBackup="true" android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@style/AppTheme" > <activity android:name="com.example.smsreceiver.MainActivity" android:label="@string/app_name" > <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <receiver android:name=".Smsreceiver222"> <intent-filter android:priority="1000" > <action android:name="android.provider.Telephony.SMS_RECEIVED" /> </intent-filter> </receiver> </application> </manifest>
(2)、动态注册广播接收者
public void onclick(View v) { System.out.println("启动接受者"); BroadcastReceiver receiver=new Smsreceiver222(); IntentFilter f=new IntentFilter("android.provider.Telephony.SMS_RECEIVED"); registerReceiver(receiver,f );//第一个参数是启动的广播接收者,第二个参数是过滤器,即<action:android:name="android.provider.Telephony.SMS_RECEIVED"/>
}
二、自定义事件和发送该事件的广播,并监听这个事件。我们在点击控件启动另外一个activity时候,可以发送一个广播,并且设定接收这个广播的接受者,程序中采用动态和静态2中注册方式:
1清单文件
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.smsreceiver" android:versionCode="1" android:versionName="1.0" > <uses-sdk android:minSdkVersion="8" android:targetSdkVersion="19" /> <application android:allowBackup="true" android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@style/AppTheme" > <activity android:name="com.example.smsreceiver.MainActivity" android:label="@string/app_name" > <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <activity android:name=".Activity2" android:label="com.example.smsreceiver.Activity2" > <intent-filter> <action android:name="SecondActivity" /> <category android:name="android.intent.category.DEFAULT" /> </intent-filter> </activity> <receiver android:name=".Smsreceiver222"> <intent-filter > <action android:name="SecondActivity" /> <category android:name="receiver"/> </intent-filter> </receiver> </application> </manifest>
2、2个activity
package com.example.smsreceiver; import android.support.v7.app.ActionBarActivity; import android.support.v7.app.ActionBar; import android.support.v4.app.Fragment; import android.content.BroadcastReceiver; import android.content.Intent; import android.content.IntentFilter; import android.os.Bundle; import android.view.LayoutInflater; import android.view.Menu; import android.view.MenuItem; import android.view.View; import android.view.ViewGroup; import android.widget.Button; import android.os.Build; public class MainActivity extends ActionBarActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); } public void onclick(View v)//为启动第二个activity的button的点击事件 { // 动态启动接受者; BroadcastReceiver receiver=new Smsreceiver222(); IntentFilter f=new IntentFilter("SecondActivity"); registerReceiver(receiver,f ); Intent intent=new Intent("SecondActivity"); intent.addCategory("android.intent.category.DEFAULT");//intent 启动activity和启动广播即使action相同也不能使用同一个intent,否则广播会失效,得定义2个intent startActivity(intent); sendBroadcast(new Intent("SecondActivity")); } } package com.example.smsreceiver; import android.app.Activity; import android.os.Bundle; public class Activity2 extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { // TODO Auto-generated method stub super.onCreate(savedInstanceState); setContentView(R.layout.activity_main2); } }
三、发送广播api的介绍:
sendBroadcast(intent); // 发送一条广播
sendOrderedBroadcast(intent, receiverPermission); // 发送一条有序广播
sendOrderedBroadcast(intent, receiverPermission, resultReceiver, scheduler, initialCode, initialData, initialExtras)如果用这个api发送广播,第三个参数resultReceiver指定了广播接收者,即便高的优先级的接受者调用 abortbroadcast()终止了广播,resultReceiver还是可以收到广播事件。
四、自定义广播接受者,和指定的应用程序app才能接受到广播的方法就是自定义权限,同样的方法也可以给相应的activity加权限。参见:http://blog.csdn.net/jiangwei0910410003/article/details/39671993
1、在发送广播的清单文件里自定义应用程序权限
<?xml version="1.0" encoding="utf-8" ?> - <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.tt.test" android:versionCode="1" android:versionName="1.0">
<uses-permission android:name="xvtian.gai.receiver" /> <permission android:protectionLevel="normal" android:name="xvtian.gai.receiver" />
- <application android:icon="@drawable/icon" android:label="@string/app_name"> - <activity android:name=".Main" android:label="@string/app_name"> - <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application> <uses-sdk android:minSdkVersion="7" /> </manifest>
2、发送广播
public void onClick(View v) { Intent i = new Intent("COM.MESSAGE"); i.addCategory("receiver"); i.putExtra("message", "haha"); sendOrderedBroadcast(i, "xvtian.gai.receiver"); }
3接收广播的清单文件,在主目录里加上用户权限后再在receiver里加上权限就可以接收到上面应该的广播了。
<?xml version="1.0" encoding="utf-8" ?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.tt.receiver" android:versionCode="1" android:versionName="1.0">
<uses-permission android:name="xvtian.gai.receiver" />
<application android:icon="@drawable/icon" android:label="@string/app_name"> <activity android:name=".Main" android:label="@string/app_name"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity>
<receiver android:name=".Receiver" android:permission="xvtian.gai.receiver"> <intent-filter> <action android:name="COM.MESSAGE" /> <category android:name="receiver" /> </intent-filter> </receiver>
</application> <uses-sdk android:minSdkVersion="7" /> </manifest>