From 8e5a498a32460c3f508a7afe6d5fa48eb95b1826 Mon Sep 17 00:00:00 2001 From: xuejunhao <1635376657@qq.com> Date: Sun, 23 Oct 2022 08:18:19 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E4=BA=86=E8=AF=AD=E9=9F=B3?= =?UTF-8?q?=E8=AF=86=E5=88=AB=E8=BE=93=E5=85=A5=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/AndroidManifest.xml | 11 ++ .../java/net/micode/notes/ui/ASRresponse.java | 149 +++++++++++++++ .../net/micode/notes/ui/NoteEditActivity.java | 171 ++++++++++++++---- src/main/res/layout/note_edit.xml | 6 + 4 files changed, 300 insertions(+), 37 deletions(-) create mode 100644 src/main/java/net/micode/notes/ui/ASRresponse.java diff --git a/src/main/AndroidManifest.xml b/src/main/AndroidManifest.xml index e551856..6df39c2 100644 --- a/src/main/AndroidManifest.xml +++ b/src/main/AndroidManifest.xml @@ -31,6 +31,17 @@ + + + + + + + + + + + results_recognition; + + public String getResult_type() { + return result_type; + } + + public void setResult_type(String result_type) { + this.result_type = result_type; + } + + public String getBest_result() { + return best_result; + } + + public void setBest_result(String best_result) { + this.best_result = best_result; + } + + public OriginResultBean getOrigin_result() { + return origin_result; + } + + public void setOrigin_result(OriginResultBean origin_result) { + this.origin_result = origin_result; + } + + public int getError() { + return error; + } + + public void setError(int error) { + this.error = error; + } + + public List getResults_recognition() { + return results_recognition; + } + + public void setResults_recognition(List results_recognition) { + this.results_recognition = results_recognition; + } + + public static class OriginResultBean { + /** + * asr_align_begin : 80 + * asr_align_end : 130 + * corpus_no : 6835867007181645805 + * err_no : 0 + * raf : 133 + * result : {"word":["你好,"]} + * sn : 82d975e0-6eb4-43ac-a0e7-850bb149f28e + */ + + private int asr_align_begin; + private int asr_align_end; + private long corpus_no; + private int err_no; + private int raf; + private ResultBean result; + private String sn; + + public int getAsr_align_begin() { + return asr_align_begin; + } + + public void setAsr_align_begin(int asr_align_begin) { + this.asr_align_begin = asr_align_begin; + } + + public int getAsr_align_end() { + return asr_align_end; + } + + public void setAsr_align_end(int asr_align_end) { + this.asr_align_end = asr_align_end; + } + + public long getCorpus_no() { + return corpus_no; + } + + public void setCorpus_no(long corpus_no) { + this.corpus_no = corpus_no; + } + + public int getErr_no() { + return err_no; + } + + public void setErr_no(int err_no) { + this.err_no = err_no; + } + + public int getRaf() { + return raf; + } + + public void setRaf(int raf) { + this.raf = raf; + } + + public ResultBean getResult() { + return result; + } + + public void setResult(ResultBean result) { + this.result = result; + } + + public String getSn() { + return sn; + } + + public void setSn(String sn) { + this.sn = sn; + } + + public static class ResultBean { + private List word; + + public List getWord() { + return word; + } + + public void setWord(List word) { + this.word = word; + } + } + } +} + diff --git a/src/main/java/net/micode/notes/ui/NoteEditActivity.java b/src/main/java/net/micode/notes/ui/NoteEditActivity.java index 2a6685d..9359103 100644 --- a/src/main/java/net/micode/notes/ui/NoteEditActivity.java +++ b/src/main/java/net/micode/notes/ui/NoteEditActivity.java @@ -73,6 +73,11 @@ import androidx.core.content.ContextCompat; import androidx.annotation.NonNull; import androidx.annotation.Nullable; +import com.baidu.speech.EventListener; +import com.baidu.speech.EventManager; +import com.baidu.speech.EventManagerFactory; +import com.baidu.speech.asr.SpeechConstant; + import net.micode.notes.R; import net.micode.notes.data.Notes; import net.micode.notes.data.Notes.TextNote; @@ -86,16 +91,21 @@ import net.micode.notes.ui.NoteEditText.OnTextViewChangeListener; import net.micode.notes.widget.NoteWidgetProvider_2x; import net.micode.notes.widget.NoteWidgetProvider_4x; +import org.json.JSONException; +import org.json.JSONObject; + import java.io.FileNotFoundException; +import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; +import java.util.LinkedHashMap; import java.util.Map; import java.util.regex.Matcher; import java.util.regex.Pattern; public class NoteEditActivity extends Activity implements OnClickListener, - NoteSettingChangedListener, OnTextViewChangeListener { + NoteSettingChangedListener, OnTextViewChangeListener, EventListener { private class HeadViewHolder { public TextView tvModified; @@ -107,6 +117,7 @@ public class NoteEditActivity extends Activity implements OnClickListener, } private static final Map sBgSelectorBtnsMap = new HashMap(); + static { sBgSelectorBtnsMap.put(R.id.iv_bg_yellow, ResourceParser.YELLOW); sBgSelectorBtnsMap.put(R.id.iv_bg_red, ResourceParser.RED); @@ -116,6 +127,7 @@ public class NoteEditActivity extends Activity implements OnClickListener, } private static final Map sBgSelectorSelectionMap = new HashMap(); + static { sBgSelectorSelectionMap.put(ResourceParser.YELLOW, R.id.iv_bg_yellow_select); sBgSelectorSelectionMap.put(ResourceParser.RED, R.id.iv_bg_red_select); @@ -125,6 +137,7 @@ public class NoteEditActivity extends Activity implements OnClickListener, } private static final Map sFontSizeBtnsMap = new HashMap(); + static { sFontSizeBtnsMap.put(R.id.ll_font_large, ResourceParser.TEXT_LARGE); sFontSizeBtnsMap.put(R.id.ll_font_small, ResourceParser.TEXT_SMALL); @@ -133,6 +146,7 @@ public class NoteEditActivity extends Activity implements OnClickListener, } private static final Map sFontSelectorSelectionMap = new HashMap(); + static { sFontSelectorSelectionMap.put(ResourceParser.TEXT_LARGE, R.id.iv_large_select); sFontSelectorSelectionMap.put(ResourceParser.TEXT_SMALL, R.id.iv_small_select); @@ -176,6 +190,11 @@ public class NoteEditActivity extends Activity implements OnClickListener, private final int PHOTO_REQUEST = 1;//请求码 + protected EditText txtResult;//识别结果 + protected Button startBtn;//开始识别 一直不说话会自动停止,需要再次打开 + + private EventManager asr;//语音识别核心库 + @Override protected void onCreate(Bundle savedInstanceState) { @@ -187,7 +206,33 @@ public class NoteEditActivity extends Activity implements OnClickListener, return; } initResources(); + initView(); + txtResult = findViewById(R.id.note_edit_view); + asr = EventManagerFactory.create(this, "asr"); +//注册自己的输出事件类 + asr.registerListener(this); // EventListener 中 onEvent方法 + startBtn.setOnTouchListener(new View.OnTouchListener() { + @Override + public boolean onTouch(View v, MotionEvent event) { + int action = event.getAction(); + switch (action) { + case MotionEvent.ACTION_DOWN: + start(); + /*mStartSpeechButton.setBackgroundResource( + R.drawable.bdspeech_btn_orangelight_pressed);*/ + break; + case MotionEvent.ACTION_UP: + stop(); + /*mStartSpeechButton.setBackgroundResource( + R.drawable.bdspeech_btn_orangelight_normal);*/ + break; + default: + return false; + } + return true; + } + }); //根据id获取添加图片按钮 @@ -198,8 +243,8 @@ public class NoteEditActivity extends Activity implements OnClickListener, public void onClick(View view) { if (ContextCompat.checkSelfPermission(NoteEditActivity.this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) { //没有授权进行权限申请 - ActivityCompat.requestPermissions(NoteEditActivity.this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE,Manifest.permission.READ_EXTERNAL_STORAGE}, GET_STORAGE_PERMISSION);} - else { + ActivityCompat.requestPermissions(NoteEditActivity.this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.READ_EXTERNAL_STORAGE}, GET_STORAGE_PERMISSION); + } else { Log.d(TAG, "onClick: click add image button"); //ACTION_GET_CONTENT: 允许用户选择特殊种类的数据,并返回(特殊种类的数据:照一张相片或录一段音) Intent loadImage = new Intent(Intent.ACTION_GET_CONTENT); @@ -282,7 +327,7 @@ public class NoteEditActivity extends Activity implements OnClickListener, getWindow().setSoftInputMode( WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN | WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE); - } else if(TextUtils.equals(Intent.ACTION_INSERT_OR_EDIT, intent.getAction())) { + } else if (TextUtils.equals(Intent.ACTION_INSERT_OR_EDIT, intent.getAction())) { // New note long folderId = intent.getLongExtra(Notes.INTENT_EXTRA_FOLDER_ID, 0); int widgetId = intent.getIntExtra(Notes.INTENT_EXTRA_WIDGET_ID, @@ -374,7 +419,8 @@ public class NoteEditActivity extends Activity implements OnClickListener, } else { mNoteHeaderHolder.tvAlertDate.setVisibility(View.GONE); mNoteHeaderHolder.ivAlertIcon.setVisibility(View.GONE); - }; + } + ; } //路径字符串格式 转换为 图片image格式 @@ -384,23 +430,23 @@ public class NoteEditActivity extends Activity implements OnClickListener, String noteText = editable.toString(); //2.将note内容转换为字符串 int length = editable.length(); //内容的长度 //3.截取img片段 [local]+uri+[local],提取uri - for(int i = 0; i < length; i++) { - for(int j = i; j < length; j++) { - String img_fragment = noteText.substring(i, j+1); //img_fragment:关于图片路径的片段 - if(img_fragment.length() > 15 && img_fragment.endsWith("[/local]") && img_fragment.startsWith("[local]")){ + for (int i = 0; i < length; i++) { + for (int j = i; j < length; j++) { + String img_fragment = noteText.substring(i, j + 1); //img_fragment:关于图片路径的片段 + if (img_fragment.length() > 15 && img_fragment.endsWith("[/local]") && img_fragment.startsWith("[local]")) { int limit = 7; //[local]为7个字符 //[local][/local]共15个字符,剩下的为真正的path长度 - int len = img_fragment.length()-15; + int len = img_fragment.length() - 15; //从[local]之后的len个字符就是path - String path = img_fragment.substring(limit,limit+len);//获取到了图片路径 + String path = img_fragment.substring(limit, limit + len);//获取到了图片路径 Bitmap bitmap = null; - Log.d(TAG, "图片的路径是:"+path); + Log.d(TAG, "图片的路径是:" + path); try { bitmap = BitmapFactory.decodeFile(path);//将图片路径解码为图片格式 } catch (Exception e) { e.printStackTrace(); } - if(bitmap!=null){ //若图片存在 + if (bitmap != null) { //若图片存在 Log.d(TAG, "图片不为null"); ImageSpan imageSpan = new ImageSpan(NoteEditActivity.this, bitmap); //4.创建一个SpannableString对象,以便插入用ImageSpan对象封装的图像 @@ -410,7 +456,7 @@ public class NoteEditActivity extends Activity implements OnClickListener, spannableString.setSpan(imageSpan, 0, ss.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); Log.d(TAG, "Create spannable string success!"); Editable edit_text = noteEditText.getEditableText(); - edit_text.delete(i,i+len+15); //6.删掉图片路径的文字 + edit_text.delete(i, i + len + 15); //6.删掉图片路径的文字 edit_text.insert(i, spannableString); //7.在路径的起始位置插入图片 } } @@ -456,7 +502,7 @@ public class NoteEditActivity extends Activity implements OnClickListener, } private boolean inRangeOfView(View view, MotionEvent ev) { - int []location = new int[2]; + int[] location = new int[2]; view.getLocationOnScreen(location); int x = location[0]; int y = location[1]; @@ -491,7 +537,8 @@ public class NoteEditActivity extends Activity implements OnClickListener, for (int id : sFontSizeBtnsMap.keySet()) { View view = findViewById(id); view.setOnClickListener(this); - }; + } + ; mSharedPrefs = PreferenceManager.getDefaultSharedPreferences(this); mFontSizeId = mSharedPrefs.getInt(PREFERENCE_FONT_SIZE, ResourceParser.BG_DEFAULT_FONT_SIZE); /** @@ -499,7 +546,7 @@ public class NoteEditActivity extends Activity implements OnClickListener, * The id may larger than the length of resources, in this case, * return the {@link ResourceParser#BG_DEFAULT_FONT_SIZE} */ - if(mFontSizeId >= TextAppearanceResources.getResourcesSize()) { + if (mFontSizeId >= TextAppearanceResources.getResourcesSize()) { mFontSizeId = ResourceParser.BG_DEFAULT_FONT_SIZE; } mEditTextList = (LinearLayout) findViewById(R.id.note_edit_list); @@ -510,7 +557,7 @@ public class NoteEditActivity extends Activity implements OnClickListener, @Override protected void onPause() { super.onPause(); - if(saveNote()) { + if (saveNote()) { Log.d(TAG, "Note data was saved with length:" + mWorkingNote.getContent().length()); } clearSettingState(); @@ -527,7 +574,7 @@ public class NoteEditActivity extends Activity implements OnClickListener, return; } - intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, new int[] { + intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, new int[]{ mWorkingNote.getWidgetId() }); @@ -564,7 +611,7 @@ public class NoteEditActivity extends Activity implements OnClickListener, @Override public void onBackPressed() { - if(clearSettingState()) { + if (clearSettingState()) { return; } @@ -669,7 +716,7 @@ public class NoteEditActivity extends Activity implements OnClickListener, DateTimePickerDialog d = new DateTimePickerDialog(this, System.currentTimeMillis()); d.setOnDateTimeSetListener(new OnDateTimeSetListener() { public void OnDateTimeSet(AlertDialog dialog, long date) { - mWorkingNote.setAlertDate(date , true); + mWorkingNote.setAlertDate(date, true); } }); d.show(); @@ -734,7 +781,7 @@ public class NoteEditActivity extends Activity implements OnClickListener, PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 0, intent, 0); AlarmManager alarmManager = ((AlarmManager) getSystemService(ALARM_SERVICE)); showAlertHeader(); - if(!set) { + if (!set) { alarmManager.cancel(pendingIntent); } else { alarmManager.set(AlarmManager.RTC_WAKEUP, date, pendingIntent); @@ -767,7 +814,7 @@ public class NoteEditActivity extends Activity implements OnClickListener, mEditTextList.removeViewAt(index); NoteEditText edit = null; - if(index == 0) { + if (index == 0) { edit = (NoteEditText) mEditTextList.getChildAt(0).findViewById( R.id.et_edit_text); } else { @@ -784,7 +831,7 @@ public class NoteEditActivity extends Activity implements OnClickListener, /** * Should not happen, check for debug */ - if(index > mEditTextList.getChildCount()) { + if (index > mEditTextList.getChildCount()) { Log.e(TAG, "Index out of mEditTextList boundrary, should not happen"); } @@ -804,7 +851,7 @@ public class NoteEditActivity extends Activity implements OnClickListener, String[] items = text.split("\n"); int index = 0; for (String item : items) { - if(!TextUtils.isEmpty(item)) { + if (!TextUtils.isEmpty(item)) { mEditTextList.addView(getListItem(item, index)); index++; } @@ -869,7 +916,7 @@ public class NoteEditActivity extends Activity implements OnClickListener, Log.e(TAG, "Wrong index, should not happen"); return; } - if(hasText) { + if (hasText) { mEditTextList.getChildAt(index).findViewById(R.id.cb_edit_item).setVisibility(View.VISIBLE); } else { mEditTextList.getChildAt(index).findViewById(R.id.cb_edit_item).setVisibility(View.GONE); @@ -995,13 +1042,13 @@ public class NoteEditActivity extends Activity implements OnClickListener, e.printStackTrace(); } - if(bitmap != null){ + if (bitmap != null) { //3.根据Bitmap对象创建ImageSpan对象 Log.d(TAG, "onActivityResult: bitmap is not null"); ImageSpan imageSpan = new ImageSpan(NoteEditActivity.this, bitmap); - String path = getPath(this,originalUri); + String path = getPath(this, originalUri); //4.使用[local][/local]将path括起来,用于之后方便识别图片路径在note中的位置 - String img_fragment= "[local]" + path + "[/local]"; + String img_fragment = "[local]" + path + "[/local]"; //创建一个SpannableString对象,以便插入用ImageSpan对象封装的图像 SpannableString spannableString = new SpannableString(img_fragment); spannableString.setSpan(imageSpan, 0, img_fragment.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); @@ -1017,13 +1064,13 @@ public class NoteEditActivity extends Activity implements OnClickListener, ContentResolver contentResolver = getContentResolver(); ContentValues contentValues = new ContentValues(); final long id = mWorkingNote.getNoteId(); - contentValues.put("snippet",mWorkingNote.mContent); - contentResolver.update(Uri.parse("content://micode_notes/note"), contentValues,"_id=?",new String[]{""+id}); + contentValues.put("snippet", mWorkingNote.mContent); + contentResolver.update(Uri.parse("content://micode_notes/note"), contentValues, "_id=?", new String[]{"" + id}); ContentValues contentValues1 = new ContentValues(); - contentValues1.put("content",mWorkingNote.mContent); - contentResolver.update(Uri.parse("content://micode_notes/data"), contentValues1,"mime_type=? and note_id=?", new String[]{"vnd.android.cursor.item/text_note",""+id}); + contentValues1.put("content", mWorkingNote.mContent); + contentResolver.update(Uri.parse("content://micode_notes/data"), contentValues1, "mime_type=? and note_id=?", new String[]{"vnd.android.cursor.item/text_note", "" + id}); - }else{ + } else { Toast.makeText(NoteEditActivity.this, "获取图片失败", Toast.LENGTH_SHORT).show(); } break; @@ -1047,7 +1094,7 @@ public class NoteEditActivity extends Activity implements OnClickListener, final String type = split[0]; if ("primary".equalsIgnoreCase(type)) { - return Environment.getExternalStorageDirectory() + "/" + split[1]; + return Environment.getExternalStorageDirectory() + "/" + split[1]; } } // DownloadsProvider @@ -1057,8 +1104,7 @@ public class NoteEditActivity extends Activity implements OnClickListener, return getDataColumn(context, contentUri, null, null); } // MediaProvider - else - if (isMediaDocument(uri)) { + else if (isMediaDocument(uri)) { final String docId = DocumentsContract.getDocumentId(uri); final String[] split = docId.split(":"); final String type = split[0]; @@ -1121,4 +1167,55 @@ public class NoteEditActivity extends Activity implements OnClickListener, public boolean isMediaDocument(Uri uri) { return "com.android.providers.media.documents".equals(uri.getAuthority()); } + + + private void start() { + Toast.makeText(NoteEditActivity.this, "请开始说话", Toast.LENGTH_SHORT).show(); + Map params = new LinkedHashMap<>();//传递Map的参数,会将Map自动序列化为json + String event = null; + event = SpeechConstant.ASR_START; + params.put(SpeechConstant.ACCEPT_AUDIO_VOLUME, false);//回调当前音量 + String json = null; + json = new JSONObject(params).toString();//demo用json数据来做数据交换的方式 + asr.send(event, json, null, 0, 0);// 初始化EventManager对象,这个实例只能创建一次,就是我们上方创建的asr,此处开始传入 + } + + private void stop() { + //txtResult.append("停止识别:ASR_STOP"); + asr.send(SpeechConstant.ASR_STOP, null, null, 0, 0);//此处停止 + } + + @Override + protected void onDestroy() { + super.onDestroy(); + asr.send(SpeechConstant.ASR_CANCEL, "{}", null, 0, 0); + asr.unregisterListener(this);//退出事件管理器 + // 必须与registerListener成对出现,否则可能造成内存泄露 + } + + public void onEvent(String name, String params, byte[] data, int offset, int length) { + String resultTxt = null; + //Log.i(TAG, params); + if (name.equals(SpeechConstant.CALLBACK_EVENT_ASR_PARTIAL)) {//识别结果参数 + if (params.contains("\"final_result\"")) {//语义结果值 + try { + JSONObject json = new JSONObject(params); + String result = json.getString("best_result");//取得key的识别结果 + resultTxt = result; + } catch (JSONException e) { + e.printStackTrace(); + } + } + } + if (resultTxt != null) { + resultTxt += "\n"; + txtResult.append(resultTxt); + } + } + + private void initView() { + txtResult = findViewById(R.id.note_edit_view); + startBtn = findViewById(R.id.listen); + //stopBtn = findViewById(R.id.stop); + } } diff --git a/src/main/res/layout/note_edit.xml b/src/main/res/layout/note_edit.xml index 1dd486b..06129fd 100644 --- a/src/main/res/layout/note_edit.xml +++ b/src/main/res/layout/note_edit.xml @@ -109,6 +109,12 @@ +