diff --git a/app/build.gradle b/app/build.gradle index 9701aa3..13ceffd 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -191,8 +191,10 @@ dependencies { exclude module: 'recyclerview-v7' } - compile 'net.grandcentrix.tray:tray:0.11.0' + compile "com.readystatesoftware.sqliteasset:sqliteassethelper:${libs.sqliteassethelper}" - compile 'com.facebook.stetho:stetho:1.4.2' - compile 'com.facebook.stetho:stetho-okhttp3:1.4.2' + compile "net.grandcentrix.tray:tray:${libs.tray}" + + compile "com.facebook.stetho:stetho:${libs.stetho}" + compile "com.facebook.stetho:stetho-okhttp3:${libs.stetho_okhttp3}" } \ No newline at end of file diff --git a/app/src/main/assets/changelog.html b/app/src/main/assets/changelog.html index 3923046..248c273 100644 --- a/app/src/main/assets/changelog.html +++ b/app/src/main/assets/changelog.html @@ -48,11 +48,12 @@ 咕咚翻译 - 一个实现手机端『划词翻译』功能的 App,可能是目前 Android 市场上翻译效率最高的应用。

-

Version 1.6.0

+

Version 1.7.0

    -
  1. 优化: 增加离线翻译支持(仅对以前查询过的单词有效)(thanks 张涛)(04-13)
  2. -
  3. 解决: 循环翻译乱序问题(04-03)
  4. +
  5. 新增: 输入单词自动联想提示(By 70kg)
  6. +
  7. 优化: 设置页面层级以及一个错别字
  8. +
  9. 修复: 背单词时偶现的奔溃

diff --git a/app/src/main/assets/databases/sample_oxford.zip b/app/src/main/assets/databases/sample_oxford.zip new file mode 100644 index 0000000..2536d68 Binary files /dev/null and b/app/src/main/assets/databases/sample_oxford.zip differ diff --git a/app/src/main/java/name/gudong/translate/listener/view/TipViewController.java b/app/src/main/java/name/gudong/translate/listener/view/TipViewController.java index b430523..6540963 100755 --- a/app/src/main/java/name/gudong/translate/listener/view/TipViewController.java +++ b/app/src/main/java/name/gudong/translate/listener/view/TipViewController.java @@ -94,10 +94,14 @@ public void onCloseAnimEnd(Animator animation) { }); return null; } - }); + }).error(new ReciteException()); mHideTipTask.subscribe(); } + protected class ReciteException extends Exception{ + + } + private void removeTipViewInner(TipView tipView) { if (tipView.getParent() != null) { mWindowManager.removeView(tipView); diff --git a/app/src/main/java/name/gudong/translate/mvp/model/entity/translate/YouDaoResult.java b/app/src/main/java/name/gudong/translate/mvp/model/entity/translate/YouDaoResult.java index c3655e8..3ff34d9 100644 --- a/app/src/main/java/name/gudong/translate/mvp/model/entity/translate/YouDaoResult.java +++ b/app/src/main/java/name/gudong/translate/mvp/model/entity/translate/YouDaoResult.java @@ -77,11 +77,13 @@ public String wrapAmPhonetic() { @Override public String wrapEnMp3() { + if(getBasic() == null)return ""; return getBasic().getUkSpeech(); } @Override public String wrapAmMp3() { + if(getBasic() == null)return ""; return getBasic().getUsSpeech(); } diff --git a/app/src/main/java/name/gudong/translate/mvp/presenters/BasePresenter.java b/app/src/main/java/name/gudong/translate/mvp/presenters/BasePresenter.java index 418098f..9ecce51 100644 --- a/app/src/main/java/name/gudong/translate/mvp/presenters/BasePresenter.java +++ b/app/src/main/java/name/gudong/translate/mvp/presenters/BasePresenter.java @@ -66,7 +66,7 @@ public class BasePresenter { protected FileManager mFileManager = new FileManager(); - public BasePresenter(LiteOrm liteOrm, WarpAipService apiService,Context context) { + public BasePresenter(LiteOrm liteOrm, WarpAipService apiService, Context context) { mLiteOrm = liteOrm; mWarpApiService = apiService; mContext = context; @@ -79,21 +79,23 @@ public BasePresenter(LiteOrm liteOrm, WarpAipService apiService, SingleRequestSe mContext = context; } - public void onCreate(){} + public void onCreate() { + } /** * attach IBaseView to Presenter + * * @param view view */ - public void attachView(V view){ + public void attachView(V view) { this.mView = view; } - public void onDestroy(){ + public void onDestroy() { this.mView = null; } - protected Context getContext(){ + protected Context getContext() { return mContext; } @@ -106,73 +108,67 @@ protected Context getContext(){ public Result isFavorite(String word) { QueryBuilder queryBuilder = new QueryBuilder(Result.class); queryBuilder = queryBuilder.whereEquals("query ", word); - Listlist = mLiteOrm.query(queryBuilder); - if(list.isEmpty()){ + List list = mLiteOrm.query(queryBuilder); + if (list.isEmpty()) { return null; } return list.get(0); } - protected long insertResultToDb(Result entity){ + protected long insertResultToDb(Result entity) { return mLiteOrm.insert(entity); } - protected int deleteResultFromDb(Result entity){ + protected int deleteResultFromDb(Result entity) { return mLiteOrm.delete(entity); } - public void playSound(String fileName,String mp3Url) { - Observable.just(mp3Url) - .subscribe(new Action1() { - @Override - public void call(String entity) { - File cacheFile = mFileManager.getCacheFileByUrl(getContext(), fileName); - if (cacheFile != null && cacheFile.exists()) { - playSound(cacheFile); - return; - } - Call call = mSingleRequestService.downloadSoundFile(mp3Url); - call.enqueue(new Callback() { - @Override - public void onResponse(Call call, Response response) { - if (response.isSuccessful()) { - try { - cacheAndPlaySound(getContext(), fileName, response.body().bytes()); - } catch (IOException e) { - e.printStackTrace(); - } - } - } - - @Override - public void onFailure(Call call, Throwable t) { - Logger.e(t.getMessage()); - t.printStackTrace(); - } - }); + public void playSound(String fileName, String mp3Url) { + File cacheFile = mFileManager.getCacheFileByUrl(getContext(), fileName); + if (cacheFile != null && cacheFile.exists()) { + playSound(cacheFile); + return; + } + Call call = mSingleRequestService.downloadSoundFile(mp3Url); + call.enqueue(new Callback() { + @Override + public void onResponse(Call call, Response response) { + if (response.isSuccessful()) { + try { + cacheAndPlaySound(getContext(), fileName, response.body().bytes()); + } catch (IOException e) { + e.printStackTrace(); } - }); + } + } + + @Override + public void onFailure(Call call, Throwable t) { + Logger.e(t.getMessage()); + t.printStackTrace(); + } + }); } - public void startSoundAnim(View view){ - addScaleAnim(view,1000,null); + public void startSoundAnim(View view) { + addScaleAnim(view, 1000, null); } - public void startFavoriteAnim(View view,AnimationEndListener listener){ - addScaleAnim(view,500,listener); + public void startFavoriteAnim(View view, AnimationEndListener listener) { + addScaleAnim(view, 500, listener); } private void addScaleAnim(View view, long duration, AnimationEndListener listener) { - ObjectAnimator animY = ObjectAnimator.ofFloat(view, "scaleY", 1f,0.5f, 1f, 1.2f,1f); - ObjectAnimator animX = ObjectAnimator.ofFloat(view, "scaleX", 1f,0.5f, 1f, 1.2f,1f); + ObjectAnimator animY = ObjectAnimator.ofFloat(view, "scaleY", 1f, 0.5f, 1f, 1.2f, 1f); + ObjectAnimator animX = ObjectAnimator.ofFloat(view, "scaleX", 1f, 0.5f, 1f, 1.2f, 1f); AnimatorSet animatorSet = new AnimatorSet(); - animatorSet.playTogether(animX,animY); + animatorSet.playTogether(animX, animY); animatorSet.setDuration(duration); animatorSet.addListener(new AnimatorListenerAdapter() { @Override public void onAnimationEnd(Animator animation) { super.onAnimationEnd(animation); - if(listener != null){ + if (listener != null) { listener.onAnimationEnd(animation); } } @@ -180,7 +176,7 @@ public void onAnimationEnd(Animator animation) { animatorSet.start(); } - public interface AnimationEndListener{ + public interface AnimationEndListener { void onAnimationEnd(Animator animation); } @@ -197,9 +193,9 @@ public void call(File file) { } private void playSound(File file) { - if(file == null)return; + if (file == null) return; Uri myUri = Uri.fromFile(file); - Logger.i("播放 "+file.getAbsolutePath()); + Logger.i("播放 " + file.getAbsolutePath()); MediaPlayer mediaPlayer = new MediaPlayer(); mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC); try { @@ -212,7 +208,6 @@ private void playSound(File file) { } - private Callable cacheFileObservable(Context context, String fileName, byte[] data) { return new Callable() { @Override @@ -224,11 +219,12 @@ public File call() throws Exception { /** * make a operation observable + * * @param func * @param * @return the Observable */ - protected Observable makeObservable(final Callable func) { + protected Observable makeObservable(final Callable func) { return Observable.create(new Observable.OnSubscribe() { @Override public void call(Subscriber subscriber) { diff --git a/app/src/main/java/name/gudong/translate/mvp/presenters/BookPresenter.java b/app/src/main/java/name/gudong/translate/mvp/presenters/BookPresenter.java index b397291..8352ea6 100644 --- a/app/src/main/java/name/gudong/translate/mvp/presenters/BookPresenter.java +++ b/app/src/main/java/name/gudong/translate/mvp/presenters/BookPresenter.java @@ -51,7 +51,6 @@ import rx.functions.Action1; import rx.schedulers.Schedulers; -import static android.support.v7.widget.StaggeredGridLayoutManager.TAG; /** * Created by GuDong on 2/28/16 17:02. @@ -60,6 +59,7 @@ public class BookPresenter extends BasePresenter { private static final String KEY_TIP_OF_RECITE_OPEN = "TIP_OF_RECITE_OPEN"; private static final String KEY_RECITE_MODE_SWITCH = "RECITE_MODE_SWITCH"; + private static final String TAG = "BOOK_PRESENTER"; @Inject public BookPresenter(LiteOrm liteOrm, WarpAipService apiService, SingleRequestService singleRequestService, Context context) { super(liteOrm, apiService, singleRequestService,context); diff --git a/app/src/main/java/name/gudong/translate/mvp/presenters/MainPresenter.java b/app/src/main/java/name/gudong/translate/mvp/presenters/MainPresenter.java index 01afa39..5732493 100644 --- a/app/src/main/java/name/gudong/translate/mvp/presenters/MainPresenter.java +++ b/app/src/main/java/name/gudong/translate/mvp/presenters/MainPresenter.java @@ -55,6 +55,7 @@ import name.gudong.translate.mvp.views.IMainView; import name.gudong.translate.ui.activitys.MainActivity; import name.gudong.translate.util.DialogUtil; +import name.gudong.translate.util.LocalDicHelper; import name.gudong.translate.util.SpUtils; import name.gudong.translate.util.Utils; import rx.Observable; @@ -91,6 +92,21 @@ public void checkIntentFromClickTipView(Intent intent) { } } + public void analysisLocalDic() { + makeObservable(new Callable>() { + @Override + public List call() throws Exception { + return LocalDicHelper.getLocalDic(mContext); + } + }).subscribeOn(Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe(new Action1>() { + @Override + public void call(List strings) { + mView.attachLocalDic(strings); + } + }); + } public boolean hasExtraResult(Intent intent) { return intent.hasExtra(KEY_RESULT); } diff --git a/app/src/main/java/name/gudong/translate/mvp/views/IMainView.java b/app/src/main/java/name/gudong/translate/mvp/views/IMainView.java index 06dc71b..6d710e9 100644 --- a/app/src/main/java/name/gudong/translate/mvp/views/IMainView.java +++ b/app/src/main/java/name/gudong/translate/mvp/views/IMainView.java @@ -20,6 +20,8 @@ package name.gudong.translate.mvp.views; +import java.util.List; + import name.gudong.translate.mvp.model.entity.dayline.IDayLine; import name.gudong.translate.mvp.model.entity.translate.Result; import name.gudong.translate.mvp.model.type.ETranslateFrom; @@ -58,4 +60,7 @@ public interface IMainView extends IBaseView { void initWithNotFavorite(); void fillDayline(IDayLine entity); + + void attachLocalDic(List dic); + } diff --git a/app/src/main/java/name/gudong/translate/ui/activitys/MainActivity.java b/app/src/main/java/name/gudong/translate/ui/activitys/MainActivity.java index ea82b03..68f7c09 100644 --- a/app/src/main/java/name/gudong/translate/ui/activitys/MainActivity.java +++ b/app/src/main/java/name/gudong/translate/ui/activitys/MainActivity.java @@ -41,8 +41,8 @@ import android.view.View; import android.widget.AdapterView; import android.widget.ArrayAdapter; +import android.widget.AutoCompleteTextView; import android.widget.Button; -import android.widget.EditText; import android.widget.ImageView; import android.widget.LinearLayout; import android.widget.RelativeLayout; @@ -53,6 +53,7 @@ import com.umeng.analytics.MobclickAgent; import java.net.UnknownHostException; +import java.util.List; import butterknife.BindView; import butterknife.ButterKnife; @@ -79,7 +80,7 @@ public class MainActivity extends BaseActivity implements IMainView { private static final String TAG = "MainActivity"; @BindView(android.R.id.input) - EditText mInput; + AutoCompleteTextView mInput; @BindView(R.id.list_result) LinearLayout mList; @BindView(R.id.sp_translate_way) @@ -132,7 +133,7 @@ protected void onCreate(Bundle savedInstanceState) { private void setUpDayline(boolean isOpenDayLine) { View bottomSheet = coordinatorLayout.findViewById(R.id.bottom_sheet_view); - if(!isOpenDayLine){ + if (!isOpenDayLine) { bottomSheet.setVisibility(View.GONE); return; } @@ -145,7 +146,6 @@ private void setUpDayline(boolean isOpenDayLine) { } - private void checkIntent() { mPresenter.checkIntentFromClickTipView(getIntent()); //每日一句 @@ -209,10 +209,11 @@ private void checkTranslateWay() { private void initConfig() { //mPresenter.clearSoundCache(); + mPresenter.analysisLocalDic(); } private void checkVersion() { - if (BuildConfig.DEBUG) return; + //if (BuildConfig.DEBUG) return; mPresenter.checkVersionAndShowChangeLog(); } @@ -306,6 +307,7 @@ private void addListener() { mInput.setOnKeyListener((v, keyCode, event) -> { if ((event.getAction() == KeyEvent.ACTION_DOWN) && (keyCode == KeyEvent.KEYCODE_ENTER)) { MobclickAgent.onEvent(this, "action_translate_by_keyboard"); + mInput.dismissDropDown(); translate(); return true; } @@ -386,7 +388,7 @@ private boolean isEmptyWord(String input, boolean withEmptyPoint) { } private void translate() { - Log.i(TAG,"execute translate"); + Log.i(TAG, "execute translate"); closeKeyboard(); final String input = mInput.getText().toString().trim(); if (checkInput(input)) { @@ -569,6 +571,17 @@ public void fillDayline(IDayLine entity) { mIvSoundDayline.setTag(entity); } + @Override + public void attachLocalDic(List dic) { + ArrayAdapter wordAdapter = new ArrayAdapter<>(MainActivity.this, + android.R.layout.simple_list_item_1, + android.R.id.text1, + dic); + mInput.setAdapter(wordAdapter); + mInput.setThreshold(1); + mInput.setOnItemClickListener((parent, view, position, id) -> translate()); + } + @OnClick(R.id.iv_sound_dayline) public void onClickDaylineSound(View view) { MobclickAgent.onEvent(getApplicationContext(), "sound_dayline_activity"); @@ -606,7 +619,7 @@ private void initSpinner() { } public void onClickBottomSheet() { - if(mBottomSheetBehavior == null){ + if (mBottomSheetBehavior == null) { return; } if (mBottomSheetBehavior.getState() == BottomSheetBehavior.STATE_EXPANDED) { @@ -627,7 +640,7 @@ public void onClickInput(View view) { * @return */ private boolean checkBottomSheetIsExpandedAndReset() { - if(mBottomSheetBehavior == null){ + if (mBottomSheetBehavior == null) { return false; } if (mBottomSheetBehavior.getState() == BottomSheetBehavior.STATE_EXPANDED) { diff --git a/app/src/main/java/name/gudong/translate/ui/activitys/SettingActivity.java b/app/src/main/java/name/gudong/translate/ui/activitys/SettingActivity.java index 9c36ad5..dde046f 100644 --- a/app/src/main/java/name/gudong/translate/ui/activitys/SettingActivity.java +++ b/app/src/main/java/name/gudong/translate/ui/activitys/SettingActivity.java @@ -17,7 +17,6 @@ import name.gudong.translate.manager.ReciteModulePreference; import name.gudong.translate.mvp.model.type.EDurationTipTime; import name.gudong.translate.mvp.model.type.EIntervalTipTime; -import name.gudong.translate.util.Utils; public class SettingActivity extends AppCompatActivity { @@ -56,7 +55,6 @@ public static class SettingsFragment extends PreferenceFragment implements Prefe private com.jenzz.materialpreference.Preference mDurationPreference; private com.jenzz.materialpreference.Preference mIntervalPreference; - private com.jenzz.materialpreference.SwitchPreference mShowIconInNotification; private com.jenzz.materialpreference.SwitchPreference mUseReciteOrNot; ReciteModulePreference mRecitePreference; @@ -74,7 +72,6 @@ public static class SettingsFragment extends PreferenceFragment implements Prefe public void onViewCreated(View view, Bundle savedInstanceState) { super.onViewCreated(view, savedInstanceState); - mShowIconInNotification = (com.jenzz.materialpreference.SwitchPreference) findPreference("preference_show_icon_in_notification"); mUseReciteOrNot = (com.jenzz.materialpreference.SwitchPreference) findPreference("preference_use_recite_or_not"); mDurationPreference = (com.jenzz.materialpreference.Preference) findPreference("preference_show_time"); @@ -82,11 +79,8 @@ public void onViewCreated(View view, Bundle savedInstanceState) { mDurationPreference.setSummary(getArrayValue(R.array.tip_time,durationTime.getIndex())); mDurationPreference.setOnPreferenceClickListener(this); - mShowIconInNotification.setOnPreferenceChangeListener(this); mUseReciteOrNot.setOnPreferenceChangeListener(this); - findPreference("preference_show_float_view_use_system").setEnabled(Utils.isSDKHigh5()); - mIntervalPreference = (com.jenzz.materialpreference.Preference) findPreference("preference_recite_time"); mIntervalPreference.setOnPreferenceClickListener(this); findPreference("preference_auto_play_sound").setOnPreferenceChangeListener(this); @@ -208,13 +202,6 @@ public boolean onPreferenceChange(Preference preference, Object newValue) { mRecitePreference.setReciteOpenOrNot((Boolean) newValue); shiftRecite(); break; - case "preference_show_icon_in_notification": - if((Boolean) newValue){ - Utils.showNormalNotification(getActivity()); - }else{ - Utils.cancelNotification(getActivity()); - } - break; case "preference_auto_play_sound": mRecitePreference.setPlaySoundAuto((Boolean) newValue); break; diff --git a/app/src/main/java/name/gudong/translate/util/LocalDicHelper.java b/app/src/main/java/name/gudong/translate/util/LocalDicHelper.java new file mode 100644 index 0000000..945c2be --- /dev/null +++ b/app/src/main/java/name/gudong/translate/util/LocalDicHelper.java @@ -0,0 +1,43 @@ +package name.gudong.translate.util; + +import android.content.Context; +import android.database.Cursor; +import android.database.sqlite.SQLiteDatabase; + +import com.readystatesoftware.sqliteasset.SQLiteAssetHelper; + +import java.util.ArrayList; +import java.util.List; + +/** + * Created by 70kg on 2017/6/2 + * LocalDicHelper + */ +public class LocalDicHelper extends SQLiteAssetHelper { + public static final String DATABASE_NAME = "sample_oxford"; + private static final int DATABASE_VERSION = 1; + public static final String COL_WORD = "word"; + + public LocalDicHelper(Context context) { + super(context, DATABASE_NAME, null, DATABASE_VERSION); + } + + public static List getLocalDic(Context context) { + List list = new ArrayList<>(); + SQLiteDatabase reader = new LocalDicHelper(context).getReadableDatabase(); + reader.beginTransaction(); + try { + Cursor c = reader.query(LocalDicHelper.DATABASE_NAME, new String[]{COL_WORD}, null, null, null, null, null); + while (c.moveToNext()) { + list.add(c.getString(c.getColumnIndex(LocalDicHelper.COL_WORD))); + } + reader.setTransactionSuccessful(); + } catch (Exception e) { + e.printStackTrace(); + } finally { + reader.endTransaction(); + reader.close(); + } + return list; + } +} diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml index 8539c09..2ddc203 100644 --- a/app/src/main/res/layout/activity_main.xml +++ b/app/src/main/res/layout/activity_main.xml @@ -43,7 +43,7 @@ tools:visibility="visible" /> - 提示显示时间 开启后,划词翻译显示结果时会自动播放单词发音。 - 开启后,咕咚翻译将会自动的在手机山循环浮动显示已收藏的单词,帮助你更好的记忆这些单词。 + 开启后,咕咚翻译将会自动的在手机上循环浮动显示已收藏的单词,帮助你更好的记忆这些单词。 开启后,每天早晨8点,手机会为你提示学习每日一句。 开启后,每次打开 App 时将会自动检测粘贴板是否有单词并翻译。 diff --git a/app/src/main/res/xml/prefs.xml b/app/src/main/res/xml/prefs.xml index 2590236..bd69536 100644 --- a/app/src/main/res/xml/prefs.xml +++ b/app/src/main/res/xml/prefs.xml @@ -38,19 +38,6 @@ android:key="preference_recite_time" android:title="自动提示间隔时间" android:summary="背单词时两次显示的间隔时间"/> - - - - -