最近项目有一个需求,android PDA无法使用有线与无线网络,只能使用USB线,需要业务需通过sqlite处理好后同步到服务器上。
设计思路:PDA将数据同步到电脑上,电脑同步到服务器上
1.android 《======》 pc
采取了一种建立在adb基础之上的Usb通信方式:由于adb可以将Usb模拟为网卡,所以可以利用socket通信的方式实现Android与PC通信,以完成同步功能
一、Android作为server,侦探socket连接请求;添加一个服务类来实现侦听功能。
二、PC端作为Client,请求建立socket连接。
三、Android端添加一个广播接收类,接受PC端通过Adb发送的广播消息,以启动或者停止①中添加的服务。
四、PC端通过Adb发送广播消息通知Android端启动或停止用来侦听socket连接的服务
a、android 端
1.AndroidManifest.xml注册服务监听USB接入事件
<service
android:name=".service.BettyService"
android:enabled="true"
android:exported="true" />
<!--网络权限-->
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.INTERNET" />
2.android服务
package com.cmeim.pcp.demodata.service;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import com.cmeim.pcp.demodata.net.SocketServerThread;
public class BettyService extends Service {
public BettyService() {
}
@Override
public IBinder onBind(Intent intent) {
// TODO: Return the communication channel to the service.
return null;
}
@Override
public void onCreate() {
super.onCreate();
new Thread(new SocketServerThread()).start();
}
}
3.socket服务端
package com.cmeim.pcp.demodata.net;
import android.util.Log;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket;
public class SocketServerThread extends Thread {
private BufferedOutputStream out;
private Socket client;
private ServerSocket serverSocket;
private static final int SERVER_PORT = 20000;
@Override
public void run() {
try {
if (serverSocket != null) {
return;
}
serverSocket = new ServerSocket(SERVER_PORT);
client = serverSocket.accept();
out = new BufferedOutputStream(client.getOutputStream());
syncSendMsg();
// 开启子线程去读去数据
BufferedInputStream bufferedInputStream = new BufferedInputStream(client.getInputStream());
String msg = readMsgFromSocket(bufferedInputStream);
Log.e("PC同步到android的数据", msg);
} catch (IOException e) {
e.printStackTrace();
}
}
//读取PC端发送过来的数据
private String readMsgFromSocket(InputStream in) {
String msg = "";
byte[] temp = new byte[1024 * 1024 * 10];
try {
int readBytes = in.read(temp, 0, temp.length);
msg = new String(temp, 0, readBytes, "utf-8");
} catch (Exception e) {
e.printStackTrace();
}
return msg;
}
//发送消息
public void syncSendMsg() throws IOException {
out.write(("pda-data:同步数据").getBytes("UTF-8"));
out.flush();
}
public void close() {
try {
if (serverSocket != null) {
serverSocket.close();
}
if (out != null) {
out.close();
}
if (client != null) {
client.close();
}
} catch (Exception e) {
}
}
}
4.activity启动服务
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Intent intent= new Intent(this, BettyService.class);
startService(intent);// 启动服务
}
b.net客户端代码
public AsycData()
{
Process p = new Process(); //实例一个Process类,启动一个独立进程
p.StartInfo.FileName = "cmd.exe"; //设定程序名
p.StartInfo.UseShellExecute = false; //关闭Shell的使用
p.StartInfo.RedirectStandardInput = true; //重定向标准输入
p.StartInfo.RedirectStandardOutput = true; //重定向标准输出
p.StartInfo.RedirectStandardError = true; //重定向错误输出
p.StartInfo.CreateNoWindow = true; // 设置不显示窗口
p.StartInfo.ErrorDialog = false;
p.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
p.Start();
Thread thread = new Thread(initSocket);
thread.Start();
}
public TcpClient tcpClient=new TcpClient();
//连接
public bool DoConnect()
{
IPAddress ipaddress = IPAddress.Parse("127.0.0.1");
try
{
tcpClient.Connect(ipaddress, 12580);
}
catch (Exception e)
{
MessageBox.Show("网络连接失败");
return false;
}
Thread.Sleep(10);
if (tcpClient != null)
{
return true;
}
else
MessageBox.Show("网络连接失败");
return false;
}
public void initSocket()
{
if (DoConnect())
{
byte[] resut = new byte[1024 * 1024 * 10];
int data = 0;
NetworkStream networkStream = tcpClient.GetStream();
//同步数据
while ((data= networkStream.Read(resut, 0, resut.Length)) > 0)
{
String message = Encoding.UTF8.GetString(resut, 0, data);//只将接收到的数据进行转化
//接收到数据
if (message.Contains("pda-data:"))
{
MessageBox.Show(message);
byte[] outBound = Encoding.UTF8.GetBytes("PC已经收到消息了");
networkStream.Write(outBound, 0, outBound.Length);
}
}
}
}
c.adb启动命令
shell am broadcast -a NotifyServiceStop
adb forward tcp:12580 tcp:20000
adb shell am broadcast -a NotifyServiceStart
adb插件直接将android SDK里面的platform-tools文件夹拷出来,编写一个启动命令
测试流程:1连接USB
2.启动测试app
3.运行adb启动命令行
4.运行.net程序
结果:安卓数据发送桌面应用上,桌面应用数据发送到android应用上,实现数据同步只需要将数据转化成json,队应的程序执行响应的逻辑处理即可实现数据同步
源码文件:链接:https://pan.baidu.com/s/1VIbvroP1OIZ0RT9fqMXGyg
提取码:490g