本文主要利用ADB通信,通过USB数据线将PC与android手机连接,通过PC控制android实现短信发送,短信接收回调,等等其他功能。这里只实现 了短信的发送与接收短信的回调。
过程中遇到的难点主要有:
1、ADB通信问题,由于android在2.3之后才实现了USB相关事件的接口调用,因此使用了adb端口转发来实现。
2、短信拦截问题,很多手机比如小米和魅族在系统内部区别,使得拦截不到短信的broadcast,因此只能使用ContentObserver来实现短信监听。
主要运行流程:
手机端启动MainActivity后会启动MainService。
MainService在Oncreate方法中创建ServerSocket来监听处理PC发起的Socket请求。
PC客户端启动后,启动ADB服务,将配置的端口设置给ADB转发。pc获取adb发现的设备并连接。并发送相关命令。
下图是PC客户端工程结构:
先上PC客户端相关代码:
Main.java是一个测试用程序
1 public class Main { 2 3 /** 4 * @param args 5 * @throws DeviceNotFoundException 6 * @throws InterruptedException 7 * @throws IOException 8 * @throws AdbCommandRejectedException 9 * @throws TimeoutException 10 */ 11 public static void main(String[] args) throws TimeoutException, AdbCommandRejectedException, IOException, InterruptedException, DeviceNotFoundException { 12 String TAG ="main test"; 13 14 DeviceHelper helper = new DeviceHelper(); 15 helper.setDeviceListener(new DeviceListener() { 16 @Override 17 public void onSendSmsReport(SmsResault resault) { 18 Utils.LogErr("SmsReport:"+JSON.toJSONString(resault)); 19 } 20 21 @Override 22 public void onRecivedSms(List<SmsInfo> smses) { 23 Utils.LogErr("RecivedSms:"+JSON.toJSONString(smses)); 24 } 25 26 @Override 27 public int onFoundMultDevice(IDevice[] devices) { 28 // TODO Auto-generated method stub 29 return 0; 30 } 31 32 @Override 33 public void onDeviceReport(Cmd cmd) { 34 // TODO Auto-generated method stub 35 Utils.LogErr("DeviceReport:"+JSON.toJSONString(cmd)); 36 } 37 38 @Override 39 public void onDeviceDidCmd(Cmd cmd) { 40 // TODO Auto-generated method stub 41 Utils.LogErr("DeviceDidCmd:"+JSON.toJSONString(cmd)); 42 } 43 44 @Override 45 public void onDeviceConnected(IDevice device) { 46 // TODO Auto-generated method stub 47 Connector.printDevice(device); 48 } 49 }); 50 51 helper.connect(); 52 53 String cmd =""; 54 BufferedReader br=new BufferedReader(new InputStreamReader(System.in)); 55 while(true){ 56 Utils.Log("输入内容:"); 57 cmd = br.readLine(); 58 if(cmd.equalsIgnoreCase("EXIT")){ 59 break; 60 } 61 62 helper.sendMsg(cmd); 63 64 } 65 helper.close(); 66 67 } 68 69 }
DeviceHelper.java是封装好的设备连接通信类
public class DeviceHelper { final static int CLIENT_LOCAL_PORT = ResourceUtil.getConfig( ResourceUtil.CLIENT_LOCAL_PORT, 12580); final static int CLIENT_REMOTE_PORT = ResourceUtil.getConfig( ResourceUtil.CLIENT_REMOTE_PORT, 10086); private Socket socket; private BufferedOutputStream out; private BufferedInputStream in; private InetAddress serverAddr; private DeviceListener deviceListener; private static boolean running = true; public DeviceHelper() throws UnknownHostException { super(); serverAddr = InetAddress.getByName(ResourceUtil.getConfig(ResourceUtil.SERVER_ADDR, "127.0.0.1")); } public DeviceHelper(DeviceListener deviceListener) throws UnknownHostException { this(); this.deviceListener = deviceListener; } /**发送短信 * @param sms 需要发送的短信,支持群发 * @throws IOException 手机没有连接或者向手机发送命令出错 */ public void sendSms(SmsInfo sms) throws IOException { out.write(CmdEnum.SEND_SMS.getCode().getBytes()); out.write(JSON.toJSONString(sms).getBytes()); out.flush(); } /**向手机发送字符串 * @param msg * @throws IOException 手机没有连接或者向手机发送命令出错 */ public void sendMsg(String msg) throws IOException{ out.write(msg.getBytes()); out.flush(); } /** * @param cmdEnum 需要执行的命令类型 * @throws IOException 手机没有连接或者向手机发送命令出错 */ public void excuteCmd(CmdEnum cmdEnum,DataObject data) throws IOException{ out.write(cmdEnum.getCode().getBytes()); out.write((JSON.toJSONString(data)).getBytes()); out.flush(); } /** * 关闭与手机连接 */ public void close(){ running = false; } /**手机是否连接 * @return */ public boolean isConnected(){ return running && socket.isConnected(); } /**打开与手机的连接 * @throws TimeoutException 连接超时 * @throws AdbCommandRejectedException adb拒绝连接 * @throws IOException IO错误 * @throws InterruptedException * @throws DeviceNotFoundException 设备未找到 */ public void connect() throws TimeoutException, AdbCommandRejectedException, IOException, InterruptedException, DeviceNotFoundException { AndroidDebugBridge.init(false); Connector connector = new Connector(deviceListener); IDevice device = connector.getDevice(); if (null != deviceListener) { deviceListener.onDeviceConnected(device); } device.createForward(CLIENT_LOCAL_PORT, CLIENT_REMOTE_PORT); Thread.sleep(3000); new Thread() { public void run() { try { socket = new Socket(serverAddr, CLIENT_LOCAL_PORT); socket.setTcpNoDelay(true); out = new BufferedOutputStream(socket.getOutputStream()); in = new BufferedInputStream(socket.getInputStream()); while (running && socket.isConnected()) { try { String say = Utils.readFromSocket(in); Cmd cmd = Cmd.getCmd(say); doAction(cmd); } catch (Exception e) { e.printStackTrace(); Utils.LogErr("手机断开了连接"); break; } } in.close(); out.close(); socket.close(); in = null; out = null; } catch (IOException e) { e.printStackTrace(); } } }.start(); } private void doAction(Cmd cmd) { if (null != deviceListener) { deviceListener.onDeviceReport(cmd); } switch (cmd.getCmdEnum()) { case SMS_RECIVED: try { List<SmsInfo> smses = JSON.parseArray(cmd.getJsonStr(), SmsInfo.class); if (null != deviceListener) { deviceListener.onRecivedSms(smses); } } catch (Exception e) { e.printStackTrace(); } break; case SMS_REPORT: try { SmsResault ssr = JSON.parseObject(cmd.getJsonStr(),SmsResault.class); if (null != deviceListener) { deviceListener.onSendSmsReport(ssr); } } catch (Exception e) { e.printStackTrace(); } break; default: if (null != deviceListener) { deviceListener.onDeviceDidCmd(cmd); } break; } } /** * @return the deviceListener */ public DeviceListener getDeviceListener() { return deviceListener; } /** * @param deviceListener the deviceListener to set */ public void setDeviceListener(DeviceListener deviceListener) { this.deviceListener = deviceListener; } public interface DeviceListener { /** * 当手机连接上触发 * * @param device */ public void onDeviceConnected(IDevice device); /** * 手机接收到新短信 * * @param smses */ public void onRecivedSms(List<SmsInfo> smses); /**当手机发送短信后,得到短信发送结果时触发 * @param resault 发送短信的结果 */ public void onSendSmsReport(SmsResault resault); /** * 手机执行pc发出的命令后的触发 * * @param cmd * 返回的命令类型以及返回的描述信息 */ public void onDeviceDidCmd(Cmd cmd); /**当PC获取到手机返回任何信息时触发 * @param cmd */ public void onDeviceReport(Cmd cmd); /**当连接手机时发现多个手机时,需要选择连接的手机 * <br> * 使用Connector.printDevice(IDevice)打印设备信息 * * @param devices 手机列表 * @return 选择的devices[<b>index<b>] */ public int onFoundMultDevice(IDevice devices[]); } }
Connector.java连接adb,设置转发相关端口、获取设备等,
public class Connector { /** * ADB服务器路径 */ static String ADB_PATH = ResourceUtil.getConfig(ResourceUtil.ADB_PATH, "C:\\Android\\adt-bundle-windows-x86_64-20130522\\sdk\\platform-tools\\adb.exe"); //"C:\\Android\\adt-bundle-windows-x86_64-20130522\\sdk\\platform-tools\\adb.exe"; /** * 是否尝试连接 */ static boolean TRY_CONNECT = true; /** * 最大连接次数 */ static int MAX_CONNECT_TIMES = 1000; /** * 连接超时时间 */ static long MAX_TIME_OUT = 1*60*1000; private DeviceListener deviceListener; public Connector(DeviceListener deviceListener) { super(); this.deviceListener = deviceListener; } public class DeviceNotFoundException extends Exception{ public DeviceNotFoundException(String string) { super(string); } private static final long serialVersionUID = 2583563525250398962L; } /**打印设备基础信息 * @param device */ public static void printDevice(IDevice device){ Utils.Log("AvdName:"+device.getAvdName()); Utils.Log("Name:"+device.getName()); Utils.Log("SerialNumber:"+device.getSerialNumber()); try { Utils.Log("BatteryLevel:"+device.getBatteryLevel()); } catch (TimeoutException e) { e.printStackTrace(); } catch (AdbCommandRejectedException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } catch (ShellCommandUnresponsiveException e) { e.printStackTrace(); } Utils.Log("Properties:"+device.getProperties()); Utils.Log("========================"); } /** * 获取得到device对象 * * @return * @throws DeviceNotFoundException */ public IDevice getDevice() throws DeviceNotFoundException { IDevice device; AndroidDebugBridge bridge = AndroidDebugBridge .createBridge(ADB_PATH, true);// 如果代码有问题请查看API,修改此处的参数值试一下 waitDevicesList(bridge); IDevice devices[] = bridge.getDevices(); if(null==devices || 0==devices.length){ throw new DeviceNotFoundException("没有设备连接到PC,确认安装了驱动?"); } int index = 0; if(null!=deviceListener){ index = deviceListener.onFoundMultDevice(devices); } device = devices[index]; return device; } /** * 等待查找device * * @param bridge */ private void waitDevicesList(AndroidDebugBridge bridge) { int count = 1; long start = System.currentTimeMillis(); while (bridge.hasInitialDeviceList() == false) { try { Thread.sleep(500); } catch (InterruptedException e) { e.printStackTrace(); } Utils.Log("等待获取设备..."+count); if(TRY_CONNECT){ long now = System.currentTimeMillis(); count++; if (count > MAX_CONNECT_TIMES || (now-start)>MAX_TIME_OUT) { Utils.LogErr("等待获取设备超时"); break; } } } } }
configs.properties是相关配置文件。包含转发端口,ADB路径等
PC客户端主要代码如上。
以下是手机客户端主要代码:
MainActivity.java
public class MainActivity extends Activity { static String TAG ="MainActivity"; private ServiceReceiver receiver = new ServiceReceiver(); AQuery aq = new AQuery(this); private List<String>cmds = new ArrayList<String>(); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); requestWindowFeature(Window.FEATURE_NO_TITLE); // getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, // WindowManager.LayoutParams.FLAG_FULLSCREEN); setContentView(R.layout.activity_main); startService(new Intent(this, MainService.class)); } @Override public boolean onCreateOptionsMenu(Menu menu) { getMenuInflater().inflate(R.menu.main, menu); return true; } @Override protected void onResume() { IntentFilter filter = new IntentFilter(MainService.BROADCAST_ACTION); //注册 registerReceiver(receiver,filter); super.onResume(); } @Override protected void onDestroy() { unregisterReceiver(receiver); super.onDestroy(); } private class ServiceReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { Log.v(TAG, "BroadcastReceiver:"+intent.getStringExtra("msg")); String code = intent.getStringExtra("msg"); if(TextUtils.isEmpty(code)) return ; MsgEnum msgEnum = MsgEnum.getByValue(Integer.parseInt(code)); switch (msgEnum) { case RECIVED_CMD: { String obj = intent.getStringExtra("obj"); if(TextUtils.isEmpty(obj)) break ; cmds.add(obj); if(cmds.size()>10) cmds.remove(0); StringBuilder sb = new StringBuilder(); for(int i=cmds.size()-1;i>=0;i--){ sb.append(cmds.get(i)+"\n"); } aq.id(R.id.text_statusline).text(sb.toString()); } break; case SERVER_PORT_CHANGE: break; case CLIENT_CONNECTED: aq.id(R.id.text_server_runing).text("PC已经连接"); break; case CLIENT_CLOSED: aq.id(R.id.text_server_runing).text("PC已经断开"); break; case START_SERVER: aq.id(R.id.text_server_runing).text("等待PC连接"); { String port = intent.getStringExtra("obj"); aq.id(R.id.text_server_port).text(port); } break; case RESTART_SERVER: aq.id(R.id.text_server_runing).text("重启服务中"); { String port = intent.getStringExtra("obj"); aq.id(R.id.text_server_port).text(port); } break; case SERVER_CLOSED: aq.id(R.id.text_server_runing).text("服务已经停止"); break; case SERVER_REPORT: { String port = intent.getStringExtra("port"); String run = intent.getStringExtra("run"); String time = intent.getStringExtra("time"); String trys = intent.getStringExtra("trys"); aq.id(R.id.text_server_port).text(port); aq.id(R.id.text_server_runing).text((run.equalsIgnoreCase("true")?"正在运行":"停止运行")); aq.id(R.id.text_server_starttime).text(time); aq.id(R.id.text_server_autorestart).text(trys); } break; default: break; } } } }
MainService.java
public class MainService extends Service { public static final String TAG = "MainService"; private final static String SEND_ACTION = "com.zcw.sms.SEND"; private final static String DELIVERED_ACTION = "com.zcw.sms.DELIVERED"; private final static String RECIVED_ACTION = "android.provider.Telephony.SMS_RECEIVED"; public final static String BROADCAST_ACTION = "com.zcw.sms.broadcast"; private BufferedOutputStream out; private BufferedInputStream in; private final static int MAX_TRY_START_SERVER_TIMES = 10; private static boolean running = true; private static int SERVER_PORT = 10086; private Date serverStartTime = new Date(); private Date smsRecivedTime = new Date(); Handler handler = new Handler() { @Override public void handleMessage(Message msg) { Map<String,String> data = new HashMap<String,String>(); data.put("msg", String.valueOf(msg.what)); Object sme = msg.obj; if(null!=sme){ data.put("obj", (String) sme); } broadcast(data); MsgEnum msgEnum = MsgEnum.getByValue(msg.what); switch (msgEnum) { case RECIVED_CMD: try { doCmd(Cmd.getCmd((String) msg.obj)); } catch (IOException e1) { e1.printStackTrace(); } break; case SERVER_PORT_CHANGE: break; case CLIENT_CONNECTED: break; case CLIENT_CLOSED: break; case START_SERVER: smsRecivedTime = new Date(); break; case RESTART_SERVER: break; case SERVER_CLOSED: break; default: break; } super.handleMessage(msg); } }; @Override public void onCreate() { // resolver = getContentResolver(); new Thread() { @Override public void run() { startServer(); super.run(); } }.start(); } @Override public void onStart(Intent intent, int startId) { Log.d(TAG, Thread.currentThread().getName() + "---->" + " onStart()"); super.onStart(intent, startId); // Uri inSMSUri = Uri.parse("content://sms") ; getContentResolver().registerContentObserver(inSMSUri,true,smsObserver); // 短信接收回调 // IntentFilter intentFilter = new IntentFilter(RECIVED_ACTION); // intentFilter.setPriority(Integer.MAX_VALUE); // registerReceiver(recivedBR,intentFilter); // 短信发送完成回调 registerReceiver(sendBR, new IntentFilter(SEND_ACTION)); // 对方接受短信完成回调 registerReceiver(delBR, new IntentFilter(DELIVERED_ACTION)); SimpleDateFormat sdf = new SimpleDateFormat("MM/dd HH:mm"); // 报告状态 Map<String,String> data = new HashMap<String,String>(); data.put("msg", String.valueOf(MsgEnum.SERVER_REPORT.getValue())); data.put("port", String.valueOf(SERVER_PORT)); data.put("run", running?"true":"false"); data.put("time", sdf.format(serverStartTime)); data.put("trys", String.valueOf(MAX_TRY_START_SERVER_TIMES)); broadcast(data); } @Override public IBinder onBind(Intent arg0) { Log.d(TAG, " onBind"); return null; } @Override public void onDestroy() { super.onDestroy(); running = false; getContentResolver().unregisterContentObserver(smsObserver); // 解除接受短信回调 // unregisterReceiver(recivedBR); // 解除短信发送完成回调 unregisterReceiver(sendBR); // 解除对方接受短信完成回调 unregisterReceiver(delBR); } /** * 启动服务 */ public void startServer() { int tryTimes = 0; /********************/ { Message msg = new Message(); msg.what = MsgEnum.START_SERVER.getValue(); msg.obj = String.valueOf(SERVER_PORT); handler.sendMessage(msg); } while (MAX_TRY_START_SERVER_TIMES >= tryTimes) { try { ServerSocket serverSocket = new ServerSocket(SERVER_PORT); Log.v(TAG, "server started ..."); serverStartTime = new Date(); while (running) { Log.v(TAG, "waite client ..."); Socket client = serverSocket.accept(); Log.v(TAG, "a client connected ..."); /********************/ { Message msg = new Message(); msg.what = MsgEnum.CLIENT_CONNECTED.getValue(); handler.sendMessage(msg); } out = new BufferedOutputStream(client.getOutputStream()); in = new BufferedInputStream(client.getInputStream()); while (true) { if (!client.isConnected()) { break; } try { String cmd = readFromSocket(in); Log.v(TAG, "client say:" + cmd); /********************/ Message msg = new Message(); msg.what = MsgEnum.RECIVED_CMD.getValue(); msg.obj = cmd; handler.sendMessage(msg); } catch (Exception e) { e.printStackTrace(); break; } } try { in.close(); out.close(); client.close(); in = null; out = null; } catch (Exception e) { e.printStackTrace(); } /********************/ { Message msg = new Message(); msg.what = MsgEnum.CLIENT_CLOSED.getValue(); handler.sendMessage(msg); } } } catch (IOException e) { e.printStackTrace(); } SERVER_PORT++; if(MAX_TRY_START_SERVER_TIMES >= tryTimes){ /********************/ { Message msg = new Message(); msg.what = MsgEnum.RESTART_SERVER.getValue(); msg.obj = String.valueOf(SERVER_PORT); handler.sendMessage(msg); } } } /********************/ { Message msg = new Message(); msg.what = MsgEnum.SERVER_CLOSED.getValue(); handler.sendMessage(msg); } } /* 读取命令 */ public static String readFromSocket(InputStream in) throws IOException { int MAX_BUFFER_BYTES = 2048; String msg = ""; byte[] tempbuffer = new byte[MAX_BUFFER_BYTES]; int numReadedBytes = in.read(tempbuffer, 0, tempbuffer.length); msg = new String(tempbuffer, 0, numReadedBytes, "utf-8"); tempbuffer = null; // Log.v(Service139.TAG, "msg=" + msg); return msg; } /** * 短信接受观察者 */ private ContentObserver smsObserver = new ContentObserver(handler){ @Override public void onChange(boolean selfChange) { //查询发件箱里的内容 Uri inSMSUri = Uri.parse("content://sms/inbox"); Cursor cursor = getContentResolver().query(inSMSUri, null, " read = '0' ", null,"date desc"); if(cursor != null){ Log.i(TAG, "the number of inbox is"+cursor.getCount()) ; List<SmsInfo> smses = new ArrayList<SmsInfo>(); //循环遍历 while(cursor.moveToNext()){ Date time = new Date(cursor.getLong(cursor.getColumnIndex("date"))); if(smsRecivedTime.after(time)) break; smsRecivedTime = new Date(); SmsInfo smsInfo = new SmsInfo(); smsInfo.setAddress(new String[] { cursor.getString(cursor.getColumnIndex("address")) }); smsInfo.setBody(cursor.getString(cursor.getColumnIndex("body"))); smsInfo.setTime(String.valueOf(time.getTime())); smsInfo.setType("1"); smses.add(smsInfo); } cursor.close(); if(!smses.isEmpty()){ try { out.write(CmdEnum.SMS_RECIVED.getCode().getBytes()); out.write(JSON.toJSONString(smses).getBytes()); out.flush(); } catch (Exception e) { e.printStackTrace(); } } } super.onChange(selfChange); } }; /** * 短信接受回调 */ private BroadcastReceiver recivedBR = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { // StringBuilder sb = new StringBuilder(); Bundle bundle = intent.getExtras(); if (null != bundle) { Object[] pdus = (Object[]) bundle.get("pdus"); SmsMessage[] msg = new SmsMessage[pdus.length]; for (int i = 0; i < pdus.length; i++) { msg[i] = SmsMessage.createFromPdu((byte[]) pdus[i]); } for (SmsMessage oneMsg : msg) { SmsInfo smsInfo = new SmsInfo(); smsInfo.setAddress(new String[] { oneMsg .getDisplayOriginatingAddress() }); smsInfo.setBody(oneMsg.getDisplayMessageBody()); smsInfo.setTime(String.valueOf(oneMsg.getTimestampMillis())); smsInfo.setType("1"); Log.v(TAG, "recived sms:" + oneMsg.getDisplayMessageBody()); try { out.write(CmdEnum.SMS_RECIVED.getCode().getBytes()); out.write(JSON.toJSONString(smsInfo).getBytes()); out.flush(); } catch (Exception e) { e.printStackTrace(); break; } } } } }; /** * 短信发送回调 */ private BroadcastReceiver sendBR = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { String to = intent.getStringExtra("to"); String content = intent.getStringExtra("content"); Log.v(TAG, "sms sended " + content); SmsResault ssr = new SmsResault(); ssr.setAction(0); ssr.setContent(content); ssr.setResultCode(getResultCode()); ssr.setSendTo(to); ssr.setTime(new Date()); try { out.write(CmdEnum.SMS_REPORT.getCode().getBytes()); out.write(JSON.toJSONString(ssr).getBytes()); out.flush(); } catch (Exception e) { e.printStackTrace(); } } }; /** * 短信抵达回调 */ private BroadcastReceiver delBR = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { String to = intent.getStringExtra("to"); String content = intent.getStringExtra("content"); Log.v(TAG, "sms delvered " + content); SmsResault ssr = new SmsResault(); ssr.setAction(1); ssr.setContent(content); ssr.setResultCode(getResultCode()); ssr.setSendTo(to); ssr.setTime(new Date()); try { out.write(CmdEnum.SMS_REPORT.getCode().getBytes()); out.write(JSON.toJSONString(ssr).getBytes()); out.flush(); } catch (Exception e) { e.printStackTrace(); } } }; /** * 执行PC发来的命令 * * @param cmd * @throws IOException */ public void doCmd(Cmd cmd) throws IOException { if(null==cmd || null==cmd.getCmdEnum()){ out.write(CmdEnum.CMD_ERROR.getCode().getBytes()); out.write("CMD ERROR.".getBytes()); out.flush(); return ; } switch (cmd.getCmdEnum()) { case SEND_SMS: sendSms(cmd); break; case READ_SMS: readSms(); break; case RECIVE_FILE: break; case STOP: break; default: break; } } /** * 发送短信操作 * * @param cmd * @throws IOException */ public void sendSms(Cmd cmd) throws IOException { SmsInfo sms = (SmsInfo) cmd.getDataObject(); if(null==sms){ out.write(CmdEnum.SEND_SMS.getCode().getBytes()); out.write("ERROR,NO SMS INFO FOUND.".getBytes()); out.flush(); Log.v(TAG,"sms cmd error,no address and body."); return; } SmsManager smsManager = SmsManager.getDefault(); List<String> contents; /* 分割短信内容 */ if (sms.getBody().length() > 70) { contents = smsManager.divideMessage(sms.getBody()); } else { contents = new ArrayList<String>(); contents.add(sms.getBody()); } /* 发送短信 */ for (String to : sms.getAddress()) { Log.v(TAG, Thread.currentThread().getName() + "---->" + "send sms: " + to + "[" + sms.getBody() + "]"); for (String sms_one : contents) { Intent sendIntent = new Intent(SEND_ACTION); sendIntent.putExtra("to", to); sendIntent.putExtra("content", sms_one); PendingIntent sentPI = PendingIntent.getBroadcast( MainService.this, 0, sendIntent, PendingIntent.FLAG_CANCEL_CURRENT); Intent delivIntent = new Intent(DELIVERED_ACTION); delivIntent.putExtra("to", to); delivIntent.putExtra("content", sms_one); PendingIntent deliveredPI = PendingIntent.getBroadcast( MainService.this, 0, delivIntent, PendingIntent.FLAG_CANCEL_CURRENT); smsManager.sendTextMessage(to, null, sms_one, sentPI, deliveredPI); /** 将发送的短信插入数据库 **/ ContentValues values = new ContentValues(); // 发送时间 values.put("date", System.currentTimeMillis()); // 阅读状态 values.put("read", 0); // 1为收 2为发 values.put("type", 2); // 送达号码 values.put("address", to); // 送达内容 values.put("body", sms_one); // 插入短信库 getContentResolver().insert(Uri.parse("content://sms"), values); } } out.write(CmdEnum.SEND_SMS.getCode().getBytes()); out.write("OKAY".getBytes()); out.flush(); } public void readSms() throws IOException { ContentResolver resolver = getContentResolver(); if (null == resolver) { out.write(CmdEnum.READ_SMS.getCode().getBytes()); out.write("FAILD,PLEASE RESTART APP ON PHONE.".getBytes()); out.flush(); return; } int smsCount = 0; Cursor cusor = resolver.query(Uri.parse("content://sms/inbox"), null, null, null, "date desc"); int phoneNumberColumn = cusor.getColumnIndex("address"); int smsbodyColumn = cusor.getColumnIndex("body"); int dateColumn = cusor.getColumnIndex("date"); int typeColumn = cusor.getColumnIndex("type"); if (null != cusor) { while (cusor.moveToNext()) { SmsInfo smsinfo = new SmsInfo(); smsinfo.setTime(cusor.getString(dateColumn)); smsinfo.setAddress(new String[] { cusor .getString(phoneNumberColumn) }); smsinfo.setBody(cusor.getString(smsbodyColumn)); smsinfo.setType(cusor.getString(typeColumn)); String json = JSON.toJSONString(smsinfo); out.write(CmdEnum.READ_SMS.getCode().getBytes()); out.write(json.getBytes()); out.flush(); smsCount++; } cusor.close(); } if (0 == smsCount) { out.write(CmdEnum.READ_SMS.getCode().getBytes()); out.write("EMPTY".getBytes()); out.flush(); } } private void broadcast(String key,String data){ Intent intent = new Intent(); intent.putExtra(key,data); intent.setAction(BROADCAST_ACTION); sendBroadcast(intent); Log.v(TAG,"send broadcast:"+data); } private void broadcast(Map<String,String>data){ Intent intent = new Intent(); for(String key : data.keySet()){ intent.putExtra(key,data.get(key)); } intent.setAction(BROADCAST_ACTION); sendBroadcast(intent); } }
附带完整源码:
android工具库WidgetLibrary.rar
android 端代码PhoneHelper.rar
pc 端代码 ConnectAndroid.rar
附带个人设计的图标PSD,勿吐槽...