250325:柒牌demo
authorxiewei <892331662@qq.com>
Tue, 25 Mar 2025 12:06:27 +0000 (20:06 +0800)
committerxiewei <892331662@qq.com>
Tue, 25 Mar 2025 12:06:27 +0000 (20:06 +0800)
25 files changed:
app/build.gradle
app/src/main/AndroidManifest.xml
app/src/main/assets/first.pcm [new file with mode: 0644]
app/src/main/java/com/zhixun/android/sdk/polymerizesdk/AudioPlayer.java
app/src/main/java/com/zhixun/android/sdk/polymerizesdk/AudioRecorderMan.java
app/src/main/java/com/zhixun/android/sdk/polymerizesdk/DoubaoMainActivity.java [new file with mode: 0644]
app/src/main/java/com/zhixun/android/sdk/polymerizesdk/MyMediaPlayer.java
app/src/main/java/com/zhixun/android/sdk/polymerizesdk/adapter/AiMsgAdapter.java [new file with mode: 0644]
app/src/main/java/com/zhixun/android/sdk/polymerizesdk/adapter/VcData.java [new file with mode: 0644]
app/src/main/java/com/zhixun/android/sdk/polymerizesdk/util/FullScreenVideoView.java [new file with mode: 0644]
app/src/main/res/drawable/ai_input_bg_shape.xml [new file with mode: 0644]
app/src/main/res/drawable/ai_msg_bg_shape.xml [new file with mode: 0644]
app/src/main/res/layout/activity_doubao_main.xml [new file with mode: 0644]
app/src/main/res/layout/layout_item_ai_msg.xml [new file with mode: 0644]
app/src/main/res/mipmap-xhdpi/bg_speek.png [new file with mode: 0644]
app/src/main/res/mipmap-xhdpi/start_icon.png [new file with mode: 0644]
app/src/main/res/raw/delfult.mp4 [new file with mode: 0644]
app/src/main/res/raw/lisening.mp4 [new file with mode: 0644]
app/src/main/res/raw/speek.mp4 [new file with mode: 0644]
app/src/main/res/raw/thinking.mp4 [new file with mode: 0644]
app/src/main/res/raw/zhayan.mp4 [new file with mode: 0644]
app/src/main/res/values/style.xml [new file with mode: 0644]
polysdk/src/main/java/com/zhixun/android/sdk/polysdk/ai/TranscriptionManager.java
polysdk/src/main/java/com/zhixun/android/sdk/polysdk/ai/VoiceChatManager.java
settings.gradle

index 4ba284a..a75864b 100644 (file)
@@ -42,7 +42,7 @@ dependencies {
     implementation 'androidx.recyclerview:recyclerview:1.1.0'
     implementation 'com.google.code.gson:gson:2.10'
     implementation 'com.github.bumptech.glide:glide:4.0.0-RC1'
-
+    implementation 'com.github.xfans:VoiceWaveView:1.0.2'//音频动效
 //    implementation "org.java-websocket:Java-WebSocket:1.5.1"
     implementation 'com.arthenica:mobile-ffmpeg-full:4.4'
 //    implementation 'com.squareup.okhttp3:okhttp:4.9.1'
index 9e59667..b9abe25 100644 (file)
         android:requestLegacyExternalStorage="true"
         android:roundIcon="@mipmap/ic_launcher_round"
         android:supportsRtl="true"
-        android:theme="@style/Theme.PolymerizeSdk"
+        android:theme="@style/AppTheme.NoActionBar"
         android:usesCleartextTraffic="true"
         tools:targetApi="31">
+        <activity
+            android:name=".DoubaoMainActivity"
+            android:exported="true">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+
+                <category android:name="android.intent.category.LAUNCHER" />
+            </intent-filter>
+        </activity>
         <activity
             android:name=".VoiceChatActivity"
             android:exported="false" />
         <activity
             android:name=".MainActivity"
             android:exported="true">
-            <intent-filter>
+            <!--<intent-filter>
                 <action android:name="android.intent.action.MAIN" />
 
                 <category android:name="android.intent.category.LAUNCHER" />
-            </intent-filter>
+            </intent-filter>-->
         </activity>
     </application>
 
diff --git a/app/src/main/assets/first.pcm b/app/src/main/assets/first.pcm
new file mode 100644 (file)
index 0000000..361709b
Binary files /dev/null and b/app/src/main/assets/first.pcm differ
index 5d52b13..6c3d6e3 100644 (file)
@@ -1,9 +1,9 @@
 package com.zhixun.android.sdk.polymerizesdk;
 
+
 import android.media.AudioFormat;
 import android.media.AudioManager;
 import android.media.AudioTrack;
-import android.os.Bundle;
 import android.os.Handler;
 import android.os.Looper;
 import android.os.Message;
@@ -11,47 +11,79 @@ import android.util.Log;
 
 import androidx.annotation.NonNull;
 
-import com.zhixun.android.sdk.polysdk.authentication.AuthMsgSendHandler;
 
+import com.zhixun.android.sdk.polysdk.util.SobLog;
+
+import java.io.BufferedInputStream;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
 import java.util.ArrayList;
 import java.util.List;
+import java.util.Queue;
+import java.util.concurrent.ConcurrentLinkedQueue;
 
 public class AudioPlayer {
     private AudioTrack audioTrack;
     private int bufferSize;
     private final int MSG_PLAY = 101;
+    private final int MSG_PLAY_OVER = 102;
     private String TAG = "AudioPlayer";
     private List<byte[]> playList = new ArrayList<>();
+    private boolean isPlaying = false;
     private Handler audioHandler;
-    private AudioLooperThread audioLooperThread;
-    class AudioLooperThread extends Thread {
+    private Queue<byte[]> queueMsg = new ConcurrentLinkedQueue<byte[]>();//线程安全到队列
+    private class AudioLooperThread extends Thread {
+
+        @Override
         public void run() {
+            super.run();
             Looper.prepare();
-            audioHandler = new Handler(){
+            audioHandler = new Handler() {
                 @Override
                 public void handleMessage(@NonNull Message msg) {
                     super.handleMessage(msg);
-                    switch (msg.what){
+                    switch (msg.what) {
                         case MSG_PLAY:
-                            Log.i(TAG,"play---111---");
-                            byte[] data = (byte[]) msg.obj;
+                            isPlaying = true;
+                            audioHandler.removeMessages(MSG_PLAY_OVER);
+                            Log.i(TAG, "play---111---");
+                            byte[] data = queueMsg.poll();
+                            if(data==null){
+                                audioHandler.sendEmptyMessageDelayed(MSG_PLAY_OVER, 1000);
+                                return;
+                            }
                             if (audioTrack != null) {
                                 audioTrack.play();
                                 int length = data.length;
-                                while (length > 0&&audioTrack != null) {
-                                    int written = audioTrack.write(data, 0, length);
-                                    length -= written;
+                                while (length > 0 && audioTrack != null&&isPlaying) {
+                                    try {
+                                        int written = audioTrack.write(data, 0, length);
+                                        length -= written;
+                                    } catch (Exception e) {
+                                        Log.e(TAG, "play---Exception---" + e.getMessage());
+                                    }
+
                                 }
-                                Log.i(TAG,"play---end---");
+                                Log.i(TAG, "play---end---");
+                            }
+                            if(isPlaying){
+                                audioHandler.sendEmptyMessage(MSG_PLAY);
+                            }
+                            break;
+                        case MSG_PLAY_OVER:
+                            isPlaying = false;
+                            if (audioPlayStateChangeListener != null) {
+                                audioPlayStateChangeListener.onStateChange(isPlaying);
                             }
-
                             break;
                     }
                 }
             };
             Looper.loop();
-
         }
+
+
     }
 
     public AudioPlayer(int sampleRate, int channelConfig, int audioFormat) {
@@ -63,12 +95,16 @@ public class AudioPlayer {
                 sampleRate, channelConfig, audioFormat, bufferSize, AudioTrack.MODE_STREAM);
     }
 
+    private AudioLooperThread audioLooperThread;
+
     public AudioPlayer() {
-        audioLooperThread = new AudioLooperThread();
-        audioLooperThread.start();
+        init();
+    }
+
+    private void init() {
         int sampleRate = 16000;
         int channelConfig = AudioFormat.CHANNEL_OUT_STEREO;
-        int audioFormat = AudioFormat.ENCODING_PCM_8BIT;
+        int audioFormat = AudioFormat.ENCODING_PCM_16BIT;
         // 初始化buffer size
         bufferSize = AudioTrack.getMinBufferSize(sampleRate, channelConfig, audioFormat);
         // 初始化AudioTrack
@@ -78,47 +114,101 @@ public class AudioPlayer {
                 AudioFormat.ENCODING_PCM_16BIT,
                 bufferSize,
                 AudioTrack.MODE_STREAM);
+
         audioTrack.setPositionNotificationPeriod(bufferSize);
-        audioTrack.setPlaybackPositionUpdateListener(new AudioTrack.OnPlaybackPositionUpdateListener() {
-            @Override
-            public void onMarkerReached(AudioTrack track) {
-                //播放完成
-                Log.i(TAG,"onMarkerReached");
 
-            }
+        audioLooperThread = new AudioLooperThread();
+        audioLooperThread.start();
 
-            @Override
-            public void onPeriodicNotification(AudioTrack track) {
 
-            }
-        });
+//        AudioManager mAm = ( AudioManager ) context.getSystemService(Context.AUDIO_SERVICE);
+//        mAm.setMode(AudioManager.MODE_IN_CALL);
+//        mAm.setBluetoothScoOn(true);
+//        mAm.startBluetoothSco();
+    }
+
+    public boolean isPlaying() {
+        return isPlaying;
+    }
+
+    public void setPlaying(boolean playing) {
+        isPlaying = playing;
     }
 
     private byte[] cacheAudio = new byte[0];
-    public synchronized void play(byte[] audioData) {
-        Log.i(TAG,"play---"+cacheAudio.length);
-//        if(cacheAudio.length<40*1024){
-//            cacheAudio = ByteTools.concatAll(cacheAudio,audioData);
-//        }else {
-            Message message = new Message();
-            message.what = MSG_PLAY;
-            message.obj = audioData;
-            audioHandler.sendMessage(message);
-            cacheAudio = new byte[0];
-//        }
 
+    public synchronized void play(byte[] audioData) {
+        if (audioTrack == null) {
+            init();
+        }
+        queueMsg.add(audioData);
+        if (!isPlaying) {
+            isPlaying = true;
+            if (audioPlayStateChangeListener != null) {
+                audioPlayStateChangeListener.onStateChange(isPlaying);
+            }
 
+            audioHandler.sendEmptyMessage(MSG_PLAY);
+        }
     }
 
+    public synchronized void play(String audioPath) {
+        if (audioTrack == null) {
+            init();
+        }
+        SobLog.d(TAG,"play--"+audioPath);
+        try {
+            InputStream inputStream = new FileInputStream(audioPath);
+            BufferedInputStream bufferedInputStream = new BufferedInputStream(inputStream);
+            byte[] data = new byte[inputStream.available()];
+            bufferedInputStream.read(data);
+            inputStream.close();
+            bufferedInputStream.close();
+            queueMsg.add(data);
+            // do something with the data
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+        SobLog.d(TAG,"play--"+isPlaying);
+        if (!isPlaying) {
+            isPlaying = true;
+            if (audioPlayStateChangeListener != null) {
+                audioPlayStateChangeListener.onStateChange(isPlaying);
+            }
+
+            audioHandler.sendEmptyMessage(MSG_PLAY);
+        }
+    }
 
     public void stop() {
+        if(!isPlaying)return;
+        isPlaying = false;
         if (audioTrack != null) {
             audioTrack.stop();
             audioTrack.release();
             audioTrack = null;
         }
+        audioHandler.removeMessages(MSG_PLAY);
+        audioHandler.removeMessages(MSG_PLAY_OVER);
+        SobLog.d(TAG,"stop--");
+
+        queueMsg.clear();
+        if (audioPlayStateChangeListener != null) {
+            audioPlayStateChangeListener.onStateChange(isPlaying);
+        }
+
     }
 
+    private AudioPlayStateChangeListener audioPlayStateChangeListener;
+
+
+    public void setAudioPlayStateChangeListener(AudioPlayStateChangeListener audioPlayStateChangeListener) {
+        this.audioPlayStateChangeListener = audioPlayStateChangeListener;
+    }
+
+    public interface AudioPlayStateChangeListener {
+        void onStateChange(boolean state);
+    }
 
 
 }
index e25aedd..90e7ac7 100644 (file)
@@ -15,7 +15,7 @@ public class AudioRecorderMan {
     private AudioRecord audioRecord;
     private int bufferSize;
     private boolean isRecording = false;
-
+    private Thread audioThread;
     private static AudioRecorderMan sInstance;
     public static AudioRecorderMan getInstance() {
         if (sInstance == null) {
@@ -39,38 +39,50 @@ public class AudioRecorderMan {
             Log.d(TAG,"startRecording--no Permission");
             return ;
         }
-        audioRecord = new AudioRecord(MediaRecorder.AudioSource.MIC,
+        audioRecord = new AudioRecord(MediaRecorder.AudioSource.VOICE_COMMUNICATION,
                 sampleRate, channelConfig, audioFormat, bufferSize);
         if (audioRecord != null) {
             isRecording = true;
             Log.d(TAG,"startRecording--");
-            new Thread(() -> {
-                audioRecord.startRecording();
-                byte[] buffer = new byte[bufferSize];
-                int read = 0;
-                while (read>=0) {
-                    read = audioRecord.read(buffer, 0, bufferSize);
-                    Log.d(TAG,"startRecording--"+read);
-                    if (read < 0) {
-                        // 处理错误
-                    } else {
-                        // 处理buffer中的数据,这里你可以将它传输或者保存
-                        if(onBuffChange!=null){
-                            onBuffChange.onChange(buffer);
-                        }
+            doRecord();
+        }
+    }
+
+    private void doRecord() {
+        audioThread = new Thread(() -> {
+            audioRecord.startRecording();
+            byte[] buffer = new byte[bufferSize];
+            int read = 0;
+            while (read>=0&&audioRecord!=null) {
+                read = audioRecord.read(buffer, 0, bufferSize);
+                Log.d(TAG,"startRecording--"+read);
+                if (read < 0) {
+                    // 处理错误
+                } else {
+                    // 处理buffer中的数据,这里你可以将它传输或者保存
+                    if(onBuffChange!=null){
+                        onBuffChange.onChange(buffer);
                     }
                 }
+            }
 
-            }, "AudioRecorderThread").start();
-        }
+        }, "AudioRecorderThread");
+        audioThread.start();
     }
 
+
     public void stopRecording() {
         Log.d(TAG,"stopRecording--");
         isRecording = false;
+        if (audioThread != null) {
+            audioThread.interrupt();
+            audioThread = null;
+        }
+
         if (audioRecord != null) {
             audioRecord.stop();
             audioRecord.release();
+            audioRecord = null;
         }
     }
 
diff --git a/app/src/main/java/com/zhixun/android/sdk/polymerizesdk/DoubaoMainActivity.java b/app/src/main/java/com/zhixun/android/sdk/polymerizesdk/DoubaoMainActivity.java
new file mode 100644 (file)
index 0000000..586f4cc
--- /dev/null
@@ -0,0 +1,416 @@
+package com.zhixun.android.sdk.polymerizesdk;
+
+import androidx.annotation.NonNull;
+import androidx.appcompat.app.AppCompatActivity;
+import androidx.recyclerview.widget.LinearLayoutManager;
+import androidx.recyclerview.widget.RecyclerView;
+
+import android.graphics.Color;
+import android.media.MediaPlayer;
+import android.net.Uri;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.Looper;
+import android.os.Message;
+import android.text.TextUtils;
+import android.util.Log;
+import android.view.Gravity;
+import android.view.MotionEvent;
+import android.view.View;
+import android.widget.ImageView;
+import android.widget.LinearLayout;
+import android.widget.TextView;
+import android.widget.VideoView;
+
+import com.zhixun.android.sdk.polymerizesdk.adapter.AiMsgAdapter;
+import com.zhixun.android.sdk.polymerizesdk.adapter.VcData;
+import com.zhixun.android.sdk.polysdk.PolymerizeAgent;
+import com.zhixun.android.sdk.polysdk.ai.VoiceChatManager;
+import com.zhixun.android.sdk.polysdk.callback.AuthCallback;
+import com.zhixun.android.sdk.polysdk.callback.IVoiceChatCallback;
+import com.zhixun.android.sdk.polysdk.callback.OnTranscriptionDataChange;
+import com.zhixun.android.sdk.polysdk.util.SobLog;
+import com.zhixun.android.sdk.polysdk.util.SpUtils;
+
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+
+import me.xfans.lib.voicewaveview.VoiceWaveView;
+import me.xfans.lib.voicewaveview.WaveMode;
+
+public class DoubaoMainActivity extends AppCompatActivity {
+
+
+    private String TAG = "DoubaoMainActivity";
+    private VideoView bq_video;
+    private TextView tv_state,tv_event;
+    private ImageView startBtn;
+    private AudioPlayer player = new AudioPlayer();
+    private boolean isStartTranscrip;
+//    private final int MSG_DO_TTS = 101;
+    private AiMsgAdapter aiMsgAdapter;
+    private RecyclerView msg_listview;
+    private VoiceWaveView voiceWaveView;
+    private LinearLayout layout_msg;
+    private int msgPosition=-1,chatPosition = -1;
+    private String responsStr = "";
+    private String asrStr = "";
+    private boolean shwoList = false;
+    private long downTime = 0;
+    private Handler handler = new Handler(Looper.getMainLooper()){
+        @Override
+        public void handleMessage(@NonNull Message msg) {
+            super.handleMessage(msg);
+            switch (msg.what){
+
+                case 102:
+                    if(isFirst){
+                        String uri="android.resource://"+getPackageName()+"/"+R.raw.zhayan;
+                        bq_video.setOnPreparedListener(null);
+                        bq_video.destroyDrawingCache();
+                        bq_video.suspend();
+                        playVideo(uri);
+                        handler.sendEmptyMessageDelayed(106,1000);
+                    }
+                    break;
+                case 103:
+                    Log.i(TAG,"onRspons--103");
+                    responsStr = "";
+                    chatPosition = aiMsgAdapter.addData(new VcData(1,responsStr));
+                    msg_listview.scrollToPosition(chatPosition);
+                    break;
+                case 104:
+                    Log.i(TAG,"onRspons--104");
+                    chatPosition = -1;
+                    responsStr = "";
+                    break;
+                case 105:
+
+                    String text = (String) msg.obj;
+                    if(TextUtils.isEmpty(text))return;
+                    Log.i(TAG,"onRspons--105"+text);
+                    responsStr = responsStr+text;
+                    if(chatPosition==-1){
+                        chatPosition = aiMsgAdapter.addData(new VcData(1,responsStr));
+                    }else {
+                        aiMsgAdapter.setData(chatPosition,new VcData(1,responsStr));
+                    }
+                    aiMsgAdapter.notifyItemChanged(chatPosition);
+                    tv_event.setText(responsStr);
+                    break;
+                case 106:
+                    tv_event.setVisibility(View.VISIBLE);
+                    break;
+            }
+        }
+    };
+
+    private boolean isFirst = true;
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.activity_doubao_main);
+        bq_video = findViewById(R.id.bq_video);
+        tv_state = findViewById(R.id.tv_state);
+        startBtn = findViewById(R.id.startBtn);
+        msg_listview = findViewById(R.id.msg_listview);
+        voiceWaveView = findViewById(R.id.voiceWaveView);
+        tv_event = findViewById(R.id.tv_event);
+        String uri="android.resource://"+getPackageName()+"/"+R.raw.delfult;
+
+        playVideo(uri);
+        PolymerizeAgent.getInstance().getAuthenAPI().setAIChannelKey("huoshan","",null);
+        goLogin();
+
+        startBtn.setOnClickListener(new View.OnClickListener() {
+            @Override
+            public void onClick(View v) {
+                player.stop();
+                String uri="android.resource://"+getPackageName()+"/"+R.raw.lisening;
+                if(isStartTranscrip){
+                    isStartTranscrip = false;
+                    AudioRecorderMan.getInstance().stopRecording();
+                    PolymerizeAgent.getInstance().getAiAPI().stopTrans();
+                    uri="android.resource://"+getPackageName()+"/"+R.raw.thinking;
+                    voiceWaveView.stop();
+                }else {
+                    isStartTranscrip = true;
+//                    PolymerizeAgent.getInstance().getAiAPI().cancleChat();
+                    VoiceChatManager.getInstance().cancleChat();
+                    PolymerizeAgent.getInstance().getAiAPI().startTrans();
+                    uri="android.resource://"+getPackageName()+"/"+R.raw.lisening;
+                    tv_state.setText("点击或停止说话发送");
+                    voiceWaveView.start();
+                }
+                playVideo(uri);
+
+            }
+        });
+        AudioRecorderMan.getInstance().setOnBuffChange(new AudioRecorderMan.onBuffChange() {
+            @Override
+            public void onChange(byte[] data) {
+                Log.i(TAG,"Audio-onChange-"+isStartTranscrip);
+                if(isStartTranscrip){
+                    Log.i(TAG,"Audio-onChange-"+data.length);
+                    PolymerizeAgent.getInstance().getAiAPI().sendTransByte(data);
+//                    VoiceChatManager.getInstance().sendVoice(data);
+                }
+            }
+        });
+
+        PolymerizeAgent.getInstance().getAiAPI().setOnTranscriptionDataChange(new OnTranscriptionDataChange() {
+            @Override
+            public void onStartChange(int action,boolean state) {
+                if(state){
+                    AudioRecorderMan.getInstance().startRecording(DoubaoMainActivity.this);
+                }
+            }
+
+            @Override
+            public void onChange(String state,String text) {
+                Log.i(TAG,"Transcription-onChange-"+state+"--"+text);
+                if(state.equals("end")){
+                    PolymerizeAgent.getInstance().getAiAPI().sendChatMsg(text);
+                }
+                runOnUiThread(new Runnable() {
+                    @Override
+                    public void run() {
+                        if(state.equals("start")){
+                            asrStr = "";
+                            msgPosition = aiMsgAdapter.addData(new VcData(0,text));
+                            tv_state.setText("点击结束说话");
+                        }
+                        else if(state.equals("SentenceEnd")||state.equals("end")){
+                            asrStr = text;
+                            tv_event.setText(asrStr);
+                            if(msgPosition==-1){
+                                msgPosition = aiMsgAdapter.addData(new VcData(0,asrStr));
+                            }else {
+                                aiMsgAdapter.setData(msgPosition,new VcData(0,asrStr));
+                            }
+                        }
+
+                        aiMsgAdapter.notifyItemChanged(msgPosition);
+                        msg_listview.scrollToPosition(msgPosition);
+                        if(state.equals("end")){
+                            msgPosition = -1;
+                            asrStr = "";
+                        }
+                    }
+                });
+            }
+        });
+
+        PolymerizeAgent.getInstance().getAiAPI().setOnVoiceChatListener(new IVoiceChatCallback() {
+            @Override
+            public void OnSpeech(byte[] data) {
+                player.play(data);
+            }
+
+            @Override
+            public void OnRespond(String type, String text) {
+                Log.d(TAG,"OnRespond--"+type);
+                doRespons(type,text);
+            }
+        });
+
+        player.setAudioPlayStateChangeListener(new AudioPlayer.AudioPlayStateChangeListener() {
+            @Override
+            public void onStateChange(boolean state) {
+                if(isFirst&&!state){
+                    isFirst = false;
+                    return;
+                }
+                if(isFirst)return;
+                Log.d(TAG,"setAudioPlayStateChangeListener--"+state);
+
+                runOnUiThread(new Runnable() {
+                    @Override
+                    public void run() {
+                        String uri="android.resource://"+getPackageName()+"/"+R.raw.speek;
+
+                        if(state){
+                            uri="android.resource://"+getPackageName()+"/"+R.raw.speek;
+                            tv_state.setText("点击打断");
+                        }else {
+                            uri="android.resource://"+getPackageName()+"/"+R.raw.zhayan;
+                            tv_state.setText("点击对话");
+//                            tv_event.setText("再聊点啥呢...");
+                        }
+                        playVideo(uri);
+                    }
+                });
+            }
+        });
+
+        LinearLayoutManager layoutManager = new LinearLayoutManager(this);
+        msg_listview.setLayoutManager(layoutManager);
+        aiMsgAdapter = new AiMsgAdapter(this, new ArrayList<>());
+        msg_listview.setAdapter(aiMsgAdapter);
+        msg_listview.getItemAnimator().setChangeDuration(0);// 通过设置动画执行时间为0来解决闪烁问题
+
+
+
+        msg_listview.setOnTouchListener(new View.OnTouchListener() {
+            @Override
+            public boolean onTouch(View v, MotionEvent event) {
+                Log.d(TAG,"layout_msg--"+event.getAction());
+                switch (event.getAction()){
+                    case MotionEvent.ACTION_DOWN:
+                        downTime = System.currentTimeMillis();
+                        break;
+                    case MotionEvent.ACTION_UP:
+                        long time = System.currentTimeMillis()-downTime;
+                        if(time<200){
+                            msg_listview.setVisibility(View.GONE);
+                            bq_video.setVisibility(View.VISIBLE);
+                        }
+                        break;
+                }
+                return false;
+            }
+        });
+
+        bq_video.setOnClickListener(new View.OnClickListener() {
+            @Override
+            public void onClick(View v) {
+                msg_listview.setVisibility(View.VISIBLE);
+                msg_listview.setFocusable(true);
+                bq_video.setVisibility(View.GONE);
+            }
+        });
+
+        voiceWaveView.setShowGravity(Gravity.CENTER);
+        voiceWaveView.setWaveMode(WaveMode.LEFT_RIGHT);
+        voiceWaveView.setLineWidth(3f);
+        voiceWaveView.setLineSpace(5f);
+        voiceWaveView.setLineColor(Color.parseColor("#ffffff"));
+        voiceWaveView.setDuration(100);
+//        voiceWaveView.addHeader(4);
+        voiceWaveView.addHeader(4);
+        voiceWaveView.addBody(16);
+        voiceWaveView.addBody(26);
+        voiceWaveView.addBody(46);
+        voiceWaveView.addBody(26);
+        voiceWaveView.addBody(16);
+//        voiceWaveView.addBody(60);
+//        voiceWaveView.addBody(38);
+//        voiceWaveView.addBody(14);
+//        voiceWaveView.addBody(8);
+        voiceWaveView.addFooter(4);
+//        voiceWaveView.addFooter(2);
+        player.play(readFile());
+
+    }
+
+    private String pwd = "RTQYOiB3zLAz5AeJSGnEPXea4qPfTY";
+    public void goLogin(){
+        pwd = SpUtils.getInstance().getStringValue("devicePwd");
+        PolymerizeAgent.getInstance().getAuthenAPI().authentication("281106010111"
+                , pwd, "4EepovakpbqhZUnUDwH42KAADYGv4UUe", new AuthCallback() {
+                    @Override
+                    public void onSuccess(String result) {
+                        Log.i(TAG,"result--"+result);
+                    }
+
+                    @Override
+                    public void onFail(int code,String msg) {
+                        Log.i(TAG,"onFail--"+msg+"code-"+code);
+                        goRegiest();
+                    }
+                });
+
+    }
+
+    public void goRegiest(){
+        PolymerizeAgent.getInstance().getAuthenAPI().regiest("4EepovakpbqhZUnUDwH42KAADYGv4UUe"
+                , "281106010111", "Y1DxRdBfnzVZQrXHdrNl", new AuthCallback() {
+                    @Override
+                    public void onSuccess(String result) {
+                        Log.i(TAG,"result--"+result);
+                        pwd = result;
+                        SpUtils.getInstance().saveValue("devicePwd",pwd);
+                        goLogin();
+                    }
+
+                    @Override
+                    public void onFail(int code,String msg) {
+                        Log.i(TAG,"onFail--"+msg+"code-"+code);
+                    }
+                });
+
+
+
+        /*ChatGPTClient.getInstance().checkAIKey("sk-proj-04ogvrZQqyaiv1OWw8OZT3BlbkFJG9Gyr8oFvRdmr3oXQNbX", new IOnKeyCheckCallback() {
+            @Override
+            public void OnKeyCheckResult(boolean result) {
+                Log.d(TAG,"result--"+result);
+            }
+        });*/
+    }
+
+
+    private void playVideo(String path){
+        bq_video.setVideoURI(Uri.parse(path));
+        bq_video.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
+            @Override
+            public void onPrepared(MediaPlayer mediaPlayer) {
+                Log.i(TAG, "init_vieofile:..main_video1...视频准备完毕,可以进行播放....." + mediaPlayer.isPlaying());
+                mediaPlayer.setVolume(0f, 0f);
+                if (!mediaPlayer.isPlaying()) {
+                    mediaPlayer.start();
+                }
+                Log.i(TAG, "isFirst....." + isFirst);
+                if(!isFirst){
+                    mediaPlayer.setLooping(true);
+                }
+
+
+            }
+        });
+        bq_video.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
+            @Override
+            public void onCompletion(MediaPlayer mp) {
+                //结束播放
+                handler.sendEmptyMessage(102);
+            }
+        });
+
+
+    }
+
+    private void doRespons(String state,String text) {
+
+        if(state.equals("start")){
+            handler.sendEmptyMessage(103);
+        }else if(state.equals("end")){
+            handler.sendEmptyMessage(104);
+        }else {
+            Message message = handler.obtainMessage(105);
+            message.obj = text;
+            handler.sendMessage(message);
+        }
+    }
+
+    private byte[] readFile() {
+        try {
+            InputStream in = getAssets().open("first.pcm");
+            byte[] filecontent = new byte[in.available()];
+            in.read(filecontent);
+
+            SobLog.show(TAG, "readFile--" + filecontent.length);
+            in.close();
+            return filecontent;
+        } catch (FileNotFoundException e) {
+            e.printStackTrace();
+            SobLog.show(TAG, "readFile---" + e.getMessage());
+            return null;
+        } catch (IOException e) {
+            e.printStackTrace();
+            SobLog.show(TAG, "readFile---" + e.getMessage());
+            return null;
+        }
+    }
+}
\ No newline at end of file
index f869e95..2850ed8 100644 (file)
@@ -28,17 +28,8 @@ public class MyMediaPlayer {
 
     private void initMedia() {
         mediaPlayer = new MediaPlayer();
-        mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
-        mediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
-            @Override
-            public void onCompletion(MediaPlayer mp) {
-                Log.d(TAG,"play over");
-                if (sourceList.size() > 0) {
-                    playData(sourceList.get(0));
-                    sourceList.remove(0);
-                }
-            }
-        });
+        mediaPlayer.setAudioStreamType(AudioManager.STREAM_SYSTEM);
+
     }
 
     private List<FileInputStream> sourceList = new ArrayList<>();
@@ -48,43 +39,25 @@ public class MyMediaPlayer {
         new Thread(new Runnable() {
             @Override
             public void run() {
-                if (mediaPlayer.isPlaying()||sourceList.size()>0) {
-                    try {
-                        File tempMp3 = File.createTempFile("temp_" + System.currentTimeMillis(), ".mp3");
-//                tempMp3.deleteOnExit();
-                        FileOutputStream fos = new FileOutputStream(tempMp3);
-                        fos.write(audioSource);
-                        fos.close();
-                        FileInputStream fis = new FileInputStream(tempMp3);
-                        sourceList.add(fis);
-                    } catch (IOException ex) {
-                        String s = ex.toString();
-                        Log.d(TAG, "playData--" + s);
-                        ex.printStackTrace();
-                    }
-
-                } else {
-                    try {
-                        File tempMp3 = File.createTempFile("temp_" + System.currentTimeMillis(), ".mp3");
-                        tempMp3.deleteOnExit();
-                        Log.i(TAG,"playData-11-");
-                        FileOutputStream fos = new FileOutputStream(tempMp3);
-                        fos.write(audioSource);
-                        fos.close();
-                        Log.i(TAG,"playData-22-");
-                        mediaPlayer.reset();
-                        FileInputStream fis = new FileInputStream(tempMp3);
-                        Log.i(TAG,"playData-33-");
-                        mediaPlayer.setDataSource(fis.getFD());
-                        mediaPlayer.prepare();
-                        mediaPlayer.start();
-                        Log.i(TAG,"playData-44-");
-                    } catch (IOException ex) {
-                        String s = ex.toString();
-                        Log.d(TAG, "playData-1-" + s);
-                        ex.printStackTrace();
-                    }
-
+                try {
+                    File tempMp3 = File.createTempFile("temp_" + System.currentTimeMillis(), ".m4a");
+                    Log.i(TAG,"playData-11-");
+                    FileOutputStream fos = new FileOutputStream(tempMp3);
+                    fos.write(audioSource);
+                    fos.close();
+                    Log.i(TAG,"playData-22-");
+                    mediaPlayer.reset();
+                    FileInputStream fis = new FileInputStream(tempMp3);
+                    Log.i(TAG,"playData-33-");
+                    mediaPlayer.setDataSource(fis.getFD());
+                    mediaPlayer.prepare();
+                    mediaPlayer.start();
+//                    tempMp3.deleteOnExit();
+                    Log.i(TAG,"playData-44-");
+                } catch (IOException ex) {
+                    String s = ex.toString();
+                    Log.d(TAG, "playData-1-" + s);
+                    ex.printStackTrace();
                 }
 
             }
@@ -106,7 +79,7 @@ public class MyMediaPlayer {
 
     }
 
-    public void playData(String  path) {
+    public void playData(String path) {
         stop();
         initMedia();
         try {
diff --git a/app/src/main/java/com/zhixun/android/sdk/polymerizesdk/adapter/AiMsgAdapter.java b/app/src/main/java/com/zhixun/android/sdk/polymerizesdk/adapter/AiMsgAdapter.java
new file mode 100644 (file)
index 0000000..1a5416a
--- /dev/null
@@ -0,0 +1,108 @@
+package com.zhixun.android.sdk.polymerizesdk.adapter;
+
+
+import android.content.ClipData;
+import android.content.ClipboardManager;
+import android.content.Context;
+import android.text.TextUtils;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.LinearLayout;
+import android.widget.TextView;
+import android.widget.Toast;
+
+import androidx.annotation.NonNull;
+import androidx.recyclerview.widget.RecyclerView;
+
+
+import com.zhixun.android.sdk.polymerizesdk.R;
+
+import java.util.ArrayList;
+
+public class AiMsgAdapter extends RecyclerView.Adapter<AiMsgAdapter.MyViewHoder> {
+
+    private ArrayList<VcData> msgList ;
+    private Context mContext;
+    public AiMsgAdapter(Context context, ArrayList<VcData> msgList) {
+        this.mContext = context;
+        this.msgList = msgList;
+    }
+
+    @NonNull
+    @Override
+    public MyViewHoder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
+        View view = View.inflate(mContext, R.layout.layout_item_ai_msg, null);
+        MyViewHoder myViewHoder = new MyViewHoder(view);
+        return myViewHoder;
+    }
+
+    @Override
+    public void onBindViewHolder(@NonNull MyViewHoder holder, int position) {
+
+        VcData vcData = msgList.get(position);
+        String msg = vcData.getMsg();
+        if(vcData.getType()==0){
+            //问
+            holder.tvMsg.setVisibility(View.GONE);
+            holder.tvInput.setVisibility(View.VISIBLE);
+            if(!TextUtils.isEmpty(msg)&&!msg.equals("null")){
+                holder.tvInput.setText(vcData.getMsg());
+            }else {
+                holder.tvInput.setText("");
+            }
+
+        }else {
+            //回复
+            holder.tvMsg.setVisibility(View.VISIBLE);
+            holder.tvInput.setVisibility(View.GONE);
+            if(!TextUtils.isEmpty(msg)&&!msg.equals("null")){
+                holder.tvMsg.setText(vcData.getMsg());
+            }else {
+                holder.tvMsg.setText("");
+            }
+        }
+
+
+    }
+
+    @Override
+    public int getItemCount() {
+        return msgList.size();
+    }
+
+
+    private void addData(ArrayList<VcData> data){
+        msgList.addAll(data);
+        notifyDataSetChanged();
+    }
+
+    public int addData(VcData data){
+        msgList.add(data);
+        notifyDataSetChanged();
+        return msgList.size()-1;
+    }
+
+    public void setData(int position,VcData data){
+        msgList.set(position,data);
+//        notifyItemChanged(position);
+    }
+
+    public ArrayList<VcData> getMsgList() {
+        return msgList;
+    }
+
+    public class MyViewHoder extends RecyclerView.ViewHolder {
+        TextView tvMsg,tvInput;
+
+        public MyViewHoder(@NonNull View itemView) {
+            super(itemView);
+            tvMsg = itemView.findViewById(R.id.tv_msg);
+            tvInput = itemView.findViewById(R.id.tv_input);
+
+
+
+        }
+
+    }
+
+}
diff --git a/app/src/main/java/com/zhixun/android/sdk/polymerizesdk/adapter/VcData.java b/app/src/main/java/com/zhixun/android/sdk/polymerizesdk/adapter/VcData.java
new file mode 100644 (file)
index 0000000..3be2487
--- /dev/null
@@ -0,0 +1,27 @@
+package com.zhixun.android.sdk.polymerizesdk.adapter;
+
+public class VcData {
+    private int type;
+    private String msg;
+
+    public VcData(int type, String msg) {
+        this.type = type;
+        this.msg = msg;
+    }
+
+    public int getType() {
+        return type;
+    }
+
+    public void setType(int type) {
+        this.type = type;
+    }
+
+    public String getMsg() {
+        return msg;
+    }
+
+    public void setMsg(String msg) {
+        this.msg = msg;
+    }
+}
diff --git a/app/src/main/java/com/zhixun/android/sdk/polymerizesdk/util/FullScreenVideoView.java b/app/src/main/java/com/zhixun/android/sdk/polymerizesdk/util/FullScreenVideoView.java
new file mode 100644 (file)
index 0000000..f847f04
--- /dev/null
@@ -0,0 +1,32 @@
+package com.zhixun.android.sdk.polymerizesdk.util;
+
+import android.content.Context;
+import android.util.AttributeSet;
+import android.widget.VideoView;
+
+
+public class FullScreenVideoView extends VideoView{
+
+
+    public FullScreenVideoView(Context context) {
+        super(context);
+// TODO Auto-generated constructor stub
+    }
+    public FullScreenVideoView(Context context, AttributeSet attrs)
+    {
+        super(context,attrs);
+    }
+    public FullScreenVideoView(Context context, AttributeSet attrs, int defStyle)
+    {
+        super(context,attrs,defStyle);
+    }
+    @Override
+    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec)
+    {
+        int width = getDefaultSize(0, widthMeasureSpec);
+        int height = getDefaultSize(0, heightMeasureSpec);
+        setMeasuredDimension(width , height);
+    }
+
+
+}
diff --git a/app/src/main/res/drawable/ai_input_bg_shape.xml b/app/src/main/res/drawable/ai_input_bg_shape.xml
new file mode 100644 (file)
index 0000000..5129148
--- /dev/null
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="utf-8"?>
+<shape android:shape="rectangle"
+  xmlns:android="http://schemas.android.com/apk/res/android">
+    <solid android:color="#D8D8D8" />
+    <corners android:radius="10.0dip" />
+    <padding android:left="14.0dip" android:top="12.0dip" android:right="14.0dip" android:bottom="12.0dip" />
+</shape>
\ No newline at end of file
diff --git a/app/src/main/res/drawable/ai_msg_bg_shape.xml b/app/src/main/res/drawable/ai_msg_bg_shape.xml
new file mode 100644 (file)
index 0000000..fcd3e2f
--- /dev/null
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="utf-8"?>
+<shape android:shape="rectangle"
+  xmlns:android="http://schemas.android.com/apk/res/android">
+    <solid android:color="#1CB1F4" />
+    <corners android:radius="10.0dip" />
+    <padding android:left="14.0dip" android:top="12.0dip" android:right="14.0dip" android:bottom="12.0dip" />
+</shape>
\ No newline at end of file
diff --git a/app/src/main/res/layout/activity_doubao_main.xml b/app/src/main/res/layout/activity_doubao_main.xml
new file mode 100644 (file)
index 0000000..8159269
--- /dev/null
@@ -0,0 +1,102 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    xmlns:tools="http://schemas.android.com/tools"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:orientation="vertical"
+    android:background="@color/black">
+
+    <RelativeLayout
+        android:layout_width="match_parent"
+        android:layout_height="0dp"
+        android:layout_weight="1">
+
+        <RelativeLayout
+            android:id="@+id/layout_video"
+            android:layout_width="match_parent"
+            android:layout_height="160dp"
+            android:orientation="vertical"
+            android:layout_marginTop="30dp">
+
+            <VideoView
+                android:id="@+id/bq_video"
+                android:layout_width="150dp"
+                android:layout_height="140dp"
+                android:layout_centerHorizontal="true"/>
+
+            <TextView
+                android:id="@+id/tv_event"
+                android:layout_width="wrap_content"
+                android:layout_marginRight="20dp"
+                android:layout_marginLeft="20dp"
+                android:maxLines="2"
+                android:ellipsize="end"
+                android:layout_height="wrap_content"
+                android:textSize="12sp"
+                android:textColor="@color/white"
+                android:layout_gravity="center_horizontal"
+                android:layout_centerHorizontal="true"
+                android:layout_marginTop="95dp"
+
+                android:visibility="gone"
+                android:text="快和我聊天吧"/>
+
+        </RelativeLayout>
+
+        <androidx.recyclerview.widget.RecyclerView
+            android:id="@+id/msg_listview"
+            android:layout_width="match_parent"
+            android:layout_height="match_parent"
+            android:background="@color/black"
+            android:visibility="gone"/>
+
+
+        <LinearLayout
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:orientation="vertical"
+            android:layout_alignParentBottom="true"
+            android:layout_centerHorizontal="true">
+
+
+
+            <RelativeLayout
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_gravity="center_horizontal"
+                android:layout_marginBottom="5dp">
+                <ImageView
+                    android:id="@+id/startBtn"
+                    android:layout_width="wrap_content"
+                    android:layout_height="45dp"
+                    android:layout_centerHorizontal="true"
+                    android:src="@mipmap/bg_speek"/>
+                <me.xfans.lib.voicewaveview.VoiceWaveView
+                    android:id="@+id/voiceWaveView"
+                    android:layout_width="wrap_content"
+                    android:layout_height="45dp"
+                    app:lineColor="@color/white"
+                    app:waveMode="left_right"
+                    android:gravity="center"
+                    />
+            </RelativeLayout>
+
+
+            <TextView
+                android:id="@+id/tv_state"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:textSize="12sp"
+                android:textColor="@color/white"
+                android:layout_marginBottom="15dp"
+                android:layout_gravity="center_horizontal"
+                android:text="点击开始对话"/>
+        </LinearLayout>
+
+
+
+    </RelativeLayout>
+
+
+</LinearLayout>
\ No newline at end of file
diff --git a/app/src/main/res/layout/layout_item_ai_msg.xml b/app/src/main/res/layout/layout_item_ai_msg.xml
new file mode 100644 (file)
index 0000000..606537f
--- /dev/null
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="utf-8"?>
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:orientation="vertical"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:paddingTop="15dp"
+    android:animateLayoutChanges="false"
+    android:id="@+id/item_parent">
+
+    <TextView
+        android:id="@+id/tv_msg"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:textSize="12sp"
+        android:textColor="@color/black"
+        android:lineSpacingExtra="2dp"
+        android:layout_marginLeft="15dp"
+        android:layout_marginRight="45dp"
+        android:background="@drawable/ai_input_bg_shape"/>
+
+    <TextView
+        android:id="@+id/tv_input"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_alignParentRight="true"
+        android:layout_marginRight="15dp"
+        android:layout_marginLeft="45dp"
+        android:background="@drawable/ai_msg_bg_shape"
+        android:lineSpacingExtra="2dp"
+        android:textColor="@color/white"
+        android:textSize="12sp" />
+
+</RelativeLayout>
\ No newline at end of file
diff --git a/app/src/main/res/mipmap-xhdpi/bg_speek.png b/app/src/main/res/mipmap-xhdpi/bg_speek.png
new file mode 100644 (file)
index 0000000..cad0ea4
Binary files /dev/null and b/app/src/main/res/mipmap-xhdpi/bg_speek.png differ
diff --git a/app/src/main/res/mipmap-xhdpi/start_icon.png b/app/src/main/res/mipmap-xhdpi/start_icon.png
new file mode 100644 (file)
index 0000000..f82fca5
Binary files /dev/null and b/app/src/main/res/mipmap-xhdpi/start_icon.png differ
diff --git a/app/src/main/res/raw/delfult.mp4 b/app/src/main/res/raw/delfult.mp4
new file mode 100644 (file)
index 0000000..e90872d
Binary files /dev/null and b/app/src/main/res/raw/delfult.mp4 differ
diff --git a/app/src/main/res/raw/lisening.mp4 b/app/src/main/res/raw/lisening.mp4
new file mode 100644 (file)
index 0000000..9e628e8
Binary files /dev/null and b/app/src/main/res/raw/lisening.mp4 differ
diff --git a/app/src/main/res/raw/speek.mp4 b/app/src/main/res/raw/speek.mp4
new file mode 100644 (file)
index 0000000..cbc6ecb
Binary files /dev/null and b/app/src/main/res/raw/speek.mp4 differ
diff --git a/app/src/main/res/raw/thinking.mp4 b/app/src/main/res/raw/thinking.mp4
new file mode 100644 (file)
index 0000000..22ed409
Binary files /dev/null and b/app/src/main/res/raw/thinking.mp4 differ
diff --git a/app/src/main/res/raw/zhayan.mp4 b/app/src/main/res/raw/zhayan.mp4
new file mode 100644 (file)
index 0000000..a77476b
Binary files /dev/null and b/app/src/main/res/raw/zhayan.mp4 differ
diff --git a/app/src/main/res/values/style.xml b/app/src/main/res/values/style.xml
new file mode 100644 (file)
index 0000000..5877a2c
--- /dev/null
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+
+    <style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
+        <!-- Customize your theme here. -->
+
+    </style>
+
+    <style name="AppTheme.NoActionBar">
+        <item name="windowActionBar">false</item>
+        <item name="windowNoTitle">true</item>
+        <item name="android:windowBackground">@color/black</item>
+    </style>
+
+</resources>
\ No newline at end of file
index a830e98..155b303 100644 (file)
@@ -219,7 +219,9 @@ public class TranscriptionManager {
                         asrMsg = "";
                     } else if (reply.getEvent().equals("SentenceEnd") && reply.getStatus() == 20000000) {
                         asrMsg = asrMsg+reply.getResult().getResult();
-
+                        if (onTranscriptionDataChange != null) {
+                            onTranscriptionDataChange.onChange("SentenceEnd", asrMsg);
+                        }
                     } else if (reply.getEvent().equals("Changed") && reply.getStatus() == 20000000) {
                         if (onTranscriptionDataChange != null) {
                             String msg = reply.getResult().getResult();
index 0c7b7c7..d16c926 100644 (file)
@@ -1,6 +1,8 @@
 package com.zhixun.android.sdk.polysdk.ai;
 
 import android.os.Handler;
+import android.os.HandlerThread;
+import android.os.Looper;
 import android.os.Message;
 import android.text.TextUtils;
 
@@ -48,34 +50,42 @@ public class VoiceChatManager {
 
         return sInstance;
     }
+    private MsgLooperThread msgLooperThread;
+    private class MsgLooperThread extends Thread {
 
+        public void run() {
+            Looper.prepare();
+            handler = new Handler(Looper.myLooper()){
+                @Override
+                public void handleMessage(@NonNull Message msg) {
+                    super.handleMessage(msg);
+                    switch (msg.what){
+                        case MSG_RECONNECT:
+                            SobLog.d(TAG, "MSG_RECONNECT");
+                            if (chatClient != null) {
+                                chatClient.close();
+                                chatClient = null;
+                            }
+                            isStart = false;
+                            connectChat();
+                            break;
+                        case MSG_SENDPING:
+//                    SobLog.d(TAG, "MSG_SENDPING");
+                            if(chatClient!=null&&chatClient.isOpen()){
+                                chatClient.sendPing();
+                            }
 
+                            break;
+                    }
+                }
+            };
+            Looper.loop();
+        }
+    }
     private final int MSG_RECONNECT = 101;
     private final int MSG_SENDPING = 102;
-    private Handler handler = new Handler(){
-        @Override
-        public void handleMessage(@NonNull Message msg) {
-            super.handleMessage(msg);
-            switch (msg.what){
-                case MSG_RECONNECT:
-                    SobLog.d(TAG, "MSG_RECONNECT");
-                    if (chatClient != null) {
-                        chatClient.close();
-                        chatClient = null;
-                    }
-                    isStart = false;
-                    connectChat();
-                    break;
-                case MSG_SENDPING:
-//                    SobLog.d(TAG, "MSG_SENDPING");
-                    if(chatClient!=null&&chatClient.isOpen()){
-                        chatClient.sendPing();
-                    }
+    private Handler handler;
 
-                    break;
-            }
-        }
-    };
 
     public VoiceChatManager() {
         SobLog.d(TAG, "-----VoiceChatManager---creat--");
@@ -91,6 +101,10 @@ public class VoiceChatManager {
     private String chatType = "";
     public void init() {
         SobLog.d(TAG, "-----VoiceChatManager---init--");
+        if(msgLooperThread==null){
+            msgLooperThread = new MsgLooperThread();
+            msgLooperThread.start();
+        }
         channelMap.put("aliyun","qianwen");
         channelMap.put("huoshan","doubao");
         channelMap.put("baidu","wenxin");
@@ -110,13 +124,19 @@ public class VoiceChatManager {
             isReConnect = false;
             return;
         }
+        SobLog.d(TAG, "channel--" + channel);
         String param = "";
         if(channelMap.containsKey(channel)){
             param = "&bot_type="+channelMap.get(channel);
         }
         String url = MyConfig.URL_VOICE_CHAT+"?is_auth=0"+"&dt="+MyConfig.TOKEN+"&platform=raisound"+param;
         URI chatRri = URI.create(url);
-        handler.removeMessages(MSG_RECONNECT);
+        if(handler!=null){
+            handler.removeMessages(MSG_RECONNECT);
+        }else {
+            return;
+        }
+
         SobLog.d(TAG, "url--" + url);
         chatClient = new JWebSocketClient(chatRri) {
             @Override
@@ -375,14 +395,15 @@ public class VoiceChatManager {
      * 设置通道
      */
     public void checkoutChannel(IAIChannelChangeCallback channelChangeCallback) {
+        if(handler==null)return;
         this.channelChangeCallback = channelChangeCallback;
-
         if (chatClient != null && chatClient.isOpen()) {
             ischeckoutChannel = true;
             close();
         } else {
             ischeckoutChannel = false;
             isReConnect = true;
+
             handler.removeMessages(MSG_RECONNECT);
             connectChat();
         }
@@ -544,9 +565,9 @@ public class VoiceChatManager {
             if (iVoiceChatCallback != null) {
                 iVoiceChatCallback.OnRespond(chatType, "");
             }
-            if (chatClient != null && chatClient.isOpen()) {
-                close();
-            }
+        }
+        if (chatClient != null && chatClient.isOpen()) {
+            close();
         }
 
     }
index b3c3389..a8f1aca 100644 (file)
@@ -3,6 +3,7 @@ pluginManagement {
         google()
         mavenCentral()
         gradlePluginPortal()
+        maven { url 'https://jitpack.io' }
     }
 }
 dependencyResolutionManagement {
@@ -10,6 +11,7 @@ dependencyResolutionManagement {
     repositories {
         google()
         mavenCentral()
+        maven { url 'https://jitpack.io' }
     }
 }