两个小时在Android上写个小应用(上)
那天酒精同学跑来问我要一个Android应用:在晚间能够让特定的短信不发出声响。
当时我的第一反应是短信屏蔽。
查阅过相关文档后我发现短信屏蔽功能在Android上是无法在应用层实现的,因为系统在接收SMS后会发送一条广播,Android SDK在M5之后改变了SMS广播的播送方式,使得广播无法在处理过程中取消,应用程序便无法干预这条广播的传递了。
那么我们就改变一下屏蔽方式,关闭系统的Message程序的声音和震动,把提醒功能交给我们的程序来做,这样虽然不是一个纯粹意义上的短信屏蔽程序,但是正好可以满足酒精同学的需求。
那么我们要做的程序就非常简单了:监听系统的SMS广播 -> 过滤SMS -> 提醒
新建一个Android项目,建立一个BroadcastReceiver子类SmsReceiver。
要让SmsReceiver接收到系统的广播,还需要在AndroidManifest.xml中注册一下,并且添加接收短信的权限(要接收短信需要添加相应的权限。这里我们也顺便把后面用到的震动权限也添加了):
<manifest xmlns:android="http://schemas.android.com/apk/res/android" .... <receiver android:name=".SmsReceiver"> <intent-filter> <action android:name="android.provider.Telephony.SMS_RECEIVED" /> </intent-filter> </receiver> </application> <uses-sdk android:minSdkVersion="3" /> <uses-permission android:name="android.permission.RECEIVE_SMS" /> <uses-permission android:name="android.permission.VIBRATE"></uses-permission> </manifest>
这里的"android.provider.Telephony.SMS_RECEIVED"就是SMS广播的消息名称(ACTION_NAME),像这样的信息在哪里可以找到呢?别忘了Android是一个开源项目,Message程序也是开源的。你可以在http://android.git.kernel.org/找到相关的代码。
然后我们跳过过滤SMS,实现一个提醒功能。这里我们创建一个Activity,他做的唯一一件事情就是发送提醒,然后退出。所以他没有界面。建立一个Activity的子类Notify:
static final int NOTIFICATION_ID = 12; /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); Notification n = new Notification(); PendingIntent pendIntent = PendingIntent.getActivity(this, 0, new Intent(this, Setting.class), Intent.FLAG_ACTIVITY_NEW_TASK); n.setLatestEventInfo(this, "Sms Filter", "Please ignore me!!", pendIntent); n.defaults |= n.DEFAULT_VIBRATE | n.DEFAULT_SOUND; n.flags |= Notification.FLAG_SHOW_LIGHTS; n.ledARGB = 0xff00ff00; n.ledOnMS = 500; n.ledOffMS = 2000; NotificationManager nm = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); nm.notify(NOTIFICATION_ID, n); finish(); }
上面的onCreate方法在最后一行调用finish()直接退出,所以系统消息栏并不会显示消息,但是提示声、震动和闪烁灯都被激活了。这里的提示音和震动都是系统默认的,后面我们还将会加入提示音选择功能。
接着打开SmsReceive.java,当接收到消息提示的时候,启动Notify就可以了。
@Override public void onReceive(Context context, Intent intent) { Intent i = new Intent(context, Notify.class); i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); context.startActivity(i); }
此时就可以运行程序测试其效果了。如果你只有模拟器的话,可以在Eclipse里打开DDMS(没有看到?打开Window->Open Perspective->Others...)中的Emulator Control中模拟一条SMS。不过你感收不到震动和提示音。
程序的第一部分就完成了,剩下的事情就是过滤SMS了,下面我们要做的是实现一个PreferenceActivity,让用户制定黑名单、选择屏蔽的时间段,以及定制提示音。

欲知如何实现,请听下一小时的课程。











