|
@@ -0,0 +1,377 @@
|
|
|
+package com.drinkertea.test2smack;
|
|
|
+
|
|
|
+import android.annotation.SuppressLint;
|
|
|
+import android.content.ContextWrapper;
|
|
|
+import android.graphics.Color;
|
|
|
+import android.graphics.Typeface;
|
|
|
+import android.media.MediaPlayer;
|
|
|
+import android.media.MediaRecorder;
|
|
|
+import android.os.Bundle;
|
|
|
+import android.os.Environment;
|
|
|
+import android.os.Handler;
|
|
|
+import android.speech.tts.TextToSpeech;
|
|
|
+import android.text.Editable;
|
|
|
+import android.text.TextWatcher;
|
|
|
+import android.util.Base64;
|
|
|
+import android.view.MotionEvent;
|
|
|
+import android.view.View;
|
|
|
+import android.widget.Button;
|
|
|
+import android.widget.EditText;
|
|
|
+import android.widget.ImageButton;
|
|
|
+import android.widget.LinearLayout;
|
|
|
+import android.widget.ScrollView;
|
|
|
+import android.widget.TextView;
|
|
|
+
|
|
|
+import androidx.appcompat.app.AppCompatActivity;
|
|
|
+
|
|
|
+import org.jivesoftware.smack.AbstractXMPPConnection;
|
|
|
+import org.jivesoftware.smack.chat2.Chat;
|
|
|
+import org.jivesoftware.smack.chat2.ChatManager;
|
|
|
+import org.jivesoftware.smack.chat2.IncomingChatMessageListener;
|
|
|
+import org.jivesoftware.smack.packet.Message;
|
|
|
+import org.jxmpp.jid.EntityBareJid;
|
|
|
+import org.jxmpp.jid.impl.JidCreate;
|
|
|
+
|
|
|
+import java.io.BufferedOutputStream;
|
|
|
+import java.io.ByteArrayOutputStream;
|
|
|
+import java.io.File;
|
|
|
+import java.io.FileInputStream;
|
|
|
+import java.io.FileOutputStream;
|
|
|
+import java.io.IOException;
|
|
|
+import java.io.InputStream;
|
|
|
+import java.util.Locale;
|
|
|
+
|
|
|
+public class VoiceActivityChat extends AppCompatActivity {
|
|
|
+
|
|
|
+ EditText ET_voice;
|
|
|
+ TextView timerView;
|
|
|
+ LinearLayout LL_voice;
|
|
|
+ TextToSpeech textToSpeech;
|
|
|
+ AbstractXMPPConnection connect = XMPPClass.connection;;
|
|
|
+ ChatManager chatManager = XMPPClass.chatManager;;
|
|
|
+ EntityBareJid jid;
|
|
|
+ ScrollView mainScroll;
|
|
|
+ Button sendVoice;
|
|
|
+ ImageButton sendText;
|
|
|
+ private int seconds = 0;
|
|
|
+ private boolean running = false;
|
|
|
+ Handler handler;
|
|
|
+ String encode = "";
|
|
|
+ private MediaPlayer mPlayer;
|
|
|
+ private MediaRecorder mRecorder;
|
|
|
+ {
|
|
|
+ try {
|
|
|
+ //jid = XMPPClass.chatJid;
|
|
|
+ jid = JidCreate.entityBareFrom("test@msg.sharix-app.org");
|
|
|
+
|
|
|
+ } catch (Exception e) {
|
|
|
+ ErrorLogFile.WriterLogs(e.getMessage());
|
|
|
+ //System.out.println(e.getMessage());
|
|
|
+ }
|
|
|
+ }
|
|
|
+ Chat chat = chatManager.chatWith(jid);
|
|
|
+
|
|
|
+ @SuppressLint("ClickableViewAccessibility")
|
|
|
+ @Override
|
|
|
+ protected void onCreate(Bundle savedInstanceState) {
|
|
|
+ super.onCreate(savedInstanceState);
|
|
|
+ setContentView(R.layout.activity_voice_chat);
|
|
|
+ ET_voice = (EditText) findViewById(R.id.voice_text_edit);
|
|
|
+ LL_voice = (LinearLayout) findViewById(R.id.voicesLayout);
|
|
|
+ mainScroll = (ScrollView) findViewById(R.id.voiceScroll);
|
|
|
+ sendText = (ImageButton) findViewById(R.id.btnSendMessage);
|
|
|
+ sendVoice = (Button) findViewById(R.id.btnSendVoice);
|
|
|
+ timerView = (TextView) findViewById(R.id.timerView);
|
|
|
+ StartTimer();
|
|
|
+ sendVoice.setOnTouchListener((view, motionEvent) -> sendVoiceMessage(motionEvent));
|
|
|
+ sendText.setOnClickListener(view -> sendChatMessage());
|
|
|
+ ET_voice.addTextChangedListener(new TextWatcher() {
|
|
|
+ @Override
|
|
|
+ public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
|
|
|
+ changeVisibleSendVoice(charSequence);
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void afterTextChanged(Editable editable) {
|
|
|
+
|
|
|
+ }
|
|
|
+ });
|
|
|
+ textToSpeech = new TextToSpeech(getApplicationContext(), i -> {
|
|
|
+ if (i != TextToSpeech.ERROR){
|
|
|
+ Locale locale = new Locale("ru");
|
|
|
+ int result = textToSpeech.setLanguage(locale);
|
|
|
+ }
|
|
|
+ });
|
|
|
+ createMessageForm();
|
|
|
+ }
|
|
|
+ public void StartRecord(){
|
|
|
+ try {
|
|
|
+ mRecorder = new MediaRecorder();
|
|
|
+ mRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
|
|
|
+ mRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
|
|
|
+ mRecorder.setOutputFile(getFileName());
|
|
|
+ mRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
|
|
|
+
|
|
|
+ mRecorder.prepare();
|
|
|
+ mRecorder.start();
|
|
|
+ System.out.println("Success all");
|
|
|
+ } catch (Exception e) {
|
|
|
+ System.out.println(e.getMessage());
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ }
|
|
|
+ public void StopRecord(){
|
|
|
+ mRecorder.stop();
|
|
|
+ mRecorder.release();
|
|
|
+ mRecorder = null;
|
|
|
+ }
|
|
|
+ public void changeVisibleForText(){
|
|
|
+ if (running){
|
|
|
+ timerView.setVisibility(View.VISIBLE);
|
|
|
+ ET_voice.setVisibility(View.GONE);
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ timerView.setVisibility(View.GONE);
|
|
|
+ ET_voice.setVisibility(View.VISIBLE);
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+ public void changeVisibleSendVoice(CharSequence charSequence){
|
|
|
+ try {
|
|
|
+ if (charSequence.length() != 0){
|
|
|
+ sendText.setVisibility(View.VISIBLE);
|
|
|
+ sendVoice.setVisibility(View.GONE);
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ sendText.setVisibility(View.GONE);
|
|
|
+ sendVoice.setVisibility(View.VISIBLE);
|
|
|
+ }
|
|
|
+ } catch (Exception ex){
|
|
|
+ ErrorLogFile.WriterLogs(ex.getMessage());
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ public void sendChatMessage() {
|
|
|
+ try {
|
|
|
+ String text = ET_voice.getText().toString();
|
|
|
+ chat.send(text);
|
|
|
+ addMessage(connect.getUser().asBareJid().toString(), text, false);
|
|
|
+ ET_voice.setText("");
|
|
|
+ mainScroll.fullScroll(ScrollView.FOCUS_DOWN);
|
|
|
+
|
|
|
+ } catch (Exception e) {
|
|
|
+ ErrorLogFile.WriterLogs(e.getMessage());
|
|
|
+ //System.out.println(e.getMessage());
|
|
|
+ }
|
|
|
+ }
|
|
|
+ public boolean sendVoiceMessage(MotionEvent motionEvent) {
|
|
|
+ try {
|
|
|
+ switch (motionEvent.getAction()){
|
|
|
+ case MotionEvent.ACTION_DOWN:
|
|
|
+ StartRecord();
|
|
|
+ //Toast.makeText(getApplicationContext(), "Start record", Toast.LENGTH_SHORT).show();
|
|
|
+ running = true;
|
|
|
+ //main_text.setText("Press");
|
|
|
+ return true;
|
|
|
+ case MotionEvent.ACTION_UP:
|
|
|
+ running = false;
|
|
|
+ seconds = 0;
|
|
|
+ StopRecord();
|
|
|
+ //Toast.makeText(getApplicationContext(), "Stop record", Toast.LENGTH_SHORT).show();
|
|
|
+ File file = new File(getFileName());
|
|
|
+ InputStream inputStream = new FileInputStream(file);
|
|
|
+ encode = "base64 ogg";
|
|
|
+ encode += Base64.encodeToString(inputStreamToByteArray(inputStream), Base64.DEFAULT);
|
|
|
+ chat.send(encode);
|
|
|
+ addMessage(connect.getUser().asBareJid().toString(), encode, false);
|
|
|
+ mainScroll.fullScroll(ScrollView.FOCUS_DOWN);
|
|
|
+ return true;
|
|
|
+ default:
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ }catch (Exception ex){
|
|
|
+ System.out.println(ex.getMessage());
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ public void StartTimer(){
|
|
|
+ seconds = 0;
|
|
|
+ handler = new Handler();
|
|
|
+ handler.post(new Runnable() {
|
|
|
+ @SuppressLint("ClickableViewAccessibility")
|
|
|
+ @Override
|
|
|
+ public void run()
|
|
|
+ {
|
|
|
+ int minutes = (seconds % 3600) / 60;
|
|
|
+ int secs = seconds % 60;
|
|
|
+ String time = String.format(Locale.getDefault(), "%01d:%02d", minutes, secs);
|
|
|
+
|
|
|
+ timerView.setText("Recording goes " + time);
|
|
|
+ changeVisibleForText();
|
|
|
+ if (running) {
|
|
|
+ seconds++;
|
|
|
+ }
|
|
|
+ if(seconds >= 10 && running){
|
|
|
+ try {
|
|
|
+ running = false;
|
|
|
+ seconds = 0;
|
|
|
+ sendVoice.setOnTouchListener(null);
|
|
|
+ StopRecord();
|
|
|
+ File file = new File(getFileName());
|
|
|
+ InputStream inputStream = new FileInputStream(file);
|
|
|
+ encode = "base64 ogg";
|
|
|
+ encode += Base64.encodeToString(inputStreamToByteArray(inputStream), Base64.DEFAULT);
|
|
|
+ chat.send(encode);
|
|
|
+ addMessage(connect.getUser().asBareJid().toString(), encode, false);
|
|
|
+ mainScroll.fullScroll(ScrollView.FOCUS_DOWN);
|
|
|
+ sendVoice.setOnTouchListener((view, motionEvent) -> sendVoiceMessage(motionEvent));
|
|
|
+ } catch (Exception e) {
|
|
|
+ e.printStackTrace();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ handler.postDelayed(this, 1000);
|
|
|
+ }
|
|
|
+ });
|
|
|
+
|
|
|
+ }
|
|
|
+ public void addMessage(String from, String body, boolean black){
|
|
|
+ try {
|
|
|
+ TextView fromName = new TextView(this);
|
|
|
+ TextView bodyView = new TextView(this);
|
|
|
+ TextView cash = new TextView(this);
|
|
|
+ cash.setVisibility(View.GONE);
|
|
|
+ cash.setText("NULL");
|
|
|
+ LinearLayout linearLayout = new LinearLayout(this);
|
|
|
+
|
|
|
+ fromName.setText(from.split("@")[0] + ": ");
|
|
|
+ fromName.setTextSize(16);
|
|
|
+ fromName.setTypeface(null, Typeface.BOLD);
|
|
|
+ if (black){
|
|
|
+ fromName.setTextColor(Color.parseColor("#000000"));
|
|
|
+ } else {
|
|
|
+ fromName.setTextColor(Color.parseColor("#006000"));
|
|
|
+ }
|
|
|
+ Button btn = new Button(this);
|
|
|
+ btn.setText("PLAY");
|
|
|
+ btn.setBackgroundColor(Color.parseColor("#0081ff"));
|
|
|
+ LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT,
|
|
|
+ LinearLayout.LayoutParams.WRAP_CONTENT);
|
|
|
+ btn.setLayoutParams(params);
|
|
|
+ btn.setTextColor(Color.parseColor("#ffffff"));
|
|
|
+ if (body.startsWith("base64 ogg") || body.length() >= 10000){
|
|
|
+ cash.setText(body);
|
|
|
+ bodyView.setText("Voice message...");
|
|
|
+ }
|
|
|
+ else{
|
|
|
+ bodyView.setText(body);
|
|
|
+ }
|
|
|
+ btn.setOnClickListener(new View.OnClickListener() {
|
|
|
+ @Override
|
|
|
+ public void onClick(View view) {
|
|
|
+ if (cash.getText().toString() == "NULL"){
|
|
|
+ textToSpeech.speak(bodyView.getText().toString(), TextToSpeech.QUEUE_ADD, null);
|
|
|
+ } else if (cash.getText().toString().startsWith("base64 ogg")){
|
|
|
+ String base_code = cash.getText().toString().replaceFirst("base64 ogg", "");
|
|
|
+ mPlayer = new MediaPlayer();
|
|
|
+ byte[] decode = Base64.decode(base_code, Base64.DEFAULT);
|
|
|
+ File file = new File(getFileName());
|
|
|
+ FileOutputStream fileOutputStream;
|
|
|
+ BufferedOutputStream bufferedOutputStream;
|
|
|
+ try {
|
|
|
+ fileOutputStream = new FileOutputStream(file);
|
|
|
+ bufferedOutputStream = new BufferedOutputStream(fileOutputStream);
|
|
|
+ bufferedOutputStream.write(decode);
|
|
|
+ bufferedOutputStream.close();
|
|
|
+ } catch (Exception e) {
|
|
|
+ e.printStackTrace();
|
|
|
+ }
|
|
|
+ try {
|
|
|
+ mPlayer.setDataSource(getFileName());
|
|
|
+ mPlayer.prepare();
|
|
|
+ mPlayer.start();
|
|
|
+ } catch (Exception e) {
|
|
|
+ System.out.println(e.getMessage());
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ });
|
|
|
+
|
|
|
+
|
|
|
+ bodyView.setTextSize(14);
|
|
|
+ bodyView.setTextColor(Color.parseColor("#000000"));
|
|
|
+ linearLayout.setOrientation(LinearLayout.VERTICAL);
|
|
|
+ linearLayout.addView(fromName);
|
|
|
+ linearLayout.addView(bodyView);
|
|
|
+ linearLayout.addView(btn);
|
|
|
+
|
|
|
+ LL_voice.addView(linearLayout);
|
|
|
+ } catch (Exception e) {
|
|
|
+ ErrorLogFile.WriterLogs(e.getMessage());
|
|
|
+ //System.out.println(e.getMessage());
|
|
|
+ }
|
|
|
+ }
|
|
|
+ public void createMessageForm() {
|
|
|
+ try {
|
|
|
+ XMPPClass.CreateChatListMessage(jid, 15);
|
|
|
+ for(Message message : XMPPClass.messages){
|
|
|
+ String from = message.getFrom().asBareJid().toString().trim();
|
|
|
+ if (from.equals(XMPPClass.myJid.asEntityBareJidString().trim())){
|
|
|
+ addMessage(message.getFrom().asBareJid().toString(), message.getBody(), false);
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ addMessage(message.getFrom().asBareJid().toString(), message.getBody(), true);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ runMessageListener();
|
|
|
+ }catch (Exception e){
|
|
|
+ ErrorLogFile.WriterLogs(e.getMessage());
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+ public void runMessageListener(){
|
|
|
+ try {
|
|
|
+ chatManager.addIncomingListener(new IncomingChatMessageListener() {
|
|
|
+ @Override
|
|
|
+ public void newIncomingMessage(EntityBareJid from, Message message, Chat chat) {
|
|
|
+ runOnUiThread(new Runnable() {
|
|
|
+ @Override
|
|
|
+ public void run() {
|
|
|
+ try {
|
|
|
+ addMessage(from.asBareJid().toString(), message.getBody(), true);
|
|
|
+ //System.out.println("New message from:" + from + ": " + message.toXML().toString());
|
|
|
+ } catch (Exception e) {
|
|
|
+ //ErrorLogFile.WriterLogs(e.getMessage());
|
|
|
+ System.out.println(e.getMessage());
|
|
|
+ }
|
|
|
+ }
|
|
|
+ });
|
|
|
+
|
|
|
+ }
|
|
|
+ });
|
|
|
+ } catch (Exception e) {
|
|
|
+ ErrorLogFile.WriterLogs(e.getMessage());
|
|
|
+ //System.out.println(e.getMessage());
|
|
|
+ }
|
|
|
+ }
|
|
|
+ private String getFileName(){
|
|
|
+ ContextWrapper contextWrapper = new ContextWrapper(getApplicationContext());
|
|
|
+ File musicDir = contextWrapper.getExternalFilesDir(Environment.DIRECTORY_MUSIC);
|
|
|
+ File file = new File(musicDir, "TestAudioFile" + ".ogg");
|
|
|
+ return file.getPath();
|
|
|
+ }
|
|
|
+ public byte[] inputStreamToByteArray(InputStream inStream) throws IOException {
|
|
|
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
|
|
+ byte[] buffer = new byte[8192];
|
|
|
+ int bytesRead;
|
|
|
+ while ((bytesRead = inStream.read(buffer)) > 0) {
|
|
|
+ baos.write(buffer, 0, bytesRead);
|
|
|
+ }
|
|
|
+ return baos.toByteArray();
|
|
|
+ }
|
|
|
+}
|