# Conflicts:
#	src/main/java/net/micode/notes/ui/NoteEditActivity.java
develop
dingruihua 3 years ago
commit a4d727770a

@ -31,6 +31,17 @@
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
<uses-permission android:name="android.permission.USE_CREDENTIALS" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<!-- 蓝牙录音使用,不需要可以去除 -->
<uses-permission android:name="android.permission.BROADCAST_STICKY" />
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
<application
android:icon="@drawable/icon_app"

@ -0,0 +1,149 @@
package net.micode.notes.ui;
import java.util.List;
public class ASRresponse {
/**
* results_recognition : ["你好,"]
* result_type : final_result
* best_result :
* origin_result : {"asr_align_begin":80,"asr_align_end":130,"corpus_no":6835867007181645805,"err_no":0,"raf":133,"result":{"word":["你好,"]},"sn":"82d975e0-6eb4-43ac-a0e7-850bb149f28e"}
* error : 0
*/
private String result_type;
private String best_result;
private OriginResultBean origin_result;
private int error;
private List<String> 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<String> getResults_recognition() {
return results_recognition;
}
public void setResults_recognition(List<String> 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<String> word;
public List<String> getWord() {
return word;
}
public void setWord(List<String> word) {
this.word = word;
}
}
}
}

@ -79,6 +79,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;
@ -92,20 +97,24 @@ 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.text.BreakIterator;
import java.util.Locale;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Locale;
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 AlertDialog alertDialog2;
private class HeadViewHolder {
public TextView tvModified;
@ -119,6 +128,7 @@ public class NoteEditActivity extends Activity implements OnClickListener,
}
private static final Map<Integer, Integer> sBgSelectorBtnsMap = new HashMap<Integer, Integer>();
static {
sBgSelectorBtnsMap.put(R.id.iv_bg_yellow, ResourceParser.YELLOW);
sBgSelectorBtnsMap.put(R.id.iv_bg_red, ResourceParser.RED);
@ -128,6 +138,7 @@ public class NoteEditActivity extends Activity implements OnClickListener,
}
private static final Map<Integer, Integer> sBgSelectorSelectionMap = new HashMap<Integer, Integer>();
static {
sBgSelectorSelectionMap.put(ResourceParser.YELLOW, R.id.iv_bg_yellow_select);
sBgSelectorSelectionMap.put(ResourceParser.RED, R.id.iv_bg_red_select);
@ -137,6 +148,7 @@ public class NoteEditActivity extends Activity implements OnClickListener,
}
private static final Map<Integer, Integer> sFontSizeBtnsMap = new HashMap<Integer, Integer>();
static {
sFontSizeBtnsMap.put(R.id.ll_font_large, ResourceParser.TEXT_LARGE);
sFontSizeBtnsMap.put(R.id.ll_font_small, ResourceParser.TEXT_SMALL);
@ -145,6 +157,7 @@ public class NoteEditActivity extends Activity implements OnClickListener,
}
private static final Map<Integer, Integer> sFontSelectorSelectionMap = new HashMap<Integer, Integer>();
static {
sFontSelectorSelectionMap.put(ResourceParser.TEXT_LARGE, R.id.iv_large_select);
sFontSelectorSelectionMap.put(ResourceParser.TEXT_SMALL, R.id.iv_small_select);
@ -189,6 +202,11 @@ public class NoteEditActivity extends Activity implements OnClickListener,
private EditText editText;
private TextView textView;
protected EditText txtResult;//识别结果
protected Button startBtn;//开始识别 一直不说话会自动停止,需要再次打开
private EventManager asr;//语音识别核心库
@Override
protected void onCreate(Bundle savedInstanceState) {
@ -209,6 +227,34 @@ public class NoteEditActivity extends Activity implements OnClickListener,
}
initResources();
speech_sum();
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获取添加图片按钮
final ImageButton add_img_btn = (ImageButton) findViewById(R.id.add_img_btn);
@ -218,8 +264,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);
@ -385,7 +431,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,
@ -477,7 +523,8 @@ public class NoteEditActivity extends Activity implements OnClickListener,
} else {
mNoteHeaderHolder.tvAlertDate.setVisibility(View.GONE);
mNoteHeaderHolder.ivAlertIcon.setVisibility(View.GONE);
};
}
;
}
//路径字符串格式 转换为 图片image格式
@ -487,23 +534,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对象封装的图像
@ -513,7 +560,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.在路径的起始位置插入图片
}
}
@ -559,7 +606,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];
@ -595,7 +642,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);
/**
@ -603,7 +651,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);
@ -614,7 +662,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();
@ -631,7 +679,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()
});
@ -668,7 +716,7 @@ public class NoteEditActivity extends Activity implements OnClickListener,
@Override
public void onBackPressed() {
if(clearSettingState()) {
if (clearSettingState()) {
return;
}
@ -775,7 +823,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();
@ -840,7 +888,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);
@ -873,7 +921,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 {
@ -890,7 +938,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");
}
@ -910,7 +958,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++;
}
@ -975,7 +1023,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);
@ -1101,13 +1149,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);
@ -1123,13 +1171,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;
@ -1153,7 +1201,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
@ -1163,8 +1211,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];
@ -1265,4 +1312,55 @@ public class NoteEditActivity extends Activity implements OnClickListener,
alertDialog2=alertBuilder.create();
alertDialog2.show();
}
private void start() {
Toast.makeText(NoteEditActivity.this, "请开始说话", Toast.LENGTH_SHORT).show();
Map<String, Object> params = new LinkedHashMap<>();//传递Map<String,Object>的参数会将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);
}
}

@ -116,6 +116,12 @@
</LinearLayout>
</ScrollView>
<Button
android:id="@+id/listen"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="按住说话" />
<ImageView
android:layout_width="fill_parent"
android:layout_height="7dip"

Loading…
Cancel
Save