diff --git a/robot_android_App/APP/UPBot/app/build.gradle b/robot_android_App/APP/UPBot/app/build.gradle
index b3422f6..c85c58c 100644
--- a/robot_android_App/APP/UPBot/app/build.gradle
+++ b/robot_android_App/APP/UPBot/app/build.gradle
@@ -3,12 +3,13 @@ plugins {
}
android {
- compileSdk 31
+ namespace 'com.example.upbot'
+ compileSdk 33
defaultConfig {
- applicationId "com.example.wifidemo"
- minSdk 26
- targetSdk 31
+ applicationId "com.example.upbot"
+ minSdk 24
+ targetSdk 33
versionCode 1
versionName "1.0"
@@ -26,13 +27,20 @@ android {
targetCompatibility JavaVersion.VERSION_1_8
}
}
-
+repositories {
+ flatDir {
+ dirs 'libs'
+ }
+}
dependencies {
- implementation 'androidx.appcompat:appcompat:1.2.0'
- implementation 'com.google.android.material:material:1.3.0'
- implementation 'androidx.constraintlayout:constraintlayout:2.0.4'
- testImplementation 'junit:junit:4.+'
- androidTestImplementation 'androidx.test.ext:junit:1.1.2'
- androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'
+ implementation 'androidx.appcompat:appcompat:1.6.1'
+ implementation 'com.google.android.material:material:1.8.0'
+ implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
+ testImplementation 'junit:junit:4.13.2'
+ androidTestImplementation 'androidx.test.ext:junit:1.1.5'
+ androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1'
+ implementation(name: 'AMap3DMap_10.0.700_AMapSearch_9.7.2_AMapLocation_6.4.5_20240508', ext: 'aar')
+ //Google推荐的EasyPermission库
+ implementation 'pub.devrel:easypermissions:3.0.0'
}
\ No newline at end of file
diff --git a/robot_android_App/APP/UPBot/app/libs/AMap3DMap_10.0.700_AMapSearch_9.7.2_AMapLocation_6.4.5_20240508.aar b/robot_android_App/APP/UPBot/app/libs/AMap3DMap_10.0.700_AMapSearch_9.7.2_AMapLocation_6.4.5_20240508.aar
new file mode 100644
index 0000000..09a8db7
Binary files /dev/null and b/robot_android_App/APP/UPBot/app/libs/AMap3DMap_10.0.700_AMapSearch_9.7.2_AMapLocation_6.4.5_20240508.aar differ
diff --git a/robot_android_App/APP/UPBot/app/release/app-release.apk b/robot_android_App/APP/UPBot/app/release/app-release.apk
index dfcf09c..a4ae16b 100644
Binary files a/robot_android_App/APP/UPBot/app/release/app-release.apk and b/robot_android_App/APP/UPBot/app/release/app-release.apk differ
diff --git a/robot_android_App/APP/UPBot/app/release/output-metadata.json b/robot_android_App/APP/UPBot/app/release/output-metadata.json
index a1abaa9..73c118e 100644
--- a/robot_android_App/APP/UPBot/app/release/output-metadata.json
+++ b/robot_android_App/APP/UPBot/app/release/output-metadata.json
@@ -4,7 +4,7 @@
"type": "APK",
"kind": "Directory"
},
- "applicationId": "com.example.wifidemo",
+ "applicationId": "com.example.upbot",
"variantName": "release",
"elements": [
{
diff --git a/robot_android_App/APP/UPBot/app/src/androidTest/java/com/example/upbot/ExampleInstrumentedTest.java b/robot_android_App/APP/UPBot/app/src/androidTest/java/com/example/upbot/ExampleInstrumentedTest.java
new file mode 100644
index 0000000..b16b59a
--- /dev/null
+++ b/robot_android_App/APP/UPBot/app/src/androidTest/java/com/example/upbot/ExampleInstrumentedTest.java
@@ -0,0 +1,26 @@
+package com.example.upbot;
+
+import android.content.Context;
+
+import androidx.test.platform.app.InstrumentationRegistry;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import static org.junit.Assert.*;
+
+/**
+ * Instrumented test, which will execute on an Android device.
+ *
+ * @see Testing documentation
+ */
+@RunWith(AndroidJUnit4.class)
+public class ExampleInstrumentedTest {
+ @Test
+ public void useAppContext() {
+ // Context of the app under test.
+ Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext();
+ assertEquals("com.example.upbot", appContext.getPackageName());
+ }
+}
\ No newline at end of file
diff --git a/robot_android_App/APP/UPBot/app/src/main/AndroidManifest.xml b/robot_android_App/APP/UPBot/app/src/main/AndroidManifest.xml
index 28715bd..80c4736 100644
--- a/robot_android_App/APP/UPBot/app/src/main/AndroidManifest.xml
+++ b/robot_android_App/APP/UPBot/app/src/main/AndroidManifest.xml
@@ -1,39 +1,55 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/robot_android_App/APP/UPBot/app/src/main/java/com/example/upbot/ClientActivity.java b/robot_android_App/APP/UPBot/app/src/main/java/com/example/upbot/ClientActivity.java
new file mode 100644
index 0000000..1262821
--- /dev/null
+++ b/robot_android_App/APP/UPBot/app/src/main/java/com/example/upbot/ClientActivity.java
@@ -0,0 +1,171 @@
+package com.example.upbot;
+
+import android.annotation.SuppressLint;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.Looper;
+import android.os.Message;
+import android.view.View;
+import android.widget.Button;
+import android.widget.EditText;
+import android.widget.TextView;
+import android.widget.Toast;
+
+import androidx.appcompat.app.ActionBar;
+import androidx.appcompat.app.AppCompatActivity;
+
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+import java.net.Socket;
+
+public class ClientActivity extends AppCompatActivity {
+
+ private EditText ipET;
+ private EditText msgET;
+ private Button confirmBtn;
+ private Button sendBtn;
+ private ActionBar actionBar;
+ private Socket mSocket;
+// private OutputStream mOutStream;
+// private InputStream mInStream;
+ private SocketConnectThread socketConnectThread;
+ private StringBuffer stringBuffer = new StringBuffer();
+ private TextView msgTV;
+
+ private final String TAG="WifiDemoLogClientActivity";
+
+ @SuppressLint("HandlerLeak")
+ public Handler handler = new Handler(Looper.myLooper()){
+ @Override
+ public void handleMessage(Message msg) {
+ super.handleMessage(msg);
+ if (msg.what == 1){
+ stringBuffer.append(msg.obj);
+ stringBuffer.append("\n");
+ msgTV.setText(stringBuffer.toString());
+ }
+ }
+ };
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_client);
+ actionBar = getSupportActionBar();
+ assert actionBar != null;
+ actionBar.setDisplayHomeAsUpEnabled(true);
+ actionBar.setTitle("机器人控制");
+
+ socketConnectThread = new SocketConnectThread();
+ initView();
+ setListener();
+ }
+
+ private void initView() {
+ ipET = (EditText) findViewById(R.id.ipET);
+ msgET = (EditText) findViewById(R.id.msgET);
+ sendBtn = findViewById(R.id.btn_send);
+ confirmBtn = findViewById(R.id.btn_confirm);
+ msgTV = (TextView) findViewById(R.id.msgTV);
+ }
+
+ private void setListener() {
+ sendBtn.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ if(mSocket==null) {
+ Toast.makeText(ClientActivity.this, "未进行连接", Toast.LENGTH_SHORT).show();
+ return;
+ }
+ sendMessage(msgET.getText().toString());
+ }
+ });
+ confirmBtn.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ socketConnectThread.start();
+ confirmBtn.setEnabled(false);//连接只点一次
+ }
+ });
+ }
+
+ /**
+ * 连接线程
+ */
+ class SocketConnectThread extends Thread{
+ public void run(){
+ try {
+ //指定ip地址和端口号
+ mSocket = new Socket(ipET.getText().toString(), 1989);
+ //获取输出流、输入流
+// mOutStream = mSocket.getOutputStream();
+// mInStream = mSocket.getInputStream();
+ } catch (Exception e) {
+ e.printStackTrace();
+ return;
+ }
+ startReader(mSocket);
+ }
+
+ }
+
+ /**
+ * 发送消息
+ * @param msg
+ */
+ public void sendMessage(final String msg) {
+ if (msg.length() == 0){
+ return;
+ }
+ new Thread() {
+ @Override
+ public void run() {
+ try {
+ DataOutputStream writer = new DataOutputStream(mSocket.getOutputStream());
+ writer.writeUTF(msg); // 写一个UTF-8的信息
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+ }.start();
+ }
+
+ /**
+ * 接收消息
+ */
+ private void startReader(final Socket socket) {
+ new Thread(){
+ @Override
+ public void run() {
+ DataInputStream reader;
+ try {
+ // 获取读取流
+ reader = new DataInputStream(socket.getInputStream());
+ while (true) {
+ // 读取数据
+ String msg = reader.readUTF();
+ Message message = new Message();
+ message.what = 1;
+ message.obj=msg;
+ handler.sendMessage(message);
+ }
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+ }.start();
+ }
+
+ @Override
+ protected void onDestroy() {
+ if(mSocket!=null){
+ try {
+ mSocket.close();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+ super.onDestroy();
+ }
+}
\ No newline at end of file
diff --git a/robot_android_App/APP/UPBot/app/src/main/java/com/example/upbot/ESP8266ClientActivity.java b/robot_android_App/APP/UPBot/app/src/main/java/com/example/upbot/ESP8266ClientActivity.java
new file mode 100644
index 0000000..51e1aba
--- /dev/null
+++ b/robot_android_App/APP/UPBot/app/src/main/java/com/example/upbot/ESP8266ClientActivity.java
@@ -0,0 +1,141 @@
+package com.example.upbot;
+
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.os.Bundle;
+import android.view.View;
+import android.widget.Button;
+import android.widget.EditText;
+import android.widget.TextView;
+import android.widget.Toast;
+
+import androidx.appcompat.app.AppCompatActivity;
+import androidx.localbroadcastmanager.content.LocalBroadcastManager;
+
+public class ESP8266ClientActivity extends AppCompatActivity {
+
+ private String mIp;//硬件的IP
+ private int mPort = 5000;//硬件的端口
+ private EditText et_ip;//输入硬件对应的IP
+ private EditText et_msg;//输入要发送的消息
+ private Button btn_confirm;//进行连接
+ private Button btn_send;//发送消息
+// Socket mSocket = null;//连接成功可得到的Socket
+// OutputStream outputStream = null;//定义输出流
+// InputStream inputStream = null;//定义输入流
+ private StringBuffer sb = new StringBuffer();//消息
+ private TextView tv_msg;//显示消息
+ private boolean connectFlage = true;//连接成功或连接3s后变false
+ private TextView connetStatusTextView;//显示连接状态
+ private int ShowPointSum = 0;//连接时显示 连接中.. 后面点的计数
+
+ private final String TAG = "WifiDemoLogESP8266ClientActivity";
+ private LocalBroadcastManager localBroadcastManager;//本地广播管理器
+ private MyLocalBroadcastReceiver localBroadcastReceiver;//广播接收者
+ private int connectingCount=0;//用来刷新 正在连接 与 正 在 连 接
+
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_esp8266_client);
+ initView();//初始化控件
+ setListener();//设置Button的点击事件
+ registerBroadcastReceiver();//广播注册
+ }
+
+ /**
+ * 初始化控件
+ */
+ private void initView() {
+ et_ip = (EditText) findViewById(R.id.et_ipESP8266);
+ et_msg = (EditText) findViewById(R.id.et_msgESP8266);
+ btn_send = findViewById(R.id.btn_sendESP8266);
+ btn_confirm = findViewById(R.id.btn_confirmESP8266);
+ tv_msg = (TextView) findViewById(R.id.tv_msgESP8266);
+ connetStatusTextView = findViewById(R.id.connetStatusTV);
+ }
+
+ /**
+ * 设置Button的点击事件
+ */
+ private void setListener() {
+ btn_confirm.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ btn_confirm.setEnabled(false);//防止正在连接时再次点击连接
+ WiFiModeUtil.connectFlage=true;
+ mIp = et_ip.getText().toString();//得到IP
+ WiFiModeUtil.connetByTCP(mIp,mPort);//进行连接
+ }
+ });
+ btn_send.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ if (WiFiModeUtil.mSocket == null) {
+ Toast.makeText(ESP8266ClientActivity.this, "未连接任何设备~~", Toast.LENGTH_SHORT).show();
+ return;
+ }
+ WiFiModeUtil.sendData(et_msg.getText().toString());//发送数据
+ }
+ });
+ }
+
+
+ @Override
+ protected void onDestroy() {
+ localBroadcastManager.unregisterReceiver(localBroadcastReceiver);//注销广播
+ WiFiModeUtil.closeSocketAndStream();//关闭Socket释放资源
+ super.onDestroy();
+ }
+
+ /**
+ * 广播注册
+ */
+ private void registerBroadcastReceiver() {
+ IntentFilter intentFilter = new IntentFilter();
+ intentFilter.addAction("WiFiModeUtil.Connecting");//正在连接
+ intentFilter.addAction("WiFiModeUtil.Connect.Succeed");//连接成功
+ intentFilter.addAction("WiFiModeUtil.Connect.Fail");//连接失败
+ intentFilter.addAction("WiFiModeUtil.Connect.ReceiveMessage");//接收到数据
+ intentFilter.addAction("WiFiModeUtil.Disconnected");//接收到数据
+ localBroadcastReceiver = new MyLocalBroadcastReceiver();
+ localBroadcastManager = LocalBroadcastManager.getInstance(this);
+ WiFiModeUtil.localBroadcastManager=localBroadcastManager;//给WiFiModeUtil工具类中的本地广播管理器赋值
+ localBroadcastManager.registerReceiver(localBroadcastReceiver,intentFilter);
+ }
+
+ /**
+ * 本地广播接收者
+ */
+ class MyLocalBroadcastReceiver extends BroadcastReceiver {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ switch (intent.getAction()) {
+ case "WiFiModeUtil.Connecting":
+ connectingCount++;
+ if(connectingCount%2==0)
+ connetStatusTextView.setText("正在连接");
+ else
+ connetStatusTextView.setText("正 在 连 接");
+ break;
+ case "WiFiModeUtil.Connect.Succeed":
+ connetStatusTextView.setText("连接成功");
+ btn_confirm.setEnabled(true);
+ break;
+ case "WiFiModeUtil.Connect.Fail":
+ connetStatusTextView.setText("连接失败");
+ btn_confirm.setEnabled(true);
+ break;
+ case "WiFiModeUtil.Connect.ReceiveMessage":
+ tv_msg.setText(WiFiModeUtil.DataRecivice.toString());
+ break;
+ case "WiFiModeUtil.Disconnected":
+ tv_msg.setText("连接已断开,请重新进行连接");
+ break;
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/robot_android_App/APP/UPBot/app/src/main/java/com/example/upbot/MainActivity.java b/robot_android_App/APP/UPBot/app/src/main/java/com/example/upbot/MainActivity.java
new file mode 100644
index 0000000..d4973e2
--- /dev/null
+++ b/robot_android_App/APP/UPBot/app/src/main/java/com/example/upbot/MainActivity.java
@@ -0,0 +1,307 @@
+package com.example.upbot;
+
+import android.content.Intent;
+import android.graphics.Color;
+import android.os.Build;
+import android.os.Bundle;
+import android.util.Log;
+import android.view.Menu;
+import android.view.MenuItem;
+import android.view.View;
+import android.widget.Toast;
+
+import androidx.annotation.NonNull;
+import androidx.appcompat.app.ActionBar;
+import androidx.appcompat.app.AppCompatActivity;
+
+import com.amap.api.location.AMapLocation;
+import com.amap.api.location.AMapLocationClient;
+import com.amap.api.location.AMapLocationClientOption;
+import com.amap.api.location.AMapLocationListener;
+import com.amap.api.maps.AMap;
+import com.amap.api.maps.LocationSource;
+import com.amap.api.maps.MapView;
+import com.amap.api.maps.model.BitmapDescriptorFactory;
+import com.amap.api.maps.model.MyLocationStyle;
+
+import pub.devrel.easypermissions.AfterPermissionGranted;
+import pub.devrel.easypermissions.EasyPermissions;
+
+public class MainActivity extends AppCompatActivity implements AMapLocationListener, LocationSource{
+ private MyLocationStyle myLocationStyle = new MyLocationStyle();
+
+ //声明AMapLocationClient类对象
+ public AMapLocationClient mLocationClient = null;
+ //声明AMapLocationClientOption对象
+ public AMapLocationClientOption mLocationOption = null;
+ //请求权限码
+ private static final int REQUEST_PERMISSIONS = 9527;
+ //内容
+ private MapView mapView;
+
+ //地图控制器
+ private AMap aMap = null;
+ //位置更改监听
+ private OnLocationChangedListener mListener;
+
+ private ActionBar actionBar;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_main);
+ actionBar = getSupportActionBar();
+ assert actionBar != null;
+ actionBar.setDisplayHomeAsUpEnabled(true);
+ actionBar.setTitle("深安割草机器人");
+ mapView = findViewById(R.id.map_view);
+ mapView.onCreate(savedInstanceState);
+ initLocation();
+ initMap(savedInstanceState);
+ checkingAndroidVersion();
+ findViewById(R.id.base_config_layout).setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View view) {
+ Intent intent=new Intent(MainActivity.this, ServiceActivity.class);
+ startActivity(intent);
+ }
+ });
+
+ findViewById(R.id.mowing_layout).setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View view) {
+ Intent intent=new Intent(MainActivity.this,ClientActivity.class);
+ startActivity(intent);
+ }
+ });
+
+
+ findViewById(R.id.client_mode_layout).setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View view) {
+ Intent intent=new Intent(MainActivity.this,ESP8266ClientActivity.class);
+ startActivity(intent);
+ }
+ });
+
+ }
+
+
+
+
+ @Override
+ public boolean onCreateOptionsMenu(Menu menu) {
+ getMenuInflater().inflate(R.menu.menu_main, menu);
+ return true;
+ }
+
+
+ @Override
+ public boolean onOptionsItemSelected(@NonNull MenuItem item) {
+ if (item.getItemId() == android.R.id.home){
+ Toast.makeText(this,"返回上一页",Toast.LENGTH_LONG).show();
+ finish();
+ }else if (item.getItemId() == R.id.action_more){
+ Toast.makeText(this,"更多设置",Toast.LENGTH_LONG).show();
+ }
+ return true;
+ }
+ public void activate(OnLocationChangedListener onLocationChangedListener) {
+ mListener = onLocationChangedListener;
+ if (mLocationClient != null) {
+ mLocationClient.startLocation();//启动定位
+ }
+ }
+
+ /**
+ * 停止定位
+ */
+ @Override
+ public void deactivate() {
+ mListener = null;
+ if (mLocationClient != null) {
+ mLocationClient.stopLocation();
+ mLocationClient.onDestroy();
+ }
+ mLocationClient = null;
+ }
+
+ /**
+ * 初始化地图
+ * @param savedInstanceState
+ */
+ private void initMap(Bundle savedInstanceState) {
+ mapView = findViewById(R.id.map_view);
+ //在activity执行onCreate时执行mMapView.onCreate(savedInstanceState),创建地图
+ mapView.onCreate(savedInstanceState);
+ //初始化地图控制器对象
+ aMap = mapView.getMap();
+
+ //设置最小缩放等级为16 ,缩放级别范围为[3, 20]
+ aMap.setMinZoomLevel(12);
+ // 自定义定位蓝点图标
+ myLocationStyle.myLocationIcon(BitmapDescriptorFactory.fromResource(R.drawable.baseline_location_on_24));
+ // 自定义精度范围的圆形边框颜色 都为0则透明
+ myLocationStyle.strokeColor(Color.argb(0, 0, 0, 0));
+ // 自定义精度范围的圆形边框宽度 0 无宽度
+ myLocationStyle.strokeWidth(0);
+ // 设置圆形的填充颜色 都为0则透明
+ myLocationStyle.radiusFillColor(Color.argb(0, 0, 0, 0));
+
+ //设置定位蓝点的Style
+ aMap.setMyLocationStyle(myLocationStyle);
+
+ // 设置定位监听
+ aMap.setLocationSource(this);
+ // 设置为true表示显示定位层并可触发定位,false表示隐藏定位层并不可触发定位,默认是false
+ aMap.setMyLocationEnabled(true);
+ }
+
+ /**
+ * 初始化定位
+ */
+ private void initLocation() {
+ //初始化定位
+ try {
+ mLocationClient = new AMapLocationClient(getApplicationContext());
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ if (mLocationClient != null) {
+ //设置定位回调监听
+ mLocationClient.setLocationListener(this);
+ //初始化AMapLocationClientOption对象
+ mLocationOption = new AMapLocationClientOption();
+ //设置定位模式为AMapLocationMode.Hight_Accuracy,高精度模式。
+ mLocationOption.setLocationMode(AMapLocationClientOption.AMapLocationMode.Hight_Accuracy);
+ //获取最近3s内精度最高的一次定位结果:
+ //设置setOnceLocationLatest(boolean b)接口为true,启动定位时SDK会返回最近3s内精度最高的一次定位结果。如果设置其为true,setOnceLocation(boolean b)接口也会被设置为true,反之不会,默认为false。
+ mLocationOption.setOnceLocationLatest(true);
+ //设置是否返回地址信息(默认返回地址信息)
+ mLocationOption.setNeedAddress(true);
+ //设置定位请求超时时间,单位是毫秒,默认30000毫秒,建议超时时间不要低于8000毫秒。
+ mLocationOption.setHttpTimeOut(20000);
+ //关闭缓存机制,高精度定位会产生缓存。
+ mLocationOption.setLocationCacheEnable(false);
+ //给定位客户端对象设置定位参数
+ mLocationClient.setLocationOption(mLocationOption);
+ }
+ }
+
+ /**
+ * 接收异步返回的定位结果
+ *
+ * @param aMapLocation
+ */
+ @Override
+ public void onLocationChanged(AMapLocation aMapLocation) {
+ if (aMapLocation != null) {
+ if (aMapLocation.getErrorCode() == 0) {
+ //地址
+ String address = aMapLocation.getAddress();
+ double latitude = aMapLocation.getLatitude();
+ double longitude = aMapLocation.getLongitude();
+ StringBuilder stringBuffer = new StringBuilder();
+ stringBuffer.append("纬度:").append(latitude).append("\n");
+ stringBuffer.append("经度:").append(longitude).append("\n");
+ stringBuffer.append("地址:").append(address).append("\n");
+ Log.d("MainActivity",stringBuffer.toString());
+ showMsg(address);
+ mLocationClient.stopLocation();
+ if (mListener != null){
+ mListener.onLocationChanged(aMapLocation);
+ }
+
+ } else {
+ //定位失败时,可通过ErrCode(错误码)信息来确定失败的原因,errInfo是错误信息,详见错误码表。
+ Log.e("AmapError", "location Error, ErrCode:"
+ + aMapLocation.getErrorCode() + ", errInfo:"
+ + aMapLocation.getErrorInfo());
+ }
+ }
+ }
+
+ /**
+ * 检查Android版本
+ */
+ private void checkingAndroidVersion() {
+ if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.M){
+ //Android6.0及以上先获取权限再定位
+ requestPermission();
+ }else {
+ //Android6.0以下直接定位
+ mLocationClient.startLocation();
+ }
+ }
+
+ /**
+ * 动态请求权限
+ */
+ @AfterPermissionGranted(REQUEST_PERMISSIONS)
+ private void requestPermission() {
+ String[] permissions = new String[]{
+ "android.permission.ACCESS_COARSE_LOCATION",
+ "android.permission.ACCESS_FINE_LOCATION",
+ "android.permission.READ_PHONE_STATE",
+ "android.permission.WRITE_EXTERNAL_STORAGE"
+ };
+
+ if (EasyPermissions.hasPermissions(this, permissions)) {
+ //true 有权限 开始定位
+ showMsg("已获得权限,可以定位啦!");
+ mLocationClient.startLocation();
+ } else {
+ //false 无权限
+ EasyPermissions.requestPermissions(this, "需要权限", REQUEST_PERMISSIONS, permissions);
+ }
+ }
+
+ /**
+ * 请求权限结果
+ * @param requestCode
+ * @param permissions
+ * @param grantResults
+ */
+ @Override
+ public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
+ super.onRequestPermissionsResult(requestCode, permissions, grantResults);
+ //设置权限请求结果
+ EasyPermissions.onRequestPermissionsResult(requestCode, permissions, grantResults, this);
+ }
+
+
+ /**
+ * Toast提示
+ * @param msg 提示内容
+ */
+ private void showMsg(String msg){
+ Toast.makeText(this,msg,Toast.LENGTH_SHORT).show();
+ }
+ @Override
+ protected void onResume() {
+ super.onResume();
+ //在activity执行onResume时执行mMapView.onResume (),重新绘制加载地图
+ mapView.onResume();
+ }
+ @Override
+ protected void onPause() {
+ super.onPause();
+ //在activity执行onPause时执行mMapView.onPause (),暂停地图的绘制
+ mapView.onPause();
+ }
+ @Override
+ protected void onSaveInstanceState(Bundle outState) {
+ super.onSaveInstanceState(outState);
+ //在activity执行onSaveInstanceState时执行mMapView.onSaveInstanceState (outState),保存地图当前的状态
+ mapView.onSaveInstanceState(outState);
+ }
+
+ @Override
+ protected void onDestroy() {
+ super.onDestroy();
+ //销毁定位客户端,同时销毁本地定位服务。
+ mLocationClient.onDestroy();
+ mapView.onDestroy();
+ }
+
+}
\ No newline at end of file
diff --git a/robot_android_App/APP/UPBot/app/src/main/java/com/example/upbot/MapApplication.java b/robot_android_App/APP/UPBot/app/src/main/java/com/example/upbot/MapApplication.java
new file mode 100644
index 0000000..763cef7
--- /dev/null
+++ b/robot_android_App/APP/UPBot/app/src/main/java/com/example/upbot/MapApplication.java
@@ -0,0 +1,25 @@
+package com.example.upbot;
+
+import android.app.Application;
+import android.content.Context;
+
+import com.amap.api.location.AMapLocationClient;
+import com.amap.api.maps.MapsInitializer;
+import com.amap.api.services.core.ServiceSettings;
+
+public class MapApplication extends Application {
+ @Override
+ public void onCreate() {
+ super.onCreate();
+ Context context = this;
+ //定位隐私政策同意
+ AMapLocationClient.updatePrivacyShow(context,true,true);
+ AMapLocationClient.updatePrivacyAgree(context,true);
+ //地图隐私政策同意
+ MapsInitializer.updatePrivacyShow(context,true,true);
+ MapsInitializer.updatePrivacyAgree(context,true);
+ //搜索隐私政策同意
+ ServiceSettings.updatePrivacyShow(context,true,true);
+ ServiceSettings.updatePrivacyAgree(context,true);
+ }
+}
diff --git a/robot_android_App/APP/UPBot/app/src/main/java/com/example/upbot/ServiceActivity.java b/robot_android_App/APP/UPBot/app/src/main/java/com/example/upbot/ServiceActivity.java
new file mode 100644
index 0000000..9e82ff6
--- /dev/null
+++ b/robot_android_App/APP/UPBot/app/src/main/java/com/example/upbot/ServiceActivity.java
@@ -0,0 +1,205 @@
+package com.example.upbot;
+
+import android.annotation.SuppressLint;
+import android.content.Context;
+import android.net.wifi.WifiInfo;
+import android.net.wifi.WifiManager;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.Looper;
+import android.os.Message;
+import android.util.Log;
+import android.view.View;
+import android.widget.Button;
+import android.widget.TextView;
+
+import androidx.appcompat.app.AppCompatActivity;
+
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+import java.net.ServerSocket;
+import java.net.Socket;
+
+public class ServiceActivity extends AppCompatActivity {
+
+ private Button clearBtn;
+ private Button showIPBtn;
+ private TextView ipTV;
+ private TextView msgTV;
+ private ServerSocket mServerSocket;
+ private Socket mSocket;
+ private StringBuffer stringBuffer = new StringBuffer();
+ private final String TAG = "WifiDemoLogServiceActivity";
+
+
+ @SuppressLint("HandlerLeak")
+ public Handler handler = new Handler(Looper.myLooper()) {
+ @Override
+ public void handleMessage(Message msg) {
+ super.handleMessage(msg);
+ if (msg.what == 1) {
+ stringBuffer.append(msg.obj);
+ stringBuffer.append("\n");
+ msgTV.setText(stringBuffer.toString());
+ }
+ }
+ };
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_service);
+ initView();
+ setListener();
+
+ try {
+ mServerSocket = new ServerSocket(5000);//端口号5000
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ //启动服务线程
+ SocketAcceptThread socketAcceptThread = new SocketAcceptThread();
+ socketAcceptThread.start();
+ }
+
+ /**
+ * 获得控件实例
+ */
+ private void initView() {
+ clearBtn = findViewById(R.id.clearBtn);
+ showIPBtn = findViewById(R.id.showIPBtn);
+ ipTV = findViewById(R.id.ipTV);
+ msgTV = findViewById(R.id.msgTV);
+ }
+
+ /**
+ * 为控件设置监听
+ */
+ private void setListener() {
+ clearBtn.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ stringBuffer.setLength(0);
+ msgTV.setText("");
+ }
+ });
+ showIPBtn.setOnClickListener(new View.OnClickListener() {
+ @SuppressLint("SetTextI18n")
+ @Override
+ public void onClick(View v) {
+ ipTV.setText(getLocalIpAddress(ServiceActivity.this) + ":5000");
+ }
+ });
+
+ }
+
+
+ /**
+ * 连接线程
+ * 得到Socket
+ */
+ class SocketAcceptThread extends Thread {
+ @Override
+ public void run() {
+ try {
+ //等待客户端的连接,Accept会阻塞,直到建立连接,
+ //所以需要放在子线程中运行
+ mSocket = mServerSocket.accept();
+ } catch (IOException e) {
+ e.printStackTrace();
+ return;
+ }
+ //启动消息接收线程
+ startReader(mSocket);
+ }
+ }
+
+ /**
+ * 从参数的Socket里获取最新的消息
+ */
+ private void startReader(final Socket socket) {
+
+ new Thread() {
+ @Override
+ public void run() {
+ DataInputStream reader;
+ try {
+ // 获取读取流
+ reader = new DataInputStream(socket.getInputStream());
+ while (true) {
+ // 读取数据
+ String msg = reader.readUTF();
+ Log.d(TAG, "客户端的信息:" + msg);
+
+ //告知客户端消息收到
+ DataOutputStream writer = new DataOutputStream(mSocket.getOutputStream());
+ writer.writeUTF("收到:" + msg); // 写一个UTF-8的信息
+
+ //发消息更新UI
+ Message message = new Message();
+ message.what = 1;
+ message.obj=msg;
+ handler.sendMessage(message);
+ }
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+ }.start();
+ }
+
+ @Override
+ protected void onDestroy() {
+ if (mServerSocket != null) {
+ try {
+ mServerSocket.close();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+ if(mSocket!=null){
+ try {
+ mSocket.close();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+ super.onDestroy();
+ }
+
+ /**
+ * 将ip的整数形式转换成ip形式
+ *
+ * @param ipInt
+ * @return
+ */
+ public static String int2ip(int ipInt) {
+ StringBuilder sb = new StringBuilder();
+ sb.append(ipInt & 0xFF).append(".");
+ sb.append((ipInt >> 8) & 0xFF).append(".");
+ sb.append((ipInt >> 16) & 0xFF).append(".");
+ sb.append((ipInt >> 24) & 0xFF);
+ return sb.toString();
+ }
+
+ /**
+ * 获取当前ip地址
+ *
+ * @param context
+ * @return
+ */
+ public static String getLocalIpAddress(Context context) {
+ try {
+
+ WifiManager wifiManager = (WifiManager) context
+ .getSystemService(Context.WIFI_SERVICE);
+ WifiInfo wifiInfo = wifiManager.getConnectionInfo();
+ int i = wifiInfo.getIpAddress();
+ return int2ip(i);
+ } catch (Exception ex) {
+ return " 获取IP出错鸟!!!!请保证是WIFI,或者请重新打开网络!\n" + ex.getMessage();
+ }
+ // return null;
+ }
+}
\ No newline at end of file
diff --git a/robot_android_App/APP/UPBot/app/src/main/java/com/example/upbot/SplashActivity.java b/robot_android_App/APP/UPBot/app/src/main/java/com/example/upbot/SplashActivity.java
new file mode 100644
index 0000000..ac7e05f
--- /dev/null
+++ b/robot_android_App/APP/UPBot/app/src/main/java/com/example/upbot/SplashActivity.java
@@ -0,0 +1,57 @@
+package com.example.upbot;
+
+import android.annotation.SuppressLint;
+import android.content.Intent;
+import android.os.Build;
+import android.os.Bundle;
+import android.view.View;
+import android.view.WindowManager;
+
+import androidx.annotation.RequiresApi;
+import androidx.appcompat.app.AppCompatActivity;
+
+@SuppressLint("CustomSplashScreen")
+public class SplashActivity extends AppCompatActivity {
+
+ @RequiresApi(api = Build.VERSION_CODES.P)
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ fullScreenDisplay();
+ setContentView(R.layout.activity_splash);
+ //创建子线程
+ Thread mThread=new Thread(){
+ @Override
+ public void run() {
+ super.run();
+ try {
+ sleep(3000);//使程序休眠3秒
+ Intent intent=new Intent(getApplicationContext(),MainActivity.class);
+ startActivity(intent);
+ finish();
+ }catch (Exception e){
+ e.printStackTrace();
+ }
+ }
+ };
+ mThread.start();//启动线程
+ }
+ @RequiresApi(api = Build.VERSION_CODES.P)
+ protected void fullScreenDisplay(){
+ // 隐藏状态栏和ActionBar,实现全屏画面的效果
+ //隐藏状态栏
+ getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
+ //隐藏标题栏
+ getSupportActionBar().hide();
+ getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
+ | View.SYSTEM_UI_FLAG_FULLSCREEN);
+
+ WindowManager.LayoutParams lp = getWindow().getAttributes();
+
+ // 始终允许窗口延伸到屏幕短边上的刘海区域
+ lp.layoutInDisplayCutoutMode = WindowManager.LayoutParams.
+ LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES;
+
+ getWindow().setAttributes(lp);
+ }
+}
\ No newline at end of file
diff --git a/robot_android_App/APP/UPBot/app/src/main/java/com/example/upbot/WiFiModeUtil.java b/robot_android_App/APP/UPBot/app/src/main/java/com/example/upbot/WiFiModeUtil.java
new file mode 100644
index 0000000..5e00b32
--- /dev/null
+++ b/robot_android_App/APP/UPBot/app/src/main/java/com/example/upbot/WiFiModeUtil.java
@@ -0,0 +1,258 @@
+package com.example.upbot;
+
+import android.annotation.SuppressLint;
+import android.content.Intent;
+import android.os.CountDownTimer;
+import android.os.Handler;
+import android.os.Looper;
+import android.os.Message;
+import android.util.Log;
+
+import androidx.localbroadcastmanager.content.LocalBroadcastManager;
+
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.Socket;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * 正在连接广播Action:"WiFiModeUtil.Connecting"
+ * 连接失败广播Action:"WiFiModeUtil.Connect.Fail"
+ * 连接成功广播Action:"WiFiModeUtil.Connect.Succeed"
+ * 收到数据广播Action:"WiFiModeUtil.Connect.ReceiveMessage"
+ * 连接断开广播Action:"WiFiModeUtil.Disconnected"
+ */
+public class WiFiModeUtil {
+ private static String mIp;//硬件的IP
+ private static int mPort = 5000;//硬件的端口
+ public static Socket mSocket = null;//连接成功可得到的Socket
+ public static OutputStream outputStream = null;//定义输出流
+ public static InputStream inputStream = null;//定义输入流
+ public static StringBuffer DataRecivice = new StringBuffer();//数据
+ public static List DataList=new ArrayList<>();//数据
+ public static boolean connectFlage = true;//连接成功或连接3s后变false
+ // private static int ShowPointSum = 0;//连接时显示 连接中.. 后面点的计数
+ private static final String TAG = "WifiDemoLogESP8266ClientActivity";
+
+ /**
+ * 本地广播管理器 从外面用:
+ * WiFiModeUtil.localBroadcastManager=localBroadcastManager;
+ * 进行赋值
+ */
+ public static LocalBroadcastManager localBroadcastManager;
+
+ /**
+ * 处理消息的Handler
+ */
+ @SuppressLint("HandlerLeak")
+ public static Handler mHandler = new Handler(Looper.myLooper()) {
+ @Override
+ public void handleMessage(Message msg) {
+ super.handleMessage(msg);
+ switch (msg.what) {
+ case 0://接收到数据
+ DataRecivice.append(msg.obj.toString());
+ DataRecivice.append("\n");
+ DataList.add(msg.obj.toString());//添加数据
+ Intent intent = new Intent("WiFiModeUtil.Connect.ReceiveMessage");
+ localBroadcastManager.sendBroadcast(intent);//发送收到数据广播
+ break;
+ case 1://连接成功
+ Intent intent2 = new Intent("WiFiModeUtil.Connect.Succeed");
+ localBroadcastManager.sendBroadcast(intent2);//发送连接成功广播
+ readData();//开启接收线程
+ connectFlage = true;
+ break;
+ case 2://连接断开
+ Intent intent3 = new Intent("WiFiModeUtil.Disconnected");
+ localBroadcastManager.sendBroadcast(intent3);//发送连接失败广播
+ connectFlage = true;
+ break;
+ }
+ }
+ };
+
+ /***
+ * 延时3s的定时器
+ * 在开始连接时计时3s
+ * 3s未连接上视为连接失败
+ */
+ private final static CountDownTimer tcpClientCountDownTimer = new CountDownTimer(3000, 300) {
+ @Override
+ public void onTick(long millisUntilFinished) {//每隔300ms进入
+ if (connectFlage) {
+ Intent intent = new Intent("WiFiModeUtil.Connecting");
+ localBroadcastManager.sendBroadcast(intent);
+ }
+ }
+
+ @Override
+ public void onFinish() {//3s后进入(没有取消定时器的情况下)
+ if (connectFlage) {
+ connectFlage = false;//连接失败
+ closeSocketAndStream();
+ }
+ tcpClientCountDownTimer.cancel();//关掉定时器
+ Intent intent = new Intent("WiFiModeUtil.Connect.Fail");
+ localBroadcastManager.sendBroadcast(intent);
+ Log.d(TAG,"连接失败");
+ }
+ };
+
+ /**
+ * 关掉Socket和输入输出流
+ */
+ public static void closeSocketAndStream() {
+ if (outputStream != null) {
+ try {
+ outputStream.close();
+ Log.d(TAG,"关闭输出流");
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ outputStream = null;
+ }
+ if (inputStream != null) {
+ try {
+ inputStream.close();
+ Log.d(TAG,"关闭输入流");
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ inputStream = null;
+ }
+ if (mSocket != null) {
+ try {
+ mSocket.close();
+ Log.d(TAG,"关闭Socket");
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ mSocket = null;
+ }
+ }
+
+ /**
+ * 连接服务器任务
+ */
+ static class ConnectSeverThread extends Thread {
+ @Override
+ public void run() {
+ Log.d(TAG,"连接线程开启");
+ while (connectFlage) {
+ try {
+ Log.d(TAG,"正在连接...");
+ mSocket = new Socket(mIp, mPort);//进行连接
+ connectFlage = false;//已连接
+ tcpClientCountDownTimer.cancel();//关掉计时器
+ /*连接成功更新显示连接状态的UI*/
+ Message msg = new Message();
+ msg.what = 1;
+ mHandler.sendMessage(msg);
+ Log.d(TAG,"连接成功");
+ inputStream = mSocket.getInputStream();//获取输入流
+ Log.d(TAG,"获取输入流");
+ outputStream = mSocket.getOutputStream();////获取输出流
+ Log.d(TAG,"获取输出流");
+ } catch (IOException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ Log.d(TAG,"连接过程中出错");
+ }
+ }
+ }
+ }
+
+ /**
+ * 传入硬件服务端IP建立TCP连接
+ * 正在连接每200ms 发送一条‘正在连接’广播
+ * 3秒后还未连接则连接失败 发送一条‘失败广播’
+ * 连接成功会 发送一条‘成功广播’
+ *
+ * @param IPAdress
+ */
+ public static void connetByTCP(String IPAdress,int Port) {
+ mIp = IPAdress;
+ mPort=Port;
+ ConnectSeverThread connectSeverThread = new ConnectSeverThread();
+ connectSeverThread.start();
+ tcpClientCountDownTimer.start();
+ }
+
+ /**
+ * 向硬件发送数据
+ */
+ public static void sendData(String data) {
+ if(mSocket!=null){
+ byte[] sendByte = data.getBytes();
+ new Thread() {
+ @Override
+ public void run() {
+ try {
+ Log.d(TAG,"发送线程开启 正在发送中...");
+ DataOutputStream writer = new DataOutputStream(outputStream);
+ writer.write(sendByte, 0, sendByte.length);
+ Log.d(TAG,"已发送数据:"+data);
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ Log.d(TAG,"发送线程结束");
+ }
+ }.start();
+ }
+ }
+
+ /**
+ * 连接成功后开启
+ * 接收硬件发送的数据
+ */
+ public static void readData() {
+ new Thread() {
+ @Override
+ public void run() {
+ Log.d(TAG,"接收线程开启");
+ try {
+ while (true) {
+ Thread.sleep(200);
+ //如果连接断开 尝试重连
+ try {
+ /*
+ sendUrgentData()方法
+ 它会往输出流发送一个字节的数据,
+ 只要对方Socket的SO_OOBINLINE属性没有打开,
+ 就会自动舍弃这个字节,
+ 就会抛出异常,
+ 而SO_OOBINLINE属性默认情况下就是关闭的
+ */
+ mSocket.sendUrgentData(0xFF);//发送1个字节的紧急数据,默认情况下,服务器端没有开启紧急数据处理,不影响正常通信
+ } catch (Exception ex) {
+ Log.d(TAG,"连接已断开,请重新进行连接");
+ Message msg=new Message();
+ msg.what=2;
+ msg.obj="连接已断开,请重新进行连接";
+ mHandler.sendMessage(msg);
+ }
+ DataInputStream reader = new DataInputStream(inputStream);
+ byte[] buffer = new byte[1024];
+ int len;
+ while ((len = reader.read(buffer)) != -1) {
+ String data = new String(buffer, 0, len);
+ Log.d(TAG,"接收到数据:"+data);
+ Message msg = new Message();
+ msg.what = 0;
+ msg.obj = data;
+ mHandler.sendMessage(msg);
+ }
+ }
+ } catch (IOException | InterruptedException e) {
+ e.printStackTrace();
+ }
+ Log.d(TAG,"接收线程结束");
+ }
+ }.start();
+ }
+}
diff --git a/robot_android_App/APP/UPBot/app/src/main/res/drawable/baseline_location_on_24.xml b/robot_android_App/APP/UPBot/app/src/main/res/drawable/baseline_location_on_24.xml
new file mode 100644
index 0000000..40ef933
--- /dev/null
+++ b/robot_android_App/APP/UPBot/app/src/main/res/drawable/baseline_location_on_24.xml
@@ -0,0 +1,5 @@
+
+
+
diff --git a/robot_android_App/APP/UPBot/app/src/main/res/layout/activity_main.xml b/robot_android_App/APP/UPBot/app/src/main/res/layout/activity_main.xml
index 7bd2813..9cfaf5b 100644
--- a/robot_android_App/APP/UPBot/app/src/main/res/layout/activity_main.xml
+++ b/robot_android_App/APP/UPBot/app/src/main/res/layout/activity_main.xml
@@ -8,12 +8,12 @@
android:orientation="vertical"
tools:context=".MainActivity">
-
+ android:layout_weight="1"
+ android:layout_marginBottom="10dp"/>
-