最近因为课设要求,需要实现从安卓端向Python服务端发送数据,由于之前也没有做过,所以上网找了许多相关文章,之后也解决了几个问题,最后实现了这个需求。以下是相关代码。
Android端:
activity_main.xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<TextView
android:id="@+id/textView"
android:layout_width="match_parent"
android:layout_height="366dp"
android:gravity="center" />
<Button
android:id="@+id/start"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="开始监听" />
<Button
android:id="@+id/stop"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="停止监听" />
</LinearLayout>
MainActivity.java 这个函数的主要功能是将手机作为一个光传感器,获取传感器数据,之后将数据发送给python端。
public class MainActivity extends AppCompatActivity {
private TextView showLightPower;//用于显示光照强度的文本视图
private Button start;//按钮,点击开始监听传感器
private Button stop;//按钮,点击停止监听传感器
private SensorManager sensorManager;//传感器管理器,用于获取传感器服务,和选择传感器类型
private Sensor sensor;//传感器对象,储存光线传感器的数据
private SensorEventListener sensorEventListener;//传感器事件监听器,用于传感器事件的监听
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if (android.os.Build.VERSION.SDK_INT > 9) {
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);
}
//初始化控件
InitWidgets();
//初始化传感器相关,包含传感器管理器和传感器的设定
InitSensors();
//设置按钮点击监听器和传感器事件监听器
setListener();
}
/**
* 函数功能:初始化传感器相关,包含传感器管理器和传感器类型
*/
private void InitSensors() {
sensorManager=(SensorManager)getSystemService(SENSOR_SERVICE);//初始化传感器管理器
sensor=sensorManager.getDefaultSensor(Sensor.TYPE_LIGHT);//给传感器初始化类型
}
/**
* 函数功能:通过匿名内部类的方式实现按钮和传感器监听器接口,实现按钮和传感器的监听
*/
private void setListener(){
sensorEventListener=new SensorEventListener() {
/**
* 函数功能:重写传感器参数改变时实现的方法
* @param event
*/
@Override
public void onSensorChanged(SensorEvent event) {
String showInfo="";//用于存储传感器的光强信息
showInfo="光照强度:"+event.values[0]+"勒克斯";
try {
TransferToPython(event.values[0]);
} catch (IOException e) {
e.printStackTrace();
}
showLightPower.setText(showInfo);//设置TextView的显示光线传感器光强信息
}
/**
* 当传感器参数精度改变时,可以通过本方法实现
* @param sensor
* @param accuracy
*/
@Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
}
};
//设置开始监听按钮被点击时实现注册传感器事件监听器
start.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
sensorManager.registerListener(sensorEventListener,sensor, SensorManager.SENSOR_DELAY_FASTEST);//注册传感器
}
});
//设置关闭监听按钮被点击时实现取消注册传感器事件监听器
stop.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
sensorManager.unregisterListener(sensorEventListener);
}
});
}
/**
* 函数功能:初始化控件
*/
private void InitWidgets(){
//获取textview和button的实例
showLightPower=(TextView) findViewById(R.id.textView);
start=(Button) findViewById(R.id.start);
stop=(Button) findViewById(R.id.stop);
}
/*
* 发送信息
* */
private void TransferToPython(Float num) throws IOException {
System.out.println("发送端启动…………");
/*
* 1、创建udp传输的发送端
2、建立UDP的socket的服务
3、将要发送的数据封装到数据包中
4、通过udp的socket服务将数据包发送出去
5、关闭socket服务
*/
//udpsocket服务,使用DatagramSocket对象
DatagramSocket ds=new DatagramSocket(8888);//监听端口
//将要发送的数据封装到数据包中
String str = Float.toString(num);
System.out.println(str);
//使用DatagramPacket将数据封装到该对象中
byte[] buf=str.getBytes();
DatagramPacket dp=
new DatagramPacket(buf, buf.length, InetAddress.getByName("192.168.2.117"),7789);
//通过udp的socket服务将数据包发送出去,通过send方法
ds.send(dp);
//关闭资源
ds.close();
}
}
注意点1:
在Android 4.0以上,网络连接不能放在主线程上,不然就会报错android.os.NetworkOnMainThreadException。但是4.0下版本可以不会报错。在Android 4.0以上,网络连接不能放在主线程上,不然就会报错android.os.NetworkOnMainThreadException。但是4.0下版本可以不会报错。
解决办法:
在Activity的onCreate()方法中加入这样一段代码,适用于网络请求数据量很小的话,如下
if (android.os.Build.VERSION.SDK_INT > 9) {
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);
}
注意点2:
赋予网络通信权限
在AndroidMainfest.xml配置文件中添加以下配置
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
Python端:
import socket
import random
import time
udpsock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
tcpsock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
udp_sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
tcp_sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
localaddr = ("", 7789)
udp_sock.bind(localaddr)
def funget():
data = udp_sock.recvfrom(1024)
data = data[0].decode(encoding='utf-8', errors='strict')
data = str(data.replace("'b'", ''))
print("接收到的数据:",data)
return data
if __name__ == '__main__':
while True:
data=funget()
time.sleep(5)
参考文章: https://blog.csdn.net/qq_29477223/article/details/81027716
评论