parent
dbb430b088
commit
d022fa5f2d
|
|
@ -3,12 +3,10 @@ package com.example.kingway.ptt;
|
|||
import android.media.AudioFormat;
|
||||
import android.media.AudioRecord;
|
||||
import android.media.MediaRecorder;
|
||||
import android.util.Log;
|
||||
import timber.log.Timber;
|
||||
|
||||
import com.stand.standapp.MyApplication;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
@SuppressWarnings("ResultOfMethodCallIgnored")
|
||||
public class AudioRecordManager {
|
||||
private final String TAG = "AudioRecordManager";
|
||||
|
|
@ -32,14 +30,17 @@ public class AudioRecordManager {
|
|||
AudioFormat.CHANNEL_IN_MONO,
|
||||
AudioFormat.ENCODING_PCM_16BIT,
|
||||
bufferSize * 2);
|
||||
Timber.tag(TAG).d("AudioRecord初始化: source=MIC, freq=%dHz, minBuf=%d", FREQUENCY, bufferSize * 2);
|
||||
}
|
||||
|
||||
public void setRecording(){
|
||||
Timber.tag(TAG).d("setRecording -> startRecording()");
|
||||
if (mRecorder == null) initAudio();
|
||||
if(mRecorder.getRecordingState() != 3) mRecorder.startRecording();
|
||||
}
|
||||
|
||||
public void stopAudio(){
|
||||
Timber.tag(TAG).d("stopAudio -> stop()");
|
||||
if (mRecorder != null){
|
||||
mRecorder.stop();
|
||||
}
|
||||
|
|
@ -51,6 +52,7 @@ public class AudioRecordManager {
|
|||
}
|
||||
|
||||
public void destroyAudio(){
|
||||
Timber.tag(TAG).d("destroyAudio -> 释放AudioRecord");
|
||||
if (mRecorder != null){
|
||||
mRecorder.stop();
|
||||
mRecorder.release();
|
||||
|
|
@ -82,12 +84,13 @@ public class AudioRecordManager {
|
|||
try {
|
||||
recordThread.interrupt();
|
||||
} catch (Exception e) {
|
||||
Timber.tag(TAG).e(e, "录音线程interrupt失败");
|
||||
recordThread = null;
|
||||
}
|
||||
}
|
||||
recordThread = null;
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
Timber.tag(TAG).e(e, "destroyThread异常");
|
||||
} finally {
|
||||
recordThread = null;
|
||||
}
|
||||
|
|
@ -97,6 +100,7 @@ public class AudioRecordManager {
|
|||
* 启动录音线程
|
||||
*/
|
||||
private void startThread() {
|
||||
Timber.tag(TAG).d("启动录音线程");
|
||||
destroyThread();
|
||||
isStart = true;
|
||||
if (mRecorder == null) {
|
||||
|
|
@ -119,10 +123,12 @@ public class AudioRecordManager {
|
|||
int bytesRecord;
|
||||
byte[] tempBuffer = new byte[bufferSize];
|
||||
if (mRecorder.getState() != AudioRecord.STATE_INITIALIZED) {
|
||||
Timber.tag(TAG).w("AudioRecord未初始化(state=%d),终止录音", mRecorder.getState());
|
||||
stopRecord();
|
||||
return;
|
||||
}
|
||||
mRecorder.startRecording();
|
||||
Timber.tag(TAG).d("录音线程: startRecording() 成功");
|
||||
int count = 0;
|
||||
while (isStart) {
|
||||
if (null != mRecorder) {
|
||||
|
|
@ -132,15 +138,16 @@ public class AudioRecordManager {
|
|||
continue;
|
||||
}
|
||||
if (bytesRecord != 0 && bytesRecord != -1) {
|
||||
Log.i(TAG, "tempBuffer->" + Arrays.toString(tempBuffer));
|
||||
Timber.tag(TAG).v("录音帧: %d bytes", bytesRecord);
|
||||
MyApplication.getAppInstance().getpNative().pttNativeSendRecordCmd(tempBuffer);
|
||||
} else {
|
||||
Timber.tag(TAG).w("录音循环退出: bytesRecord=%d", bytesRecord);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
Timber.tag(TAG).e(e, "录音线程异常");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -150,12 +157,13 @@ public class AudioRecordManager {
|
|||
* 启动录音
|
||||
*/
|
||||
public void startRecord() {
|
||||
Timber.tag(TAG).d("startRecord() 被调用");
|
||||
try {
|
||||
stopRecord();
|
||||
|
||||
startThread();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
Timber.tag(TAG).e(e, "startRecord异常");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -163,6 +171,7 @@ public class AudioRecordManager {
|
|||
* 停止录音
|
||||
*/
|
||||
public void stopRecord() {
|
||||
Timber.tag(TAG).d("stopRecord() 被调用");
|
||||
try {
|
||||
destroyThread();
|
||||
if (mRecorder != null) {
|
||||
|
|
@ -172,10 +181,10 @@ public class AudioRecordManager {
|
|||
}
|
||||
mRecorder.release();
|
||||
mRecorder = null;
|
||||
} catch (Exception e) { }
|
||||
} catch (Exception e) { Timber.tag(TAG).e(e, "释放AudioRecord失败"); }
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
Timber.tag(TAG).e(e, "stopRecord异常");
|
||||
} finally {
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,6 +2,8 @@ package com.example.kingway.ptt;
|
|||
|
||||
import android.util.Log;
|
||||
|
||||
import timber.log.Timber;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.Executors;
|
||||
|
|
@ -55,22 +57,23 @@ public class CallBackResolution {
|
|||
|
||||
String ngx = "\\u";
|
||||
try {
|
||||
Log.i(TAG, "lisHex-->" + lisHex.toString());
|
||||
Timber.tag(TAG).i( "lisHex-->" + lisHex.toString());
|
||||
String firstHex = lisHex.get(0);
|
||||
String errorNum = lisHex.get(1);
|
||||
Log.d(TAG, "at_OEM_AT_cb firstHex: " + firstHex + ", errorNum: " + errorNum);
|
||||
Timber.tag(TAG).d( "at_OEM_AT_cb firstHex: " + firstHex + ", errorNum: " + errorNum);
|
||||
switch (firstHex){
|
||||
case "82"://登录状态通知指令
|
||||
String loginId = lisHex.get(2) + "" + lisHex.get(3) + "" + lisHex.get(4) + "" + lisHex.get(5);
|
||||
pttLoginStatus = errorNum;
|
||||
pttLoginId = loginId;
|
||||
Log.d(TAG,"PTT login status: "+pttLoginStatus+", id: "+pttLoginId);
|
||||
Timber.tag(TAG).d("PTT login status: "+pttLoginStatus+", id: "+pttLoginId);
|
||||
// 实时推送状态到前端
|
||||
com.stand.standapp.MainActivity.executeJs("updatePttLoginStatus('" + pttLoginStatus + "','" + pttLoginId + "')");
|
||||
CallBackUtil.callBackLoinState(errorNum, loginId);
|
||||
loginState = isLoginConflict(errorNum);
|
||||
CallBackUtil.callBackLoginConflict(loginState);
|
||||
if (loginState) {
|
||||
Timber.tag(TAG).w("Login conflict detected, showing conflict dialog");
|
||||
com.stand.standapp.MainActivity.showPttConflictDialog();
|
||||
}
|
||||
if ("02".equals(errorNum)) {
|
||||
|
|
@ -94,17 +97,17 @@ public class CallBackResolution {
|
|||
break;
|
||||
|
||||
case "0b"://发起讲话返回状态
|
||||
Log.d(TAG, "at_OEM_AT_cb ptt speak...");
|
||||
Timber.tag(TAG).d( "at_OEM_AT_cb ptt speak...");
|
||||
CallBackUtil.callBackSpeakPlaySuccess(errorNum.equals("00")? true : false);
|
||||
break;
|
||||
|
||||
case "0c"://结束讲话返回状态
|
||||
Log.d(TAG, "at_OEM_AT_cb speak end...");
|
||||
Timber.tag(TAG).d( "at_OEM_AT_cb speak end...");
|
||||
CallBackUtil.callBackSpeakReleaseSuccess(errorNum.equals("00")? true : false);
|
||||
break;
|
||||
|
||||
case "80"://返回群组信息
|
||||
Log.d(TAG, "at_OEM_AT_cb get group info: " + lisHex);
|
||||
Timber.tag(TAG).d( "at_OEM_AT_cb get group info: " + lisHex);
|
||||
StringBuilder strGroup = new StringBuilder();
|
||||
String groupId = lisHex.get(6) + "" + lisHex.get(7) + "" + lisHex.get(8) + "" + lisHex.get(9);
|
||||
int groupNo = Integer.valueOf((lisHex.get(4) + "" + lisHex.get(5)), 16);
|
||||
|
|
@ -123,13 +126,13 @@ public class CallBackResolution {
|
|||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
Timber.tag(TAG).e(e, "Decode hex failed");
|
||||
} finally {
|
||||
String tempTxt = "";
|
||||
tempTxt = unicodeToString(strGroup.toString());
|
||||
Log.i(TAG, " 组名称 " + tempTxt);
|
||||
Timber.tag(TAG).i( " 组名称 " + tempTxt);
|
||||
CallBackUtil.callBackGroupInfo(groupId, tempTxt, groupNo, groupCount);
|
||||
Log.d(TAG, "at_OEM_AT_cb group info groupId: " + groupId + ", groupNo: " + groupNo+", groupCount: " +groupCount);
|
||||
Timber.tag(TAG).d( "at_OEM_AT_cb group info groupId: " + groupId + ", groupNo: " + groupNo+", groupCount: " +groupCount);
|
||||
if (1 == groupNo) groupInfos.clear();
|
||||
GroupInfoDto groupInfo = new GroupInfoDto(groupId, tempTxt, groupNo, groupCount);
|
||||
groupInfos.add(groupInfo);
|
||||
|
|
@ -156,7 +159,7 @@ public class CallBackResolution {
|
|||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
Timber.tag(TAG).e(e, "Decode hex failed");
|
||||
} finally {
|
||||
String tempTxt = unicodeToString(groupMemberName.toString());
|
||||
GroupMemberInfoDto infoDto = new GroupMemberInfoDto(memberId, tempTxt, status, memberNo, haveVideo);
|
||||
|
|
@ -192,7 +195,7 @@ public class CallBackResolution {
|
|||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
Timber.tag(TAG).e(e, "Decode hex failed");
|
||||
} finally {
|
||||
String tempTxt = "";
|
||||
for (int i = 0; i < stringsSpker.size(); i++) {
|
||||
|
|
@ -232,7 +235,7 @@ public class CallBackResolution {
|
|||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
Timber.tag(TAG).e(e, "Decode hex failed");
|
||||
} finally {
|
||||
String tempTxt = "";
|
||||
for (int i = 0; i < stringsTalk.size(); i++) {
|
||||
|
|
@ -251,7 +254,7 @@ public class CallBackResolution {
|
|||
code=-1;
|
||||
}
|
||||
|
||||
Log.i(TAG, " 临时讲话 信息通知的指令 " + tempTxt + " code=" + code);
|
||||
Timber.tag(TAG).i( " 临时讲话 信息通知的指令 " + tempTxt + " code=" + code);
|
||||
CallBackUtil.callBackTempCallNotify(tempTxt);
|
||||
|
||||
// 处理临时呼叫页面逻辑
|
||||
|
|
@ -274,7 +277,7 @@ public class CallBackResolution {
|
|||
);
|
||||
com.stand.standapp.MyApplication.getAppInstance().startActivity(intent);
|
||||
} catch (Exception e) {
|
||||
Log.e(TAG, "Failed to open TempCallActivity: " + e.getMessage());
|
||||
Timber.tag(TAG).e( "Failed to open TempCallActivity: " + e.getMessage());
|
||||
}
|
||||
} else if (code == 0) {
|
||||
// 退出临时呼叫 → 关闭临时呼叫页面
|
||||
|
|
@ -318,13 +321,13 @@ public class CallBackResolution {
|
|||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
Timber.tag(TAG).e(e, "Decode hex failed");
|
||||
} finally {
|
||||
String userGroupName = "";
|
||||
for (int i = 0; i < stringsJumpGroup.size(); i++) {
|
||||
userGroupName += unicode(stringsJumpGroup.get(i));
|
||||
}
|
||||
Log.i(TAG,"进入群组 " + userGroupName);
|
||||
Timber.tag(TAG).i("进入群组 " + userGroupName);
|
||||
indexGroupId = userGroupId;
|
||||
indexGroupName = userGroupName;
|
||||
CallBackUtil.callBackNotifyUpdateGroup(userGroupId, userGroupName);
|
||||
|
|
@ -351,7 +354,7 @@ public class CallBackResolution {
|
|||
String time = strLis[2];
|
||||
CallBackUtil.callBackNotifyLocationStatus(0, locationMemberId, latitude, longitude, time);
|
||||
} catch (Exception e) {
|
||||
Log.e(TAG, "获取定位Exception-->" + e.getMessage());
|
||||
Timber.tag(TAG).e( "获取定位Exception-->" + e.getMessage());
|
||||
}
|
||||
} else {
|
||||
CallBackUtil.callBackNotifyLocationStatus(1, "", 0.0, 0.0, "");
|
||||
|
|
@ -410,7 +413,7 @@ public class CallBackResolution {
|
|||
string += lisHex.get(i).toString();
|
||||
}
|
||||
String address = hexString2String(string);
|
||||
Log.i(TAG, "address-->" + address);
|
||||
Timber.tag(TAG).i( "address-->" + address);
|
||||
|
||||
String[] strLis = address.split(",");
|
||||
latitude = Double.parseDouble(strLis[0]);
|
||||
|
|
@ -452,7 +455,7 @@ public class CallBackResolution {
|
|||
break;
|
||||
}
|
||||
}catch (Exception e){
|
||||
Log.e(TAG,"at_OEM_AT_cb Exception " + e.getMessage());
|
||||
Timber.tag(TAG).e("at_OEM_AT_cb Exception " + e.getMessage());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -469,26 +472,30 @@ public class CallBackResolution {
|
|||
* tip:1min内会出现40次左右0-1切换
|
||||
*/
|
||||
public static boolean isLoginConflict(String state) {
|
||||
Log.d(TAG, " isLoginConflict state: " + state + ",oldLoginSate: " + oldLoginSate + ", logNum: " + logNum);
|
||||
Timber.tag(TAG).d( " isLoginConflict state: " + state + ",oldLoginSate: " + oldLoginSate + ", logNum: " + logNum);
|
||||
if (oldLoginSate.equals("00") && state.equals("01")) {
|
||||
Log.d(TAG, "isLoginConflict first login...");
|
||||
Timber.tag(TAG).d( "isLoginConflict first login...");
|
||||
logNum++;
|
||||
oldLoginSate = state;
|
||||
} else if (oldLoginSate.equals("01") && state.equals("00")) {
|
||||
Log.d(TAG, "isLoginConflict login state changed...");
|
||||
Timber.tag(TAG).d( "isLoginConflict login state changed...");
|
||||
logNum++;
|
||||
oldLoginSate = state;
|
||||
}
|
||||
if (1 == logNum) {
|
||||
offlineTime = System.currentTimeMillis();
|
||||
}
|
||||
Log.d(TAG, "isLoginConflict logNum: " + logNum + ", offlineTime: " + offlineTime);
|
||||
if (logNum > 4) {
|
||||
Log.d(TAG, "isLoginConflict current time: " + System.currentTimeMillis() + ", diffTime: " + (System.currentTimeMillis() - offlineTime));
|
||||
if (System.currentTimeMillis() - offlineTime >= 60 * 1000) {
|
||||
Log.d(TAG, "isLoginConflict login state changed: " + logNum + " in 1min");
|
||||
Timber.tag(TAG).d( "isLoginConflict logNum: " + logNum + ", offlineTime: " + offlineTime);
|
||||
if (System.currentTimeMillis() - offlineTime <= 60 * 1000) {
|
||||
if (logNum > 5) {
|
||||
Timber.tag(TAG).d("isLoginConflict login state changed: " + logNum + " in 1min");
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
Timber.tag(TAG).d("isLoginConflict maybe network change, reset...");
|
||||
logNum = 0;
|
||||
offlineTime = System.currentTimeMillis();
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
|
@ -497,7 +504,7 @@ public class CallBackResolution {
|
|||
try {
|
||||
String[] txt = sData.split("\"");
|
||||
String data = txt[1];
|
||||
Log.d(TAG, "at_Play_TTS_cb sData: " + sData);
|
||||
Timber.tag(TAG).d( "at_Play_TTS_cb sData: " + sData);
|
||||
|
||||
String ngx = "\\u";
|
||||
List<String> strings = new ArrayList<>();
|
||||
|
|
@ -521,38 +528,37 @@ public class CallBackResolution {
|
|||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
Timber.tag(TAG).e(e, "Decode hex failed");
|
||||
} finally {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (int k = 0; k < strings.size(); k++) {
|
||||
sb.append(unicode(strings.get(k)));
|
||||
}
|
||||
String tempTxt = sb.toString();
|
||||
Log.i(TAG,"at_Play_TTS_cb " + tempTxt);
|
||||
Timber.tag(TAG).i("at_Play_TTS_cb " + tempTxt);
|
||||
if (tempTxt.contains("已登录")) {
|
||||
String showName = tempTxt.substring(3, tempTxt.length());
|
||||
CallBackUtil.callBackLogin(true, showName);
|
||||
ScheduledExecutorService executor = Executors.newScheduledThreadPool(1);
|
||||
Runnable task = () -> {
|
||||
Log.d(TAG, "callBackLogin send tcp and udp");
|
||||
Timber.tag(TAG).d( "callBackLogin send tcp and udp");
|
||||
SendAtUtil.sendUDP();
|
||||
SendAtUtil.sendTCP();
|
||||
};
|
||||
executor.scheduleAtFixedRate(task, 0, 40, TimeUnit.SECONDS);
|
||||
} else if (tempTxt.contains("账号已更新")) {
|
||||
// com.stand.standapp.MainActivity.showPttUpdateDialog("您的 PTT 账号信息已被更新,需要重新登录以应用更改。\n请点击确认重启应用。","账号更新");
|
||||
Log.d(TAG, "--------------------------1");
|
||||
Log.d(TAG, tempTxt);
|
||||
Timber.tag(TAG).w("TTS reports account updated: '%s'", tempTxt);
|
||||
} else if (tempTxt.contains("账号或密码错误")) {
|
||||
CallBackUtil.callBackLogin(false, "");
|
||||
Timber.tag(TAG).e("Account/password error, showing dialog. TTS: '%s'", tempTxt);
|
||||
com.stand.standapp.MainActivity.showPttUpdateDialog("您的 PTT 账号信息账号或密码错误。\n请点击确认重启应用。","账号或密码错误");
|
||||
}else if (tempTxt.contains("请配置账号")) {
|
||||
// com.stand.standapp.MainActivity.showPttUpdateDialog("首次登录信息更新。\n请点击确认重启应用。","登录信息更新");
|
||||
Timber.tag(TAG).w("TTS reports no account configured: '%s'", tempTxt);
|
||||
}
|
||||
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
Timber.tag(TAG).e(e, "Decode hex failed");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
package com.example.kingway.ptt;
|
||||
|
||||
import android.util.Log;
|
||||
import timber.log.Timber;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
|
@ -18,7 +18,7 @@ public class CallBackUtil {
|
|||
* name 用户名
|
||||
*/
|
||||
public static void callBackLogin(boolean loginState, String name) {
|
||||
Log.i(TAG, "callBackLogin loginState " + loginState + " name " + name);
|
||||
Timber.tag(TAG).d("callBackLogin loginState=%s name=%s", loginState, name);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -34,7 +34,7 @@ public class CallBackUtil {
|
|||
* loginId 用户ID,登录成功id有效
|
||||
*/
|
||||
public static void callBackLoinState(String state, String loginId) {
|
||||
Log.d(TAG, "callBackLoinState state: " + state + ", loginId: " + loginId);
|
||||
Timber.tag(TAG).d("callBackLoinState state=%s loginId=%s", state, loginId);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -43,13 +43,14 @@ public class CallBackUtil {
|
|||
* false:登录不冲突
|
||||
* */
|
||||
public static void callBackLoginConflict(boolean loginConflict) {
|
||||
Log.d(TAG, "callBackLoginConflict: " + loginConflict);
|
||||
Timber.tag(TAG).d("callBackLoginConflict: %s", loginConflict);
|
||||
}
|
||||
|
||||
/**
|
||||
* 登录账号有视频功能通知
|
||||
*/
|
||||
public static boolean callBackHaveVideo() {
|
||||
Timber.tag(TAG).d("callBackHaveVideo invoked");
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -60,7 +61,7 @@ public class CallBackUtil {
|
|||
* state true-成功, false-失败
|
||||
*/
|
||||
public static void callBackOnGroupSuccess(boolean state) {
|
||||
|
||||
Timber.tag(TAG).d("callBackOnGroupSuccess state=%s", state);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -80,7 +81,7 @@ public class CallBackUtil {
|
|||
}
|
||||
}
|
||||
com.stand.standapp.MainActivity.executeJs("if(window.onPttEvent){window.onPttEvent('MemberList', " + arr.toString() + ");}");
|
||||
} catch (Exception e) {}
|
||||
} catch (Exception e) { Timber.tag(TAG).e(e, "Failed to push PTT event to JS"); }
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -88,13 +89,16 @@ public class CallBackUtil {
|
|||
* state true-成功, false-失败
|
||||
*/
|
||||
public static void callBackSpeakPlaySuccess(boolean state) {
|
||||
Log.d(TAG, "callBackSpeakPlaySuccess state: " + state);
|
||||
if (state) AudioRecordManager.getInstance().startRecord();
|
||||
Timber.tag(TAG).d("callBackSpeakPlaySuccess state=%s", state);
|
||||
if (state) {
|
||||
AudioRecordManager.getInstance().startRecord();
|
||||
Timber.tag(TAG).d("AudioRecord started");
|
||||
}
|
||||
try {
|
||||
org.json.JSONObject obj = new org.json.JSONObject();
|
||||
obj.put("success", state);
|
||||
com.stand.standapp.MainActivity.executeJs("if(window.onPttEvent){window.onPttEvent('SpeakResult', " + obj.toString() + ");}");
|
||||
} catch (Exception e) {}
|
||||
} catch (Exception e) { Timber.tag(TAG).e(e, "Failed to push PTT event to JS"); }
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -106,7 +110,7 @@ public class CallBackUtil {
|
|||
org.json.JSONObject obj = new org.json.JSONObject();
|
||||
obj.put("success", state);
|
||||
com.stand.standapp.MainActivity.executeJs("if(window.onPttEvent){window.onPttEvent('SpeakEnd', " + obj.toString() + ");}");
|
||||
} catch (Exception e) {}
|
||||
} catch (Exception e) { Timber.tag(TAG).e(e, "Failed to push PTT event to JS"); }
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -116,7 +120,9 @@ public class CallBackUtil {
|
|||
* groupNo 表示此组为第几个组
|
||||
* groupCount 表示此组用户成员数
|
||||
*/
|
||||
public static void callBackGroupInfo(String groupId, String groupName, int groupNo, int groupCount) {}
|
||||
public static void callBackGroupInfo(String groupId, String groupName, int groupNo, int groupCount) {
|
||||
Timber.tag(TAG).d("callBackGroupInfo groupId=%s name=%s no=%d count=%d", groupId, groupName, groupNo, groupCount);
|
||||
}
|
||||
|
||||
/**
|
||||
* 返回群组集合信息
|
||||
|
|
@ -133,7 +139,7 @@ public class CallBackUtil {
|
|||
arr.put(obj);
|
||||
}
|
||||
com.stand.standapp.MainActivity.executeJs("if(window.onPttEvent){window.onPttEvent('GroupList', " + arr.toString() + ");}");
|
||||
} catch (Exception e) {}
|
||||
} catch (Exception e) { Timber.tag(TAG).e(e, "Failed to push PTT event to JS"); }
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -143,6 +149,7 @@ public class CallBackUtil {
|
|||
* talkName 讲话用户名字
|
||||
* */
|
||||
public static void callBackNotifySpker ( int speckType, String groupId, String groupName, String talkId, String talkName){
|
||||
Timber.tag(TAG).d("callBackNotifySpker speckType=%d groupId=%s talkId=%s talkName=%s", speckType, groupId, talkId, talkName);
|
||||
try {
|
||||
org.json.JSONObject obj = new org.json.JSONObject();
|
||||
obj.put("speckType", speckType);
|
||||
|
|
@ -151,10 +158,11 @@ public class CallBackUtil {
|
|||
obj.put("talkId", talkId);
|
||||
obj.put("talkName", talkName);
|
||||
com.stand.standapp.MainActivity.executeJs("if(window.onPttEvent){window.onPttEvent('SpeakerUpdate', " + obj.toString() + ");}");
|
||||
} catch (Exception e) {}
|
||||
} catch (Exception e) { Timber.tag(TAG).e(e, "Failed to push PTT event to JS"); }
|
||||
}
|
||||
|
||||
public static void callBackNotifyPlayStatus ( int playStatus, int speckType, String groupId, String groupName, String talkId, String talkName){
|
||||
Timber.tag(TAG).d("callBackNotifyPlayStatus playStatus=%d talkId=%s", playStatus, talkId);
|
||||
try {
|
||||
org.json.JSONObject obj = new org.json.JSONObject();
|
||||
obj.put("playStatus", playStatus);
|
||||
|
|
@ -164,24 +172,26 @@ public class CallBackUtil {
|
|||
obj.put("talkId", talkId);
|
||||
obj.put("talkName", talkName);
|
||||
com.stand.standapp.MainActivity.executeJs("if(window.onPttEvent){window.onPttEvent('PlayStatus', " + obj.toString() + ");}");
|
||||
} catch (Exception e) {}
|
||||
} catch (Exception e) { Timber.tag(TAG).e(e, "Failed to push PTT event to JS"); }
|
||||
}
|
||||
|
||||
public static void callBackTempCallNotify (String tempCallNotify){
|
||||
Timber.tag(TAG).d("callBackTempCallNotify msg=%s", tempCallNotify);
|
||||
try {
|
||||
org.json.JSONObject obj = new org.json.JSONObject();
|
||||
obj.put("msg", tempCallNotify);
|
||||
com.stand.standapp.MainActivity.executeJs("if(window.onPttEvent){window.onPttEvent('TempCall', " + obj.toString() + ");}");
|
||||
} catch (Exception e) {}
|
||||
} catch (Exception e) { Timber.tag(TAG).e(e, "Failed to push PTT event to JS"); }
|
||||
}
|
||||
|
||||
public static void callBackNotifyUpdateGroup (String userGroupId, String userGroupName){
|
||||
Timber.tag(TAG).d("callBackNotifyUpdateGroup groupId=%s groupName=%s", userGroupId, userGroupName);
|
||||
try {
|
||||
org.json.JSONObject obj = new org.json.JSONObject();
|
||||
obj.put("groupId", userGroupId);
|
||||
obj.put("groupName", userGroupName);
|
||||
com.stand.standapp.MainActivity.executeJs("if(window.onPttEvent){window.onPttEvent('UpdateGroup', " + obj.toString() + ");}");
|
||||
} catch (Exception e) {}
|
||||
} catch (Exception e) { Timber.tag(TAG).e(e, "Failed to push PTT event to JS"); }
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -193,6 +203,7 @@ public class CallBackUtil {
|
|||
* time 时间
|
||||
*/
|
||||
public static void callBackNotifyLocationStatus ( int status, String userId,double latitude, double longitude, String time){
|
||||
Timber.tag(TAG).d("callBackNotifyLocationStatus status=%d userId=%s lat=%f lng=%f", status, userId, latitude, longitude);
|
||||
try {
|
||||
org.json.JSONObject obj = new org.json.JSONObject();
|
||||
obj.put("status", status);
|
||||
|
|
@ -201,7 +212,7 @@ public class CallBackUtil {
|
|||
obj.put("longitude", longitude);
|
||||
obj.put("time", time);
|
||||
com.stand.standapp.MainActivity.executeJs("if(window.onPttEvent){window.onPttEvent('LocationStatus', " + obj.toString() + ");}");
|
||||
} catch (Exception e) {}
|
||||
} catch (Exception e) { Timber.tag(TAG).e(e, "Failed to push PTT event to JS"); }
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -209,7 +220,7 @@ public class CallBackUtil {
|
|||
* status true:成功, false:失败
|
||||
* */
|
||||
public static void callBackNotifyUploadLocation ( boolean status){
|
||||
|
||||
Timber.tag(TAG).d("callBackNotifyUploadLocation status=%s", status);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -221,7 +232,7 @@ public class CallBackUtil {
|
|||
* inv=1:1勾选单呼,0不勾选单呼
|
||||
* */
|
||||
public static void callBackNotifyCodeInfo (String codeInfo){
|
||||
|
||||
Timber.tag(TAG).d("callBackNotifyCodeInfo: %s", codeInfo);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -231,7 +242,7 @@ public class CallBackUtil {
|
|||
* pwd=111111 账号密码:111111
|
||||
* */
|
||||
public static void callBackNotifyPwdInfo (String pwdInfo){
|
||||
|
||||
Timber.tag(TAG).d("callBackNotifyPwdInfo: %s", pwdInfo);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -239,7 +250,7 @@ public class CallBackUtil {
|
|||
* status true:成功,false:失败
|
||||
* */
|
||||
public static void callBackNotifyCodeOpenStatus ( boolean status){
|
||||
|
||||
Timber.tag(TAG).d("callBackNotifyCodeOpenStatus status=%s", status);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -247,7 +258,7 @@ public class CallBackUtil {
|
|||
* status true:成功,false:失败
|
||||
* */
|
||||
public static void callBackNotifyCodeExiteStatus ( boolean status){
|
||||
|
||||
Timber.tag(TAG).d("callBackNotifyCodeExiteStatus status=%s", status);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -255,7 +266,7 @@ public class CallBackUtil {
|
|||
* status true:成功,false:失败
|
||||
* */
|
||||
public static void callBackNotifyUploadAgentPwd ( boolean status){
|
||||
|
||||
Timber.tag(TAG).d("callBackNotifyUploadAgentPwd status=%s", status);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -263,7 +274,7 @@ public class CallBackUtil {
|
|||
* status true:成功,false:失败
|
||||
* */
|
||||
public static void callBackRequestReportAlarm ( boolean status){
|
||||
|
||||
Timber.tag(TAG).d("callBackRequestReportAlarm status=%s", status);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -271,7 +282,7 @@ public class CallBackUtil {
|
|||
* status true:成功,false:失败
|
||||
* */
|
||||
public static void callBackRequestStopAlarm ( boolean status){
|
||||
|
||||
Timber.tag(TAG).d("callBackRequestStopAlarm status=%s", status);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -281,19 +292,21 @@ public class CallBackUtil {
|
|||
* longitude 经度
|
||||
* */
|
||||
public static void callBackEnotifyAlarm (String memberName,double latitude, double longitude){
|
||||
Timber.tag(TAG).w("callBackEnotifyAlarm memberName=%s lat=%f lng=%f", memberName, latitude, longitude);
|
||||
try {
|
||||
org.json.JSONObject obj = new org.json.JSONObject();
|
||||
obj.put("memberName", memberName);
|
||||
obj.put("latitude", latitude);
|
||||
obj.put("longitude", longitude);
|
||||
com.stand.standapp.MainActivity.executeJs("if(window.onPttEvent){window.onPttEvent('Alarm', " + obj.toString() + ");}");
|
||||
} catch (Exception e) {}
|
||||
} catch (Exception e) { Timber.tag(TAG).e(e, "Failed to push PTT event to JS"); }
|
||||
}
|
||||
|
||||
/**
|
||||
* 收到群成员停止警告通知
|
||||
* */
|
||||
public static void callBackEnotifyStopAlarm () {
|
||||
Timber.tag(TAG).d("callBackEnotifyStopAlarm invoked");
|
||||
com.stand.standapp.MainActivity.executeJs("if(window.onPttEvent){window.onPttEvent('StopAlarm', {});}");
|
||||
}
|
||||
|
||||
|
|
@ -302,7 +315,7 @@ public class CallBackUtil {
|
|||
* status true:成功,false:失败
|
||||
* */
|
||||
public static void callBackRequestNfc ( boolean status){
|
||||
|
||||
Timber.tag(TAG).d("callBackRequestNfc status=%s", status);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -48,6 +48,7 @@ public class SendAtUtil {
|
|||
* tempCall 是否开启单呼 1开启单呼,0关闭单呼
|
||||
* */
|
||||
public static void toLogin(String account, String pwd, String ip, int location, int tempCall){
|
||||
Timber.tag("PTT").i("Login: account=%s, ip=%s, gps=%d, tempCall=%d", account, ip, location, tempCall);
|
||||
String ipHex = str2HexStr("ip=" + ip + ";");
|
||||
String accountHex = str2HexStr("id=" + account + ";");
|
||||
String pwdHex = str2HexStr("pwd=" + pwd + ";");
|
||||
|
|
@ -62,22 +63,26 @@ public class SendAtUtil {
|
|||
* 按下PTT开始呼叫
|
||||
* */
|
||||
public static void speakPlay(){
|
||||
Timber.tag("PTT").i("PTT speak START (press)");
|
||||
send("0B0000");
|
||||
}
|
||||
|
||||
/** 松开PTT结束呼叫*/
|
||||
public static void speakRelease(){
|
||||
Timber.tag("PTT").i("PTT speak STOP (release)");
|
||||
AudioRecordManager.getInstance().stopRecord();
|
||||
send("0C0000");
|
||||
}
|
||||
|
||||
/** 发送TCP包 登录成功后需要定时发送TCP包*/
|
||||
public static void sendTCP(){
|
||||
Timber.tag("PTT").v("TCP keepalive sent");
|
||||
send("570000\r\n");
|
||||
}
|
||||
|
||||
/** 发送UDP包 登录后需要定时发送UDP包*/
|
||||
public static void sendUDP(){
|
||||
Timber.tag("PTT").v("UDP keepalive sent");
|
||||
send("580000\r\n");
|
||||
}
|
||||
|
||||
|
|
@ -97,6 +102,7 @@ public class SendAtUtil {
|
|||
* groupId 十六进制群组Id
|
||||
* */
|
||||
public static void jumpGroup(String groupId){
|
||||
Timber.tag("PTT").i("Jump to group: %s", groupId);
|
||||
send("090000" + groupId);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ import android.media.AudioFormat;
|
|||
import android.media.AudioManager;
|
||||
import android.media.AudioRecord;
|
||||
import android.media.AudioTrack;
|
||||
import android.util.Log;
|
||||
import timber.log.Timber;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
|
@ -15,8 +15,9 @@ public class pttNative {
|
|||
static {
|
||||
try {
|
||||
System.loadLibrary("ptt");
|
||||
Timber.tag(TAG).d("Native library 'ptt' loaded successfully");
|
||||
} catch (Throwable e) {
|
||||
Log.e(TAG, "Failed to load ptt library: " + e.getMessage());
|
||||
Timber.tag(TAG).e(e, "Failed to load ptt library");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -36,7 +37,7 @@ public class pttNative {
|
|||
//Callback Function for Recv the message from POC Lib
|
||||
public void OEM_AT_cb(String sData)
|
||||
{
|
||||
Log.e(TAG,"Poc2 AT Callback: " + sData);
|
||||
Timber.tag(TAG).d("Poc2 AT Callback: %s", sData);
|
||||
int len, i, j=0;
|
||||
char[] bytes = sData.toCharArray();
|
||||
|
||||
|
|
@ -50,12 +51,15 @@ public class pttNative {
|
|||
lisHex.add(temp.length() == 1 ? "0" + temp : temp);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
Timber.tag(TAG).w("OEM_AT_cb: unexpected format, len=%d, data=%s", bytes.length, sData);
|
||||
}
|
||||
|
||||
CallBackResolution.at_OEM_AT_cb(lisHex);
|
||||
}
|
||||
|
||||
public void OEM_Play_cb(byte[] bytes){
|
||||
Timber.tag(TAG).d("OEM_Play_cb: %d bytes", bytes.length);
|
||||
if (mAudioTrack == null) {
|
||||
initAudioTrack();
|
||||
}
|
||||
|
|
@ -68,27 +72,27 @@ public class pttNative {
|
|||
|
||||
public void OEM_Play_Start_cb()
|
||||
{
|
||||
Log.e("Play Start!!!!\r\n","");
|
||||
Timber.tag(TAG).e("Play Start!!!!");
|
||||
}
|
||||
|
||||
public void OEM_Play_Stop_cb()
|
||||
{
|
||||
Log.e("Play Stop!!!!\r\n","");
|
||||
Timber.tag(TAG).e("Play Stop!!!!");
|
||||
}
|
||||
|
||||
public void OEM_Record_Start_cb()
|
||||
{
|
||||
Log.e("Record Start!!!!\r\n","");
|
||||
Timber.tag(TAG).e("Record Start!!!!");
|
||||
}
|
||||
|
||||
public void OEM_Record_Stop_cb()
|
||||
{
|
||||
Log.e("Record Stop!!!!\r\n","");
|
||||
Timber.tag(TAG).e("Record Stop!!!!");
|
||||
}
|
||||
|
||||
public void OEM_Play_TTS_cb(String sData)
|
||||
{
|
||||
Log.e(TAG , "Play TTS " + sData);
|
||||
Timber.tag(TAG).e("Play TTS " + sData);
|
||||
CallBackResolution.at_Play_TTS_cb(sData);
|
||||
}
|
||||
|
||||
|
|
@ -112,16 +116,17 @@ public class pttNative {
|
|||
private native int OEM_Set_Package_Name(String name);
|
||||
|
||||
public void pttNativeSendRecordCmd(byte[] data) {
|
||||
Timber.tag(TAG).d("pttNativeSendRecordCmd: %d bytes", data.length);
|
||||
OEM_Push_Record_Data(data);
|
||||
}
|
||||
|
||||
public void pttNativeSendAtCmd(String strAtCmd)
|
||||
{
|
||||
try {
|
||||
Log.i(TAG,"strAtCmd " + strAtCmd);
|
||||
Timber.tag(TAG).i("AT Send: %s", strAtCmd);
|
||||
OEM_AT_Send(strAtCmd);
|
||||
} catch (Throwable e) {
|
||||
Log.e(TAG, "Native AT Send failed: " + e.getMessage());
|
||||
Timber.tag(TAG).e( "Native AT Send failed: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -130,7 +135,7 @@ public class pttNative {
|
|||
try {
|
||||
OEM_Poc_Task_Start();
|
||||
} catch (Throwable e) {
|
||||
Log.e(TAG, "Native PocTaskStart failed");
|
||||
Timber.tag(TAG).e(e, "Native PocTaskStart failed");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -139,6 +144,7 @@ public class pttNative {
|
|||
try {
|
||||
return OEM_Set_AT_CallBack("OEM_AT_cb");
|
||||
} catch (Throwable e) {
|
||||
Timber.tag(TAG).e(e, "Failed to set AT callback");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
|
@ -148,6 +154,7 @@ public class pttNative {
|
|||
try {
|
||||
return OEM_Set_Play_CallBack("OEM_Play_cb");
|
||||
} catch (Throwable e) {
|
||||
Timber.tag(TAG).e(e, "Failed to set Play callback");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
|
@ -157,6 +164,7 @@ public class pttNative {
|
|||
try {
|
||||
return OEM_Set_Play_Start_Callback("OEM_Play_Start_cb");
|
||||
} catch (Throwable e) {
|
||||
Timber.tag(TAG).e(e, "Failed to set PlayStart callback");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
|
@ -166,6 +174,7 @@ public class pttNative {
|
|||
try {
|
||||
return OEM_Set_Play_Stop_Callback("OEM_Play_Stop_cb");
|
||||
} catch (Throwable e) {
|
||||
Timber.tag(TAG).e(e, "Failed to set PlayStop callback");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
|
@ -175,6 +184,7 @@ public class pttNative {
|
|||
try {
|
||||
return OEM_Set_Record_Start_Callback("OEM_Record_Start_cb");
|
||||
} catch (Throwable e) {
|
||||
Timber.tag(TAG).e(e, "Failed to set RecordStart callback");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
|
@ -184,6 +194,7 @@ public class pttNative {
|
|||
try {
|
||||
return OEM_Set_Record_Stop_Callback("OEM_Record_Stop_cb");
|
||||
} catch (Throwable e) {
|
||||
Timber.tag(TAG).e(e, "Failed to set RecordStop callback");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
|
@ -193,6 +204,7 @@ public class pttNative {
|
|||
try {
|
||||
return OEM_Set_TTS_Callback("OEM_Play_TTS_cb");
|
||||
} catch (Throwable e) {
|
||||
Timber.tag(TAG).e(e, "Failed to set TTS callback");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
|
@ -202,17 +214,20 @@ public class pttNative {
|
|||
try {
|
||||
return OEM_Set_Package_Name(name);
|
||||
} catch (Throwable e) {
|
||||
Timber.tag(TAG).e(e, "Failed to set package callback");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
public pttNative() {
|
||||
Timber.tag(TAG).d("pttNative instance created");
|
||||
initAudioTrack();
|
||||
}
|
||||
|
||||
private AudioTrack mAudioTrack;
|
||||
public void initAudioTrack() {
|
||||
int mAudioMinBufSize = AudioTrack.getMinBufferSize(8000, AudioFormat.CHANNEL_OUT_MONO, AudioFormat.ENCODING_PCM_16BIT);
|
||||
Timber.tag(TAG).d("AudioTrack init: minBufSize=%d", mAudioMinBufSize);
|
||||
|
||||
AudioAttributes audioAttributes = new AudioAttributes.Builder()
|
||||
.setUsage(AudioAttributes.USAGE_VOICE_COMMUNICATION) // 通信场景
|
||||
|
|
@ -245,7 +260,7 @@ public class pttNative {
|
|||
}
|
||||
mAudioTrack.release();
|
||||
mAudioTrack = null;
|
||||
} catch (Exception e) {}
|
||||
} catch (Exception e) { Timber.tag(TAG).e(e, "AudioTrack destroy failed"); }
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -107,6 +107,8 @@ class AndroidInterface(private val activity: MainActivity) {
|
|||
SendAtUtil.speakPlay()
|
||||
Timber.tag("PTT").d("Speak Play")
|
||||
MainActivity.executeJs("updatePttTalkStatus(true)")
|
||||
} else {
|
||||
Timber.tag("PTT").w("Speak Play ignored: already speaking")
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -125,11 +127,13 @@ class AndroidInterface(private val activity: MainActivity) {
|
|||
json.put("groupName", com.example.kingway.ptt.CallBackResolution.getCurrentGroupName())
|
||||
json.toString()
|
||||
} catch (e: Exception) {
|
||||
Timber.tag("PTT").e(e, "pttGetCurrentGroup failed")
|
||||
"{\"groupId\":\"\",\"groupName\":\"\"}"
|
||||
}
|
||||
}
|
||||
|
||||
fun pttSpeakRelease() {
|
||||
Timber.tag("PTT").d("pttSpeakRelease called, isSpeaking=%s", isSpeaking)
|
||||
if (isSpeaking) {
|
||||
val now = System.currentTimeMillis()
|
||||
val duration = now - lastSpeakTime
|
||||
|
|
@ -152,34 +156,42 @@ class AndroidInterface(private val activity: MainActivity) {
|
|||
SendAtUtil.speakRelease()
|
||||
Timber.tag("PTT").d("Real Speak Release")
|
||||
MainActivity.executeJs("updatePttTalkStatus(false)")
|
||||
} else {
|
||||
Timber.tag("PTT").w("realRelease skipped: already released")
|
||||
}
|
||||
}
|
||||
|
||||
fun pttForceRelease() {
|
||||
val wasSpeaking = isSpeaking
|
||||
isSpeaking = false
|
||||
SendAtUtil.speakRelease()
|
||||
Timber.tag("PTT").d("Force Release")
|
||||
Timber.tag("PTT").d("Force Release (wasSpeaking=%s)", wasSpeaking)
|
||||
}
|
||||
|
||||
fun pttGetGroupInfo() {
|
||||
Timber.tag("PTT").d("pttGetGroupInfo called")
|
||||
SendAtUtil.getGroupInfo()
|
||||
}
|
||||
|
||||
fun pttGetGroupMemberInfo(gid: String) {
|
||||
Timber.tag("PTT").d("pttGetGroupMemberInfo: gid=%s", gid)
|
||||
SendAtUtil.getGroupMemberInfo(gid)
|
||||
}
|
||||
|
||||
fun simulatePttConflict() {
|
||||
Timber.tag("PTT").w("simulatePttConflict: showing conflict dialog via JS bridge")
|
||||
Handler(Looper.getMainLooper()).post {
|
||||
MainActivity.showPttConflictDialog()
|
||||
}
|
||||
}
|
||||
|
||||
fun pttSendAtCmd(cmd: String) {
|
||||
Timber.tag("PTT").d("pttSendAtCmd: %s", cmd)
|
||||
SendAtUtil.sendRawCmd(cmd)
|
||||
}
|
||||
|
||||
fun pttJumpGroup(gid: String) {
|
||||
Timber.tag("PTT").d("pttJumpGroup: gid=%s", gid)
|
||||
SendAtUtil.jumpGroup(gid)
|
||||
}
|
||||
|
||||
|
|
@ -358,6 +370,7 @@ class AndroidInterface(private val activity: MainActivity) {
|
|||
val packageInfo = activity.packageManager.getPackageInfo(activity.packageName, 0)
|
||||
packageInfo.versionName ?: "1.0.0"
|
||||
} catch (e: Exception) {
|
||||
Timber.tag("AndroidInterface").e(e, "getVersionName failed")
|
||||
"1.0.0"
|
||||
}
|
||||
}
|
||||
|
|
@ -383,6 +396,7 @@ class AndroidInterface(private val activity: MainActivity) {
|
|||
|
||||
json.toString()
|
||||
} catch (e: Exception) {
|
||||
Timber.tag("AndroidInterface").e(e, "getAboutInfo failed")
|
||||
"{ \"appName\": \"消防值守台\", \"versionName\": \"1.0.0\" }"
|
||||
}
|
||||
}
|
||||
|
|
@ -405,6 +419,7 @@ class AndroidInterface(private val activity: MainActivity) {
|
|||
val prefs = activity.getSharedPreferences("msg_records", Context.MODE_PRIVATE)
|
||||
prefs.getString("history", "") ?: ""
|
||||
} catch (e: Exception) {
|
||||
Timber.tag("Storage").e(e, "getMessages failed")
|
||||
""
|
||||
}
|
||||
}
|
||||
|
|
@ -442,6 +457,7 @@ class AndroidInterface(private val activity: MainActivity) {
|
|||
}
|
||||
|
||||
fun showRestartDialog(message: String, title: String) {
|
||||
Timber.tag("AndroidInterface").w("showRestartDialog from JS: title=%s msg=%s", title, message)
|
||||
Handler(Looper.getMainLooper()).post {
|
||||
com.stand.standapp.MainActivity.showPttUpdateDialog(message, title)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -106,6 +106,7 @@ class LoginActivity : AppCompatActivity() {
|
|||
}
|
||||
|
||||
private fun performLogin(username: String, password: String, remember: Boolean, officialMode: Boolean) {
|
||||
Timber.tag("Login").d("开始登录: username=%s, server=%s", username, AppConfig.getServerUrl(this))
|
||||
val serverUrl = AppConfig.getServerUrl(this)
|
||||
val loginUrl = "$serverUrl/api/auth/login"
|
||||
|
||||
|
|
@ -128,6 +129,7 @@ class LoginActivity : AppCompatActivity() {
|
|||
|
||||
client.newCall(request).enqueue(object : Callback {
|
||||
override fun onFailure(call: Call, e: IOException) {
|
||||
Timber.tag("Login").e(e, "登录网络请求失败")
|
||||
runOnUiThread {
|
||||
loadingDialog.dismiss()
|
||||
Toast.makeText(applicationContext, "网络异常: ${e.message}", Toast.LENGTH_SHORT).show()
|
||||
|
|
@ -160,12 +162,14 @@ class LoginActivity : AppCompatActivity() {
|
|||
Toast.makeText(applicationContext, "登录成功", Toast.LENGTH_SHORT).show()
|
||||
|
||||
// 获取独立的 PTT 账号并初始化
|
||||
Timber.tag("PTT").d("开始PTT初始化流程: username=%s, hasToken=%b", username, accessToken.isNotEmpty())
|
||||
initPttWithAccount(username, accessToken)
|
||||
|
||||
// 2. 启动硬件 GPIO 监听
|
||||
try {
|
||||
com.stand.standapp.utils.GpioManager.init(this@LoginActivity)
|
||||
com.stand.standapp.utils.GpioManager.startListening()
|
||||
Timber.tag("GPIO").d("GPIO初始化并启动监听成功")
|
||||
} catch (e: Exception) {
|
||||
Timber.tag("GPIO").e(e, "GPIO init error")
|
||||
}
|
||||
|
|
@ -312,6 +316,7 @@ class LoginActivity : AppCompatActivity() {
|
|||
|
||||
private fun initPttWithAccount(username: String, accessToken: String) {
|
||||
if (accessToken.isEmpty()) {
|
||||
Timber.tag("PTT").w("accessToken为空,使用默认PTT密码: username=%s", username)
|
||||
doPttInit(username, "123456")
|
||||
return
|
||||
}
|
||||
|
|
@ -339,8 +344,10 @@ class LoginActivity : AppCompatActivity() {
|
|||
val data = json.optJSONObject("data")
|
||||
val pttUsername = data?.optString("cardNumber", username) ?: username
|
||||
val pttPassword = data?.optString("pocPassword", "123456") ?: "123456"
|
||||
Timber.tag("PTT").d("获取到服务器PTT账号: cardNumber=%s", pttUsername)
|
||||
doPttInit(pttUsername, pttPassword)
|
||||
} else {
|
||||
Timber.tag("PTT").w("获取PTT账号失败, code=%d", json.optInt("code"))
|
||||
doPttInit(username, "123456")
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
|
|
@ -352,21 +359,26 @@ class LoginActivity : AppCompatActivity() {
|
|||
}
|
||||
|
||||
private fun doPttInit(pttUsername: String, pttPassword: String) {
|
||||
Timber.tag("PTT").d("PTT初始化开始: username=%s", pttUsername)
|
||||
android.os.Handler(android.os.Looper.getMainLooper()).post {
|
||||
Toast.makeText(applicationContext, "PTT初始化中...", Toast.LENGTH_SHORT).show()
|
||||
}
|
||||
|
||||
// 1. PTT 引擎强制重置后登录 (销毁旧 session,确保干净状态)
|
||||
try {
|
||||
Timber.tag("PTT").d("发送PTT取消登录指令")
|
||||
com.example.kingway.ptt.SendAtUtil.toCancelLogin()
|
||||
Timber.tag("PTT").d("发送PTT注销指令")
|
||||
com.example.kingway.ptt.SendAtUtil.toLogout()
|
||||
} catch (e: Exception) {
|
||||
Timber.tag("PTT").e(e, "PTT init error")
|
||||
}
|
||||
|
||||
// 使用 Handler 替代硬编码 Thread.sleep,避免阻塞或随意开辟线程
|
||||
Timber.tag("PTT").d("等待1500ms以确保旧session完全清理")
|
||||
android.os.Handler(android.os.Looper.getMainLooper()).postDelayed({
|
||||
try {
|
||||
Timber.tag("PTT").d("发送PTT登录指令: username=%s, ip=%s", pttUsername, "220.154.131.231")
|
||||
com.example.kingway.ptt.SendAtUtil.toLogin(pttUsername, pttPassword, "220.154.131.231", 1, 1)
|
||||
} catch (e: Exception) {
|
||||
Timber.tag("PTT").e(e, "PTT login error")
|
||||
|
|
|
|||
|
|
@ -49,6 +49,7 @@ class MainActivity : AppCompatActivity() {
|
|||
// 硬件按键触发
|
||||
@JvmStatic
|
||||
fun onHardwarePttDown() {
|
||||
Timber.tag("MainActivity").d("onHardwarePttDown triggered")
|
||||
instance?.runOnUiThread {
|
||||
instance?.pttInterface?.pttSpeakPlay()
|
||||
executeJs("onHardwarePttDown()")
|
||||
|
|
@ -57,6 +58,7 @@ class MainActivity : AppCompatActivity() {
|
|||
|
||||
@JvmStatic
|
||||
fun onHardwarePttUp() {
|
||||
Timber.tag("MainActivity").d("onHardwarePttUp triggered")
|
||||
instance?.runOnUiThread {
|
||||
instance?.pttInterface?.pttSpeakRelease()
|
||||
executeJs("onHardwarePttUp()")
|
||||
|
|
@ -65,6 +67,7 @@ class MainActivity : AppCompatActivity() {
|
|||
|
||||
@JvmStatic
|
||||
fun showPttConflictDialog() {
|
||||
Timber.tag("PTT").w("showPttConflictDialog: account conflict detected")
|
||||
if (isConflictDialogShowing) return
|
||||
isConflictDialogShowing = true
|
||||
instance?.runOnUiThread {
|
||||
|
|
@ -83,10 +86,12 @@ class MainActivity : AppCompatActivity() {
|
|||
|
||||
@JvmStatic
|
||||
fun showPttUpdateDialog(msg: String, title: String) {
|
||||
Timber.tag("PTT").w("showPttUpdateDialog: title=%s msg=%s", title, msg)
|
||||
if (isConflictDialogShowing) return
|
||||
val ctx = instance
|
||||
if (ctx == null) {
|
||||
pendingDialog = title to msg
|
||||
Timber.tag("PTT").d("Pending dialog stored (instance null): title=%s", title)
|
||||
return
|
||||
}
|
||||
isConflictDialogShowing = true
|
||||
|
|
@ -106,6 +111,7 @@ class MainActivity : AppCompatActivity() {
|
|||
@JvmStatic
|
||||
fun showPendingDialogIfNeeded() {
|
||||
val pending = pendingDialog ?: return
|
||||
Timber.tag("PTT").d("Flushing pending dialog: %s", pending.second)
|
||||
pendingDialog = null
|
||||
showPttUpdateDialog(pending.second, pending.first)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -78,10 +78,14 @@ object GpioManager {
|
|||
MainActivity.executeJs("updatePttTalkStatus(true)")
|
||||
// 同步 TempCallActivity
|
||||
TempCallActivity.instance?.onGpioPressed()
|
||||
Timber.tag("GPIO").d("Notified TempCallActivity: onGpioPressed")
|
||||
} else {
|
||||
Timber.tag("GPIO").w("GPIO pressed but isSpeaking already true — ignoring")
|
||||
}
|
||||
|
||||
} else {
|
||||
// 硬件松开 PTT
|
||||
Timber.tag("GPIO").d("GPIO released, isSpeaking=%s", isSpeaking)
|
||||
if (isSpeaking) {
|
||||
val now = System.currentTimeMillis()
|
||||
val duration = now - lastSpeakTime
|
||||
|
|
@ -109,6 +113,9 @@ object GpioManager {
|
|||
MainActivity.executeJs("updatePttTalkStatus(false)")
|
||||
// 同步 TempCallActivity
|
||||
TempCallActivity.instance?.onGpioReleased()
|
||||
Timber.tag("GPIO").d("Notified TempCallActivity: onGpioReleased")
|
||||
} else {
|
||||
Timber.tag("GPIO").w("GPIO realRelease skipped: already released")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue