实现Android助手类应用

本文主要利用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)+"
");
                    }
                    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,勿吐槽...

phone_helper_icon.rar

原文地址:https://www.cnblogs.com/zhouchanwen/p/3372301.html