单号: SN20260315888
-物料: 工业级调度终端 x 5
-物料: 工业级调度终端 x 5
-物料: 工业级调度终端 x 5
-物料: 工业级调度终端 x 5
-物料: 工业级调度终端 x 5
-物料: 工业级调度终端 x 5
-物料: 工业级调度终端 x 5
-物料: 工业级调度终端 x 5
-物料: 工业级调度终端 x 5
-物料: 工业级调度终端 x 5
-物料: 工业级调度终端 x 5
-物料: 工业级调度终端 x 5
-物料: 工业级调度终端 x 5
-物料: 工业级调度终端 x 5
-物料: 工业级调度终端 x 5
-物料: 工业级调度终端 x 5
-物料: 工业级调度终端 x 5
-物料: 工业级调度终端 x 5
-物料: 工业级调度终端 x 5
-物料: 工业级调度终端 x 5
-物料: 工业级调度终端 x 5
-物料: 工业级调度终端 x 5
-物料: 工业级调度终端 x 5
-物料: 工业级调度终端 x 5
-物料: 工业级调度终端 x 5
-物料: 工业级调度终端 x 5
-物料: 工业级调度终端 x 5
-物料: 工业级调度终端 x 5
-物料: 工业级调度终端 x 5
-物料: 工业级调度终端 x 5
-物料: 工业级调度终端 x 5
-物料: 工业级调度终端 x 5
-物料: 工业级调度终端 x 5
-物料: 工业级调度终端 x 5
-物料: 工业级调度终端 x 5
-物料: 工业级调度终端 x 5
-物料: 工业级调度终端 x 5
-物料: 工业级调度终端 x 5
-物料: 工业级调度终端 x 5
-物料: 工业级调度终端 x 5
-物料: 工业级调度终端 x 5
-物料: 工业级调度终端 x 5
-物料: 工业级调度终端 x 5
-物料: 工业级调度终端 x 5
-物料: 工业级调度终端 x 5
-物料: 工业级调度终端 x 5
-物料: 工业级调度终端 x 5
-物料: 工业级调度终端 x 5
-物料: 工业级调度终端 x 5
-物料: 工业级调度终端 x 5
-物料: 工业级调度终端 x 5
-物料: 工业级调度终端 x 5
-物料: 工业级调度终端 x 5
-物料: 工业级调度终端 x 5
-物料: 工业级调度终端 x 5
-物料: 工业级调度终端 x 5
-物料: 工业级调度终端 x 5
-物料: 工业级调度终端 x 5
-物料: 工业级调度终端 x 5
-物料: 工业级调度终端 x 5
-物料: 工业级调度终端 x 5
-物料: 工业级调度终端 x 5
-物料: 工业级调度终端 x 5
-物料: 工业级调度终端 x 5
+物料: 工业级调度终端 x 5
+时间:
+ * loginId 用户ID,登录成功id有效
+ */
+ public static void callBackLoinState(String state, String loginId) {
+ Log.d(TAG, "callBackLoinState state: " + state + ", loginId: " + loginId);
+ }
+
+ /**
+ * 判断账号登录是否冲突
+ * true:登录冲突
+ * false:登录不冲突
+ * */
+ public static void callBackLoginConflict(boolean loginConflict) {
+ Log.d(TAG, "callBackLoginConflict: " + loginConflict);
+ }
+
+ /**
+ * 登录账号有视频功能通知
+ */
+ public static boolean callBackHaveVideo() {
+ return true;
+ }
+
+
+
+ /**
+ * 查询群组返回
+ * state true-成功, false-失败
+ */
+ public static void callBackOnGroupSuccess(boolean state) {
+
+ }
+
+ /**
+ * 查询群组成员返回
+ * state true-成功, false-失败
+ */
+ public static void callBackOnMemberSuccess(boolean state, List
+ * desc : 组
+ *
+ */
+
+public class GroupInfoDto {
+
+
+ private int groupNo; //表示此组为第一个组
+ private int groupCount; //表示此组有 3 个用户成员
+ private String groupId;
+ private String groupName;
+
+ public GroupInfoDto() {
+
+ }
+
+ public GroupInfoDto(String groupId, String groupName, int groupNo, int groupCount) {
+ this.groupId = groupId;
+ this.groupName = groupName;
+ this.groupNo = groupNo;
+ this.groupCount = groupCount;
+ }
+
+ public int getGroupNo() {
+ return groupNo;
+ }
+
+ public void setGroupNo(int groupNo) {
+ this.groupNo = groupNo;
+ }
+
+ public int getGroupCount() {
+ return groupCount;
+ }
+
+ public void setGroupCount(int groupCount) {
+ this.groupCount = groupCount;
+ }
+
+ public String getGroupId() {
+ return groupId == null ? "" : groupId;
+ }
+
+ public void setGroupId(String groupId) {
+ this.groupId = groupId;
+ }
+
+ public String getGroupName() {
+ return groupName == null ? "" : groupName;
+ }
+
+ public void setGroupName(String groupName) {
+ this.groupName = groupName;
+ }
+
+ @Override
+ public String toString() {
+ return "GroupInfoDto{" +
+ "groupNo=" + groupNo +
+ ", groupCount=" + groupCount +
+ ", groupId='" + groupId + '\'' +
+ ", groupName='" + groupName + '\'' +
+ '}';
+ }
+}
diff --git a/app/src/main/java/com/example/kingway/ptt/GroupMemberInfoDto.java b/app/src/main/java/com/example/kingway/ptt/GroupMemberInfoDto.java
new file mode 100644
index 0000000..be661bd
--- /dev/null
+++ b/app/src/main/java/com/example/kingway/ptt/GroupMemberInfoDto.java
@@ -0,0 +1,80 @@
+package com.example.kingway.ptt;
+
+import java.io.Serializable;
+
+/**
+ *
+ * desc : 组 成员
+ *
+ */
+
+public class GroupMemberInfoDto implements Serializable {
+ private static final long serialVersionUID = 1L;
+
+ private int memberNo; //表示此成员为第几个用户
+ private String memberId;
+ private String gmemberName;
+ private String status;
+ private boolean haveVideo;//此成员是否有视频功能
+
+ public GroupMemberInfoDto(){}
+
+ public GroupMemberInfoDto(String memberId, String gmemberName, String status, int memberNo, boolean haveVideo) {
+ this.memberId = memberId;
+ this.gmemberName = gmemberName;
+ this.memberNo = memberNo;
+ this.status = status;
+ this.haveVideo = haveVideo;
+ }
+
+ public int getMemberNo() {
+ return memberNo;
+ }
+
+ public void setMemberNo(int memberNo) {
+ this.memberNo = memberNo;
+ }
+
+ public String getStatus() {
+ return status == null ? "" : status;
+ }
+
+ public void setStatus(String status) {
+ this.status = status;
+ }
+
+ public String getMemberId() {
+ return memberId == null ? "" : memberId;
+ }
+
+ public void setMemberId(String memberId) {
+ this.memberId = memberId;
+ }
+
+ public String getGmemberName() {
+ return gmemberName == null ? "" : gmemberName;
+ }
+
+ public void setGmemberName(String gmemberName) {
+ this.gmemberName = gmemberName;
+ }
+
+ public boolean isHaveVideo() {
+ return haveVideo;
+ }
+
+ public void setHaveVideo(boolean haveVideo) {
+ this.haveVideo = haveVideo;
+ }
+
+ @Override
+ public String toString() {
+ return "GroupMemberInfoDto{" +
+ "memberNo=" + memberNo +
+ ", memberId='" + memberId + '\'' +
+ ", gmemberName='" + gmemberName + '\'' +
+ ", status='" + status + '\'' +
+ ", haveVideo=" + haveVideo +
+ '}';
+ }
+}
diff --git a/app/src/main/java/com/example/kingway/ptt/MyApplication.java b/app/src/main/java/com/example/kingway/ptt/MyApplication.java
new file mode 100644
index 0000000..935b839
--- /dev/null
+++ b/app/src/main/java/com/example/kingway/ptt/MyApplication.java
@@ -0,0 +1,45 @@
+package com.example.kingway.ptt;
+
+import android.content.Context;
+import android.util.Log;
+
+public class MyApplication {
+ private static Context mContext;
+ public static String pageName = "";
+ public static pttNative pNative;
+ private static MyApplication mAppInstance = new MyApplication();
+
+ public static void init(Context context) {
+ if (mContext != null) return;
+ mContext = context.getApplicationContext();
+ pageName = mContext.getPackageName();
+ initPTT();
+ }
+
+ public static MyApplication getAppInstance() {
+ if (pNative == null && mContext != null) {
+ initPTT();
+ }
+ return mAppInstance;
+ }
+
+ public pttNative getpNative() {
+ return pNative;
+ }
+
+ public static void initPTT() {
+ if (pNative != null) return;
+ pNative = new pttNative();
+
+ pNative.pttNativeSetPackageName(pageName);
+ pNative.pttNativeSetAtCallback();
+ pNative.pttNativeSetPlayCallback();
+ pNative.pttNativeSetPalyStartCallback();
+ pNative.pttNativeSetPlayStopCallback();
+ pNative.pttNativeSetRecordStartCallback();
+ pNative.pttNativeSetRecordStopCallback();
+ pNative.pttNativeSetTTSCallback();
+
+ pNative.pttNativePocTaskStart();
+ }
+}
diff --git a/app/src/main/java/com/example/kingway/ptt/SendAtUtil.java b/app/src/main/java/com/example/kingway/ptt/SendAtUtil.java
new file mode 100644
index 0000000..e0be413
--- /dev/null
+++ b/app/src/main/java/com/example/kingway/ptt/SendAtUtil.java
@@ -0,0 +1,96 @@
+package com.example.kingway.ptt;
+
+/**
+ * 指令发送类
+ * */
+public class SendAtUtil {
+
+ /**
+ * 账号登录接口
+ * account 账号
+ * pwd 密码
+ * ip 服务器ip
+ * location 是否开启定位 1-开启,0关闭
+ * tempCall 是否开启单呼 1开启单呼,0关闭单呼
+ * */
+ public static void toLogin(String account, String pwd, String ip, int location, int tempCall){
+ String ipHex = str2HexStr("ip=" + ip + ";");
+ String accountHex = str2HexStr("id=" + account + ";");
+ String pwdHex = str2HexStr("pwd=" + pwd + ";");
+ String locationHex = str2HexStr("gps=" + location + ";");
+ String tempCallHex = str2HexStr("inv=" + tempCall + ";");
+ String loginAt = "010000" + ipHex + "" + accountHex + "" + pwdHex + locationHex + tempCallHex + "\r\n";
+ MyApplication.getAppInstance().getpNative().pttNativeSendAtCmd(loginAt);
+ MyApplication.getAppInstance().getpNative().pttNativeSendAtCmd("00000000\r\n");
+ }
+
+ /**
+ * 按下PTT开始呼叫
+ * */
+ public static void speakPlay(){
+ MyApplication.getAppInstance().getpNative().pttNativeSendAtCmd("0B0000");
+ }
+
+ /** 松开PTT结束呼叫*/
+ public static void speakRelease(){
+ AudioRecordManager.getInstance().stopRecord();
+ MyApplication.getAppInstance().getpNative().pttNativeSendAtCmd("0C0000");
+ }
+
+ /** 发送TCP包 登录成功后需要定时发送TCP包*/
+ public static void sendTCP(){
+ MyApplication.getAppInstance().getpNative().pttNativeSendAtCmd("570000\r\n");
+ }
+
+ /** 发送UDP包 登录后需要定时发送UDP包*/
+ public static void sendUDP(){
+ MyApplication.getAppInstance().getpNative().pttNativeSendAtCmd("580000\r\n");
+ }
+
+ /** 请求群组信息 */
+ public static void getGroupInfo(){
+ MyApplication.getAppInstance().getpNative().pttNativeSendAtCmd("0D0000");
+ }
+
+ /** 请求群组成员信息
+ * groupId 十六进制群组Id
+ * */
+ public static void getGroupMemberInfo(String groupId){
+ MyApplication.getAppInstance().getpNative().pttNativeSendAtCmd("0E0000" + groupId);
+ }
+
+ /** 切换群组
+ * groupId 十六进制群组Id
+ * */
+ public static void jumpGroup(String groupId){
+ MyApplication.getAppInstance().getpNative().pttNativeSendAtCmd("090000" + groupId);
+ }
+
+ /** 请求好友信息 */
+ public static void getFriendInfo(){
+ MyApplication.getAppInstance().getpNative().pttNativeSendAtCmd("0E000000000000\r\n");
+ }
+
+
+ /**
+ * 字符串转换成十六进制字符串
+ *
+ * @param str 待转换的ASCII字符串
+ * @return String
+ */
+ public static String str2HexStr(String str) {
+
+ char[] chars = "0123456789ABCDEF".toCharArray();
+ StringBuilder sb = new StringBuilder("");
+ byte[] bs = str.getBytes();
+ int bit;
+
+ for (int i = 0; i < bs.length; i++) {
+ bit = (bs[i] & 0x0f0) >> 4;
+ sb.append(chars[bit]);
+ bit = bs[i] & 0x0f;
+ sb.append(chars[bit]);
+ }
+ return sb.toString().trim();
+ }
+}
diff --git a/app/src/main/java/com/example/kingway/ptt/pttActivity.java b/app/src/main/java/com/example/kingway/ptt/pttActivity.java
new file mode 100644
index 0000000..be0d3d2
--- /dev/null
+++ b/app/src/main/java/com/example/kingway/ptt/pttActivity.java
@@ -0,0 +1,83 @@
+package com.example.kingway.ptt;
+
+import android.graphics.Color;
+
+import androidx.appcompat.app.AppCompatActivity;
+
+import android.os.Bundle;
+import android.util.Log;
+
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.util.Arrays;
+
+import android.view.MotionEvent;
+import android.view.View;
+import android.widget.Button;
+
+import com.hjq.permissions.Permission;
+import com.hjq.permissions.XXPermissions;
+import com.stand.standapp.R;
+
+public class pttActivity extends AppCompatActivity {
+ private Button pttBtn;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_ptt);
+ pttBtn = (Button) findViewById(R.id.pttBtn);
+
+ // 初始化 PTT
+ MyApplication.init(this);
+
+ XXPermissions.with(this)
+ .permission(Permission.RECORD_AUDIO)
+ .request(null);
+ pttBtn.setOnTouchListener(new View.OnTouchListener() {
+ @Override
+ public boolean onTouch(View view, MotionEvent motionEvent) {
+ if (motionEvent.getAction() == MotionEvent.ACTION_DOWN) {
+ pttBtn.setBackgroundColor(Color.RED);
+ SendAtUtil.speakPlay();
+ } else if (motionEvent.getAction() == MotionEvent.ACTION_UP) {
+ pttBtn.setBackgroundColor(Color.BLUE);
+ SendAtUtil.speakRelease();
+ }
+ return false;
+ }
+ });
+
+
+ findViewById(R.id.login).setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ SendAtUtil.toLogin("test012", "123456", "106.15.8.60", 1, 1);
+ }
+ });
+
+ /** 获取群组 */
+ findViewById(R.id.button2).setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ SendAtUtil.getGroupInfo();
+ }
+ });
+
+ /** 获取群成员 */
+ findViewById(R.id.button3).setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ SendAtUtil.getGroupMemberInfo("0002b199");
+ }
+ });
+
+ /** 切换群组 */
+ findViewById(R.id.btnJumpGroup).setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ SendAtUtil.jumpGroup("0002b199");
+ }
+ });
+ }
+}
diff --git a/app/src/main/java/com/example/kingway/ptt/pttNative.java b/app/src/main/java/com/example/kingway/ptt/pttNative.java
new file mode 100644
index 0000000..9b311f6
--- /dev/null
+++ b/app/src/main/java/com/example/kingway/ptt/pttNative.java
@@ -0,0 +1,208 @@
+package com.example.kingway.ptt;
+
+import android.media.AudioAttributes;
+import android.media.AudioFormat;
+import android.media.AudioManager;
+import android.media.AudioRecord;
+import android.media.AudioTrack;
+import android.util.Log;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class pttNative {
+ private static String TAG = "pttNative";
+ static {
+ System.loadLibrary("ptt");
+ }
+
+ public static char Char2ASCII(char c)
+ {
+ return (char) (c <= 9 ? (c+0x30) : (c+0x37));
+ }
+
+ public static char Ascii2Char(char nib_h, char nib_l)
+ {
+ nib_h = (nib_h <= '9')?((char)(nib_h-0x30)):(((nib_h<='F')?((char)(nib_h-0x37)):((char)(nib_h-0x57))));
+ nib_l = (nib_l <= '9')?((char)(nib_l-0x30)):(((nib_l<='F')?((char)(nib_l-0x37)):((char)(nib_l-0x57))));
+ return (char)((nib_h<<4)+nib_l);
+ }
+
+
+ //Callback Function for Recv the message from POC Lib
+ public void OEM_AT_cb(String sData)
+ {
+ Log.e(TAG,"Poc2 AT Callback: " + sData);
+ int len, i;
+ char[] bytes = sData.toCharArray();
+
+ List