修复语音朗读部分bug

pull/5/head
fengyuecanzhu 4 years ago
parent 850dc6c3df
commit bfd7e1c977
  1. 10
      .idea/markdown-navigator-enh.xml
  2. 62
      .idea/markdown-navigator.xml
  3. 37
      app/src/androidTest/java/xyz/fycz/myreader/ExampleInstrumentedTest.java
  4. 19
      app/src/androidTest/java/xyz/fycz/myreader/TestAudioPlay.java
  5. 17
      app/src/main/java/xyz/fycz/myreader/ui/dialog/AudioPlayerDialog.java
  6. 54
      app/src/main/java/xyz/fycz/myreader/util/SystemUtil.java
  7. 170
      app/src/main/java/xyz/fycz/myreader/util/utils/AudioMngHelper.java
  8. 56
      app/src/main/java/xyz/fycz/myreader/widget/page/BookChapterBean.java
  9. 12
      app/src/main/res/drawable/ic_exit.xml
  10. 9
      app/src/main/res/drawable/ic_home.xml
  11. 9
      app/src/main/res/drawable/ic_last.xml
  12. 12
      app/src/main/res/drawable/ic_listen_book.xml
  13. 9
      app/src/main/res/drawable/ic_next.xml
  14. 9
      app/src/main/res/drawable/ic_pause_24dp.xml
  15. 12
      app/src/main/res/drawable/ic_play.xml
  16. 9
      app/src/main/res/drawable/ic_play_24dp.xml
  17. 12
      app/src/main/res/drawable/ic_stop.xml
  18. 9
      app/src/main/res/drawable/ic_timer.xml
  19. 9
      app/src/main/res/drawable/ic_volume_up.xml
  20. 207
      app/src/main/res/layout/diallog_audio_player.xml
  21. 45
      app/src/main/res/layout/dialog_hour_minute_picker.xml
  22. BIN
      app/src/main/res/mipmap-xhdpi/ic_avatar_fycz.jpg
  23. BIN
      app/src/main/res/mipmap-xhdpi/ic_read.png
  24. BIN
      app/src/main/res/raw/silent_sound.mp3
  25. 1
      release/output.json
  26. BIN
      release/风月读书v1.20.111211.apk
  27. BIN
      splash/default_cover.jpg
  28. BIN
      splash/ic_launcher.png
  29. BIN
      splash/splash-new.jpg
  30. BIN
      splash/splash-new.png
  31. BIN
      splash/splash-感恩节.png
  32. BIN
      splash/splash-立冬.png

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="MarkdownEnhProjectSettings">
<AnnotatorSettings targetHasSpaces="true" linkCaseMismatch="true" wikiCaseMismatch="true" wikiLinkHasDashes="true" notUnderWikiHome="true" targetNotWikiPageExt="true" notUnderSourceWikiHome="true" targetNameHasAnchor="true" targetPathHasAnchor="true" wikiLinkHasSlash="true" wikiLinkHasSubdir="true" wikiLinkHasOnlyAnchor="true" linkTargetsWikiHasExt="true" linkTargetsWikiHasBadExt="true" notUnderSameRepo="true" targetNotUnderVcs="false" linkNeedsExt="true" linkHasBadExt="true" linkTargetNeedsExt="true" linkTargetHasBadExt="true" wikiLinkNotInWiki="true" imageTargetNotInRaw="true" repoRelativeAcrossVcsRoots="true" multipleWikiTargetsMatch="true" unresolvedLinkReference="true" linkIsIgnored="true" anchorIsIgnored="true" anchorIsUnresolved="true" anchorLineReferenceIsUnresolved="true" anchorLineReferenceFormat="true" anchorHasDuplicates="true" abbreviationDuplicates="true" abbreviationNotUsed="true" attributeIdDuplicateDefinition="true" attributeIdNotUsed="true" footnoteDuplicateDefinition="true" footnoteUnresolved="true" footnoteDuplicates="true" footnoteNotUsed="true" macroDuplicateDefinition="true" macroUnresolved="true" macroDuplicates="true" macroNotUsed="true" referenceDuplicateDefinition="true" referenceUnresolved="true" referenceDuplicates="true" referenceNotUsed="true" referenceUnresolvedNumericId="true" enumRefDuplicateDefinition="true" enumRefUnresolved="true" enumRefDuplicates="true" enumRefNotUsed="true" enumRefLinkUnresolved="true" enumRefLinkDuplicates="true" simTocUpdateNeeded="true" simTocTitleSpaceNeeded="true" />
<HtmlExportSettings updateOnSave="false" parentDir="" targetDir="" cssDir="css" scriptDir="js" plainHtml="false" imageDir="" copyLinkedImages="false" imagePathType="0" targetPathType="2" targetExt="" useTargetExt="false" noCssNoScripts="false" useElementStyleAttribute="false" linkToExportedHtml="true" exportOnSettingsChange="true" regenerateOnProjectOpen="false" linkFormatType="HTTP_ABSOLUTE" />
<LinkMapSettings>
<textMaps />
</LinkMapSettings>
</component>
</project>

@ -0,0 +1,62 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="MarkdownProjectSettings">
<PreviewSettings splitEditorLayout="SPLIT" splitEditorPreview="PREVIEW" useGrayscaleRendering="false" zoomFactor="1.0" maxImageWidth="0" synchronizePreviewPosition="true" highlightPreviewType="LINE" highlightFadeOut="5" highlightOnTyping="true" synchronizeSourcePosition="true" verticallyAlignSourceAndPreviewSyncPosition="true" showSearchHighlightsInPreview="true" showSelectionInPreview="true" lastLayoutSetsDefault="false">
<PanelProvider>
<provider providerId="com.vladsch.md.nav.editor.swing.html.panel" providerName="Default - Swing" />
</PanelProvider>
</PreviewSettings>
<ParserSettings gitHubSyntaxChange="false" correctedInvalidSettings="false" emojiShortcuts="1" emojiImages="0">
<PegdownExtensions>
<option name="ATXHEADERSPACE" value="true" />
<option name="FENCED_CODE_BLOCKS" value="true" />
<option name="INTELLIJ_DUMMY_IDENTIFIER" value="true" />
<option name="RELAXEDHRULES" value="true" />
<option name="STRIKETHROUGH" value="true" />
<option name="TABLES" value="true" />
<option name="TASKLISTITEMS" value="true" />
</PegdownExtensions>
<ParserOptions>
<option name="COMMONMARK_LISTS" value="true" />
<option name="EMOJI_SHORTCUTS" value="true" />
<option name="GFM_TABLE_RENDERING" value="true" />
<option name="PRODUCTION_SPEC_PARSER" value="true" />
<option name="SIM_TOC_BLANK_LINE_SPACER" value="true" />
</ParserOptions>
</ParserSettings>
<HtmlSettings headerTopEnabled="false" headerBottomEnabled="false" bodyTopEnabled="false" bodyBottomEnabled="false" addPageHeader="false" addAnchorLinks="false" anchorLinksWrapText="false" imageUriSerials="false" addDocTypeHtml="true" noParaTags="false" defaultUrlTitle="false" migratedPlantUml="true" migratedAnchorLinks="true" plantUmlConversion="0">
<GeneratorProvider>
<provider providerId="com.vladsch.md.nav.editor.text.html.generator" providerName="Unmodified HTML Generator" />
</GeneratorProvider>
<headerTop />
<headerBottom />
<bodyTop />
<bodyBottom />
<fencedCodeConversions>
<option name="c4plantuml" value="NONE" />
<option name="ditaa" value="NONE" />
<option name="erd" value="NONE" />
<option name="graphviz" value="NONE" />
<option name="latex" value="KATEX" />
<option name="math" value="KATEX" />
<option name="mermaid" value="NONE" />
<option name="nomnoml" value="NONE" />
<option name="plantuml" value="NONE" />
<option name="puml" value="NONE" />
<option name="svgbob" value="NONE" />
<option name="umlet" value="NONE" />
<option name="vega" value="NONE" />
<option name="vegalite" value="NONE" />
<option name="wavedrom" value="NONE" />
</fencedCodeConversions>
</HtmlSettings>
<CssSettings previewScheme="UI_SCHEME" cssUri="" isCssUriEnabled="false" isCssUriSerial="true" isCssTextEnabled="false" isDynamicPageWidth="true">
<StylesheetProvider>
<provider providerId="com.vladsch.md.nav.editor.text.html.css" providerName="No Stylesheet" />
</StylesheetProvider>
<ScriptProviders />
<cssText />
<cssUriHistory />
</CssSettings>
</component>
</project>

@ -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 <a href="http://d.android.com/tools/testing">Testing documentation</a>
*/
@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("科幻电影是我们从小就爱看的电影题材,我们也都梦想过生活在那样的科幻世界里。科幻片,顾名思义即“科学幻想片”,是“以科学幻想为内容的故事片,其基本特点是从今天已知的科学原理和科学成就出发,对未来的世界或遥远的过去的情景作幻想式的描述。”");
}
}

@ -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("科幻电影是我们从小就爱看的电影题材,我们也都梦想过生活在那样的科幻世界里。科幻片,顾名思义即“科学幻想片”,是“以科学幻想为内容的故事片,其基本特点是从今天已知的科学原理和科学成就出发,对未来的世界或遥远的过去的情景作幻想式的描述。”");
}
}

@ -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;
@ -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);

@ -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) {
}
}
}
}

@ -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;
/**
* <pre>
* 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:
* </pre>
*/
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();
}
/**
* 步进加步进值可修改
* 0100
* @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();
}
/**
* 步进减步进值可修改
* 0100
* @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();
}
}

@ -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 +
'}';
}
}

@ -0,0 +1,12 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="1024"
android:viewportHeight="1024">
<path
android:pathData="M546.13,128a42.67,42.67 0,0 0,-42.67 42.67v341.33a42.67,42.67 0,0 0,85.33 0V170.67a42.67,42.67 0,0 0,-42.67 -42.67z"
android:fillColor="#666666"/>
<path
android:pathData="M631.47,180.48v87.89a298.67,298.67 0,1 1,-170.67 0V180.48a384,384 0,0 0,-298.67 374.19,388.69 388.69,0 0,0 372.91,384A384,384 0,0 0,631.47 180.48z"
android:fillColor="#666666"/>
</vector>

@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="1024"
android:viewportHeight="1024">
<path
android:fillColor="#FF000000"
android:pathData="M947.2,416L576,102.4c-35.2,-30.4 -88,-30.4 -123.2,0L76.8,416c-8,6.4 -12.8,14.4 -12.8,25.6 0,17.6 14.4,32 32,32 8,0 16,-3.2 20.8,-8L128,456v356.8c0,72 54.4,131.2 123.2,131.2h521.6C840,944 896,884.8 896,812.8L896,456l9.6,8c6.4,4.8 12.8,8 22.4,8 17.6,0 32,-14.4 32,-32 0,-8 -4.8,-17.6 -12.8,-24zM448,880L448,656c0,-17.6 14.4,-32 32,-32h64c17.6,0 32,14.4 32,32v224L448,880zM832,812.8c0,36.8 -27.2,67.2 -60.8,67.2L640,880L640,656c0,-52.8 -43.2,-96 -96,-96h-64c-52.8,0 -96,43.2 -96,96v224L252.8,880c-33.6,0 -60.8,-30.4 -60.8,-67.2L192,403.2L492.8,152c11.2,-9.6 28.8,-9.6 41.6,0L832,401.6v411.2z"/>
</vector>

@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="1024"
android:viewportHeight="1024">
<path
android:pathData="M364.3,465.6L687.95,218.59c38.42,-29.33 93.79,-1.93 93.79,46.4v494.03c0,48.33 -55.37,75.73 -93.79,46.4L364.3,558.4c-30.6,-23.36 -30.6,-69.44 0,-92.79zM238.95,780.8V451.68v-164.56c0,-19.63 -5.9,-60.48 17.06,-75.84 25.52,-17.07 59.75,1.21 59.75,31.92v493.68c0,19.63 5.92,60.47 -17.05,75.84 -25.53,17.07 -59.76,-1.21 -59.76,-31.92z"
android:fillColor="#ffffff"/>
</vector>

@ -0,0 +1,12 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="1024"
android:viewportHeight="1024">
<path
android:fillColor="#FFFFFF"
android:pathData="M660.8,430.4c1.6,0 4.8,0 6.4,-1.6 8,-3.2 11.2,-12.8 8,-20.8 -4.8,-11.2 -11.2,-22.4 -19.2,-33.6 -4.8,-6.4 -16,-8 -22.4,-3.2 -6.4,4.8 -8,16 -3.2,22.4 6.4,8 11.2,17.6 16,27.2 3.2,4.8 8,9.6 14.4,9.6zM606.4,332.8c-24,-12.8 -49.6,-19.2 -75.2,-19.2 -36.8,0 -72,12.8 -99.2,35.2 -6.4,4.8 -8,16 -3.2,22.4 3.2,3.2 8,6.4 12.8,6.4 3.2,0 6.4,-1.6 9.6,-3.2 40,-32 96,-36.8 140.8,-12.8 8,4.8 17.6,1.6 22.4,-6.4 1.6,-9.6 -1.6,-19.2 -8,-22.4z"/>
<path
android:fillColor="#FFFFFF"
android:pathData="M785.6,510.4v-44.8c0,-145.6 -118.4,-264 -264,-264S257.6,320 257.6,465.6v44.8c-48,14.4 -80,57.6 -80,107.2v80c0,62.4 49.6,112 112,112s112,-49.6 112,-112v-80c0,-49.6 -32,-92.8 -80,-107.2v-44.8c0,-110.4 89.6,-200 200,-200s200,89.6 200,200v44.8c-48,14.4 -80,57.6 -80,107.2v80c0,62.4 49.6,112 112,112s112,-49.6 112,-112v-80c0,-49.6 -32,-92.8 -80,-107.2zM337.6,617.6v80c0,27.2 -20.8,48 -48,48s-48,-20.8 -48,-48v-80c0,-27.2 20.8,-48 48,-48s48,20.8 48,48zM801.6,697.6c0,27.2 -20.8,48 -48,48s-48,-20.8 -48,-48v-80c0,-27.2 20.8,-48 48,-48s48,20.8 48,48v80z"/>
</vector>

@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="1024"
android:viewportHeight="1024">
<path
android:pathData="M655.71,465.6L332.05,218.59c-38.41,-29.33 -93.79,-1.93 -93.79,46.4v494.03c0,48.33 55.38,75.73 93.79,46.4l323.65,-247.01c30.6,-23.36 30.6,-69.44 0,-92.79zM781.06,780.8V451.68v-164.56c0,-19.63 5.9,-60.48 -17.06,-75.84 -25.52,-17.07 -59.75,1.21 -59.75,31.92v493.68c0,19.63 -5.92,60.47 17.05,75.84 25.53,17.07 59.76,-1.21 59.76,-31.92z"
android:fillColor="#ffffff"/>
</vector>

@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path
android:fillColor="#FFFFFFFF"
android:pathData="M6,19h4L10,5L6,5v14zM14,5v14h4L18,5h-4z"/>
</vector>

@ -0,0 +1,12 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="1024"
android:viewportHeight="1024">
<path
android:pathData="M772.7,217.7a32.2,32.1 0,1 0,64.4 0,32.2 32.1,0 1,0 -64.4,0zM415.8,679.9c5.9,0 11.5,-1.6 16.2,-4.5l231.1,-134.6c10.9,-5.2 18.5,-16.3 18.5,-29.2 0,-11.9 -6.4,-22.3 -16,-27.8L439.7,352.2c-5.8,-6.7 -14.4,-10.9 -23.9,-10.9 -17.6,0 -31.8,14.4 -31.8,32.1 0,0.6 0,1.2 0.1,1.8l-0.4,0.2 0.5,269c-0.1,1.1 -0.2,2.2 -0.2,3.4 0,17.7 14.3,32.1 31.8,32.1z"
android:fillColor="#ffffff"/>
<path
android:pathData="M909.8,306.6c-5.4,-10.5 -16.3,-17.8 -28.9,-17.8 -17.8,0 -32.2,14.4 -32.2,32.1 0,6 1.7,11.7 4.6,16.5l-0.1,0.1c26.9,52.4 42.1,111.8 42.1,174.7 0,211.6 -171.6,383.2 -383.2,383.2S128.8,723.8 128.8,512.2 300.4,129.1 512,129.1c62.5,0 121.5,15 173.6,41.5l0.2,-0.4c4.6,2.6 10,4.1 15.7,4.1 17.8,0 32.2,-14.4 32.2,-32.1 0,-13.1 -7.9,-24.4 -19.3,-29.4C653.6,81.9 584.9,64.5 512,64.5 264.7,64.5 64.3,265 64.3,512.2S264.7,959.9 512,959.9s447.7,-200.4 447.7,-447.7c0,-74.1 -18,-144 -49.9,-205.6z"
android:fillColor="#ffffff"/>
</vector>

@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path
android:fillColor="#FFFFFFFF"
android:pathData="M8,5v14l11,-7z"/>
</vector>

@ -0,0 +1,12 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="1024"
android:viewportHeight="1024">
<path
android:fillColor="#FFFFFF"
android:pathData="M416,720c-17.67,0 -32,-14.33 -32,-32V336c0,-17.67 14.33,-32 32,-32s32,14.33 32,32v352c0,17.67 -14.33,32 -32,32zM608,720c-17.67,0 -32,-14.33 -32,-32V336c0,-17.67 14.33,-32 32,-32s32,14.33 32,32v352c0,17.67 -14.33,32 -32,32z"/>
<path
android:fillColor="#FFFFFF"
android:pathData="M512,128c211.74,0 384,172.26 384,384S723.74,896 512,896 128,723.74 128,512s172.26,-384 384,-384m0,-64C264.58,64 64,264.58 64,512s200.58,448 448,448 448,-200.58 448,-448S759.42,64 512,64z"/>
</vector>

@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="1024"
android:viewportHeight="1024">
<path
android:pathData="M788.86,513.73a19.84,19.84 0,0 1,19.97 19.84v39.04a162.55,162.55 0,0 1,24.32 13.89l34.11,-19.52a20.1,20.1 0,0 1,27.33 7.3l44.99,77.25a19.71,19.71 0,0 1,-7.3 27.07l-34.11,19.58a147.65,147.65 0,0 1,0 27.84l34.11,19.58a19.84,19.84 0,0 1,7.3 27.07l-44.99,77.25a20.1,20.1 0,0 1,-27.33 7.3l-34.11,-19.52a154.62,154.62 0,0 1,-24.32 13.82v39.1a19.84,19.84 0,0 1,-19.97 19.84h-90.05a19.84,19.84 0,0 1,-19.97 -19.84v-39.04a156.61,156.61 0,0 1,-24.32 -13.89l-34.11,19.52a20.1,20.1 0,0 1,-27.26 -7.3l-45.06,-77.25a19.78,19.78 0,0 1,7.36 -27.07l34.05,-19.58a292.22,292.22 0,0 1,0 -27.84l-34.05,-19.58a19.78,19.78 0,0 1,-7.36 -27.07l44.99,-77.25a20.1,20.1 0,0 1,27.33 -7.3l34.11,19.52a156.81,156.81 0,0 1,24.32 -13.82v-39.1c0,-11.01 8.96,-19.84 19.97,-19.84h90.05zM468.29,158.91c172.8,0 319.23,125.31 347.26,293.95a32,32 0,1 1,-63.17 10.5,288.06 288.06,0 0,0 -572.1,47.55A288,288 0,0 0,498.56 797.44a32,32 0,1 1,6.66 63.62,350.53 350.53,0 0,1 -260.8,-78.46l-79.62,80.32a32,32 0,0 1,-49.15 -40.64l3.71,-4.48 79.55,-80.26a352,352 0,0 1,269.44 -578.56zM767.17,570.3h-45.5L721.66,600c0,7.68 -5.25,13.44 -12.16,17.02 -11.52,6.02 -21.12,11.78 -33.02,18.88 -6.59,3.97 -14.27,5.76 -20.99,1.92l-25.86,-14.78 -22.78,39.04 25.92,14.91c6.66,3.84 8.77,12.61 8.77,18.88v37.95c0,6.27 -2.11,15.1 -8.77,18.94l-25.92,14.85 22.78,39.04 25.86,-14.78c6.72,-3.84 14.27,-1.79 20.99,1.92 8.7,4.86 24,14.59 33.02,18.88 7.04,3.33 12.16,9.41 12.16,17.09v29.7h45.5L767.17,829.76c0,-7.68 5.31,-13.44 12.16,-17.02 11.2,-6.02 21.25,-11.46 33.02,-18.94 6.53,-4.1 14.27,-5.76 20.99,-1.92L859.2,806.72l22.78,-39.1 -25.86,-14.85c-6.59,-3.84 -8.77,-9.98 -8.83,-16.26v-40.58c0,-6.27 2.18,-15.17 8.83,-18.94l25.92,-14.85 -22.78,-39.1 -25.86,14.85c-6.66,3.84 -14.53,2.11 -20.99,-1.92a418.69,418.69 0,0 0,-33.02 -18.94c-6.91,-3.52 -12.16,-9.34 -12.16,-17.02v-29.76zM744.9,644.16a70.4,70.4 0,1 1,0 140.8,70.4 70.4,0 0,1 0,-140.8zM744.38,683.46a32,32 0,1 0,0 64.06,32 32,0 0,0 0,-64zM469.76,304.32a32,32 0,0 1,31.55 26.24l0.51,5.76v161.34l57.79,37.63a32,32 0,0 1,12.1 39.17l-2.75,5.12a32,32 0,0 1,-39.17 12.1l-5.12,-2.75 -72.32,-47.04a32,32 0,0 1,-14.08 -21.5l-0.45,-5.31L437.82,336.32a32,32 0,0 1,32 -32zM211.78,135.68a32,32 0,0 1,-0.64 45.25l-77.95,75.71a32,32 0,1 1,-44.67 -45.89l77.95,-75.71a32,32 0,0 1,45.25 0.64zM726.46,135.68a32,32 0,0 1,45.25 -0.64l77.95,75.78a32,32 0,0 1,-44.61 45.89l-78.02,-75.78a32,32 0,0 1,-0.64 -45.25z"
android:fillColor="#ffffff"/>
</vector>

@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path
android:fillColor="#FFFFFFFF"
android:pathData="M3,9v6h4l5,5L12,4L7,9L3,9zM16.5,12c0,-1.77 -1.02,-3.29 -2.5,-4.03v8.05c1.48,-0.73 2.5,-2.25 2.5,-4.02zM14,3.23v2.06c2.89,0.86 5,3.54 5,6.71s-2.11,5.85 -5,6.71v2.06c4.01,-0.91 7,-4.49 7,-8.77s-2.99,-7.86 -7,-8.77z"/>
</vector>

@ -0,0 +1,207 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:orientation="vertical"
android:background="@color/read_menu_bg"
android:gravity="bottom"
android:layout_width="match_parent"
android:layout_height="match_parent">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="5dp"
android:paddingBottom="5dp"
>
<TextView
android:id="@+id/tv_volume"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="音量"
android:textSize="@dimen/text_normal_size"
android:layout_alignParentStart="true"
android:textColor="@color/read_menu_text"
android:layout_centerVertical="true"
/>
<SeekBar
android:id="@+id/sb_volume_progress"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="2dp"
android:layout_marginLeft="5dp"
android:layout_marginRight="5dp"
android:progress="50"
android:max="100"
android:layout_weight="1"
android:maxHeight="1dp"
android:minHeight="1dp"
android:progressDrawable="@drawable/seekbar_bg"
android:thumb="@mipmap/thumb"
android:layout_toEndOf="@+id/tv_volume"
android:layout_toStartOf="@+id/iv_go_tts_setting"
android:layout_centerInParent="true"/>
<androidx.appcompat.widget.AppCompatImageView
android:id="@+id/iv_go_tts_setting"
android:padding="4dp"
android:layout_width="40dp"
android:layout_height="40dp"
app:srcCompat="@drawable/ic_settings"
app:tint="@color/read_menu_text"
android:layout_alignParentEnd="true"
android:layout_centerVertical="true"
/>
</RelativeLayout>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="5dp"
android:paddingBottom="5dp"
>
<TextView
android:id="@+id/tv_pitch"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="音调"
android:textSize="@dimen/text_normal_size"
android:layout_alignParentStart="true"
android:textColor="@color/read_menu_text"
android:layout_centerVertical="true"
/>
<SeekBar
android:id="@+id/sb_pitch_progress"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="2dp"
android:layout_marginLeft="5dp"
android:layout_marginRight="5dp"
android:progress="50"
android:max="50"
android:maxHeight="1dp"
android:minHeight="1dp"
android:progressDrawable="@drawable/seekbar_bg"
android:thumb="@mipmap/thumb"
android:layout_toEndOf="@+id/tv_pitch"
android:layout_toStartOf="@+id/iv_read_timer"
android:layout_centerInParent="true"/>
<androidx.appcompat.widget.AppCompatImageView
android:id="@+id/iv_read_timer"
android:padding="7dp"
android:layout_width="40dp"
android:layout_height="40dp"
app:srcCompat="@drawable/ic_timer"
app:tint="@color/read_menu_text"
android:layout_alignParentEnd="true"
android:layout_centerVertical="true"
/>
</RelativeLayout>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="5dp"
android:paddingBottom="5dp"
>
<TextView
android:id="@+id/tv_speech_rate"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="语速"
android:textSize="@dimen/text_normal_size"
android:layout_alignParentStart="true"
android:textColor="@color/read_menu_text"
android:layout_centerVertical="true"
/>
<SeekBar
android:id="@+id/sb_speech_rate_progress"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="2dp"
android:layout_marginLeft="5dp"
android:layout_marginRight="5dp"
android:progress="50"
android:max="100"
android:layout_weight="1"
android:maxHeight="1dp"
android:minHeight="1dp"
android:progressDrawable="@drawable/seekbar_bg"
android:thumb="@mipmap/thumb"
android:layout_toEndOf="@+id/tv_speech_rate"
android:layout_toStartOf="@+id/iv_read_home"
android:layout_centerInParent="true"/>
<androidx.appcompat.widget.AppCompatImageView
android:id="@+id/iv_read_home"
android:padding="8dp"
android:layout_width="40dp"
android:layout_height="40dp"
app:srcCompat="@drawable/ic_home"
app:tint="@color/read_menu_text"
android:layout_alignParentEnd="true"
android:layout_centerVertical="true"
/>
</RelativeLayout>
<RelativeLayout
android:paddingTop="5dp"
android:paddingBottom="5dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_vertical"
>
<TextView
android:id="@+id/iv_reset_setting"
android:layout_width="40dp"
android:layout_height="40dp"
android:text="重置"
android:gravity="center_vertical"
android:layout_centerVertical="true"
android:textColor="@color/read_menu_text"
android:textSize="@dimen/text_normal_size"/>
<androidx.appcompat.widget.AppCompatImageView
android:id="@+id/iv_read_last_paragraph"
android:padding="1dp"
android:layout_marginEnd="15dp"
android:layout_width="40dp"
android:layout_height="40dp"
app:srcCompat="@drawable/ic_last"
android:layout_toStartOf="@+id/iv_read_play_stop"
app:tint="@color/read_menu_text"
android:layout_centerVertical="true"
/>
<androidx.appcompat.widget.AppCompatImageView
android:id="@+id/iv_read_play_stop"
android:layout_width="45dp"
android:layout_height="45dp"
app:srcCompat="@drawable/ic_stop"
app:tint="@color/read_menu_text"
android:layout_centerInParent="true"
/>
<androidx.appcompat.widget.AppCompatImageView
android:id="@+id/iv_read_next_paragraph"
android:layout_marginStart="15dp"
android:padding="1dp"
android:layout_width="40dp"
android:layout_height="40dp"
app:srcCompat="@drawable/ic_next"
app:tint="@color/read_menu_text"
android:layout_toEndOf="@+id/iv_read_play_stop"
android:layout_centerVertical="true"
/>
<androidx.appcompat.widget.AppCompatImageView
android:id="@+id/iv_read_stop"
android:padding="6dp"
android:layout_marginEnd="1dp"
android:layout_width="40dp"
android:layout_height="40dp"
app:srcCompat="@drawable/ic_exit"
android:layout_alignParentEnd="true"
android:layout_centerVertical="true"
app:tint="@color/read_menu_text" />
</RelativeLayout>
</LinearLayout>

@ -0,0 +1,45 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:gravity="center"
android:orientation="horizontal"
tools:ignore="UselessParent">
<NumberPicker
android:id="@+id/hour_picker"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
</NumberPicker>
<TextView
android:layout_marginStart="15dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="@dimen/text_normal_size"
android:textColor="@color/textPrimary"
android:text="时"/>
<NumberPicker
android:layout_marginStart="15dp"
android:id="@+id/minute_picker"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
</NumberPicker>
<TextView
android:layout_marginStart="15dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="@dimen/text_normal_size"
android:textColor="@color/textPrimary"
android:text="分"/>
</LinearLayout>
</LinearLayout>

Binary file not shown.

After

Width:  |  Height:  |  Size: 49 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.0 KiB

@ -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":{}}]

Binary file not shown.

After

Width:  |  Height:  |  Size: 63 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 48 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.6 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 MiB

Loading…
Cancel
Save