diff --git a/.idea/markdown-navigator-enh.xml b/.idea/markdown-navigator-enh.xml new file mode 100644 index 0000000..a8fcc84 --- /dev/null +++ b/.idea/markdown-navigator-enh.xml @@ -0,0 +1,10 @@ + + + + + + + + + + \ No newline at end of file diff --git a/.idea/markdown-navigator.xml b/.idea/markdown-navigator.xml new file mode 100644 index 0000000..a2fc086 --- /dev/null +++ b/.idea/markdown-navigator.xml @@ -0,0 +1,62 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/androidTest/java/xyz/fycz/myreader/ExampleInstrumentedTest.java b/app/src/androidTest/java/xyz/fycz/myreader/ExampleInstrumentedTest.java new file mode 100644 index 0000000..db8d9cc --- /dev/null +++ b/app/src/androidTest/java/xyz/fycz/myreader/ExampleInstrumentedTest.java @@ -0,0 +1,37 @@ +package xyz.fycz.myreader; + +import android.content.Context; + +import androidx.test.ext.junit.runners.AndroidJUnit4; +import androidx.test.platform.app.InstrumentationRegistry; + +import org.junit.Test; +import org.junit.runner.RunWith; + + +import xyz.fycz.myreader.model.audio.ReadService; + +import static org.junit.Assert.assertEquals; + +/** + * Instrumented test, which will execute on an Android device. + * + * @see Testing documentation + */ +@RunWith(AndroidJUnit4.class) +public class ExampleInstrumentedTest { + @Test + public void useAppContext() { + // Context of the app under test. + Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext(); + assertEquals("xyz.fycz.myreader", appContext.getPackageName()); + } + + @Test + public void test() { + ReadService readService = new ReadService(); + readService.initSynthesizer(); + readService.startSynthesizer("科幻电影是我们从小就爱看的电影题材,我们也都梦想过生活在那样的科幻世界里。科幻片,顾名思义即“科学幻想片”,是“以科学幻想为内容的故事片,其基本特点是从今天已知的科学原理和科学成就出发,对未来的世界或遥远的过去的情景作幻想式的描述。”"); + } + +} \ No newline at end of file diff --git a/app/src/androidTest/java/xyz/fycz/myreader/TestAudioPlay.java b/app/src/androidTest/java/xyz/fycz/myreader/TestAudioPlay.java new file mode 100644 index 0000000..f5a5e55 --- /dev/null +++ b/app/src/androidTest/java/xyz/fycz/myreader/TestAudioPlay.java @@ -0,0 +1,19 @@ +package xyz.fycz.myreader; + +import androidx.test.ext.junit.runners.AndroidJUnit4; + +import org.junit.runner.RunWith; + +import xyz.fycz.myreader.model.audio.ReadService; + +@RunWith(AndroidJUnit4.class) +public class TestAudioPlay { + + public void test() { + ReadService readService = new ReadService(); + readService.initSynthesizer(); + readService.startSynthesizer("科幻电影是我们从小就爱看的电影题材,我们也都梦想过生活在那样的科幻世界里。科幻片,顾名思义即“科学幻想片”,是“以科学幻想为内容的故事片,其基本特点是从今天已知的科学原理和科学成就出发,对未来的世界或遥远的过去的情景作幻想式的描述。”"); + } + +} + diff --git a/app/src/main/java/xyz/fycz/myreader/ui/dialog/AudioPlayerDialog.java b/app/src/main/java/xyz/fycz/myreader/ui/dialog/AudioPlayerDialog.java index 5b89137..f555175 100644 --- a/app/src/main/java/xyz/fycz/myreader/ui/dialog/AudioPlayerDialog.java +++ b/app/src/main/java/xyz/fycz/myreader/ui/dialog/AudioPlayerDialog.java @@ -12,6 +12,7 @@ import android.view.Window; import android.view.WindowManager; import android.widget.NumberPicker; import android.widget.SeekBar; +import android.widget.TextView; import androidx.annotation.NonNull; import androidx.appcompat.widget.AppCompatImageView; @@ -33,8 +34,8 @@ import xyz.fycz.myreader.widget.page.PageLoader; import static xyz.fycz.myreader.util.utils.StringUtils.getString; -public class AudioPlayerDialog extends Dialog{ - private static final String TAG="AudioPlayerDialog"; +public class AudioPlayerDialog extends Dialog { + private static final String TAG = "AudioPlayerDialog"; private PageLoader mPageLoader; private ReadActivity mReadActivity; private boolean aloudNextPage; @@ -45,6 +46,8 @@ public class AudioPlayerDialog extends Dialog{ private int speechRate; private int timer; + @BindView(R.id.iv_reset_setting) + TextView tvResetSetting; @BindView(R.id.sb_volume_progress) SeekBar sbVolume; @BindView(R.id.sb_pitch_progress) @@ -122,6 +125,18 @@ public class AudioPlayerDialog extends Dialog{ sbVolume.setOnSeekBarChangeListener(seekBarChangeListener); sbPitch.setOnSeekBarChangeListener(seekBarChangeListener); sbSpeechRate.setOnSeekBarChangeListener(seekBarChangeListener); + tvResetSetting.setOnClickListener(v ->{ + pitch = 10; + speechRate = 10; + sbPitch.setProgress(pitch); + sbSpeechRate.setProgress(speechRate); + SharedPreUtils.getInstance().putInt("pitch", pitch); + SharedPreUtils.getInstance().putInt("speechRate", speechRate); + if (ReadAloudService.running) { + ReadAloudService.pause(mReadActivity); + ReadAloudService.resume(mReadActivity); + } + }); } private class SeekBarChangeListener implements SeekBar.OnSeekBarChangeListener{ @@ -206,7 +221,7 @@ public class AudioPlayerDialog extends Dialog{ NumberPicker hourPicker = timer.findViewById(R.id.hour_picker); int hour = this.timer / 60; int minute = this.timer % 60; - hourPicker.setMaxValue(24); + hourPicker.setMaxValue(5); hourPicker.setMinValue(0); hourPicker.setValue(hour); NumberPicker minutePicker = timer.findViewById(R.id.minute_picker); diff --git a/app/src/main/java/xyz/fycz/myreader/util/SystemUtil.java b/app/src/main/java/xyz/fycz/myreader/util/SystemUtil.java new file mode 100644 index 0000000..3d16ec5 --- /dev/null +++ b/app/src/main/java/xyz/fycz/myreader/util/SystemUtil.java @@ -0,0 +1,54 @@ +package xyz.fycz.myreader.util; + +import android.annotation.SuppressLint; +import android.app.Activity; +import android.content.Context; +import android.content.Intent; +import android.net.Uri; +import android.os.PowerManager; +import android.provider.Settings; +import android.util.DisplayMetrics; + +import androidx.appcompat.app.AppCompatActivity; + +import static android.content.Context.POWER_SERVICE; + +/** + */ + +public class SystemUtil { + + public static double getScreenPhysicalSize(AppCompatActivity ctx) { + DisplayMetrics dm = new DisplayMetrics(); + ctx.getWindowManager().getDefaultDisplay().getMetrics(dm); + double diagonalPixels = Math.sqrt(Math.pow(dm.widthPixels, 2) + Math.pow(dm.heightPixels, 2)); + return diagonalPixels / (160 * dm.density); + } + public static int getScreenOffTime(Context context) { + int screenOffTime = 0; + try { + screenOffTime = Settings.System.getInt(context.getContentResolver(), + Settings.System.SCREEN_OFF_TIMEOUT); + } catch (Exception e) { + e.printStackTrace(); + } + return screenOffTime; + } + + public static void ignoreBatteryOptimization(Activity activity) { + if (android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.M) return; + + PowerManager powerManager = (PowerManager) activity.getSystemService(POWER_SERVICE); + boolean hasIgnored = powerManager.isIgnoringBatteryOptimizations(activity.getPackageName()); + // 判断当前APP是否有加入电池优化的白名单,如果没有,弹出加入电池优化的白名单的设置对话框。 + if (!hasIgnored) { + try { + @SuppressLint("BatteryLife") + Intent intent = new Intent(Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS); + intent.setData(Uri.parse("package:" + activity.getPackageName())); + activity.startActivity(intent); + } catch (Throwable ignored) { + } + } + } +} diff --git a/app/src/main/java/xyz/fycz/myreader/util/utils/AudioMngHelper.java b/app/src/main/java/xyz/fycz/myreader/util/utils/AudioMngHelper.java new file mode 100644 index 0000000..c1e8e32 --- /dev/null +++ b/app/src/main/java/xyz/fycz/myreader/util/utils/AudioMngHelper.java @@ -0,0 +1,170 @@ +package xyz.fycz.myreader.util.utils; + +import android.content.Context; +import android.media.AudioManager; + +import androidx.annotation.IntDef; + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + +import xyz.fycz.myreader.application.MyApplication; +import xyz.fycz.myreader.util.SharedPreUtils; + +/** + *
+ *     author: Chestnut
+ *     blog  : http://www.jianshu.com/u/a0206b5f4526
+ *     time  : 2017/6/17 16:11
+ *     desc  :  集成音量控制
+ *     thanks To:   http://blog.csdn.net/hufeng882412/article/details/7310131
+ *     dependent on:
+ *     update log:
+ * 
+ */ + +public class AudioMngHelper { + + private final String TAG = "AudioMngHelper"; + private final boolean OpenLog = true; + private static volatile AudioMngHelper sInstance; + + + private AudioManager audioManager; + private int NOW_AUDIO_TYPE = TYPE_MUSIC; + private int NOW_FLAG = FLAG_NOTHING; + private int VOICE_STEP_100 = 2; //0-100的步进。 + + /** + * 封装:STREAM_类型 + */ + public final static int TYPE_MUSIC = AudioManager.STREAM_MUSIC; + public final static int TYPE_ALARM = AudioManager.STREAM_ALARM; + public final static int TYPE_RING = AudioManager.STREAM_RING; + @IntDef({TYPE_MUSIC, TYPE_ALARM, TYPE_RING}) + @Retention(RetentionPolicy.SOURCE) + public @interface TYPE {} + + /** + * 封装:FLAG + */ + public final static int FLAG_SHOW_UI = AudioManager.FLAG_SHOW_UI; + public final static int FLAG_PLAY_SOUND = AudioManager.FLAG_PLAY_SOUND; + public final static int FLAG_NOTHING = 0; + @IntDef({FLAG_SHOW_UI, FLAG_PLAY_SOUND, FLAG_NOTHING}) + @Retention(RetentionPolicy.SOURCE) + public @interface FLAG {} + + public static AudioMngHelper getInstance(){ + if(sInstance == null){ + synchronized (SharedPreUtils.class){ + if (sInstance == null){ + sInstance = new AudioMngHelper(MyApplication.getmContext()); + } + } + } + return sInstance; + } + /** + * 初始化,获取音量管理者 + * @param context 上下文 + */ + public AudioMngHelper(Context context) { + audioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE); + } + + public int getSystemMaxVolume() { + return audioManager.getStreamMaxVolume(NOW_AUDIO_TYPE); + } + + public int getSystemCurrentVolume() { + return audioManager.getStreamVolume(NOW_AUDIO_TYPE); + } + + /** + * 以0-100为范围,获取当前的音量值 + * @return 获取当前的音量值 + */ + public int get100CurrentVolume() { + return 100*getSystemCurrentVolume()/getSystemMaxVolume(); + } + + /** + * 修改步进值 + * @param step step + * @return this + */ + public AudioMngHelper setVoiceStep100(int step) { + VOICE_STEP_100 = step; + return this; + } + + /** + * 改变当前的模式,对全局API生效 + * @param type + * @return + */ + public AudioMngHelper setAudioType(@TYPE int type) { + NOW_AUDIO_TYPE = type; + return this; + } + + /** + * 改变当前FLAG,对全局API生效 + * @param flag + * @return + */ + public AudioMngHelper setFlag(@FLAG int flag) { + NOW_FLAG = flag; + return this; + } + + public AudioMngHelper addVoiceSystem() { + audioManager.adjustStreamVolume(NOW_AUDIO_TYPE,AudioManager.ADJUST_RAISE,NOW_FLAG); + return this; + } + + public AudioMngHelper subVoiceSystem() { + audioManager.adjustStreamVolume(NOW_AUDIO_TYPE,AudioManager.ADJUST_LOWER,NOW_FLAG); + return this; + } + + /** + * 调整音量,自定义 + * @param num 0-100 + * @return 改完后的音量值 + */ + public int setVoice100(int num) { + int a = (int) Math.ceil((num)*getSystemMaxVolume()*0.01); + a = a<=0 ? 0 : a; + a = a>=100 ? 100 : a; + audioManager.setStreamVolume(NOW_AUDIO_TYPE,a,0); + return get100CurrentVolume(); + } + + /** + * 步进加,步进值可修改 + * 0——100 + * @return 改完后的音量值 + */ + public int addVoice100() { + int a = (int) Math.ceil((VOICE_STEP_100 + get100CurrentVolume())*getSystemMaxVolume()*0.01); + a = a<=0 ? 0 : a; + a = a>=100 ? 100 : a; + audioManager.setStreamVolume(NOW_AUDIO_TYPE,a,NOW_FLAG); + return get100CurrentVolume(); + } + + /** + * 步进减,步进值可修改 + * 0——100 + * @return 改完后的音量值 + */ + public int subVoice100() { + int a = (int) Math.floor((get100CurrentVolume() - VOICE_STEP_100)*getSystemMaxVolume()*0.01); + a = a<=0 ? 0 : a; + a = a>=100 ? 100 : a; + audioManager.setStreamVolume(NOW_AUDIO_TYPE,a,NOW_FLAG); + return get100CurrentVolume(); + } +} \ No newline at end of file diff --git a/app/src/main/java/xyz/fycz/myreader/widget/page/BookChapterBean.java b/app/src/main/java/xyz/fycz/myreader/widget/page/BookChapterBean.java new file mode 100644 index 0000000..239dd5c --- /dev/null +++ b/app/src/main/java/xyz/fycz/myreader/widget/page/BookChapterBean.java @@ -0,0 +1,56 @@ +package xyz.fycz.myreader.widget.page; + + +public class BookChapterBean { + + //章节所属的小说(网络) + String bookId; + //章节名 + String title; + + //章节内容在文章中的起始位置(本地) + long start; + //章节内容在文章中的终止位置(本地) + long end; + + public String getBookId() { + return bookId; + } + + public void setBookId(String id) { + this.bookId = id; + } + + public String getTitle() { + return title; + } + + public void setTitle(String title) { + this.title = title; + } + + public long getStart() { + return start; + } + + public void setStart(long start) { + this.start = start; + } + + public long getEnd() { + return end; + } + + public void setEnd(long end) { + this.end = end; + } + + @Override + public String toString() { + return "BookChapterBean{" + + "title='" + title + '\'' + + ", start=" + start + + ", end=" + end + + '}'; + } +} diff --git a/app/src/main/res/drawable/ic_exit.xml b/app/src/main/res/drawable/ic_exit.xml new file mode 100644 index 0000000..d94b81e --- /dev/null +++ b/app/src/main/res/drawable/ic_exit.xml @@ -0,0 +1,12 @@ + + + + diff --git a/app/src/main/res/drawable/ic_home.xml b/app/src/main/res/drawable/ic_home.xml new file mode 100644 index 0000000..0520e3a --- /dev/null +++ b/app/src/main/res/drawable/ic_home.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_last.xml b/app/src/main/res/drawable/ic_last.xml new file mode 100644 index 0000000..905a856 --- /dev/null +++ b/app/src/main/res/drawable/ic_last.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_listen_book.xml b/app/src/main/res/drawable/ic_listen_book.xml new file mode 100644 index 0000000..8663f4a --- /dev/null +++ b/app/src/main/res/drawable/ic_listen_book.xml @@ -0,0 +1,12 @@ + + + + diff --git a/app/src/main/res/drawable/ic_next.xml b/app/src/main/res/drawable/ic_next.xml new file mode 100644 index 0000000..ccccc29 --- /dev/null +++ b/app/src/main/res/drawable/ic_next.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_pause_24dp.xml b/app/src/main/res/drawable/ic_pause_24dp.xml new file mode 100644 index 0000000..8356ff5 --- /dev/null +++ b/app/src/main/res/drawable/ic_pause_24dp.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_play.xml b/app/src/main/res/drawable/ic_play.xml new file mode 100644 index 0000000..42326cd --- /dev/null +++ b/app/src/main/res/drawable/ic_play.xml @@ -0,0 +1,12 @@ + + + + diff --git a/app/src/main/res/drawable/ic_play_24dp.xml b/app/src/main/res/drawable/ic_play_24dp.xml new file mode 100644 index 0000000..81a8f74 --- /dev/null +++ b/app/src/main/res/drawable/ic_play_24dp.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_stop.xml b/app/src/main/res/drawable/ic_stop.xml new file mode 100644 index 0000000..86e2a25 --- /dev/null +++ b/app/src/main/res/drawable/ic_stop.xml @@ -0,0 +1,12 @@ + + + + diff --git a/app/src/main/res/drawable/ic_timer.xml b/app/src/main/res/drawable/ic_timer.xml new file mode 100644 index 0000000..5a39ddf --- /dev/null +++ b/app/src/main/res/drawable/ic_timer.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_volume_up.xml b/app/src/main/res/drawable/ic_volume_up.xml new file mode 100644 index 0000000..5e5cb11 --- /dev/null +++ b/app/src/main/res/drawable/ic_volume_up.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/layout/diallog_audio_player.xml b/app/src/main/res/layout/diallog_audio_player.xml new file mode 100644 index 0000000..cc55279 --- /dev/null +++ b/app/src/main/res/layout/diallog_audio_player.xml @@ -0,0 +1,207 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/dialog_hour_minute_picker.xml b/app/src/main/res/layout/dialog_hour_minute_picker.xml new file mode 100644 index 0000000..238cf15 --- /dev/null +++ b/app/src/main/res/layout/dialog_hour_minute_picker.xml @@ -0,0 +1,45 @@ + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/mipmap-xhdpi/ic_avatar_fycz.jpg b/app/src/main/res/mipmap-xhdpi/ic_avatar_fycz.jpg new file mode 100644 index 0000000..d8233e8 Binary files /dev/null and b/app/src/main/res/mipmap-xhdpi/ic_avatar_fycz.jpg differ diff --git a/app/src/main/res/mipmap-xhdpi/ic_read.png b/app/src/main/res/mipmap-xhdpi/ic_read.png new file mode 100644 index 0000000..e74c6ee Binary files /dev/null and b/app/src/main/res/mipmap-xhdpi/ic_read.png differ diff --git a/app/src/main/res/raw/silent_sound.mp3 b/app/src/main/res/raw/silent_sound.mp3 new file mode 100644 index 0000000..ce236a2 Binary files /dev/null and b/app/src/main/res/raw/silent_sound.mp3 differ diff --git a/release/output.json b/release/output.json new file mode 100644 index 0000000..809e66c --- /dev/null +++ b/release/output.json @@ -0,0 +1 @@ +[{"outputType":{"type":"APK"},"apkData":{"type":"MAIN","splits":[],"versionCode":157,"versionName":"1.20.111211","enabled":true,"outputFile":"风月读书v1.20.111211.apk","fullName":"release","baseName":"release","dirName":""},"path":"风月读书v1.20.111211.apk","properties":{}}] \ No newline at end of file diff --git a/release/风月读书v1.20.111211.apk b/release/风月读书v1.20.111211.apk new file mode 100644 index 0000000..ec65957 Binary files /dev/null and b/release/风月读书v1.20.111211.apk differ diff --git a/splash/default_cover.jpg b/splash/default_cover.jpg new file mode 100644 index 0000000..3515f68 Binary files /dev/null and b/splash/default_cover.jpg differ diff --git a/splash/ic_launcher.png b/splash/ic_launcher.png new file mode 100644 index 0000000..1c174be Binary files /dev/null and b/splash/ic_launcher.png differ diff --git a/splash/splash-new.jpg b/splash/splash-new.jpg new file mode 100644 index 0000000..1d1e403 Binary files /dev/null and b/splash/splash-new.jpg differ diff --git a/splash/splash-new.png b/splash/splash-new.png new file mode 100644 index 0000000..d2b5ea0 Binary files /dev/null and b/splash/splash-new.png differ diff --git a/splash/splash-感恩节.png b/splash/splash-感恩节.png new file mode 100644 index 0000000..90c0379 Binary files /dev/null and b/splash/splash-感恩节.png differ diff --git a/splash/splash-立冬.png b/splash/splash-立冬.png new file mode 100644 index 0000000..2ac3d08 Binary files /dev/null and b/splash/splash-立冬.png differ