Эх сурвалжийг харах

1、引入OKHttp3 网络通信模块
2、修改为DJI SDK 5.3.0 开始支持DJI MINI3和DJI MINI3 Pro机型
3、Kotline方式的网络通信模块已基本调通,可以传递JSON数据,IDEA接口进行同步修改

不会爬树的猴 2 жил өмнө
parent
commit
db3b938cb7

+ 4 - 3
app/build.gradle

@@ -84,9 +84,9 @@ dependencies {
     androidTestImplementation 'androidx.test.ext:junit:1.1.1'
     androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
 
-    implementation "com.dji:dji-sdk-v5-aircraft:5.2.0"
-    implementation "com.dji:dji-sdk-v5-networkImp:5.2.0"
-    compileOnly "com.dji:dji-sdk-v5-aircraft-provided:5.2.0"
+    implementation "com.dji:dji-sdk-v5-aircraft:5.3.0"
+    implementation "com.dji:dji-sdk-v5-networkImp:5.3.0"
+    compileOnly "com.dji:dji-sdk-v5-aircraft-provided:5.3.0"
 
     implementation 'com.squareup.okio:okio:1.15.0'
     implementation 'com.squareup.wire:wire-runtime:2.2.0'
@@ -98,4 +98,5 @@ dependencies {
     api "androidx.activity:activity-ktx:1.2.0-alpha01"
     api "androidx.fragment:fragment-ktx:1.2.0-alpha01"
     api 'com.squareup:otto:1.3.8'
+    api 'com.squareup.okhttp3:okhttp:4.2.0'
 }

+ 2 - 1
app/src/main/AndroidManifest.xml

@@ -38,7 +38,8 @@
         android:label="@string/app_name"
         android:roundIcon="@drawable/app_icon"
         android:supportsRtl="true"
-        android:theme="@style/Theme.DJIV5Demo">
+        android:networkSecurityConfig="@xml/network_security_config"
+        android:theme="@style/Theme.CrUAV">
         <activity
             android:name=".AvMain"
             android:exported="false" />

+ 2 - 1
app/src/main/java/com/cr/common/ClassManager.java

@@ -39,7 +39,8 @@ public class ClassManager {
      * @param object 类
      */
     private static void toJSONObject(JSONObject jsonObj,Object object){
-        for(Field field : object.getClass().getFields()){
+        for(Field field : object.getClass().getDeclaredFields()){
+            field.setAccessible(true);
             String fldName = field.getName();
             try {
                 String fldValue = "";

+ 12 - 1
app/src/main/java/com/cr/cruav/AvLogin.kt

@@ -26,10 +26,13 @@ import com.cr.dialog.DialogNormal
 import com.cr.dialog.DialogNormal.DialogNormalListener
 import com.cr.event.EventFragmentBarAction
 import com.cr.models.UserModel
+import com.cr.network.NetManager
+import com.cr.network.TCPDataTask
 import com.cr.pages.FragmentSetIpAndCom
 import com.cr.widget.CrEditTextWidget
 import com.squareup.otto.Subscribe
 import kotlinx.android.synthetic.main.av_login.*
+import org.json.JSONArray
 
 class AvLogin : CrActivity(), OnClickListener {
     // define: 2023/3/31 权限列表
@@ -174,6 +177,15 @@ class AvLogin : CrActivity(), OnClickListener {
         if(isSave){
             if(DataManager.saveUser(userName,password)) {
                 CrUtil.showMessage("登录成功并保存")
+                var user:UserModel = UserModel(userName, password)
+                TCPDataTask.getInstance().sendJSON(NetManager.getServerUrl("appQueryUser"),user,object :TCPDataTask.OnChangeListener{
+                    override fun onSuccess(jsonArray: JSONArray) {
+                        CrUtil.print(jsonArray.optString(0))
+                    }
+                    override fun onFailed(message: String) {
+                        CrUtil.print(message)
+                    }
+                })
             }
         }else{
             if(DataManager.deleteUser())
@@ -196,7 +208,6 @@ class AvLogin : CrActivity(), OnClickListener {
         }
         // TODO: 4/8/21 请求缺少的权限
         if (missingPermission.isEmpty()) {
-            CrUtil.showMessage("权限齐全!")
             init()
         } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
             ActivityCompat.requestPermissions(

+ 7 - 0
app/src/main/java/com/cr/data/utils.kt

@@ -29,6 +29,13 @@ const val MEDIA_FILE_DETAILS_STR = "MEDIA_FILE_DETAILS"
 const val REGISTER_SUCCESS = "Cr"
 const val REGISTER_FAILED = "Err"
 const val TAG: String = "CrUAV"
+const val RES_ERR_FLAG = "RES_ERR"
+const val RES_NULL_FLAG = "RES_NO"
+const val RES_SUCCESS_FLAG = "RES_OK"
+const val RES_CONTENT = "data"
+const val RES_ERR_DES = "errDes"
+const val RES_ERR_CODE = "errCode"
+const val RES_HEAD = "res"
 
 /**
  * 公共类

+ 2 - 0
app/src/main/java/com/cr/models/iNetDataModel.kt

@@ -1,5 +1,7 @@
 package com.cr.models
 
+import org.json.JSONObject
+
 /**
  * 操作系统:MAC系统
  * 创建者:王成

+ 24 - 0
app/src/main/java/com/cr/network/NetManager.kt

@@ -0,0 +1,24 @@
+package com.cr.network
+
+import com.cr.common.DataManager
+import com.cr.models.IPAndComModel
+
+/**
+ * 操作系统:MAC系统
+ * 创建者:王成
+ * 创建日期:2023/4/8 15:10
+ * 描述:网络管理器
+ */
+class NetManager {
+    companion object{
+        /**
+         * 获取完整的网络服务地址
+         * @param urlName String 服务名
+         * @return String
+         */
+        fun getServerUrl(urlName:String):String{
+            var model:IPAndComModel = DataManager.getNetworkLinkInfo()
+            return "http://${model.ip}:${model.com}/${model.serverName}/${urlName}"
+        }
+    }
+}

+ 120 - 0
app/src/main/java/com/cr/network/TCPDataTask.kt

@@ -0,0 +1,120 @@
+package com.cr.network
+
+import com.cr.data.*
+import com.cr.models.iNetDataModel
+import okhttp3.*
+import okhttp3.MediaType.Companion.toMediaType
+import okhttp3.RequestBody.Companion.toRequestBody
+import org.json.JSONArray
+import org.json.JSONException
+import org.json.JSONObject
+import java.io.IOException
+import java.util.concurrent.TimeUnit
+
+/**
+ * 操作系统:MAC系统
+ * 创建者:王成
+ * 创建日期:2023/4/8 14:39
+ * 描述:网络通信
+ */
+class TCPDataTask {
+    /**
+     * 对外接口
+     */
+    interface OnChangeListener{
+        fun onSuccess(jsonArray:JSONArray)
+        fun onFailed(message:String)
+    }
+    // todo: 2023/4/8 网络连接
+    var okHttp: OkHttpClient? = null
+
+    /**
+     * 单例方法
+     */
+    companion object{
+        fun getInstance() = InstanceHelper.self
+    }
+
+    object InstanceHelper{
+        var self = TCPDataTask()
+    }
+
+    /**
+     * 初始化
+     * @constructor
+     */
+    constructor(){
+        /**
+         * 初始化连接
+         */
+        okHttp = OkHttpClient.Builder()
+            .connectTimeout(6000,TimeUnit.MINUTES)
+            .readTimeout(6000,TimeUnit.MINUTES)
+            .writeTimeout(6000,TimeUnit.MINUTES)
+            .build()
+    }
+
+    /**
+     * 发送JSON数据
+     * @param url String 服务地址
+     * @param iModel iNetDataModel<T> 发送数据
+     * @param callback OnChangeListener 监听
+     */
+    fun<T> sendJSON(url:String,iModel:iNetDataModel<T>,callback:OnChangeListener){
+        // todo: 2023/4/8 确定传输类型
+        var mediaType:MediaType = "application/json;charset=utf-8".toMediaType()
+        // todo: 2023/4/8 创建数据传输内容
+        var requestBody:RequestBody = iModel.toJSON().toRequestBody(mediaType)
+        var request:Request = Request.Builder().url(url).post(requestBody).build()
+        // todo: 2023/4/8 连接发送
+        okHttp?.newCall(request)?.enqueue(object :Callback{
+            // todo: 2023/4/8 失败
+            override fun onFailure(call: Call, e: IOException) {
+                var errMessage: String? = e.message
+                if(callback != null) callback.onFailed(errMessage!!)
+            }
+            // todo: 2023/4/8 成功
+            override fun onResponse(call: Call, response: Response) {
+                if(response.code == 200){
+                    try{
+                        var successMessage:String = response.body!!.string()
+                        checkJSON(successMessage,callback)
+                    }catch (e:java.lang.Exception){
+                        if(callback != null) callback.onFailed(e.message!!)
+                    }
+                }
+            }
+        })
+    }
+
+    /**
+     * 解析JSON数据
+     * @param JSON String JSON字符串
+     * @param callback OnChangeListener
+     */
+    private fun checkJSON(JSON: String,callback:OnChangeListener) {
+        val jsonObject: JSONObject
+        try {
+            jsonObject = JSONObject(JSON)
+            val res = jsonObject.optString("res")
+            if (res == RES_ERR_FLAG) {
+                val resObj = jsonObject.getJSONArray(RES_CONTENT)
+                if (callback != null) callback.onFailed(
+                    resObj.getJSONObject(0).optString(RES_ERR_DES)
+                )
+            } else if (res == RES_NULL_FLAG) {
+                val resObj = jsonObject.getJSONArray(RES_CONTENT)
+                if (callback != null) callback.onFailed(
+                    resObj.getJSONObject(0).optString(RES_ERR_DES)
+                )
+            } else if (res == RES_SUCCESS_FLAG) {
+                val resObj = jsonObject.getJSONArray(RES_CONTENT)
+                if (callback != null) callback.onSuccess(resObj)
+            } else {
+                if (callback != null) callback.onFailed("未知错误!")
+            }
+        } catch (ex: JSONException) {
+            if (callback != null) callback.onFailed("数据解析错误!")
+        }
+    }
+}

+ 1 - 1
app/src/main/res/values-night/themes.xml

@@ -1,6 +1,6 @@
 <resources xmlns:tools="http://schemas.android.com/tools">
     <!-- Base application theme. -->
-    <style name="Theme.DJIV5Demo" parent="Theme.MaterialComponents.DayNight.DarkActionBar">
+    <style name="Theme.CrUAV" parent="Theme.MaterialComponents.DayNight.DarkActionBar">
         <!-- Primary brand color. -->
         <item name="colorPrimary">@color/purple_200</item>
         <item name="colorPrimaryVariant">@color/purple_700</item>

+ 1 - 1
app/src/main/res/values/themes.xml

@@ -1,6 +1,6 @@
 <resources xmlns:tools="http://schemas.android.com/tools">
     <!-- Base application theme. -->
-    <style name="Theme.DJIV5Demo" parent="Theme.MaterialComponents.DayNight.NoActionBar.Bridge">
+    <style name="Theme.CrUAV" parent="Theme.MaterialComponents.DayNight.NoActionBar.Bridge">
         <!-- Primary brand color. -->
         <item name="colorPrimary">@color/black</item>
         <item name="colorPrimaryVariant">@color/purple_700</item>

+ 4 - 0
app/src/main/res/xml/network_security_config.xml

@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<network-security-config>
+    <base-config cleartextTrafficPermitted="true"/>
+</network-security-config>