本文主要利用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,勿吐槽...
phone_helper_icon.rar