| @@ -0,0 +1 @@ | |||
| WebEBook | |||
| @@ -1,6 +1,6 @@ | |||
| <?xml version="1.0" encoding="UTF-8"?> | |||
| <project version="4"> | |||
| <component name="CompilerConfiguration"> | |||
| <bytecodeTargetLevel target="1.8" /> | |||
| <bytecodeTargetLevel target="11" /> | |||
| </component> | |||
| </project> | |||
| @@ -0,0 +1,17 @@ | |||
| <?xml version="1.0" encoding="UTF-8"?> | |||
| <project version="4"> | |||
| <component name="deploymentTargetDropDown"> | |||
| <targetSelectedWithDropDown> | |||
| <Target> | |||
| <type value="QUICK_BOOT_TARGET" /> | |||
| <deviceKey> | |||
| <Key> | |||
| <type value="VIRTUAL_DEVICE_PATH" /> | |||
| <value value="C:\Users\Administrator\.android\avd\EScreen_API_27.avd" /> | |||
| </Key> | |||
| </deviceKey> | |||
| </Target> | |||
| </targetSelectedWithDropDown> | |||
| <timeTargetWasSelectedWithDropDown value="2022-04-20T04:41:22.102557200Z" /> | |||
| </component> | |||
| </project> | |||
| @@ -5,7 +5,7 @@ | |||
| <option name="linkedExternalProjectsSettings"> | |||
| <GradleProjectSettings> | |||
| <option name="delegatedBuild" value="true" /> | |||
| <option name="testRunner" value="PLATFORM" /> | |||
| <option name="testRunner" value="GRADLE" /> | |||
| <option name="disableWrapperSourceDistributionNotification" value="true" /> | |||
| <option name="distributionType" value="DEFAULT_WRAPPED" /> | |||
| <option name="externalProjectPath" value="$PROJECT_DIR$" /> | |||
| @@ -16,7 +16,6 @@ | |||
| </set> | |||
| </option> | |||
| <option name="resolveModulePerSourceSet" value="false" /> | |||
| <option name="useQualifiedModuleNames" value="true" /> | |||
| </GradleProjectSettings> | |||
| </option> | |||
| </component> | |||
| @@ -1,6 +1,16 @@ | |||
| <?xml version="1.0" encoding="UTF-8"?> | |||
| <project version="4"> | |||
| <component name="ProjectRootManager" version="2" languageLevel="JDK_1_8" default="true" project-jdk-name="1.8" project-jdk-type="JavaSDK"> | |||
| <component name="DesignSurface"> | |||
| <option name="filePathToZoomLevelMap"> | |||
| <map> | |||
| <entry key="..\:/work/escreen/app/src/main/res/layout/activity_book.xml" value="0.37135416666666665" /> | |||
| <entry key="..\:/work/escreen/app/src/main/res/layout/activity_main.xml" value="0.37135416666666665" /> | |||
| <entry key="..\:/work/escreen/app/src/main/res/layout/activity_main1.xml" value="0.37135416666666665" /> | |||
| <entry key="..\:/work/escreen/app/src/main/res/layout/activity_note.xml" value="0.37135416666666665" /> | |||
| </map> | |||
| </option> | |||
| </component> | |||
| <component name="ProjectRootManager" version="2" languageLevel="JDK_11" default="true" project-jdk-name="11" project-jdk-type="JavaSDK"> | |||
| <output url="file://$PROJECT_DIR$/build/classes" /> | |||
| </component> | |||
| <component name="ProjectType"> | |||
| @@ -1,12 +0,0 @@ | |||
| <?xml version="1.0" encoding="UTF-8"?> | |||
| <project version="4"> | |||
| <component name="RunConfigurationProducerService"> | |||
| <option name="ignoredProducers"> | |||
| <set> | |||
| <option value="org.jetbrains.plugins.gradle.execution.test.runner.AllInPackageGradleConfigurationProducer" /> | |||
| <option value="org.jetbrains.plugins.gradle.execution.test.runner.TestClassGradleConfigurationProducer" /> | |||
| <option value="org.jetbrains.plugins.gradle.execution.test.runner.TestMethodGradleConfigurationProducer" /> | |||
| </set> | |||
| </option> | |||
| </component> | |||
| </project> | |||
| @@ -6,13 +6,13 @@ apply plugin: 'kotlin-android-extensions' | |||
| //apply from: 'https://raw.githubusercontent.com/apache/incubator-weex/release/0.28/android/sdk/buildSrc/download_jsc.gradle' | |||
| apply plugin: 'org.greenrobot.greendao' | |||
| //apply plugin: 'org.greenrobot.greendao' | |||
| android { | |||
| compileSdkVersion 30 | |||
| buildToolsVersion "30.0.3" | |||
| defaultConfig { | |||
| applicationId "com.yzx.webebook" | |||
| applicationId "com.yzx.escreen" | |||
| // minSdkVersion 26 | |||
| minSdkVersion 21 | |||
| targetSdkVersion 25 | |||
| @@ -20,9 +20,9 @@ android { | |||
| versionName "2.0.1" | |||
| testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" | |||
| ndk { | |||
| abiFilters "armeabi-v7a", "arm64-v8a", "x86" | |||
| } | |||
| // ndk { | |||
| // abiFilters "armeabi-v7a", "arm64-v8a", "x86" | |||
| // } | |||
| } | |||
| signingConfigs { | |||
| yzx { | |||
| @@ -115,11 +115,11 @@ android { | |||
| } | |||
| greendao{ | |||
| schemaVersion 4 | |||
| daoPackage 'com.yzx.webebook.model.gen' | |||
| targetGenDir 'src/main/java' | |||
| } | |||
| //greendao{ | |||
| // schemaVersion 4 | |||
| // daoPackage 'com.yzx.webebook.model.gen' | |||
| // targetGenDir 'src/main/java' | |||
| //} | |||
| repositories { | |||
| maven { | |||
| @@ -144,7 +144,6 @@ dependencies { | |||
| testImplementation 'junit:junit:4.12' | |||
| androidTestImplementation 'androidx.test.ext:junit:1.1.0' | |||
| androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.1' | |||
| implementation files('libs/wenote.jar') | |||
| implementation 'com.github.bumptech.glide:glide:4.11.0' | |||
| implementation 'com.lzy.net:okgo:3.0.4' | |||
| implementation 'com.blankj:utilcodex:1.30.5' | |||
| @@ -157,17 +156,19 @@ dependencies { | |||
| implementation 'com.github.thomhurst:RoundImageView:1.0.2' | |||
| implementation 'com.github.CymChad:BaseRecyclerViewAdapterHelper:3.0.4' | |||
| implementation 'org.apache.weex:sdk:0.28.0' | |||
| implementation 'com.alibaba:fastjson:1.1.46.android' | |||
| // implementation 'org.apache.weex:sdk:0.28.0' | |||
| // implementation 'com.alibaba:fastjson:1.1.46.android' | |||
| //ORM Database | |||
| implementation deps.greendao.runtime | |||
| testImplementation deps.testing.junit | |||
| // implementation deps.greendao.runtime | |||
| // testImplementation deps.testing.junit | |||
| //RxJava | |||
| implementation deps.reactivex.rxandroid | |||
| implementation deps.reactivex.rxjava2 | |||
| // implementation deps.reactivex.rxandroid | |||
| // implementation deps.reactivex.rxjava2 | |||
| implementation 'es.voghdev.pdfviewpager:library:1.1.2' | |||
| implementation 'io.github.h07000223:flycoTabLayout:3.0.0' | |||
| } | |||
| @@ -65,10 +65,10 @@ | |||
| } | |||
| #bean | |||
| -keep class com.yzx.webebook.model.** { *; } | |||
| -keep class com.yzx.webebook.model.Note { *; } | |||
| -keep class com.yzx.webebook.model.UploadBean { *; } | |||
| -keep class com.yzx.webebook.model.UploadContent { *; } | |||
| -keep class com.yzx.escreen.model.** { *; } | |||
| -keep class com.yzx.escreen.model.Note { *; } | |||
| -keep class com.yzx.escreen.model.UploadBean { *; } | |||
| -keep class com.yzx.escreen.model.UploadContent { *; } | |||
| -keep class **$Properties {*;} | |||
| @@ -1,4 +1,4 @@ | |||
| package com.yzx.webebook | |||
| package com.yzx.escreen | |||
| import androidx.test.platform.app.InstrumentationRegistry | |||
| import androidx.test.ext.junit.runners.AndroidJUnit4 | |||
| @@ -1,7 +1,7 @@ | |||
| <?xml version="1.0" encoding="utf-8"?> | |||
| <manifest xmlns:android="http://schemas.android.com/apk/res/android" | |||
| xmlns:tools="http://schemas.android.com/tools" | |||
| package="com.yzx.webebook"> | |||
| package="com.yzx.escreen"> | |||
| <uses-permission android:name="android.permission.INTERNET" /> | |||
| <uses-permission android:name="android.permission.READ_PHONE_STATE" /> | |||
| @@ -17,7 +17,7 @@ | |||
| <uses-permission android:name="android.permission.WAKE_LOCK" /> | |||
| <application | |||
| android:name=".App" | |||
| android:name="com.yzx.escreen.App" | |||
| android:allowBackup="true" | |||
| android:icon="@mipmap/ic_launcher" | |||
| android:label="@string/app_name" | |||
| @@ -27,42 +27,32 @@ | |||
| android:supportsRtl="true" | |||
| android:theme="@style/AppTheme" | |||
| android:usesCleartextTraffic="true"> | |||
| <activity android:name=".activity.PDFViewActivity"></activity> | |||
| <activity android:name=".activity.ReadActivity" /> | |||
| <activity android:name=".activity.WeexTestActivity" /> | |||
| <activity android:name="com.yzx.escreen.activity.WeexTestActivity" /> | |||
| <activity | |||
| android:name=".activity.HomeActivity" | |||
| android:name="com.yzx.escreen.MainActivity" | |||
| android:configChanges="orientation|keyboard" | |||
| android:launchMode="singleTask" | |||
| android:screenOrientation="portrait"> | |||
| android:screenOrientation="landscape"> | |||
| <intent-filter> | |||
| <action android:name="android.intent.action.MAIN" /> | |||
| <category android:name="android.intent.category.HOME" /> | |||
| <category android:name="android.intent.category.DEFAULT" /> | |||
| <!-- <category android:name="android.intent.category.HOME" />--> | |||
| <!-- <category android:name="android.intent.category.DEFAULT" />--> | |||
| <category android:name="android.intent.category.LAUNCHER" /> | |||
| </intent-filter> | |||
| </activity> | |||
| <activity | |||
| android:name=".activity.NoteActivity" | |||
| android:configChanges="orientation|keyboard" | |||
| android:screenOrientation="portrait" /> | |||
| <activity | |||
| android:name=".activity.WebActivity" | |||
| android:configChanges="orientation|keyboard" | |||
| android:screenOrientation="portrait" /> | |||
| <activity | |||
| android:name=".MainActivity" | |||
| android:configChanges="orientation|keyboard" | |||
| android:launchMode="singleTask" | |||
| android:screenOrientation="portrait" /> | |||
| <activity | |||
| android:name=".activity.BookActivity" | |||
| android:name="com.yzx.escreen.activity.WebActivity" | |||
| android:configChanges="orientation|keyboard" | |||
| android:screenOrientation="portrait" /> | |||
| <!-- <activity--> | |||
| <!-- android:name="com.yzx.escreen.MainActivity"--> | |||
| <!-- android:configChanges="orientation|keyboard"--> | |||
| <!-- android:launchMode="singleTask"--> | |||
| <!-- android:screenOrientation="portrait" />--> | |||
| <provider | |||
| android:name=".utils.YzxFileProvider" | |||
| android:name="com.yzx.escreen.utils.YzxFileProvider" | |||
| android:authorities="${applicationId}.fileProvider" | |||
| android:exported="false" | |||
| android:grantUriPermissions="true" | |||
| @@ -0,0 +1,48 @@ | |||
| package com.yzx.escreen | |||
| import android.app.Application | |||
| import com.blankj.utilcode.util.Utils | |||
| import com.lzy.okgo.OkGo | |||
| import com.lzy.okgo.model.HttpHeaders | |||
| import com.umeng.analytics.MobclickAgent | |||
| import com.umeng.commonsdk.UMConfigure | |||
| import com.yzx.escreen.model.User | |||
| class App : Application() { | |||
| companion object { | |||
| var app: App? = null | |||
| fun getContext(): App { | |||
| return app ?: App() | |||
| } | |||
| } | |||
| override fun onCreate() { | |||
| super.onCreate() | |||
| app = this | |||
| val headers = HttpHeaders() | |||
| val user = User.getUser() | |||
| headers.put("phone",user.phone) | |||
| headers.put("token",user.token) | |||
| OkGo.getInstance() | |||
| .addCommonHeaders(headers) | |||
| .init(this) | |||
| Utils.init(this) | |||
| UMConfigure.init( | |||
| this, | |||
| "60334d01425ec25f10fbd5b4", | |||
| "ebook", | |||
| UMConfigure.DEVICE_TYPE_PHONE, | |||
| "" | |||
| ) | |||
| MobclickAgent.setPageCollectionMode(MobclickAgent.PageMode.AUTO) | |||
| } | |||
| } | |||
| @@ -0,0 +1,45 @@ | |||
| package com.yzx.escreen | |||
| import android.annotation.SuppressLint | |||
| import android.content.Intent | |||
| import com.flyco.tablayout.listener.CustomTabEntity | |||
| import com.yzx.escreen.activity.base.BaseActivity | |||
| import com.yzx.escreen.model.TabEntity | |||
| import com.yzx.escreen.presenter.base.BasePresenter | |||
| import kotlinx.android.synthetic.main.activity_main.* | |||
| /** | |||
| * Yun.Lei | |||
| * 2020年5月6日14:49:10 | |||
| */ | |||
| class MainActivity : BaseActivity<BasePresenter<*>>() { | |||
| override val inflateId: Int | |||
| get() = R.layout.activity_main | |||
| override fun initView() { | |||
| val tabData = arrayListOf<CustomTabEntity>() | |||
| tabData.add(TabEntity("首页",R.mipmap.home_select,R.mipmap.home_unselect)) | |||
| tabData.add(TabEntity("我的",R.mipmap.my_select,R.mipmap.my_unselect)) | |||
| tabLayout.setTabData(tabData) | |||
| } | |||
| override fun initData() { | |||
| } | |||
| override fun initPresenter(): BasePresenter<*>? { | |||
| return null | |||
| } | |||
| @SuppressLint("SetTextI18n") | |||
| override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { | |||
| super.onActivityResult(requestCode, resultCode, data) | |||
| } | |||
| } | |||
| @@ -1,4 +1,4 @@ | |||
| package com.yzx.webebook.activity | |||
| package com.yzx.escreen.activity | |||
| import android.Manifest | |||
| import android.annotation.SuppressLint | |||
| @@ -6,12 +6,9 @@ import android.app.AlertDialog | |||
| import android.app.Dialog | |||
| import android.content.Context | |||
| import android.content.DialogInterface | |||
| import android.content.IntentFilter | |||
| import android.net.ConnectivityManager | |||
| import android.util.Log | |||
| import android.view.View | |||
| import android.widget.TextView | |||
| import androidx.core.app.ActivityCompat | |||
| import androidx.core.widget.ContentLoadingProgressBar | |||
| import androidx.recyclerview.widget.GridLayoutManager | |||
| import com.allenliu.versionchecklib.v2.AllenVersionChecker | |||
| @@ -24,17 +21,17 @@ import com.google.gson.reflect.TypeToken | |||
| import com.lzy.okgo.OkGo | |||
| import com.lzy.okgo.callback.StringCallback | |||
| import com.lzy.okgo.model.Response | |||
| import com.yzx.webebook.MainActivity | |||
| import com.yzx.webebook.R | |||
| import com.yzx.webebook.activity.base.BaseActivity | |||
| import com.yzx.webebook.adapter.HomeAdapter | |||
| import com.yzx.webebook.config.Config | |||
| import com.yzx.webebook.model.BaseBean | |||
| import com.yzx.webebook.model.HomeItem | |||
| import com.yzx.webebook.model.User | |||
| import com.yzx.webebook.model.Version | |||
| import com.yzx.webebook.presenter.base.BasePresenter | |||
| import com.yzx.webebook.widget.BaseDialog | |||
| import com.yzx.escreen.MainActivity | |||
| import com.yzx.escreen.R | |||
| import com.yzx.escreen.activity.base.BaseActivity | |||
| import com.yzx.escreen.adapter.HomeAdapter | |||
| import com.yzx.escreen.config.Config | |||
| import com.yzx.escreen.model.BaseBean | |||
| import com.yzx.escreen.model.HomeItem | |||
| import com.yzx.escreen.model.User | |||
| import com.yzx.escreen.model.Version | |||
| import com.yzx.escreen.presenter.base.BasePresenter | |||
| import com.yzx.escreen.widget.BaseDialog | |||
| import kotlinx.android.synthetic.main.activity_home.* | |||
| import org.jetbrains.anko.find | |||
| import org.jetbrains.anko.startActivity | |||
| @@ -1,4 +1,4 @@ | |||
| package com.yzx.webebook.activity | |||
| package com.yzx.escreen.activity | |||
| import android.annotation.SuppressLint | |||
| import android.app.Activity | |||
| @@ -22,29 +22,24 @@ import com.allenliu.versionchecklib.v2.builder.UIData | |||
| import com.allenliu.versionchecklib.v2.callback.CustomDownloadingDialogListener | |||
| import com.blankj.utilcode.util.AppUtils | |||
| import com.blankj.utilcode.util.SPUtils | |||
| import com.blankj.utilcode.util.ToastUtils | |||
| import com.google.gson.Gson | |||
| import com.google.gson.reflect.TypeToken | |||
| import com.lzy.okgo.OkGo | |||
| import com.lzy.okgo.callback.StringCallback | |||
| import com.lzy.okgo.model.Response | |||
| import com.yzx.webebook.R | |||
| import com.yzx.webebook.activity.base.BaseActivity | |||
| import com.yzx.webebook.config.Config | |||
| import com.yzx.webebook.model.BaseBean | |||
| import com.yzx.webebook.model.User | |||
| import com.yzx.webebook.model.Version | |||
| import com.yzx.webebook.model.local.BookRepository | |||
| import com.yzx.webebook.presenter.ReadPresenter | |||
| import com.yzx.webebook.presenter.ReadView | |||
| import com.yzx.webebook.presenter.base.BasePresenter | |||
| import com.yzx.webebook.widget.BaseDialog | |||
| import com.yzx.escreen.R | |||
| import com.yzx.escreen.activity.base.BaseActivity | |||
| import com.yzx.escreen.config.Config | |||
| import com.yzx.escreen.model.BaseBean | |||
| import com.yzx.escreen.model.User | |||
| import com.yzx.escreen.model.Version | |||
| import com.yzx.escreen.presenter.base.BasePresenter | |||
| import com.yzx.escreen.widget.BaseDialog | |||
| import kotlinx.android.synthetic.main.activity_web.* | |||
| import org.jetbrains.anko.ctx | |||
| import org.jetbrains.anko.find | |||
| import org.jetbrains.anko.startActivity | |||
| import org.jetbrains.anko.toast | |||
| import org.json.JSONObject | |||
| import java.util.* | |||
| /** | |||
| @@ -346,22 +341,7 @@ class WebActivity : BaseActivity<BasePresenter<*>>() { | |||
| @SuppressLint("SetTextI18n") | |||
| override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { | |||
| super.onActivityResult(requestCode, resultCode, data) | |||
| if (requestCode == BookActivity.REQ_CODE && resultCode == Activity.RESULT_OK) { | |||
| val mKey = data?.getStringExtra("key") ?: "" | |||
| val mIdentity = data?.getStringExtra("identity") ?: "" | |||
| val obj = JSONObject() | |||
| obj.put("key", mKey) | |||
| obj.put("identity", mIdentity) | |||
| obj.put("name", data?.getStringExtra("name") ?: "") | |||
| obj.put("index", data?.getIntExtra("index", 0)) | |||
| obj.put("type", data?.getIntExtra("type", 1)) | |||
| evaluateJavascript("onImageUploadSuccess", obj.toString()) | |||
| } | |||
| if (requestCode == NoteActivity.REQ_CODE && resultCode == Activity.RESULT_OK) { | |||
| val json = data?.getStringExtra("note_info") ?: "" | |||
| evaluateJavascript("onImageUploadSuccess", json) | |||
| } | |||
| } | |||
| } | |||
| @@ -387,7 +367,7 @@ class YzxJavascriptInterface(var ctx: Activity) { | |||
| index: Int, | |||
| type: Int | |||
| ) { | |||
| BookActivity.active(ctx, title, key, identity, name, index, type) | |||
| } | |||
| /** | |||
| @@ -402,7 +382,7 @@ class YzxJavascriptInterface(var ctx: Activity) { | |||
| note_info: String, | |||
| can_add_page: Int = 1 | |||
| ) { | |||
| NoteActivity.active(ctx, title, note_info, can_add_page) | |||
| } | |||
| /** | |||
| @@ -415,7 +395,7 @@ class YzxJavascriptInterface(var ctx: Activity) { | |||
| title: String, | |||
| note_info: String | |||
| ) { | |||
| NoteActivity.active(ctx, title, note_info, 1) | |||
| } | |||
| /** | |||
| @@ -479,68 +459,12 @@ class YzxJavascriptInterface(var ctx: Activity) { | |||
| @JavascriptInterface | |||
| fun readPage(bookTaskId: String) { | |||
| val presenter = ReadPresenter(object : ReadView { | |||
| override fun finishChapter() { | |||
| } | |||
| override fun onProgressSuccess(progress: Float) { | |||
| } | |||
| override fun errorChapter() { | |||
| } | |||
| override fun showCategory(localId: String?) { | |||
| val collBook = BookRepository.getInstance().getCollBook(localId) | |||
| if (collBook.cover.endsWith(".txt")) { | |||
| ctx.startActivity<ReadActivity>("book_id" to localId) | |||
| } else { | |||
| ToastUtils.showLong("暂不支持该格式预览!") | |||
| } | |||
| } | |||
| }) | |||
| presenter.loadCategory(bookTaskId) | |||
| } | |||
| @JavascriptInterface | |||
| fun readPage(bookTaskId: String, readTaskId: String) { | |||
| val presenter = ReadPresenter(object : ReadView { | |||
| override fun finishChapter() { | |||
| } | |||
| override fun errorChapter() { | |||
| } | |||
| override fun showCategory(localId: String?) { | |||
| val collBook = BookRepository.getInstance().getCollBook(localId) | |||
| if (collBook.cover.endsWith(".txt")) { | |||
| ctx.startActivity<ReadActivity>( | |||
| "book_id" to localId, | |||
| "read_task_id" to readTaskId, | |||
| "real_book_id" to bookTaskId | |||
| ) | |||
| } else if (collBook.cover.endsWith(".pdf")) { | |||
| ctx.startActivity<PDFViewActivity>( | |||
| "book_id" to localId, | |||
| "read_task_id" to readTaskId, | |||
| "real_book_id" to bookTaskId | |||
| ) | |||
| } else { | |||
| ToastUtils.showLong("暂不支持该格式预览!") | |||
| } | |||
| } | |||
| override fun onProgressSuccess(progress: Float) { | |||
| } | |||
| }) | |||
| presenter.loadCategory(bookTaskId) | |||
| } | |||
| } | |||
| @@ -1,12 +1,10 @@ | |||
| package com.yzx.webebook.activity.base | |||
| package com.yzx.escreen.activity.base | |||
| import android.os.Bundle | |||
| import androidx.appcompat.app.AppCompatActivity | |||
| import com.gyf.immersionbar.ktx.immersionBar | |||
| import com.yzx.webebook.R | |||
| import com.yzx.webebook.presenter.base.BasePresenter | |||
| import io.reactivex.disposables.CompositeDisposable | |||
| import io.reactivex.disposables.Disposable | |||
| import com.yzx.escreen.R | |||
| import com.yzx.escreen.presenter.base.BasePresenter | |||
| /** | |||
| * 类名:BaseActivity | |||
| @@ -40,7 +38,6 @@ abstract class BaseActivity<out P : BasePresenter<*>> : AppCompatActivity() { | |||
| abstract fun initPresenter(): P? | |||
| protected var mDisposable: CompositeDisposable? = null | |||
| override fun onCreate(savedInstanceState: Bundle?) { | |||
| super.onCreate(savedInstanceState) | |||
| @@ -61,12 +58,7 @@ abstract class BaseActivity<out P : BasePresenter<*>> : AppCompatActivity() { | |||
| } | |||
| protected open fun addDisposable(d: Disposable?) { | |||
| if (mDisposable == null) { | |||
| mDisposable = CompositeDisposable() | |||
| } | |||
| mDisposable!!.add(d!!) | |||
| } | |||
| override fun onBackPressed() { | |||
| @@ -75,9 +67,7 @@ abstract class BaseActivity<out P : BasePresenter<*>> : AppCompatActivity() { | |||
| override fun onDestroy() { | |||
| super.onDestroy() | |||
| if (mDisposable != null) { | |||
| mDisposable!!.dispose() | |||
| } | |||
| } | |||
| } | |||
| @@ -1,9 +1,9 @@ | |||
| package com.yzx.webebook.adapter | |||
| package com.yzx.escreen.adapter | |||
| import com.chad.library.adapter.base.BaseQuickAdapter | |||
| import com.chad.library.adapter.base.viewholder.BaseViewHolder | |||
| import com.yzx.webebook.R | |||
| import com.yzx.webebook.model.HomeItem | |||
| import com.yzx.escreen.R | |||
| import com.yzx.escreen.model.HomeItem | |||
| import kotlinx.android.synthetic.main.item_home.view.* | |||
| class HomeAdapter(list: MutableList<HomeItem>) : BaseQuickAdapter<HomeItem, BaseViewHolder>(R.layout.item_home,list) { | |||
| @@ -1,4 +1,4 @@ | |||
| package com.yzx.webebook.adapter.base; | |||
| package com.yzx.escreen.adapter.base; | |||
| import android.os.Handler; | |||
| import android.view.View; | |||
| @@ -1,4 +1,4 @@ | |||
| package com.yzx.webebook.adapter.base; | |||
| package com.yzx.escreen.adapter.base; | |||
| import android.view.View; | |||
| @@ -1,4 +1,4 @@ | |||
| package com.yzx.webebook.adapter.base; | |||
| package com.yzx.escreen.adapter.base; | |||
| import android.view.View; | |||
| import android.view.ViewGroup; | |||
| @@ -1,4 +1,4 @@ | |||
| package com.yzx.webebook.adapter.base; | |||
| package com.yzx.escreen.adapter.base; | |||
| import android.view.View; | |||
| import android.view.ViewGroup; | |||
| @@ -1,4 +1,4 @@ | |||
| package com.yzx.webebook.adapter.base; | |||
| package com.yzx.escreen.adapter.base; | |||
| import android.view.View; | |||
| import android.view.ViewGroup; | |||
| @@ -1,4 +1,4 @@ | |||
| package com.yzx.webebook.adapter.base; | |||
| package com.yzx.escreen.adapter.base; | |||
| import android.content.Context; | |||
| import android.view.LayoutInflater; | |||
| @@ -1,6 +1,6 @@ | |||
| package com.yzx.webebook.config | |||
| package com.yzx.escreen.config | |||
| import com.yzx.webebook.BuildConfig | |||
| import com.yzx.escreen.BuildConfig | |||
| object Config { | |||
| var BASE_URL = BuildConfig.BASE_URL | |||
| @@ -1,4 +1,4 @@ | |||
| package com.yzx.webebook.model | |||
| package com.yzx.escreen.model | |||
| data class BaseBean<T>( | |||
| var code: Int, | |||
| @@ -1,4 +1,4 @@ | |||
| package com.yzx.webebook.model | |||
| package com.yzx.escreen.model | |||
| class Book { | |||
| var book_name:String = "" | |||
| @@ -1,4 +1,4 @@ | |||
| package com.yzx.webebook.model | |||
| package com.yzx.escreen.model | |||
| class HomeItem ( | |||
| var title:String, | |||
| @@ -1,4 +1,4 @@ | |||
| package com.yzx.webebook.model | |||
| package com.yzx.escreen.model | |||
| class Note { | |||
| var key:String = "" | |||
| @@ -0,0 +1,21 @@ | |||
| package com.yzx.escreen.model | |||
| import com.flyco.tablayout.listener.CustomTabEntity | |||
| data class TabEntity(var title: String, | |||
| var selectedIcon: Int, | |||
| var unSelectedIcon: Int) : | |||
| CustomTabEntity { | |||
| override fun getTabTitle(): String { | |||
| return title | |||
| } | |||
| override fun getTabSelectedIcon(): Int { | |||
| return selectedIcon | |||
| } | |||
| override fun getTabUnselectedIcon(): Int { | |||
| return unSelectedIcon | |||
| } | |||
| } | |||
| @@ -1,4 +1,4 @@ | |||
| package com.yzx.webebook.model | |||
| package com.yzx.escreen.model | |||
| class UploadBean { | |||
| var code:Int = 0 | |||
| @@ -1,6 +1,5 @@ | |||
| package com.yzx.webebook.model | |||
| package com.yzx.escreen.model | |||
| import android.content.Context | |||
| import com.blankj.utilcode.util.SPUtils | |||
| class User( | |||
| @@ -1,4 +1,4 @@ | |||
| package com.yzx.webebook.model | |||
| package com.yzx.escreen.model | |||
| class Version { | |||
| var version: String = "" | |||
| @@ -1,4 +1,4 @@ | |||
| package com.yzx.webebook.presenter.base | |||
| package com.yzx.escreen.presenter.base | |||
| /** | |||
| * 类名:BasePresenter | |||
| @@ -1,4 +1,4 @@ | |||
| package com.yzx.webebook.presenter.base | |||
| package com.yzx.escreen.presenter.base | |||
| /** | |||
| * 类名:IView | |||
| @@ -1,10 +1,10 @@ | |||
| package com.yzx.webebook.presenter.base | |||
| package com.yzx.escreen.presenter.base | |||
| import com.google.gson.Gson | |||
| import com.google.gson.reflect.TypeToken | |||
| import com.lzy.okgo.callback.AbsCallback | |||
| import com.lzy.okgo.convert.StringConvert | |||
| import com.yzx.webebook.model.BaseBean | |||
| import com.yzx.escreen.model.BaseBean | |||
| import okhttp3.Response | |||
| abstract class JsonCallBack<T> : AbsCallback<BaseBean<T>>() { | |||
| @@ -0,0 +1,2 @@ | |||
| package com.yzx.escreen.utils | |||
| @@ -1,4 +1,4 @@ | |||
| package com.yzx.webebook.utils | |||
| package com.yzx.escreen.utils | |||
| import androidx.core.content.FileProvider | |||
| @@ -1,4 +1,4 @@ | |||
| package com.yzx.webebook.widget | |||
| package com.yzx.escreen.widget | |||
| import android.app.Dialog | |||
| import android.content.Context | |||
| @@ -1,4 +1,4 @@ | |||
| package com.yzx.webebook.widget | |||
| package com.yzx.escreen.widget | |||
| import android.content.Context | |||
| import android.view.MotionEvent | |||
| @@ -1,73 +0,0 @@ | |||
| package com.yzx.webebook | |||
| import android.app.Application | |||
| import android.content.Context | |||
| import android.util.Log | |||
| import com.blankj.utilcode.util.Utils | |||
| import com.lzy.okgo.OkGo | |||
| import com.lzy.okgo.model.HttpHeaders | |||
| import com.umeng.analytics.MobclickAgent | |||
| import com.umeng.commonsdk.UMConfigure | |||
| import com.yzx.webebook.adapter.ImageAdapter | |||
| import com.yzx.webebook.model.User | |||
| import com.yzx.webebook.modules.ActivityWXModule | |||
| import org.apache.weex.InitConfig | |||
| import org.apache.weex.WXEnvironment | |||
| import org.apache.weex.WXSDKEngine | |||
| import org.apache.weex.adapter.DefaultWXHttpAdapter | |||
| import org.apache.weex.bridge.WXBridgeManager | |||
| class App : Application() { | |||
| companion object { | |||
| var app: App? = null | |||
| fun getContext(): App { | |||
| return app ?: App() | |||
| } | |||
| } | |||
| override fun onCreate() { | |||
| super.onCreate() | |||
| app = this | |||
| val config = InitConfig.Builder() //图片库接口 | |||
| .setImgAdapter(ImageAdapter()) //网络库接口 | |||
| .setHttpAdapter(DefaultWXHttpAdapter()) | |||
| .build() | |||
| WXSDKEngine.initialize(this, config) | |||
| WXBridgeManager.updateGlobalConfig("wson_on") | |||
| WXEnvironment.setOpenDebugLog(true) | |||
| WXEnvironment.setApkDebugable(true) | |||
| WXSDKEngine.addCustomOptions("appName", "WXSample") | |||
| WXSDKEngine.addCustomOptions("appGroup", "WXApp") | |||
| val registerSuccess = WXSDKEngine.registerModule("navevent", ActivityWXModule::class.java) | |||
| Log.i("welog", "WXSDKEngine.isInitializedApplication: " + WXSDKEngine.isInitialized()) | |||
| Log.i("welog", "WXSDKEngine.registerModule: $registerSuccess") | |||
| val headers = HttpHeaders() | |||
| val user = User.getUser() | |||
| headers.put("phone",user.phone) | |||
| headers.put("token",user.token) | |||
| OkGo.getInstance() | |||
| .addCommonHeaders(headers) | |||
| .init(this) | |||
| Utils.init(this) | |||
| UMConfigure.init( | |||
| this, | |||
| "60334d01425ec25f10fbd5b4", | |||
| "ebook", | |||
| UMConfigure.DEVICE_TYPE_PHONE, | |||
| "" | |||
| ) | |||
| MobclickAgent.setPageCollectionMode(MobclickAgent.PageMode.AUTO) | |||
| } | |||
| } | |||
| @@ -1,211 +0,0 @@ | |||
| package com.yzx.webebook | |||
| import android.annotation.SuppressLint | |||
| import android.app.Activity | |||
| import android.content.Intent | |||
| import android.text.TextUtils | |||
| import android.util.Log | |||
| import com.blankj.utilcode.util.StringUtils | |||
| import com.bumptech.glide.Glide | |||
| import com.yzx.webebook.activity.* | |||
| import com.yzx.webebook.activity.base.BaseActivity | |||
| import com.yzx.webebook.config.Config | |||
| import com.yzx.webebook.model.User | |||
| import com.yzx.webebook.model.bean.CollBookBean | |||
| import com.yzx.webebook.model.local.BookRepository | |||
| import com.yzx.webebook.presenter.ReadPresenter | |||
| import com.yzx.webebook.presenter.ReadView | |||
| import kotlinx.android.synthetic.main.activity_main.* | |||
| import org.jetbrains.anko.startActivity | |||
| import org.jetbrains.anko.toast | |||
| /** | |||
| * Yun.Lei | |||
| * 2020年5月6日14:49:10 | |||
| */ | |||
| class MainActivity : BaseActivity<ReadPresenter>(),ReadView { | |||
| override val inflateId: Int | |||
| get() = R.layout.activity_main | |||
| override fun initView() { | |||
| btn1.setOnClickListener { | |||
| Config.APP_NAME = "家校互通" | |||
| Config.BASE_URL = "https://oa.qbjjyyun.net/api" | |||
| Config.M_URL = "https://m.qbjjyyun.net" | |||
| User.clearUserInfo() | |||
| startActivity<HomeActivity>() | |||
| } | |||
| btn2.setOnClickListener { | |||
| Config.APP_NAME = "家校互通(LIVE)" | |||
| Config.BASE_URL = "https://oa.live.educlouddata.com/api" | |||
| Config.M_URL = "https://m.live.educlouddata.com" | |||
| User.clearUserInfo() | |||
| startActivity<HomeActivity>() | |||
| } | |||
| btn6.setOnClickListener { | |||
| Config.APP_NAME = "家校互通(测试)" | |||
| Config.BASE_URL = "http://192.168.69.99:9009" | |||
| Config.M_URL = "http://192.168.69.99:8098" | |||
| if (BuildConfig.BUILD_TYPE != "debug") { | |||
| User.clearUserInfo() | |||
| } | |||
| startActivity<HomeActivity>() | |||
| } | |||
| btn3.setOnClickListener { | |||
| val mBaseUrl = mBaseUrlTv.text.toString() | |||
| if(StringUtils.isTrimEmpty(mBaseUrl)){ | |||
| toast("请输入BASE_URL") | |||
| return@setOnClickListener | |||
| } | |||
| val mUrl = mUrlTv.text.toString() | |||
| if(StringUtils.isTrimEmpty(mUrl)){ | |||
| toast("请输入M_URL") | |||
| return@setOnClickListener | |||
| } | |||
| Config.APP_NAME = "家校互通(本地)" | |||
| Config.BASE_URL = mBaseUrl | |||
| Config.M_URL = mUrl | |||
| if (BuildConfig.BUILD_TYPE != "debug") { | |||
| User.clearUserInfo() | |||
| } | |||
| startActivity<HomeActivity>() | |||
| } | |||
| btn4.setOnClickListener { | |||
| BookActivity.active( | |||
| this, | |||
| "教育云空间", | |||
| "f04be754f6cb3f6168f582403a514c39", | |||
| "filec", | |||
| "", | |||
| 1, | |||
| 1 | |||
| ) | |||
| } | |||
| btn5.setOnClickListener { | |||
| // BookActivity.active(this,"教育云空间(无图)","","","",2,2) | |||
| val json ="" | |||
| NoteActivity.active(this, "测试笔记写字", json,1) | |||
| } | |||
| btn7.setOnClickListener { | |||
| startActivity<PDFViewActivity>() | |||
| // mPresenter?.loadCategory("17") | |||
| } | |||
| /*OkGo.post<String>("https://fileupload.oa.qbjjyyun.net/edufile/fileUpload") | |||
| .tag(this) | |||
| .params("token","0fc58a8df03c46d3f85b1047c4693cf6") | |||
| .params("user","97244") | |||
| .params("file",file) | |||
| .execute(object : StringCallback(){ | |||
| override fun onError(response: Response<String>?) { | |||
| super.onError(response) | |||
| Log.d("onError",response?.body()) | |||
| } | |||
| override fun onSuccess(response: Response<String>?) { | |||
| val json = response?.body() | |||
| Log.d("onSuccess",response?.body()) | |||
| val jsonObject = JSONObject(json) | |||
| val content = jsonObject.optString("content") | |||
| Log.d("onSuccess,content",content) | |||
| val contentObject = JSONObject(content) | |||
| val key = contentObject.optString("key") | |||
| val identity = contentObject.optString("identity") | |||
| Log.d("onSuccess,identity",identity) | |||
| Log.d("onSuccess,key",key) | |||
| } | |||
| })*/ | |||
| // val apps = AppUtils.getAppInfo("com.tencent.weread.eink") | |||
| // appInfos.text = apps.toString(); | |||
| appInfos.setOnClickListener { | |||
| val intent = packageManager.getLaunchIntentForPackage("com.tencent.weread.eink") | |||
| intent?.flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED | |||
| startActivity(intent) | |||
| Log.d("AppUtils", "initView: ${intent.toString()}") | |||
| } | |||
| btn8.setOnClickListener { | |||
| startActivity<WeexTestActivity>("url" to "weex/index.js","params" to "我是android传递的消息") | |||
| } | |||
| btn9.setOnClickListener { | |||
| val intent = packageManager.getLaunchIntentForPackage("com.example.weexdemo") | |||
| intent?.flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED | |||
| startActivity(intent) | |||
| Log.d("AppUtils", "initView: ${intent.toString()}") | |||
| } | |||
| } | |||
| override fun initData() { | |||
| saveDb() | |||
| } | |||
| fun saveDb(){ | |||
| val path = "/storage/emulated/0/xxjs.pdf"; | |||
| val collBook = CollBookBean() | |||
| collBook._id = "xxjs" | |||
| collBook.title = "三国演义sgyy" | |||
| collBook.author = "yzx" | |||
| collBook.shortIntro = "" | |||
| collBook.cover = path | |||
| collBook.lastChapter = "开始阅读" | |||
| collBook.updated = "2021年5月7日18:20:25" | |||
| collBook.lastRead = "2021年5月7日18:20:34" | |||
| collBook.setIsLocal(true) | |||
| BookRepository.getInstance() | |||
| .saveCollBooks(mutableListOf(collBook)) | |||
| } | |||
| override fun initPresenter(): ReadPresenter = ReadPresenter(this) | |||
| @SuppressLint("SetTextI18n") | |||
| override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { | |||
| super.onActivityResult(requestCode, resultCode, data) | |||
| if (requestCode == BookActivity.REQ_CODE && resultCode == Activity.RESULT_OK) { | |||
| val mKey = data?.getStringExtra("key") | |||
| val mIdentity = data?.getStringExtra("identity") | |||
| if(!TextUtils.isEmpty(mKey)&&!TextUtils.isEmpty(mIdentity)){ | |||
| val url = "https://$mIdentity.oa.qbjjyyun.net/edufile/imageView?uniqueKey=$mKey" | |||
| Glide.with(this) | |||
| .load(url) | |||
| .into(testImageView) | |||
| } | |||
| val json = data?.getStringExtra("note_info")?:"" | |||
| backInfo.text = json | |||
| } | |||
| if (requestCode == NoteActivity.REQ_CODE && resultCode == Activity.RESULT_OK) { | |||
| val json = data?.getStringExtra("note_info")?:"" | |||
| backInfo.text = json | |||
| } | |||
| } | |||
| override fun finishChapter() { | |||
| } | |||
| override fun errorChapter() { | |||
| } | |||
| override fun showCategory(localId: String?) { | |||
| // startActivity<ReadActivity>("book_id" to "xxjs") | |||
| } | |||
| override fun onProgressSuccess(progress: Float) { | |||
| } | |||
| } | |||
| @@ -1,687 +0,0 @@ | |||
| package com.yzx.webebook.activity | |||
| import android.Manifest | |||
| import android.annotation.SuppressLint | |||
| import android.app.Activity | |||
| import android.content.BroadcastReceiver | |||
| import android.content.Context | |||
| import android.content.Intent | |||
| import android.content.IntentFilter | |||
| import android.content.pm.ActivityInfo | |||
| import android.content.pm.PackageManager | |||
| import android.graphics.Bitmap | |||
| import android.graphics.Rect | |||
| import android.graphics.drawable.Drawable | |||
| import android.os.Handler | |||
| import android.os.Message | |||
| import android.text.TextUtils | |||
| import android.util.Log | |||
| import android.view.KeyEvent | |||
| import android.view.View | |||
| import android.widget.Toast | |||
| import com.blankj.utilcode.util.FileUtils | |||
| import com.blankj.utilcode.util.GsonUtils | |||
| import com.blankj.utilcode.util.ImageUtils | |||
| import com.bumptech.glide.Glide | |||
| import com.bumptech.glide.load.engine.DiskCacheStrategy | |||
| import com.bumptech.glide.request.target.CustomTarget | |||
| import com.bumptech.glide.request.target.Target | |||
| import com.bumptech.glide.request.transition.Transition | |||
| import com.google.gson.Gson | |||
| import com.lzy.okgo.OkGo | |||
| import com.lzy.okgo.callback.StringCallback | |||
| import com.lzy.okgo.model.Response | |||
| import com.wetao.note.NotePageInfo | |||
| import com.wetao.note.OnInitedListener | |||
| import com.wetao.note.WeNoteView | |||
| import com.wetao.note.WePoint | |||
| import com.yzx.webebook.R | |||
| import com.yzx.webebook.activity.base.BaseActivity | |||
| import com.yzx.webebook.model.Note | |||
| import com.yzx.webebook.presenter.base.BasePresenter | |||
| import kotlinx.android.synthetic.main.activity_note.* | |||
| import org.jetbrains.anko.startActivityForResult | |||
| import org.jetbrains.anko.toast | |||
| import org.json.JSONArray | |||
| import org.json.JSONObject | |||
| import java.io.File | |||
| import java.util.* | |||
| import kotlin.system.exitProcess | |||
| /** | |||
| * 笔记页面 | |||
| */ | |||
| class NoteActivity : BaseActivity<BasePresenter<*>>() { | |||
| private val mBGDrawableList = intArrayOf( | |||
| R.drawable.background0, | |||
| R.drawable.background1, | |||
| R.drawable.background2, | |||
| R.drawable.background3, | |||
| R.drawable.background4, | |||
| R.drawable.background5, | |||
| R.drawable.background6, | |||
| R.drawable.background7, | |||
| R.drawable.background8, | |||
| R.drawable.background9, | |||
| R.drawable.background10 | |||
| ) | |||
| private var mBgId = 0 | |||
| private var mWePointList = mutableListOf<WePoint>() | |||
| private var mHandler = Handler() | |||
| private var mScreenH = 0 | |||
| private var mScreenW = 0 | |||
| private val MSG_SAVE_END = 2001 | |||
| private var mNotePageInfo: NotePageInfo? = null | |||
| private var notList = mutableListOf<Note>() | |||
| private var currKey = "" | |||
| private var currIndex = 0 | |||
| val TAG = "NoteActivity" | |||
| companion object { | |||
| const val NOTE_FOLDER_DIR = "/mnt/sdcard/ebook/" | |||
| const val REQ_CODE = 0x98 | |||
| fun active(act: Activity, title: String, noteInfo: String, can_add_page: Int = 1) { | |||
| act.startActivityForResult<NoteActivity>( | |||
| REQ_CODE, | |||
| "note_info" to noteInfo, | |||
| "title" to title, | |||
| "can_add_page" to can_add_page | |||
| ) | |||
| } | |||
| } | |||
| override val inflateId: Int | |||
| get() = R.layout.activity_note | |||
| override fun initView() { | |||
| checkPermission() | |||
| requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT | |||
| mScreenH = resources.displayMetrics.heightPixels | |||
| mScreenW = resources.displayMetrics.widthPixels | |||
| //背景 | |||
| new_init.setOnClickListener { | |||
| mBgId++ | |||
| if (mBgId >= mBGDrawableList.size) { | |||
| mBgId = 0 | |||
| } | |||
| note_view.setBackgroundResource(mBGDrawableList[mBgId]) | |||
| val note = notList[currIndex] | |||
| note.BGid = mBgId | |||
| } | |||
| //清除 | |||
| new_clear.setOnClickListener { | |||
| note_view.clear(); | |||
| } | |||
| //笔 | |||
| pen.setOnClickListener { | |||
| if (note_view.penType == WeNoteView.TYPE_DRAW_ERASER) { | |||
| note_view.penType = WeNoteView.TYPE_DRAW_CURVE | |||
| note_view.updateEnableStatus() | |||
| Log.d(TAG, "initNoteView: ${note_view.penType}") | |||
| pen.setCompoundDrawablesWithIntrinsicBounds( | |||
| 0, | |||
| R.mipmap.ic_book_pen_select, | |||
| 0, | |||
| 0 | |||
| ) | |||
| new_eraser.setCompoundDrawablesWithIntrinsicBounds( | |||
| 0, | |||
| R.mipmap.ic_book_rubber, | |||
| 0, | |||
| 0 | |||
| ) | |||
| } | |||
| } | |||
| //橡皮 | |||
| new_eraser.setOnClickListener { | |||
| if (note_view.penType != WeNoteView.TYPE_DRAW_ERASER) { | |||
| note_view.penType = WeNoteView.TYPE_DRAW_ERASER | |||
| note_view.updateEnableStatus() | |||
| Log.d(TAG, "initNoteView: ${note_view.penType}") | |||
| pen.setCompoundDrawablesWithIntrinsicBounds(0, R.mipmap.ic_book_pen, 0, 0) | |||
| new_eraser.setCompoundDrawablesWithIntrinsicBounds( | |||
| 0, | |||
| R.mipmap.ic_book_rubber_select, | |||
| 0, | |||
| 0 | |||
| ) | |||
| } | |||
| } | |||
| //加纸 | |||
| new_add.setOnClickListener { | |||
| val lastBGid = notList[notList.size - 1].BGid | |||
| val note = Note() | |||
| note.BGid = lastBGid | |||
| notList.add(note) | |||
| tv_page_index.text = "${currIndex + 1}/${notList.size}" | |||
| indexBox.visibility = if (notList.size > 1) { | |||
| View.VISIBLE | |||
| } else { | |||
| View.GONE | |||
| } | |||
| } | |||
| //title | |||
| btnBack.setOnClickListener { onBackPressed() } | |||
| titleTv.text = intent.getStringExtra("title") | |||
| //初始化笔记 | |||
| mWePointList.clear() | |||
| //屏幕初始化 | |||
| val filter = IntentFilter() | |||
| filter.addAction(SCREEN_ON) | |||
| filter.addAction(SCREEN_OFF) | |||
| if (mReceiver != null) { | |||
| registerReceiver(mReceiver, filter) | |||
| } | |||
| btnPre.setOnClickListener { | |||
| if (currIndex - 1 >= 0) { | |||
| ImageUtils.save( | |||
| note_view.currentNoteBitmap, | |||
| "${NOTE_FOLDER_DIR}/${currKey}.png", | |||
| Bitmap.CompressFormat.PNG | |||
| ) | |||
| loadImage(currIndex - 1) | |||
| } | |||
| } | |||
| btnNext.setOnClickListener { | |||
| if (currIndex + 1 < notList.size) { | |||
| ImageUtils.save( | |||
| note_view.currentNoteBitmap, | |||
| "${NOTE_FOLDER_DIR}/${currKey}.png", | |||
| Bitmap.CompressFormat.PNG | |||
| ) | |||
| loadImage(currIndex + 1) | |||
| } | |||
| } | |||
| saveBtn.setOnClickListener { | |||
| saveTip.visibility = View.VISIBLE | |||
| saveTip.text = "保存中..." | |||
| ImageUtils.save( | |||
| note_view.currentNoteBitmap, | |||
| "${NOTE_FOLDER_DIR}/${currKey}.png", | |||
| Bitmap.CompressFormat.PNG | |||
| ) | |||
| save(0) | |||
| } | |||
| } | |||
| override fun onWindowFocusChanged(hasFocus: Boolean) { | |||
| super.onWindowFocusChanged(hasFocus) | |||
| if (hasFocus) { | |||
| note_view.onResume() | |||
| } else { | |||
| note_view.onPause() | |||
| } | |||
| } | |||
| @SuppressLint("SetTextI18n") | |||
| override fun initData() { | |||
| val json = intent.getStringExtra("note_info") | |||
| notList.clear() | |||
| if (!TextUtils.isEmpty(json)) { | |||
| val jsonArray = JSONArray(json) | |||
| if (jsonArray.length() > 0) { | |||
| for (index in 0 until jsonArray.length()) { | |||
| val jsonObj: JSONObject? = jsonArray?.opt(index) as JSONObject | |||
| val identity = jsonObj?.getString("identity"); | |||
| val key = jsonObj?.getString("key") | |||
| val bgId = jsonObj?.getInt("BGid") | |||
| val note = Note() | |||
| note.BGid = bgId ?: 0 | |||
| note.identity = identity ?: "" | |||
| note.key = key ?: "" | |||
| notList.add(note) | |||
| } | |||
| } else { | |||
| notList.add(Note()) | |||
| } | |||
| } else { | |||
| notList.add(Note()) | |||
| } | |||
| // Log.d(TAG, "初始化开始note_view") | |||
| // note_view.post { | |||
| // Log.d(TAG, "初始化开始note_view.post") | |||
| // mHandler.post(mRunnable) | |||
| // } | |||
| Log.d(TAG, "初始化开始note_view") | |||
| note_view.setOnFinishListener(object : OnInitedListener { | |||
| override fun onSizeChanged() { | |||
| } | |||
| override fun onInited() { | |||
| // note_view.post { | |||
| // Log.d(TAG, "初始化开始note_view.post") | |||
| // mHandler.post(mRunnable) | |||
| // } | |||
| if (mNotePageInfo == null) { | |||
| mNotePageInfo = getNotePageInfo(NOTE_FOLDER_DIR) | |||
| } | |||
| if (mNotePageInfo == null) { | |||
| Log.d(TAG, "Flash test : +++++ no note, so init a page"); | |||
| initPage() | |||
| } | |||
| loadImage(0) | |||
| initNoteView() | |||
| } | |||
| }) | |||
| tv_page_index.text = "1/${notList.size}" | |||
| indexBox.visibility = if (notList.size > 1) { | |||
| View.VISIBLE | |||
| } else { | |||
| View.GONE | |||
| } | |||
| val canAddPage = intent.getIntExtra("can_add_page", 1) | |||
| if (canAddPage == 1) { | |||
| new_add.visibility = View.VISIBLE | |||
| } else { | |||
| new_add.visibility = View.GONE | |||
| } | |||
| } | |||
| private fun loadImage(index: Int = 0) { | |||
| val note = notList[index] | |||
| val identity = note.identity | |||
| val key = note.key | |||
| val bgId = note.BGid | |||
| if (TextUtils.isEmpty(key)) { | |||
| note.key = Date().time.toString() | |||
| note_view.showExistPage("") | |||
| note_view.setBackgroundResource(mBGDrawableList[bgId]) | |||
| currKey = note.key | |||
| currIndex = index | |||
| mBgId = bgId | |||
| tv_page_index.text = "${index + 1}/${notList.size}" | |||
| return | |||
| } | |||
| val path = "${NOTE_FOLDER_DIR}/${key}.png" | |||
| if (FileUtils.isFileExists(path)) { | |||
| if (mNotePageInfo == null) { | |||
| return | |||
| } | |||
| mBgId = bgId ?: 0 | |||
| note_view.showExistPage(path) | |||
| note_view.setBackgroundResource(mBGDrawableList[bgId]) | |||
| currKey = key | |||
| currIndex = index | |||
| tv_page_index.text = "${index + 1}/${notList.size}" | |||
| } else { | |||
| if (!TextUtils.isEmpty(key) && !TextUtils.isEmpty(identity)) { | |||
| saveTip.visibility = View.VISIBLE | |||
| saveTip.text = "加载中..." | |||
| val url = "https://${identity}.oa.qbjjyyun.net/edufile/imageView?uniqueKey=${key}" | |||
| val customTarget: CustomTarget<Drawable> = object : CustomTarget<Drawable>() { | |||
| override fun onLoadCleared(placeholder: Drawable?) {} | |||
| override fun onLoadFailed(errorDrawable: Drawable?) { | |||
| toast("文档加载失败!") | |||
| saveTip.visibility = View.GONE | |||
| } | |||
| override fun onResourceReady( | |||
| resource: Drawable, | |||
| transition: Transition<in Drawable>? | |||
| ) { | |||
| val bmp = ImageUtils.drawable2Bitmap(resource) | |||
| ImageUtils.save(bmp, path, Bitmap.CompressFormat.PNG) | |||
| if (FileUtils.isFileExists(path)) { | |||
| if (mNotePageInfo == null) { | |||
| return | |||
| } | |||
| mBgId = bgId ?: 0 | |||
| note_view.showExistPage(path) | |||
| note_view.setBackgroundResource(mBGDrawableList[bgId]) | |||
| currKey = key | |||
| currIndex = index | |||
| tv_page_index.text = "${index + 1}/${notList.size}" | |||
| } | |||
| saveTip.visibility = View.GONE | |||
| } | |||
| } | |||
| Glide.with(this) | |||
| .load(url) | |||
| .diskCacheStrategy(DiskCacheStrategy.ALL) | |||
| .override( | |||
| Target.SIZE_ORIGINAL, | |||
| Target.SIZE_ORIGINAL | |||
| ) | |||
| .into(customTarget) | |||
| } else { | |||
| note.key = Date().time.toString() | |||
| note_view.showExistPage("") | |||
| note_view.setBackgroundResource(mBGDrawableList[bgId]) | |||
| currKey = note.key | |||
| currIndex = index | |||
| mBgId = bgId ?: 0 | |||
| tv_page_index.text = "${index + 1}/${notList.size}" | |||
| } | |||
| } | |||
| } | |||
| private fun save(index: Int) { | |||
| val item = notList[index] | |||
| val path = "${NOTE_FOLDER_DIR}/${item.key}.png" | |||
| if (!TextUtils.isEmpty(item.key)) { | |||
| if (FileUtils.isFileExists(path)) { //存在就上传 | |||
| OkGo.post<String>("https://fileupload.oa.qbjjyyun.net/edufile/fileUpload") | |||
| .tag(this) | |||
| .params("token", "0fc58a8df03c46d3f85b1047c4693cf6") | |||
| .params("user", Date().time) | |||
| .params("file", File(path)) | |||
| .execute(object : StringCallback() { | |||
| override fun onSuccess(response: Response<String>) { | |||
| try { | |||
| val json = response.body() | |||
| Log.d("onSuccess", response.body()) | |||
| val jsonObject = JSONObject(json) | |||
| val content = jsonObject.optString("content") | |||
| Log.d("onSuccess,content", content) | |||
| val contentObject = JSONObject(content) | |||
| val key = contentObject.optString("key") | |||
| val identity = contentObject.optString("identity") | |||
| Log.d("onSuccess,identity", identity) | |||
| Log.d("onSuccess,key", key) | |||
| item.key = key | |||
| item.identity = identity | |||
| FileUtils.copy(path, "${NOTE_FOLDER_DIR}/${key}.png") | |||
| if (index == notList.size - 1) { | |||
| saveTip.visibility = View.GONE | |||
| toast("保存成功!") | |||
| backToH5() | |||
| } else { | |||
| save(index + 1) | |||
| } | |||
| } catch (e: Exception) { | |||
| } | |||
| } | |||
| override fun onError(response: Response<String>) { | |||
| super.onError(response) | |||
| toast("保存失败!") | |||
| } | |||
| override fun onFinish() { | |||
| super.onFinish() | |||
| saveTip.visibility = View.GONE | |||
| } | |||
| }) | |||
| } else { | |||
| if (index == notList.size - 1) { | |||
| saveTip.visibility = View.GONE | |||
| toast("保存成功!") | |||
| backToH5() | |||
| } else { | |||
| save(index + 1) | |||
| } | |||
| } | |||
| } else { | |||
| if (index == notList.size - 1) { | |||
| saveTip.visibility = View.GONE | |||
| toast("保存成功!") | |||
| backToH5() | |||
| } else { | |||
| save(index + 1) | |||
| } | |||
| } | |||
| } | |||
| private fun backToH5() { | |||
| val intent = Intent() | |||
| Log.d(TAG + "--------1------->", copyList().toString()) | |||
| Log.d(TAG + "---------2------>", Gson().toJson(copyList())) | |||
| Log.d(TAG + "---------3------>", GsonUtils.toJson(notList)) | |||
| intent.putExtra("note_info", GsonUtils.toJson(copyList())) | |||
| setResult(Activity.RESULT_OK, intent) | |||
| onBackPressed() | |||
| } | |||
| private fun copyList(): MutableList<Note> { | |||
| val list = mutableListOf<Note>() | |||
| notList.forEach { | |||
| if (!TextUtils.isEmpty(it.key) && !TextUtils.isEmpty(it.identity)) { | |||
| val item = Note() | |||
| item.key = it.key | |||
| item.identity = it.identity | |||
| item.BGid = it.BGid | |||
| list.add(item) | |||
| } | |||
| } | |||
| return list | |||
| } | |||
| data class CopyNote(val key: String, val identity: String, val BGid: Int) | |||
| override fun initPresenter(): BasePresenter<*>? = null | |||
| private fun checkPermission() { | |||
| var isGranted = true | |||
| if (checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) { | |||
| //如果没有写sd卡权限 | |||
| isGranted = false | |||
| } | |||
| if (checkSelfPermission(Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) { | |||
| isGranted = false | |||
| } | |||
| Log.i("cbs", "isGranted == $isGranted") | |||
| if (!isGranted) { | |||
| requestPermissions( | |||
| arrayOf( | |||
| Manifest.permission.ACCESS_COARSE_LOCATION, | |||
| Manifest.permission.ACCESS_FINE_LOCATION, | |||
| Manifest.permission.READ_EXTERNAL_STORAGE, | |||
| Manifest.permission.WRITE_EXTERNAL_STORAGE | |||
| ), | |||
| 102 | |||
| ) | |||
| } | |||
| } | |||
| override fun onResume() { | |||
| note_view.onResume() | |||
| super.onResume() | |||
| } | |||
| override fun onPause() { | |||
| note_view.onPause() | |||
| super.onPause() | |||
| } | |||
| override fun onDestroy() { | |||
| //mView.exitView(); | |||
| mHandler.removeCallbacks(mRunnable) | |||
| note_view.exitView() | |||
| if (mReceiver != null) { | |||
| unregisterReceiver(mReceiver) | |||
| mReceiver = null | |||
| } | |||
| super.onDestroy() | |||
| } | |||
| override fun onKeyDown(keyCode: Int, event: KeyEvent?): Boolean { | |||
| if (keyCode == KeyEvent.KEYCODE_BACK) { | |||
| note_view.exitView() | |||
| if (mReceiver != null) { | |||
| unregisterReceiver(mReceiver) | |||
| mReceiver = null | |||
| } | |||
| finish() | |||
| return true | |||
| } | |||
| return super.onKeyDown(keyCode, event) | |||
| } | |||
| val SCREEN_ON = "android.intent.action.SCREEN_ON" | |||
| val SCREEN_OFF = "android.intent.action.SCREEN_OFF" | |||
| private var mReceiver: BroadcastReceiver? = object : BroadcastReceiver() { | |||
| override fun onReceive(context: Context, intent: Intent) { | |||
| // 屏幕唤醒 | |||
| // if (SCREEN_ON == intent.action) { | |||
| // note_view.setSleepMode(true) | |||
| // } else if (SCREEN_OFF == intent.action) { | |||
| // note_view.setSleepMode(true) | |||
| // } | |||
| } | |||
| } | |||
| private val mRunnable: Runnable = object : Runnable { | |||
| override fun run() { | |||
| Log.d(TAG, "初始化开始-------------》"); | |||
| var count = 0 | |||
| while (note_view.height <= 0) { | |||
| try { | |||
| Thread.sleep(50) | |||
| } catch (e: InterruptedException) { | |||
| e.printStackTrace() | |||
| } | |||
| if (count++ > 40) { | |||
| Log.d(TAG, "Flash test : ++++++++ removeCallbacks"); | |||
| mHandler.removeCallbacks(this) | |||
| exitProcess(0) | |||
| } | |||
| } | |||
| //note_view.initNative(new Rect(mScreenW, mScreenH - note_view.getHeight(), 0, mScreenH), SAVE_PIC_PATH); | |||
| Log.d( | |||
| TAG, | |||
| "Flash test : ++++++++ mView.getHeight() = " + note_view.height + ", count = " + count | |||
| ); | |||
| // note_view.initNative( | |||
| // Rect( | |||
| // mScreenW, | |||
| // mScreenH - note_view.height, | |||
| // 0, | |||
| // mScreenH | |||
| // ) | |||
| // ) | |||
| note_view.setTouchEventHander(mPointHandler) | |||
| Log.d(TAG, "Flash test : ++++++ mRunnable() start loader notepageinfo"); | |||
| if (mNotePageInfo == null) { | |||
| mNotePageInfo = getNotePageInfo(NOTE_FOLDER_DIR) | |||
| } | |||
| if (mNotePageInfo == null) { | |||
| Log.d(TAG, "Flash test : +++++ no note, so init a page"); | |||
| initPage() | |||
| } | |||
| loadImage(0) | |||
| initNoteView() | |||
| Log.d(TAG, "初始化结束-------------》"); | |||
| } | |||
| } | |||
| private fun initNoteView() { | |||
| //写字板初始化 | |||
| // note_view.setEnable(true) | |||
| note_view.penWidth = 3 | |||
| note_view.eraserWidth = 20 | |||
| note_view.penType = WeNoteView.TYPE_DRAW_CURVE | |||
| note_view.updateEnableStatus() | |||
| Log.d(TAG, "initNoteView: ${note_view.penType}") | |||
| } | |||
| override fun finish() { | |||
| note_view.exitView() | |||
| if (mReceiver != null) { | |||
| unregisterReceiver(mReceiver) | |||
| mReceiver = null | |||
| } | |||
| super.finish() | |||
| } | |||
| override fun onBackPressed() { | |||
| note_view.exitView() | |||
| if (mReceiver != null) { | |||
| unregisterReceiver(mReceiver) | |||
| mReceiver = null | |||
| } | |||
| super.onBackPressed() | |||
| } | |||
| private fun initPage(): Boolean { | |||
| var file = File(NOTE_FOLDER_DIR) | |||
| if (!file.exists()) { | |||
| if (!FileUtils.createOrExistsDir(file)) { | |||
| return false | |||
| } | |||
| } | |||
| var notePath: String? = null | |||
| file = File("$NOTE_FOLDER_DIR/${currKey}.png") | |||
| if (file.exists()) { | |||
| notePath = "$NOTE_FOLDER_DIR/${currKey}.png" | |||
| } | |||
| mNotePageInfo = NotePageInfo(notePath, mBgId) | |||
| return true | |||
| } | |||
| private fun loadOldPage() { | |||
| if (mNotePageInfo == null) { | |||
| return | |||
| } | |||
| mBgId = mNotePageInfo?.drwId ?: 0 | |||
| note_view.showExistPage(mNotePageInfo?.notePath) | |||
| note_view.setBackgroundResource(mBGDrawableList[mBgId]) | |||
| } | |||
| //从笔记文件夹中读取当前笔记的页面信息 | |||
| private fun getNotePageInfo(path: String): NotePageInfo? { | |||
| var file = File(path) | |||
| if (!file.exists()) { | |||
| return null | |||
| } | |||
| file.listFiles() ?: return null | |||
| val info = NotePageInfo(null, 0) | |||
| val notePath = "$path/${currKey}.png" | |||
| file = File(notePath) | |||
| if (file.exists()) { | |||
| info.notePath = notePath | |||
| } | |||
| info.drwId = 0 //Integer.parseInt(drwId); | |||
| return info | |||
| } | |||
| private val mPointHandler: Handler = @SuppressLint("HandlerLeak") | |||
| object : Handler() { | |||
| override fun handleMessage(msg: Message) { | |||
| val what = msg.what | |||
| //同步获取的笔记点坐标信息msg | |||
| if (what == WeNoteView.TOUCH_EVENT) { | |||
| val point = msg.obj as WePoint | |||
| mWePointList.add(point) | |||
| } | |||
| //保存笔记结束msg | |||
| if (what == MSG_SAVE_END) { | |||
| val status = msg.arg1 | |||
| if (status > 0) { //保存成功 | |||
| Toast.makeText(applicationContext, "保存成功!", Toast.LENGTH_SHORT).show(); | |||
| } else { //保存失败 | |||
| Toast.makeText(applicationContext, "保存失败!", Toast.LENGTH_SHORT) | |||
| .show(); | |||
| } | |||
| } | |||
| } | |||
| } | |||
| } | |||
| @@ -1,171 +0,0 @@ | |||
| package com.yzx.webebook.activity | |||
| import android.content.Context | |||
| import android.os.PowerManager | |||
| import android.os.PowerManager.WakeLock | |||
| import androidx.viewpager.widget.ViewPager | |||
| import com.blankj.utilcode.util.NumberUtils | |||
| import com.yzx.webebook.R | |||
| import com.yzx.webebook.activity.base.BaseActivity | |||
| import com.yzx.webebook.model.bean.BookRecordBean | |||
| import com.yzx.webebook.model.bean.CollBookBean | |||
| import com.yzx.webebook.model.local.BookRepository | |||
| import com.yzx.webebook.presenter.ReadPresenter | |||
| import com.yzx.webebook.presenter.ReadView | |||
| import com.yzx.webebook.widget.YzxPDFViewPager | |||
| import kotlinx.android.synthetic.main.activity_pdf_view.* | |||
| /** | |||
| * pdf 预览页面 | |||
| */ | |||
| class PDFViewActivity : BaseActivity<ReadPresenter>(), ReadView { | |||
| private var mBookRecord: BookRecordBean? = null | |||
| private var mCollBook: CollBookBean? = null | |||
| private var mRealBookId: String = "" | |||
| private var mReadTaskId: String = "" | |||
| private var mBookId: String = "" | |||
| var currPage = 0 | |||
| var total = 0 | |||
| var oldPosition = 0 | |||
| var lastProgress = 0f | |||
| //控制屏幕常亮 | |||
| private var mWakeLock: WakeLock? = null | |||
| override val inflateId: Int | |||
| get() = R.layout.activity_pdf_view | |||
| override fun initView() { | |||
| mBookId = intent.getStringExtra("book_id") ?: "" | |||
| mReadTaskId = intent.getStringExtra("read_task_id") ?: "" | |||
| mRealBookId = intent.getStringExtra("real_book_id") ?: "" | |||
| mCollBook = BookRepository.getInstance().getCollBook(mBookId) | |||
| mCollBook.apply { | |||
| loadPdf() | |||
| } | |||
| mPresenter?.getReadProgress(mRealBookId, mReadTaskId) | |||
| } | |||
| private fun loadPdf() { | |||
| val pdf = YzxPDFViewPager(this, mCollBook?.cover ?: "") | |||
| pdfView.addView(pdf) | |||
| total = pdf.adapter?.count ?: 0 | |||
| btnLeft.setOnClickListener { | |||
| if (currPage > 0) { | |||
| pdf.currentItem = --currPage | |||
| } | |||
| } | |||
| btnRight.setOnClickListener { | |||
| if (currPage < total - 1) { | |||
| pdf.currentItem = ++currPage | |||
| } | |||
| } | |||
| prepareBook() | |||
| pdf.addOnPageChangeListener(object : ViewPager.OnPageChangeListener { | |||
| override fun onPageScrollStateChanged(state: Int) { | |||
| } | |||
| override fun onPageScrolled( | |||
| position: Int, | |||
| positionOffset: Float, | |||
| positionOffsetPixels: Int | |||
| ) { | |||
| } | |||
| override fun onPageSelected(position: Int) { | |||
| currPageTv.text = "${position + 1}" | |||
| percentTv.text = "${getPercent(position.toFloat(), total.toFloat())}%" | |||
| mBookRecord?.pagePos = position | |||
| } | |||
| }) | |||
| val pos = mBookRecord?.pagePos ?: 0; | |||
| pdf.currentItem = pos | |||
| currPage = pos | |||
| } | |||
| /** | |||
| * 初始化书籍 | |||
| */ | |||
| private fun prepareBook() { | |||
| mBookRecord = BookRepository.getInstance() | |||
| .getBookRecord(mCollBook!!._id) | |||
| if (mBookRecord == null) { | |||
| mBookRecord = BookRecordBean() | |||
| mBookRecord?.bookId = mBookId | |||
| totalPageTv.text = "$total" | |||
| currPageTv.text = "${currPage + 1}" | |||
| percentTv.text = "${getPercent(1f, total.toFloat())}%" | |||
| oldPosition = 0 | |||
| } else { | |||
| oldPosition = mBookRecord!!.pagePos | |||
| totalPageTv.text = "$total" | |||
| currPageTv.text = "${mBookRecord!!.pagePos + 1}" | |||
| percentTv.text = | |||
| "${getPercent((mBookRecord!!.pagePos + 1).toFloat(), total.toFloat())}%" | |||
| } | |||
| } | |||
| override fun initData() { | |||
| //初始化屏幕常亮类 | |||
| //初始化屏幕常亮类 | |||
| val pm = | |||
| getSystemService(Context.POWER_SERVICE) as PowerManager | |||
| mWakeLock = pm.newWakeLock(PowerManager.SCREEN_DIM_WAKE_LOCK, "ireader:keep bright") | |||
| } | |||
| private fun getPercent(curr: Float, total: Float): String { | |||
| val percent = NumberUtils.format(curr * 100f / total, 2) | |||
| return "$percent" | |||
| } | |||
| override fun initPresenter(): ReadPresenter = ReadPresenter(this) | |||
| override fun onResume() { | |||
| super.onResume() | |||
| mWakeLock?.acquire() | |||
| } | |||
| override fun onPause() { | |||
| super.onPause() | |||
| mWakeLock?.release() | |||
| //存储到数据库 | |||
| if (mBookRecord != null) { | |||
| BookRepository.getInstance() | |||
| .saveBookRecord(mBookRecord) | |||
| val currProgress = getPercent( | |||
| (mBookRecord!!.pagePos + 1).toFloat(), | |||
| total.toFloat() | |||
| ).toFloat() | |||
| if (mBookRecord!!.pagePos > oldPosition && currProgress > lastProgress) { | |||
| mPresenter?.updateReadProgress( | |||
| mRealBookId, mReadTaskId, currProgress.toString() | |||
| ) | |||
| } | |||
| } | |||
| } | |||
| override fun finishChapter() { | |||
| } | |||
| override fun errorChapter() { | |||
| } | |||
| override fun showCategory(localId: String?) { | |||
| } | |||
| override fun onProgressSuccess(progress: Float) { | |||
| lastProgress = progress | |||
| } | |||
| } | |||
| @@ -1,730 +0,0 @@ | |||
| package com.yzx.webebook.activity; | |||
| import android.app.Activity; | |||
| import android.app.AlertDialog; | |||
| import android.content.BroadcastReceiver; | |||
| import android.content.ContentResolver; | |||
| import android.content.Context; | |||
| import android.content.Intent; | |||
| import android.content.IntentFilter; | |||
| import android.database.ContentObserver; | |||
| import android.graphics.drawable.Drawable; | |||
| import android.net.Uri; | |||
| import android.os.Build; | |||
| import android.os.Bundle; | |||
| import android.os.Handler; | |||
| import android.os.Message; | |||
| import android.os.PowerManager; | |||
| import android.provider.Settings; | |||
| import android.util.Log; | |||
| import android.view.Gravity; | |||
| import android.view.KeyEvent; | |||
| import android.view.View; | |||
| import android.view.ViewGroup; | |||
| import android.view.animation.Animation; | |||
| import android.view.animation.AnimationUtils; | |||
| import android.widget.LinearLayout; | |||
| import android.widget.ListView; | |||
| import android.widget.SeekBar; | |||
| import android.widget.TextView; | |||
| import androidx.core.content.ContextCompat; | |||
| import androidx.core.view.GravityCompat; | |||
| import androidx.drawerlayout.widget.DrawerLayout; | |||
| import com.blankj.utilcode.util.NumberUtils; | |||
| import com.google.android.material.appbar.AppBarLayout; | |||
| import com.yzx.webebook.R; | |||
| import com.yzx.webebook.activity.base.BaseActivity; | |||
| import com.yzx.webebook.adapter.CategoryAdapter; | |||
| import com.yzx.webebook.model.bean.BookChapterBean; | |||
| import com.yzx.webebook.model.bean.CollBookBean; | |||
| import com.yzx.webebook.model.local.BookRepository; | |||
| import com.yzx.webebook.model.local.ReadSettingManager; | |||
| import com.yzx.webebook.presenter.ReadPresenter; | |||
| import com.yzx.webebook.presenter.ReadView; | |||
| import com.yzx.webebook.utils.BrightnessUtils; | |||
| import com.yzx.webebook.utils.Constant; | |||
| import com.yzx.webebook.utils.LogUtils; | |||
| import com.yzx.webebook.utils.RxUtils; | |||
| import com.yzx.webebook.utils.ScreenUtils; | |||
| import com.yzx.webebook.utils.StringUtils; | |||
| import com.yzx.webebook.utils.SystemBarUtils; | |||
| import com.yzx.webebook.widget.ReadSettingDialog; | |||
| import com.yzx.webebook.widget.page.PageLoader; | |||
| import com.yzx.webebook.widget.page.PageView; | |||
| import com.yzx.webebook.widget.page.TxtChapter; | |||
| import org.jetbrains.annotations.Nullable; | |||
| import java.util.List; | |||
| import io.reactivex.disposables.Disposable; | |||
| import static android.view.View.GONE; | |||
| import static android.view.View.VISIBLE; | |||
| public class ReadActivity extends BaseActivity<ReadPresenter> implements ReadView { | |||
| private static final String TAG = "ReadActivity"; | |||
| public static final int REQUEST_MORE_SETTING = 1; | |||
| public static final String EXTRA_COLL_BOOK = "extra_coll_book"; | |||
| public static final String EXTRA_IS_COLLECTED = "extra_is_collected"; | |||
| // 注册 Brightness 的 uri | |||
| private final Uri BRIGHTNESS_MODE_URI = | |||
| Settings.System.getUriFor(Settings.System.SCREEN_BRIGHTNESS_MODE); | |||
| private final Uri BRIGHTNESS_URI = | |||
| Settings.System.getUriFor(Settings.System.SCREEN_BRIGHTNESS); | |||
| private final Uri BRIGHTNESS_ADJ_URI = | |||
| Settings.System.getUriFor("screen_auto_brightness_adj"); | |||
| private static final int WHAT_CATEGORY = 1; | |||
| private static final int WHAT_CHAPTER = 2; | |||
| DrawerLayout mDlSlide; | |||
| /*************top_menu_view*******************/ | |||
| // AppBarLayout mAblTopMenu; | |||
| // TextView mTvCommunity; | |||
| // TextView mTvBrief; | |||
| /***************content_view******************/ | |||
| PageView mPvPage; | |||
| /***************bottom_menu_view***************************/ | |||
| TextView mTvPageTip; | |||
| LinearLayout mLlBottomMenu; | |||
| TextView mTvPreChapter; | |||
| SeekBar mSbChapterProgress; | |||
| TextView mTvNextChapter; | |||
| TextView mTvCategory; | |||
| TextView mTvNightMode; | |||
| TextView mTvSetting; | |||
| /***************left slide*******************************/ | |||
| ListView mLvCategory; | |||
| /*****************view******************/ | |||
| private ReadSettingDialog mSettingDialog; | |||
| private PageLoader mPageLoader; | |||
| private Animation mTopInAnim; | |||
| private Animation mTopOutAnim; | |||
| private Animation mBottomInAnim; | |||
| private Animation mBottomOutAnim; | |||
| private CategoryAdapter mCategoryAdapter; | |||
| private CollBookBean mCollBook; | |||
| //控制屏幕常亮 | |||
| private PowerManager.WakeLock mWakeLock; | |||
| /***************params*****************/ | |||
| private boolean isCollected = false; // isFromSDCard | |||
| private boolean isNightMode = false; | |||
| private boolean isFullScreen = false; | |||
| private boolean isRegistered = false; | |||
| private String mBookId; | |||
| private String mRealBookId; | |||
| private String mReadTaskId; | |||
| private float lastProgress = 0f; | |||
| private Handler mHandler = new Handler() { | |||
| @Override | |||
| public void handleMessage(Message msg) { | |||
| super.handleMessage(msg); | |||
| switch (msg.what) { | |||
| case WHAT_CATEGORY: | |||
| mLvCategory.setSelection(mPageLoader.getChapterPos()); | |||
| break; | |||
| case WHAT_CHAPTER: | |||
| mPageLoader.openChapter(); | |||
| break; | |||
| } | |||
| } | |||
| }; | |||
| // 接收电池信息和时间更新的广播 | |||
| private BroadcastReceiver mReceiver = new BroadcastReceiver() { | |||
| @Override | |||
| public void onReceive(Context context, Intent intent) { | |||
| if (intent.getAction().equals(Intent.ACTION_BATTERY_CHANGED)) { | |||
| int level = intent.getIntExtra("level", 0); | |||
| if (mPageLoader != null) { | |||
| mPageLoader.updateBattery(level); | |||
| } | |||
| } | |||
| // 监听分钟的变化 | |||
| else if (intent.getAction().equals(Intent.ACTION_TIME_TICK)) { | |||
| if (mPageLoader != null) { | |||
| mPageLoader.updateTime(); | |||
| } | |||
| } | |||
| } | |||
| }; | |||
| // 亮度调节监听 | |||
| // 由于亮度调节没有 Broadcast 而是直接修改 ContentProvider 的。所以需要创建一个 Observer 来监听 ContentProvider 的变化情况。 | |||
| private ContentObserver mBrightObserver = new ContentObserver(new Handler()) { | |||
| @Override | |||
| public void onChange(boolean selfChange) { | |||
| onChange(selfChange, null); | |||
| } | |||
| @Override | |||
| public void onChange(boolean selfChange, Uri uri) { | |||
| super.onChange(selfChange); | |||
| // 判断当前是否跟随屏幕亮度,如果不是则返回 | |||
| if (selfChange || !mSettingDialog.isBrightFollowSystem()) return; | |||
| // 如果系统亮度改变,则修改当前 Activity 亮度 | |||
| if (BRIGHTNESS_MODE_URI.equals(uri)) { | |||
| Log.d(TAG, "亮度模式改变"); | |||
| } else if (BRIGHTNESS_URI.equals(uri) && !BrightnessUtils.isAutoBrightness(ReadActivity.this)) { | |||
| Log.d(TAG, "亮度模式为手动模式 值改变"); | |||
| BrightnessUtils.setBrightness(ReadActivity.this, BrightnessUtils.getScreenBrightness(ReadActivity.this)); | |||
| } else if (BRIGHTNESS_ADJ_URI.equals(uri) && BrightnessUtils.isAutoBrightness(ReadActivity.this)) { | |||
| Log.d(TAG, "亮度模式为自动模式 值改变"); | |||
| BrightnessUtils.setDefaultBrightness(ReadActivity.this); | |||
| } else { | |||
| Log.d(TAG, "亮度调整 其他"); | |||
| } | |||
| } | |||
| }; | |||
| @Override | |||
| protected void onCreate(Bundle savedInstanceState) { | |||
| super.onCreate(savedInstanceState); | |||
| } | |||
| @Override | |||
| public int getInflateId() { | |||
| return R.layout.activity_read; | |||
| } | |||
| @Override | |||
| public void initView() { | |||
| mDlSlide = findViewById(R.id.read_dl_slide); | |||
| // mTvCommunity = findViewById(R.id.read_tv_community); | |||
| // mTvBrief = findViewById(R.id.read_tv_brief); | |||
| mPvPage = findViewById(R.id.read_pv_page); | |||
| mTvPageTip = findViewById(R.id.read_tv_page_tip); | |||
| mLlBottomMenu = findViewById(R.id.read_ll_bottom_menu); | |||
| mTvPreChapter = findViewById(R.id.read_tv_pre_chapter); | |||
| mSbChapterProgress = findViewById(R.id.read_sb_chapter_progress); | |||
| mTvNextChapter = findViewById(R.id.read_tv_next_chapter); | |||
| mTvCategory = findViewById(R.id.read_tv_category); | |||
| mTvNightMode = findViewById(R.id.read_tv_night_mode); | |||
| mTvSetting = findViewById(R.id.read_tv_setting); | |||
| mLvCategory = findViewById(R.id.read_iv_category); | |||
| } | |||
| @Override | |||
| public void initData() { | |||
| String id = getIntent().getStringExtra("book_id"); | |||
| mReadTaskId = getIntent().getStringExtra("read_task_id"); | |||
| mRealBookId = getIntent().getStringExtra("real_book_id"); | |||
| loadBookData(id); | |||
| getMPresenter().getReadProgress(mRealBookId, mReadTaskId); | |||
| } | |||
| private void loadBookData(String id) { | |||
| mCollBook = BookRepository.getInstance().getCollBook(id); | |||
| isNightMode = ReadSettingManager.getInstance().isNightMode(); | |||
| isFullScreen = ReadSettingManager.getInstance().isFullScreen(); | |||
| mBookId = mCollBook.get_id(); | |||
| Log.d(TAG, "initData: " + mCollBook.toString()); | |||
| //获取页面加载器 | |||
| mPageLoader = mPvPage.getPageLoader(mCollBook); | |||
| //禁止滑动展示DrawerLayout | |||
| mDlSlide.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_CLOSED); | |||
| //侧边打开后,返回键能够起作用 | |||
| mDlSlide.setFocusableInTouchMode(false); | |||
| mSettingDialog = new ReadSettingDialog(this, mPageLoader); | |||
| setUpAdapter(); | |||
| //夜间模式按钮的状态 | |||
| toggleNightMode(); | |||
| //注册广播 | |||
| IntentFilter intentFilter = new IntentFilter(); | |||
| intentFilter.addAction(Intent.ACTION_BATTERY_CHANGED); | |||
| intentFilter.addAction(Intent.ACTION_TIME_TICK); | |||
| registerReceiver(mReceiver, intentFilter); | |||
| //设置当前Activity的Brightness | |||
| if (ReadSettingManager.getInstance().isBrightnessAuto()) { | |||
| BrightnessUtils.setDefaultBrightness(this); | |||
| } else { | |||
| BrightnessUtils.setBrightness(this, ReadSettingManager.getInstance().getBrightness()); | |||
| } | |||
| //初始化屏幕常亮类 | |||
| PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE); | |||
| mWakeLock = pm.newWakeLock(PowerManager.SCREEN_DIM_WAKE_LOCK, "ireader:keep bright"); | |||
| //初始化BottomMenu | |||
| initBottomMenu(); | |||
| Disposable disposable = BookRepository.getInstance() | |||
| .getBookChaptersInRx(mBookId) | |||
| .compose(RxUtils::toSimpleSingle) | |||
| .subscribe( | |||
| (bookChapterBeen, throwable) -> { | |||
| // 设置 CollBook | |||
| mPageLoader.getCollBook().setBookChapters(bookChapterBeen); | |||
| // 刷新章节列表 | |||
| mPageLoader.refreshChapterList(); | |||
| LogUtils.e(throwable); | |||
| } | |||
| ); | |||
| addDisposable(disposable); | |||
| initClick(); | |||
| } | |||
| private void saveBookInfo() { | |||
| if (mCollBook != null) { | |||
| mCollBook.setLastRead(StringUtils. | |||
| dateConvert(System.currentTimeMillis(), Constant.FORMAT_BOOK_DATE)); | |||
| BookRepository.getInstance() | |||
| .saveCollBookWithAsync(mCollBook); | |||
| } | |||
| } | |||
| private void initClick() { | |||
| mPageLoader.setOnPageChangeListener( | |||
| new PageLoader.OnPageChangeListener() { | |||
| @Override | |||
| public void onChapterChange(int pos) { | |||
| mCategoryAdapter.setChapter(pos); | |||
| } | |||
| @Override | |||
| public void requestChapters(List<TxtChapter> requestChapters) { | |||
| getMPresenter().loadChapter(mBookId, requestChapters); | |||
| mHandler.sendEmptyMessage(WHAT_CATEGORY); | |||
| //隐藏提示 | |||
| mTvPageTip.setVisibility(GONE); | |||
| } | |||
| @Override | |||
| public void onCategoryFinish(List<TxtChapter> chapters) { | |||
| for (TxtChapter chapter : chapters) { | |||
| chapter.setTitle(StringUtils.convertCC(chapter.getTitle(), mPvPage.getContext())); | |||
| } | |||
| mCategoryAdapter.refreshItems(chapters); | |||
| } | |||
| @Override | |||
| public void onPageCountChange(int count) { | |||
| mSbChapterProgress.setMax(Math.max(0, count - 1)); | |||
| mSbChapterProgress.setProgress(0); | |||
| // 如果处于错误状态,那么就冻结使用 | |||
| if (mPageLoader.getPageStatus() == PageLoader.STATUS_LOADING | |||
| || mPageLoader.getPageStatus() == PageLoader.STATUS_ERROR) { | |||
| mSbChapterProgress.setEnabled(false); | |||
| } else { | |||
| mSbChapterProgress.setEnabled(true); | |||
| } | |||
| } | |||
| @Override | |||
| public void onPageChange(int pos) { | |||
| mSbChapterProgress.post( | |||
| () -> { | |||
| mSbChapterProgress.setProgress(pos); | |||
| } | |||
| ); | |||
| } | |||
| } | |||
| ); | |||
| mSbChapterProgress.setOnSeekBarChangeListener( | |||
| new SeekBar.OnSeekBarChangeListener() { | |||
| @Override | |||
| public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { | |||
| if (mLlBottomMenu.getVisibility() == VISIBLE) { | |||
| //显示标题 | |||
| mTvPageTip.setText((progress + 1) + "/" + (mSbChapterProgress.getMax() + 1)); | |||
| mTvPageTip.setVisibility(VISIBLE); | |||
| } | |||
| } | |||
| @Override | |||
| public void onStartTrackingTouch(SeekBar seekBar) { | |||
| } | |||
| @Override | |||
| public void onStopTrackingTouch(SeekBar seekBar) { | |||
| //进行切换 | |||
| int pagePos = mSbChapterProgress.getProgress(); | |||
| if (pagePos != mPageLoader.getPagePos()) { | |||
| mPageLoader.skipToPage(pagePos); | |||
| } | |||
| //隐藏提示 | |||
| mTvPageTip.setVisibility(GONE); | |||
| } | |||
| } | |||
| ); | |||
| mPvPage.setTouchListener(new PageView.TouchListener() { | |||
| @Override | |||
| public boolean onTouch() { | |||
| return !hideReadMenu(); | |||
| } | |||
| @Override | |||
| public void center() { | |||
| toggleMenu(true); | |||
| } | |||
| @Override | |||
| public void prePage() { | |||
| } | |||
| @Override | |||
| public void nextPage() { | |||
| } | |||
| @Override | |||
| public void cancel() { | |||
| } | |||
| }); | |||
| mLvCategory.setOnItemClickListener( | |||
| (parent, view, position, id) -> { | |||
| mDlSlide.closeDrawer(GravityCompat.START); | |||
| mPageLoader.skipToChapter(position); | |||
| } | |||
| ); | |||
| mTvCategory.setOnClickListener( | |||
| (v) -> { | |||
| //移动到指定位置 | |||
| if (mCategoryAdapter.getCount() > 0) { | |||
| mLvCategory.setSelection(mPageLoader.getChapterPos()); | |||
| } | |||
| //切换菜单 | |||
| toggleMenu(true); | |||
| //打开侧滑动栏 | |||
| mDlSlide.openDrawer(GravityCompat.START); | |||
| } | |||
| ); | |||
| mTvSetting.setOnClickListener( | |||
| (v) -> { | |||
| toggleMenu(false); | |||
| mSettingDialog.show(); | |||
| } | |||
| ); | |||
| mTvPreChapter.setOnClickListener( | |||
| (v) -> { | |||
| if (mPageLoader.skipPreChapter()) { | |||
| mCategoryAdapter.setChapter(mPageLoader.getChapterPos()); | |||
| } | |||
| } | |||
| ); | |||
| mTvNextChapter.setOnClickListener( | |||
| (v) -> { | |||
| if (mPageLoader.skipNextChapter()) { | |||
| mCategoryAdapter.setChapter(mPageLoader.getChapterPos()); | |||
| } | |||
| } | |||
| ); | |||
| mTvNightMode.setOnClickListener( | |||
| (v) -> { | |||
| if (isNightMode) { | |||
| isNightMode = false; | |||
| } else { | |||
| isNightMode = true; | |||
| } | |||
| mPageLoader.setNightMode(isNightMode); | |||
| toggleNightMode(); | |||
| } | |||
| ); | |||
| } | |||
| @Nullable | |||
| @Override | |||
| public ReadPresenter initPresenter() { | |||
| return new ReadPresenter(this); | |||
| } | |||
| @Override | |||
| public void showCategory(String localId) { | |||
| loadBookData(localId); | |||
| } | |||
| @Override | |||
| public void finishChapter() { | |||
| } | |||
| @Override | |||
| public void errorChapter() { | |||
| } | |||
| private void initBottomMenu() { | |||
| //判断是否全屏 | |||
| if (ReadSettingManager.getInstance().isFullScreen()) { | |||
| //还需要设置mBottomMenu的底部高度 | |||
| ViewGroup.MarginLayoutParams params = (ViewGroup.MarginLayoutParams) mLlBottomMenu.getLayoutParams(); | |||
| params.bottomMargin = ScreenUtils.getNavigationBarHeight(); | |||
| mLlBottomMenu.setLayoutParams(params); | |||
| } else { | |||
| //设置mBottomMenu的底部距离 | |||
| ViewGroup.MarginLayoutParams params = (ViewGroup.MarginLayoutParams) mLlBottomMenu.getLayoutParams(); | |||
| params.bottomMargin = 0; | |||
| mLlBottomMenu.setLayoutParams(params); | |||
| } | |||
| } | |||
| @Override | |||
| public void onWindowFocusChanged(boolean hasFocus) { | |||
| super.onWindowFocusChanged(hasFocus); | |||
| } | |||
| private void toggleNightMode() { | |||
| if (isNightMode) { | |||
| mTvNightMode.setText("日间"); | |||
| Drawable drawable = ContextCompat.getDrawable(this, R.mipmap.ic_read_menu_morning); | |||
| mTvNightMode.setCompoundDrawablesWithIntrinsicBounds(null, drawable, null, null); | |||
| } else { | |||
| mTvNightMode.setText("夜间"); | |||
| Drawable drawable = ContextCompat.getDrawable(this, R.mipmap.ic_read_menu_night); | |||
| mTvNightMode.setCompoundDrawablesWithIntrinsicBounds(null, drawable, null, null); | |||
| } | |||
| } | |||
| private void setUpAdapter() { | |||
| mCategoryAdapter = new CategoryAdapter(); | |||
| mLvCategory.setAdapter(mCategoryAdapter); | |||
| mLvCategory.setFastScrollEnabled(true); | |||
| } | |||
| // 注册亮度观察者 | |||
| private void registerBrightObserver() { | |||
| try { | |||
| if (mBrightObserver != null) { | |||
| if (!isRegistered) { | |||
| final ContentResolver cr = getContentResolver(); | |||
| cr.unregisterContentObserver(mBrightObserver); | |||
| cr.registerContentObserver(BRIGHTNESS_MODE_URI, false, mBrightObserver); | |||
| cr.registerContentObserver(BRIGHTNESS_URI, false, mBrightObserver); | |||
| cr.registerContentObserver(BRIGHTNESS_ADJ_URI, false, mBrightObserver); | |||
| isRegistered = true; | |||
| } | |||
| } | |||
| } catch (Throwable throwable) { | |||
| LogUtils.e(TAG, "register mBrightObserver error! " + throwable); | |||
| } | |||
| } | |||
| //解注册 | |||
| private void unregisterBrightObserver() { | |||
| try { | |||
| if (mBrightObserver != null) { | |||
| if (isRegistered) { | |||
| getContentResolver().unregisterContentObserver(mBrightObserver); | |||
| isRegistered = false; | |||
| } | |||
| } | |||
| } catch (Throwable throwable) { | |||
| LogUtils.e(TAG, "unregister BrightnessObserver error! " + throwable); | |||
| } | |||
| } | |||
| /** | |||
| * 隐藏阅读界面的菜单显示 | |||
| * | |||
| * @return 是否隐藏成功 | |||
| */ | |||
| private boolean hideReadMenu() { | |||
| if (mLlBottomMenu.getVisibility() == VISIBLE) { | |||
| toggleMenu(true); | |||
| return true; | |||
| } else if (mSettingDialog.isShowing()) { | |||
| mSettingDialog.dismiss(); | |||
| return true; | |||
| } | |||
| return false; | |||
| } | |||
| /** | |||
| * 切换菜单栏的可视状态 | |||
| * 默认是隐藏的 | |||
| */ | |||
| private void toggleMenu(boolean hideStatusBar) { | |||
| initMenuAnim(); | |||
| if (mLlBottomMenu.getVisibility() == View.VISIBLE) { | |||
| //关闭 | |||
| mLlBottomMenu.setVisibility(GONE); | |||
| mTvPageTip.setVisibility(GONE); | |||
| } else { | |||
| mLlBottomMenu.setVisibility(View.VISIBLE); | |||
| } | |||
| } | |||
| //初始化菜单动画 | |||
| private void initMenuAnim() { | |||
| if (mTopInAnim != null) return; | |||
| mTopInAnim = AnimationUtils.loadAnimation(this, R.anim.slide_top_in); | |||
| mTopOutAnim = AnimationUtils.loadAnimation(this, R.anim.slide_top_out); | |||
| mBottomInAnim = AnimationUtils.loadAnimation(this, R.anim.slide_bottom_in); | |||
| mBottomOutAnim = AnimationUtils.loadAnimation(this, R.anim.slide_bottom_out); | |||
| //退出的速度要快 | |||
| mTopOutAnim.setDuration(200); | |||
| mBottomOutAnim.setDuration(200); | |||
| } | |||
| @Override | |||
| public void onBackPressed() { | |||
| if (mLlBottomMenu.getVisibility() == View.VISIBLE) { | |||
| // 非全屏下才收缩,全屏下直接退出 | |||
| if (!ReadSettingManager.getInstance().isFullScreen()) { | |||
| toggleMenu(true); | |||
| return; | |||
| } | |||
| } else if (mSettingDialog.isShowing()) { | |||
| mSettingDialog.dismiss(); | |||
| return; | |||
| } else if (mDlSlide.isDrawerOpen(GravityCompat.START)) { | |||
| mDlSlide.closeDrawer(GravityCompat.START); | |||
| return; | |||
| } | |||
| if (!mCollBook.isLocal() && !isCollected | |||
| && !mCollBook.getBookChapters().isEmpty() && false) { | |||
| AlertDialog alertDialog = new AlertDialog.Builder(this) | |||
| .setTitle("加入书架") | |||
| .setMessage("喜欢本书就加入书架吧") | |||
| .setPositiveButton("确定", (dialog, which) -> { | |||
| //设置为已收藏 | |||
| isCollected = true; | |||
| //设置阅读时间 | |||
| mCollBook.setLastRead(StringUtils. | |||
| dateConvert(System.currentTimeMillis(), Constant.FORMAT_BOOK_DATE)); | |||
| BookRepository.getInstance() | |||
| .saveCollBookWithAsync(mCollBook); | |||
| exit(); | |||
| }) | |||
| .setNegativeButton("取消", (dialog, which) -> { | |||
| exit(); | |||
| }).create(); | |||
| alertDialog.show(); | |||
| } else { | |||
| exit(); | |||
| } | |||
| } | |||
| // 退出 | |||
| private void exit() { | |||
| // 退出 | |||
| super.onBackPressed(); | |||
| } | |||
| @Override | |||
| protected void onStart() { | |||
| super.onStart(); | |||
| registerBrightObserver(); | |||
| } | |||
| @Override | |||
| protected void onResume() { | |||
| super.onResume(); | |||
| if (mWakeLock != null) { | |||
| mWakeLock.acquire(); | |||
| } | |||
| } | |||
| @Override | |||
| protected void onPause() { | |||
| super.onPause(); | |||
| if (mWakeLock != null) { | |||
| mWakeLock.release(); | |||
| } | |||
| if (mPageLoader != null) { | |||
| saveBookInfo(); | |||
| mPageLoader.saveRecord(); | |||
| } | |||
| if (getMPresenter() != null && mPageLoader != null) { | |||
| float currProgress = Float.parseFloat(mPageLoader.getPercent()); | |||
| if (currProgress > lastProgress) { | |||
| getMPresenter().updateReadProgress(mRealBookId, mReadTaskId, String.valueOf(mPageLoader.getPercent())); | |||
| } | |||
| } | |||
| } | |||
| @Override | |||
| protected void onStop() { | |||
| super.onStop(); | |||
| unregisterBrightObserver(); | |||
| } | |||
| @Override | |||
| protected void onDestroy() { | |||
| super.onDestroy(); | |||
| unregisterReceiver(mReceiver); | |||
| mHandler.removeMessages(WHAT_CATEGORY); | |||
| mHandler.removeMessages(WHAT_CHAPTER); | |||
| mPageLoader.closeBook(); | |||
| mPageLoader = null; | |||
| } | |||
| @Override | |||
| public boolean onKeyDown(int keyCode, KeyEvent event) { | |||
| boolean isVolumeTurnPage = ReadSettingManager | |||
| .getInstance().isVolumeTurnPage(); | |||
| switch (keyCode) { | |||
| case KeyEvent.KEYCODE_VOLUME_UP: | |||
| if (isVolumeTurnPage) { | |||
| return mPageLoader.skipToPrePage(); | |||
| } | |||
| break; | |||
| case KeyEvent.KEYCODE_VOLUME_DOWN: | |||
| if (isVolumeTurnPage) { | |||
| return mPageLoader.skipToNextPage(); | |||
| } | |||
| break; | |||
| } | |||
| return super.onKeyDown(keyCode, event); | |||
| } | |||
| @Override | |||
| protected void onActivityResult(int requestCode, int resultCode, Intent data) { | |||
| super.onActivityResult(requestCode, resultCode, data); | |||
| if (requestCode == REQUEST_MORE_SETTING) { | |||
| boolean fullScreen = ReadSettingManager.getInstance().isFullScreen(); | |||
| if (isFullScreen != fullScreen) { | |||
| isFullScreen = fullScreen; | |||
| // 刷新BottomMenu | |||
| initBottomMenu(); | |||
| } | |||
| } | |||
| } | |||
| @Override | |||
| public void onProgressSuccess(float progress) { | |||
| lastProgress = progress; | |||
| } | |||
| } | |||
| @@ -1,19 +0,0 @@ | |||
| package com.yzx.webebook.activity | |||
| import androidx.appcompat.app.AppCompatActivity | |||
| import android.os.Bundle | |||
| import com.yzx.webebook.activity.base.BaseWeexActivity | |||
| class WeexTestActivity : BaseWeexActivity() { | |||
| override fun initView() { | |||
| } | |||
| override fun initData() { | |||
| val url = intent.getStringExtra("url") ?: "" | |||
| val params = intent.getStringExtra("params") ?: "" | |||
| setUrlInfo(url, "RaderPage", params) | |||
| } | |||
| } | |||
| @@ -1,201 +0,0 @@ | |||
| package com.yzx.webebook.activity.base | |||
| import android.annotation.SuppressLint | |||
| import android.os.Bundle | |||
| import android.os.Handler | |||
| import android.os.Message | |||
| import android.util.Log | |||
| import android.view.View | |||
| import androidx.appcompat.app.AppCompatActivity | |||
| import com.gyf.immersionbar.ktx.immersionBar | |||
| import com.yzx.webebook.R | |||
| import com.yzx.webebook.modules.ActivityWXModule | |||
| import com.yzx.webebook.utils.StringUtils | |||
| import kotlinx.android.synthetic.main.activity_base_weex.* | |||
| import org.apache.weex.IWXRenderListener | |||
| import org.apache.weex.WXSDKEngine | |||
| import org.apache.weex.WXSDKInstance | |||
| import org.apache.weex.common.WXRenderStrategy | |||
| import org.apache.weex.utils.WXFileUtils | |||
| /** | |||
| * 类名:BaseActivity | |||
| * 作者:Yun.Lei | |||
| * 功能: | |||
| * 创建日期:2020年5月6日14:27:04 | |||
| * 修改人: | |||
| * 修改时间: | |||
| * 修改备注: | |||
| */ | |||
| abstract class BaseWeexActivity : AppCompatActivity(), IWXRenderListener { | |||
| /** | |||
| * 初始化视图操作在这里执行,执行时机为onCreate之后 | |||
| */ | |||
| abstract fun initView(): Unit | |||
| /** | |||
| * 数据初始化在这里执行,执行时机为initView之后 | |||
| */ | |||
| abstract fun initData(): Unit | |||
| var mWXSDKInstance: WXSDKInstance? = null | |||
| var pageName: String = "WeexPage" | |||
| var bundleUrl: String = "" | |||
| var params: String = "" | |||
| private val handler: Handler = @SuppressLint("HandlerLeak") | |||
| object : Handler() { | |||
| override fun handleMessage(msg: Message) { | |||
| super.handleMessage(msg) | |||
| /** | |||
| * 轮询访问 WXSDKEngine 初始化状态 防止异步造成的初始化失败问题 | |||
| */ | |||
| if (msg.what == 1) { | |||
| Log.i( | |||
| "welog", | |||
| "WXSDKEngine.isInitializedActivity: " + WXSDKEngine.isInitialized() | |||
| ) | |||
| //&& !StringUtils.isEmpty(pageName) && !StringUtils.isEmpty( bundleUrl) | |||
| if (WXSDKEngine.isInitialized()) { | |||
| startRender() | |||
| } else { | |||
| sendEmptyMessageDelayed(1, 300) | |||
| } | |||
| } | |||
| } | |||
| } | |||
| override fun onCreate(savedInstanceState: Bundle?) { | |||
| super.onCreate(savedInstanceState) | |||
| setContentView(R.layout.activity_base_weex) | |||
| initView() | |||
| initData() | |||
| setStatusBar() | |||
| mWXSDKInstance = WXSDKInstance(this) | |||
| mWXSDKInstance!!.registerRenderListener(this) | |||
| startRender() | |||
| if (WXSDKEngine.isInitialized()) { | |||
| } else { | |||
| handler.sendEmptyMessageDelayed(1, 300) | |||
| } | |||
| } | |||
| /** | |||
| * WXSDKEngine 初始化成功后 开始渲染 | |||
| */ | |||
| private fun startRender() { | |||
| /** | |||
| * 防止空指针 | |||
| */ | |||
| if (mWXSDKInstance == null) { | |||
| mWXSDKInstance = WXSDKInstance(this) | |||
| mWXSDKInstance!!.registerRenderListener(this) | |||
| } | |||
| /** | |||
| * 渲染远程js | |||
| */ | |||
| // bundleUrl = "http://dotwe.org/raw/dist/38e202c16bdfefbdb88a8754f975454c.bundle.wx"; | |||
| try { | |||
| Log.d("welog", "开始加载") | |||
| bundleUrl = "https://oa.live.educlouddata.com/index.js"; | |||
| mWXSDKInstance?.renderByUrl("https://oa.live.educlouddata.com", bundleUrl, null, null, WXRenderStrategy.APPEND_ASYNC) | |||
| Log.d("welog", "加载中") | |||
| }catch (e:Exception){ | |||
| Log.d("welog", "加载失败,$e") | |||
| } | |||
| /** | |||
| * 渲染本地js | |||
| */ | |||
| // val options = mapOf("params" to this.params) | |||
| // Log.d("welog", "startRender: $options") | |||
| // mWXSDKInstance!!.render( | |||
| // pageName, | |||
| // WXFileUtils.loadAsset(bundleUrl, this), | |||
| // options, | |||
| // null, | |||
| // WXRenderStrategy.APPEND_ASYNC | |||
| // ) | |||
| } | |||
| fun setUrlInfo(url: String, pageName: String, params: String = "") { | |||
| this.pageName = pageName | |||
| this.bundleUrl = url | |||
| this.params = params | |||
| } | |||
| open fun setStatusBar() { | |||
| immersionBar { | |||
| statusBarColor(R.color.white) | |||
| fitsSystemWindows(true) | |||
| statusBarDarkFont(true, 0.2f) | |||
| keyboardEnable(true) | |||
| init() | |||
| } | |||
| btnBack.setOnClickListener { onBackPressed() } | |||
| btnClose.setOnClickListener { | |||
| finish() | |||
| } | |||
| } | |||
| override fun onViewCreated(instance: WXSDKInstance?, view: View) { | |||
| Log.d("welog", "onViewCreated:") | |||
| if (view.parent == null) { | |||
| webLayout.addView(view); | |||
| } | |||
| webLayout.requestLayout(); | |||
| } | |||
| override fun onRenderSuccess(instance: WXSDKInstance?, width: Int, height: Int) { | |||
| Log.d("welog", "onRenderSuccess:") | |||
| } | |||
| override fun onRefreshSuccess(instance: WXSDKInstance?, width: Int, height: Int) { | |||
| Log.d("welog", "onRefreshSuccess:") | |||
| } | |||
| override fun onException(instance: WXSDKInstance?, errCode: String?, msg: String?) { | |||
| Log.d("welog", "onException: $errCode//$msg") | |||
| handler.sendEmptyMessageDelayed(1, 300) | |||
| } | |||
| override fun onResume() { | |||
| super.onResume() | |||
| if (mWXSDKInstance != null) { | |||
| mWXSDKInstance!!.onActivityResume() | |||
| } | |||
| } | |||
| override fun onPause() { | |||
| super.onPause() | |||
| if (mWXSDKInstance != null) { | |||
| mWXSDKInstance!!.onActivityPause() | |||
| } | |||
| } | |||
| override fun onStop() { | |||
| super.onStop() | |||
| if (mWXSDKInstance != null) { | |||
| mWXSDKInstance!!.onActivityStop() | |||
| } | |||
| } | |||
| override fun onBackPressed() { | |||
| super.onBackPressed() | |||
| } | |||
| override fun onDestroy() { | |||
| super.onDestroy() | |||
| if (mWXSDKInstance != null) { | |||
| mWXSDKInstance!!.onActivityDestroy() | |||
| } | |||
| } | |||
| } | |||
| @@ -1,38 +0,0 @@ | |||
| package com.yzx.webebook.adapter; | |||
| import android.view.View; | |||
| import android.view.ViewGroup; | |||
| import com.yzx.webebook.adapter.base.EasyAdapter; | |||
| import com.yzx.webebook.adapter.base.IViewHolder; | |||
| import com.yzx.webebook.widget.page.TxtChapter; | |||
| /** | |||
| * Created by newbiechen on 17-6-5. | |||
| */ | |||
| public class CategoryAdapter extends EasyAdapter<TxtChapter> { | |||
| private int currentSelected = 0; | |||
| @Override | |||
| protected IViewHolder<TxtChapter> onCreateViewHolder(int viewType) { | |||
| return new CategoryHolder(); | |||
| } | |||
| @Override | |||
| public View getView(int position, View convertView, ViewGroup parent) { | |||
| View view = super.getView(position, convertView, parent); | |||
| CategoryHolder holder = (CategoryHolder) view.getTag(); | |||
| if (position == currentSelected){ | |||
| holder.setSelectedChapter(); | |||
| } | |||
| return view; | |||
| } | |||
| public void setChapter(int pos){ | |||
| currentSelected = pos; | |||
| notifyDataSetChanged(); | |||
| } | |||
| } | |||
| @@ -1,63 +0,0 @@ | |||
| package com.yzx.webebook.adapter; | |||
| import android.graphics.drawable.Drawable; | |||
| import android.widget.TextView; | |||
| import androidx.core.content.ContextCompat; | |||
| import com.yzx.webebook.R; | |||
| import com.yzx.webebook.adapter.base.ViewHolderImpl; | |||
| import com.yzx.webebook.utils.BookManager; | |||
| import com.yzx.webebook.widget.page.TxtChapter; | |||
| /** | |||
| * Created by newbiechen on 17-5-16. | |||
| */ | |||
| public class CategoryHolder extends ViewHolderImpl<TxtChapter> { | |||
| private TextView mTvChapter; | |||
| @Override | |||
| public void initView() { | |||
| mTvChapter = findById(R.id.category_tv_chapter); | |||
| } | |||
| @Override | |||
| public void onBind(TxtChapter value, int pos){ | |||
| //首先判断是否该章已下载 | |||
| Drawable drawable = null; | |||
| //TODO:目录显示设计的有点不好,需要靠成员变量是否为null来判断。 | |||
| //如果没有链接地址表示是本地文件 | |||
| if (value.getLink() == null){ | |||
| drawable = ContextCompat.getDrawable(getContext(),R.drawable.selector_category_load); | |||
| } | |||
| else { | |||
| if (value.getBookId() != null | |||
| && BookManager | |||
| .isChapterCached(value.getBookId(),value.getTitle())){ | |||
| drawable = ContextCompat.getDrawable(getContext(),R.drawable.selector_category_load); | |||
| } | |||
| else { | |||
| drawable = ContextCompat.getDrawable(getContext(), R.drawable.selector_category_unload); | |||
| } | |||
| } | |||
| mTvChapter.setSelected(false); | |||
| mTvChapter.setTextColor(ContextCompat.getColor(getContext(),R.color.nb_text_default)); | |||
| mTvChapter.setCompoundDrawablesWithIntrinsicBounds(drawable,null,null,null); | |||
| mTvChapter.setText(value.getTitle()); | |||
| } | |||
| @Override | |||
| protected int getItemLayoutId() { | |||
| return R.layout.item_category; | |||
| } | |||
| public void setSelectedChapter(){ | |||
| mTvChapter.setTextColor(ContextCompat.getColor(getContext(),R.color.light_red)); | |||
| mTvChapter.setSelected(true); | |||
| } | |||
| } | |||
| @@ -1,21 +0,0 @@ | |||
| package com.yzx.webebook.adapter | |||
| import android.widget.ImageView | |||
| import com.bumptech.glide.Glide | |||
| import org.apache.weex.WXEnvironment | |||
| import org.apache.weex.adapter.IWXImgLoaderAdapter | |||
| import org.apache.weex.common.WXImageStrategy | |||
| import org.apache.weex.dom.WXImageQuality | |||
| class ImageAdapter:IWXImgLoaderAdapter { | |||
| override fun setImage( | |||
| url: String?, | |||
| view: ImageView?, | |||
| quality: WXImageQuality?, | |||
| strategy: WXImageStrategy? | |||
| ) { | |||
| Glide.with(WXEnvironment.sApplication) | |||
| .load(url) | |||
| .into(view!!) | |||
| } | |||
| } | |||
| @@ -1,46 +0,0 @@ | |||
| package com.yzx.webebook.adapter; | |||
| import android.graphics.drawable.Drawable; | |||
| import android.view.View; | |||
| import androidx.recyclerview.widget.RecyclerView; | |||
| import com.yzx.webebook.adapter.base.BaseListAdapter; | |||
| import com.yzx.webebook.adapter.base.BaseViewHolder; | |||
| import com.yzx.webebook.adapter.base.IViewHolder; | |||
| import com.yzx.webebook.widget.page.PageStyle; | |||
| /** | |||
| * Created by newbiechen on 17-5-19. | |||
| */ | |||
| public class PageStyleAdapter extends BaseListAdapter<Drawable> { | |||
| private int currentChecked; | |||
| @Override | |||
| protected IViewHolder<Drawable> createViewHolder(int viewType) { | |||
| return new PageStyleHolder(); | |||
| } | |||
| @Override | |||
| public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) { | |||
| super.onBindViewHolder(holder, position); | |||
| IViewHolder iHolder = ((BaseViewHolder) holder).holder; | |||
| PageStyleHolder pageStyleHolder = (PageStyleHolder) iHolder; | |||
| if (currentChecked == position){ | |||
| pageStyleHolder.setChecked(); | |||
| } | |||
| } | |||
| public void setPageStyleChecked(PageStyle pageStyle){ | |||
| currentChecked = pageStyle.ordinal(); | |||
| } | |||
| @Override | |||
| protected void onItemClick(View v, int pos) { | |||
| super.onItemClick(v, pos); | |||
| currentChecked = pos; | |||
| notifyDataSetChanged(); | |||
| } | |||
| } | |||
| @@ -1,40 +0,0 @@ | |||
| package com.yzx.webebook.adapter; | |||
| import android.graphics.drawable.Drawable; | |||
| import android.view.View; | |||
| import android.widget.ImageView; | |||
| import com.yzx.webebook.R; | |||
| import com.yzx.webebook.adapter.base.ViewHolderImpl; | |||
| /** | |||
| * Created by newbiechen on 17-5-19. | |||
| */ | |||
| public class PageStyleHolder extends ViewHolderImpl<Drawable> { | |||
| private View mReadBg; | |||
| private ImageView mIvChecked; | |||
| @Override | |||
| public void initView() { | |||
| mReadBg = findById(R.id.read_bg_view); | |||
| mIvChecked = findById(R.id.read_bg_iv_checked); | |||
| } | |||
| @Override | |||
| public void onBind(Drawable data, int pos) { | |||
| mReadBg.setBackground(data); | |||
| mIvChecked.setVisibility(View.GONE); | |||
| } | |||
| @Override | |||
| protected int getItemLayoutId() { | |||
| return R.layout.item_read_bg; | |||
| } | |||
| public void setChecked(){ | |||
| mIvChecked.setVisibility(View.VISIBLE); | |||
| } | |||
| } | |||
| @@ -1,116 +0,0 @@ | |||
| package com.yzx.webebook.model.bean; | |||
| import org.greenrobot.greendao.annotation.Entity; | |||
| import org.greenrobot.greendao.annotation.Generated; | |||
| import org.greenrobot.greendao.annotation.Id; | |||
| /** | |||
| * Created by newbiechen on 17-4-20. | |||
| * 作者 | |||
| */ | |||
| @Entity | |||
| public class AuthorBean { | |||
| /** | |||
| * _id : 553136ba70feaa764a096f6f | |||
| * avatar : /avatar/26/eb/26ebf8ede76d7f52cd377960bd66383b | |||
| * nickname : 九歌 | |||
| * activityAvatar : | |||
| * type : normal | |||
| * lv : 8 | |||
| * gender : female | |||
| */ | |||
| @Id | |||
| private String _id; | |||
| private String avatar; | |||
| private String nickname; | |||
| private String activityAvatar; | |||
| private String type; | |||
| private int lv; | |||
| private String gender; | |||
| @Generated(hash = 1152582024) | |||
| public AuthorBean(String _id, String avatar, String nickname, | |||
| String activityAvatar, String type, int lv, String gender) { | |||
| this._id = _id; | |||
| this.avatar = avatar; | |||
| this.nickname = nickname; | |||
| this.activityAvatar = activityAvatar; | |||
| this.type = type; | |||
| this.lv = lv; | |||
| this.gender = gender; | |||
| } | |||
| @Generated(hash = 1694633584) | |||
| public AuthorBean() { | |||
| } | |||
| public String get_id() { | |||
| return _id; | |||
| } | |||
| public void set_id(String _id) { | |||
| this._id = _id; | |||
| } | |||
| public String getAvatar() { | |||
| return avatar; | |||
| } | |||
| public void setAvatar(String avatar) { | |||
| this.avatar = avatar; | |||
| } | |||
| public String getNickname() { | |||
| return nickname; | |||
| } | |||
| public void setNickname(String nickname) { | |||
| this.nickname = nickname; | |||
| } | |||
| public String getActivityAvatar() { | |||
| return activityAvatar; | |||
| } | |||
| public void setActivityAvatar(String activityAvatar) { | |||
| this.activityAvatar = activityAvatar; | |||
| } | |||
| public String getType() { | |||
| return type; | |||
| } | |||
| public void setType(String type) { | |||
| this.type = type; | |||
| } | |||
| public int getLv() { | |||
| return lv; | |||
| } | |||
| public void setLv(int lv) { | |||
| this.lv = lv; | |||
| } | |||
| public String getGender() { | |||
| return gender; | |||
| } | |||
| public void setGender(String gender) { | |||
| this.gender = gender; | |||
| } | |||
| @Override | |||
| public String toString() { | |||
| return "AuthorBean{" + | |||
| "_id='" + _id + '\'' + | |||
| ", avatar='" + avatar + '\'' + | |||
| ", nickname='" + nickname + '\'' + | |||
| ", activityAvatar='" + activityAvatar + '\'' + | |||
| ", type='" + type + '\'' + | |||
| ", lv=" + lv + | |||
| ", gender='" + gender + '\'' + | |||
| '}'; | |||
| } | |||
| } | |||
| @@ -1,146 +0,0 @@ | |||
| package com.yzx.webebook.model.bean; | |||
| import org.greenrobot.greendao.annotation.Entity; | |||
| import org.greenrobot.greendao.annotation.Generated; | |||
| import org.greenrobot.greendao.annotation.Id; | |||
| import org.greenrobot.greendao.annotation.Index; | |||
| import java.io.Serializable; | |||
| /** | |||
| * Created by newbiechen on 17-5-10. | |||
| * 书的章节链接(作为下载的进度数据) | |||
| * 同时作为网络章节和本地章节 (没有找到更好分离两者的办法) | |||
| */ | |||
| @Entity | |||
| public class BookChapterBean implements Serializable{ | |||
| private static final long serialVersionUID = 56423411313L; | |||
| /** | |||
| * title : 第一章 他叫白小纯 | |||
| * link : http://read.qidian.com/chapter/rJgN8tJ_cVdRGoWu-UQg7Q2/6jr-buLIUJSaGfXRMrUjdw2 | |||
| * unreadble : false | |||
| */ | |||
| @Id | |||
| private String id; | |||
| private String link; | |||
| private String title; | |||
| //所属的下载任务 | |||
| private String taskName; | |||
| private boolean unreadble; | |||
| //所属的书籍 | |||
| @Index | |||
| private String bookId; | |||
| //本地书籍参数 | |||
| //在书籍文件中的起始位置 | |||
| private long start; | |||
| //在书籍文件中的终止位置 | |||
| private long end; | |||
| @Generated(hash = 1508543635) | |||
| public BookChapterBean(String id, String link, String title, String taskName, | |||
| boolean unreadble, String bookId, long start, long end) { | |||
| this.id = id; | |||
| this.link = link; | |||
| this.title = title; | |||
| this.taskName = taskName; | |||
| this.unreadble = unreadble; | |||
| this.bookId = bookId; | |||
| this.start = start; | |||
| this.end = end; | |||
| } | |||
| @Generated(hash = 853839616) | |||
| public BookChapterBean() { | |||
| } | |||
| public String getTitle() { | |||
| return title; | |||
| } | |||
| public void setTitle(String title) { | |||
| this.title = title; | |||
| } | |||
| public String getLink() { | |||
| return link; | |||
| } | |||
| public void setLink(String link) { | |||
| this.link = link; | |||
| } | |||
| public boolean isUnreadble() { | |||
| return unreadble; | |||
| } | |||
| public void setUnreadble(boolean unreadble) { | |||
| this.unreadble = unreadble; | |||
| } | |||
| public String getTaskName() { | |||
| return taskName; | |||
| } | |||
| public void setTaskName(String taskName) { | |||
| this.taskName = taskName; | |||
| } | |||
| public boolean getUnreadble() { | |||
| return this.unreadble; | |||
| } | |||
| public String getBookId() { | |||
| return bookId; | |||
| } | |||
| public void setBookId(String bookId) { | |||
| this.bookId = bookId; | |||
| } | |||
| public String getId() { | |||
| return id; | |||
| } | |||
| public void setId(String id) { | |||
| this.id = id; | |||
| } | |||
| 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{" + | |||
| "id='" + id + '\'' + | |||
| ", link='" + link + '\'' + | |||
| ", title='" + title + '\'' + | |||
| ", taskName='" + taskName + '\'' + | |||
| ", unreadble=" + unreadble + | |||
| ", bookId='" + bookId + '\'' + | |||
| ", start=" + start + | |||
| ", end=" + end + | |||
| '}'; | |||
| } | |||
| } | |||
| @@ -1,38 +0,0 @@ | |||
| package com.yzx.webebook.model.bean; | |||
| import org.greenrobot.greendao.annotation.Entity; | |||
| import org.greenrobot.greendao.annotation.Id; | |||
| import org.greenrobot.greendao.annotation.Generated; | |||
| @Entity | |||
| public class BookCount { | |||
| @Id | |||
| private String _id; // 本地书籍中,path 的 md5 值作为本地书籍的 id | |||
| private int total; | |||
| @Generated(hash = 433479827) | |||
| public BookCount(String _id, int total) { | |||
| this._id = _id; | |||
| this.total = total; | |||
| } | |||
| @Generated(hash = 2056164259) | |||
| public BookCount() { | |||
| } | |||
| public int getTotal() { | |||
| return total; | |||
| } | |||
| public String get_id() { | |||
| return _id; | |||
| } | |||
| public void set_id(String _id) { | |||
| this._id = _id; | |||
| } | |||
| public void setTotal(int total) { | |||
| this.total = total; | |||
| } | |||
| } | |||
| @@ -1,54 +0,0 @@ | |||
| package com.yzx.webebook.model.bean; | |||
| import org.greenrobot.greendao.annotation.Entity; | |||
| import org.greenrobot.greendao.annotation.Generated; | |||
| import org.greenrobot.greendao.annotation.Id; | |||
| /** | |||
| * Created by newbiechen on 17-5-20. | |||
| */ | |||
| @Entity | |||
| public class BookRecordBean { | |||
| //所属的书的id | |||
| @Id | |||
| private String bookId; | |||
| //阅读到了第几章 | |||
| private int chapter; | |||
| //当前的页码 | |||
| private int pagePos; | |||
| @Generated(hash = 340380968) | |||
| public BookRecordBean(String bookId, int chapter, int pagePos) { | |||
| this.bookId = bookId; | |||
| this.chapter = chapter; | |||
| this.pagePos = pagePos; | |||
| } | |||
| @Generated(hash = 398068002) | |||
| public BookRecordBean() { | |||
| } | |||
| public String getBookId() { | |||
| return bookId; | |||
| } | |||
| public void setBookId(String bookId) { | |||
| this.bookId = bookId; | |||
| } | |||
| public int getChapter() { | |||
| return chapter; | |||
| } | |||
| public void setChapter(int chapter) { | |||
| this.chapter = chapter; | |||
| } | |||
| public int getPagePos() { | |||
| return pagePos; | |||
| } | |||
| public void setPagePos(int pagePos) { | |||
| this.pagePos = pagePos; | |||
| } | |||
| } | |||
| @@ -1,89 +0,0 @@ | |||
| package com.yzx.webebook.model.bean; | |||
| /** | |||
| * Created by newbiechen on 17-5-10. | |||
| */ | |||
| public class ChapterInfoBean { | |||
| /** | |||
| * title : 第一章 他叫白小纯 | |||
| * body : 帽儿山,位于东林山脉中,山下有一个村子,民风淳朴,以耕田为生,与世隔绝。 | |||
| 清晨,村庄的大门前,整个村子里的乡亲,正为一个十五六岁少年送别,这少年瘦弱,但却白白净净,看起来很是乖巧,衣着尽管是寻常的青衫,可却洗的泛白,穿在这少年的身上,与他目中的纯净搭配在一起,透出一股子灵动。 | |||
| 他叫白小纯。 | |||
| “父老乡亲们,我要去修仙了,可我舍不得你们啊。”少年满脸不舍,原本就乖巧的样子,此刻看起来更为纯朴。 | |||
| 四周的乡亲,面面相觑,顿时摆出难舍之色。 | |||
| “小纯,你爹娘走的早,你是个……好孩子!!难道你不想长生了么,成为仙人就可以长生,能活的很久很久,走吧,雏鹰长大,总有飞出去的那一天。”人群内走出一个头发花白的老者,说道好孩子三个字时,他顿了一下。 | |||
| “在外面遇到任何事情,都要坚持下去,走出村子,就不要回来,因为你的路在前方!”老人神色慈祥,拍了拍少年的肩膀。 | |||
| “长生……”白小纯身体一震,目中慢慢坚定起来,在老者以及四周乡亲鼓励的目光下,他重重的点了点头,深深的看了一眼四周的乡亲,转身迈着大步,渐渐走出了村子。 | |||
| 眼看少年的身影远去,村中的众人,一个个都激动起来,目中的难舍刹那就被喜悦代替,那之前满脸慈祥的老者,此刻也在颤抖,眼中流下泪水。 | |||
| “苍天有眼,这白鼠狼,他终于……终于走了,是谁告诉他在附近看到仙人的,你为村子立下了大功!” | |||
| “这白鼠狼终于肯离开了,可怜我家的几只鸡,就因为这白鼠狼怕鸡打鸣,不知用了什么方法,唆使一群孩子吃鸡肉,把全村的鸡都给吃的干干净净……” | |||
| “今天过年了!”欢呼之声,立刻在这不大的村子里,沸腾而起,甚至有人拿出了锣鼓,高兴的敲打起来。 | |||
| 村子外,白小纯还没等走远,他就听到了身后村子内,传出了敲锣打鼓的声音,还夹着欢呼。 | |||
| 白小纯脚步一顿,神色有些古怪,干咳一声,伴随着耳边传来的锣鼓,白小纯顺着山路,走上了帽儿山。 | |||
| 这帽儿山虽不高,却灌木杂多,虽是清晨,可看起来也是黑压压一片,很是安静。 | |||
| “听二狗说,他前几天在这里被一头野猪追赶时,看到天上有仙人飞过……”白小纯走在山路上,心脏怦怦跳动时,忽然一旁的灌林中传来阵阵哗哗声,似野猪一样,这声音来的突然,让本就紧张的白小纯,顿时背后发凉。 | |||
| “谁,谁在那里!”白小纯右手快速从行囊中拿出四把斧头,六把柴刀,还觉得不放心,又从怀里取出了一小根黑色的香,死死的抓住。 | |||
| “别出来,千万别出来,我有斧头,有柴刀,手里的香还可以召唤天雷,能引仙人降临,你敢出来,就劈死你!”白小纯哆嗦的大喊,连滚带爬的夹着那些武器,赶紧顺着山路跑去,沿途叮当乱响,斧头柴刀掉了一地。 | |||
| 或许是真的被他给吓住了,很快的哗哗声就消失,没有什么野兽跑出来,白小纯面色苍白,擦了擦冷汗,有心放弃继续上山,可一想到手中这根香是他爹娘去世前留给他的,据说是祖上曾偶然的救下一个落魄的仙人,那仙人离去时留下这根香作为报答,曾言会收下白家血脉一人为弟子,只要点燃,仙人就会到来。 | |||
| 可至今为止,这根香他点过十多次,始终不见仙人到来,让白小纯开始怀疑仙人是不是真的会来,这一次之所以下定决心,一方面是香所剩不多,另一方面是他听村子里人说,头几天在这看到有仙人从天上飞过。 | |||
| 所以他这才到来,想着距离仙人近一些,或许仙人就察觉到了也说不定。 | |||
| 踌躇一番,白小纯咬牙继续,好在此山不高,不久他气喘吁吁的到了山顶,站在那里,他遥望山下的村庄,神色颇为感慨,又低头看着手中的只有指甲盖大小的黑香,此香似乎被燃烧了好多次,所剩不多。 | |||
| “三年了,爹娘保佑我,这次一定要成功!”白小纯深吸口气,小心的将香点燃,立刻四周狂风顿起,天空更是眨眼间乌云密布,一道道闪电划过,还有震耳欲聋的雷鸣在白小纯耳边直接炸开。 | |||
| 声音之大,气势之强,让白小纯身体哆嗦,有种随时会被雷劈死的感觉,下意识的就想要吐口唾沫将那根香灭掉,但却挣扎忍住。 | |||
| “三年了,我点这根香点了十二次,这是第十三次,这次一定要忍住,小纯不怕,应该不会被劈死……”白小纯想起了这三年的经历,不算这次,点了十二次,每次都是这样的雷鸣闪电,仙人也没有到来,吓的本就怕死的他每次都吐口唾沫将其熄灭,说来也怪,这根香看似不凡,可实际上一样是浇水就灭。 | |||
| 在白小纯这里心惊肉跳,艰难的于那雷声中等待时,距离这里不远处的天空上,有一道长虹正急速的呼啸而来。 | |||
| 长虹内是一个中年男子,这男子衣着华丽,仙风道骨,可偏偏风尘仆仆,甚至仔细去看,可以看到他神色内深深的疲惫。 | |||
| “我倒要看看,到底是个什么样的人,竟然点根香点了三年!” | |||
| 一想到自己这三年的经历,中年男子就气恼,三年前他察觉有人点燃自己还是凝气时送出的香药,想起了当年在凡俗中的一段人情。 | |||
| 这才飞出寻来,原本按照他的打算,很快就会回来,可没成想,刚寻着香气过去,还没等多远,那气息就瞬间消失,断了联系。若是一次也就罢了,这三年,气息出现了十多次。 | |||
| 使得他这里,多次在寻找时中断,就这样来来回回,折腾了三年…… | |||
| 此刻他遥遥的看到了帽儿山,看到了山顶上白小纯,气不打一处来,一瞬飞出,直接就站在了山顶,大手一挥,那根所剩不多的香,直接熄灭。 | |||
| 雷声刹那消失,白小纯愣了一下,抬头一看,看到了自己的身边多了一个中年男子。 | |||
| “仙人?”白小纯小心翼翼的开口,有些拿不准,背后偷偷捡起一把斧头。 | |||
| “本座李青候,你是白家后人?”中年修士目光如电,无视白小纯身后的斧子,打量了白小纯一番,觉得眼前此子眉清目秀,依稀与当年的故人相似,资质也不错,心底的恼意,也不由缓了一些。 | |||
| “晚辈正是白家后人,白小纯。”白小纯眨了眨眼,小声说道,虽然心中有些畏惧,但还是挺了挺腰板。 | |||
| “我问你,点一根香,为什么点了三年!”中年修士淡淡开口,问出了他这三年里,最想要知道的问题。 | |||
| 白小纯听到这个问题,脑筋飞速转动,然后脸上摆出惆怅,遥望山下的村庄。 | |||
| “晚辈是一个重情重义的人,舍不得那些乡亲们,每一次我点燃香,他们也都不舍得我离去,如今山下的他们,还在因为我的离去而悲伤呢。” | |||
| 中年修士一愣,这个缘由,是他之前没想到的,目中的恼色又少了一些,单单从话语上看,此子的本性还是不错的。 | |||
| 可当他的目光落在山下的村子时,他的神识随之扫过,听到了村子里的敲锣打鼓以及那一句句欢呼白鼠狼离去的话语,面色立刻难看起来,有些头疼,看着眼前这个外表乖巧纯朴,人畜无害的白小纯,已心底明朗对方实际上一肚子坏水。 | |||
| “说实话!”中年修士一瞪眼,声音如同雷声一样,白小纯吓得一个哆嗦。 | |||
| “这不怨我啊,你那什么破香啊,每次点燃都会打雷,好几次都差点劈死我,我躲过了十三次,已经很不容易了。”白小纯可怜兮兮的说道。 | |||
| 中年修士看着白小纯,半晌无语。 | |||
| “既然你这么害怕,为什么还要强行去点香十多次?”中年修士缓缓开口。 | |||
| “我怕死啊,修仙不是能长生么,我想长生啊。”白小纯委屈的说道。 | |||
| 中年修士再次无语,不过觉得此子总算执念可嘉,扔到门派里磨炼一番,或可在性子上改变一二。 | |||
| 于是略一思索,大袖一甩卷着白小纯化作一道长虹,直奔天边而去。 | |||
| “跟我走吧。” | |||
| “去哪?这也太高了吧……”白小纯看到自己在天上飞,下面是万丈深渊,立刻脸色苍白,斧头一扔,死死的抱住仙人的大腿。 | |||
| 中年修士看了眼自己的腿,无奈开口。 | |||
| “灵溪宗。” | |||
| 兄弟姐妹们,阔别2个月,你们想不想我啊,我非常想你们! | |||
| 这本书,我做了详细的大纲,每次回顾大纲里的情节,都很兴奋,有种燃烧的感觉,我非常满意,明天,正式更新,依旧是中午一章,晚上一章! | |||
| 很兴奋,我们已沉寂了数月,如今归来,要……再战起点! | |||
| 新书期,兄弟姐妹,别忘了收藏与推荐啊,收藏与推荐至关重要! | |||
| 求收藏!!求推荐!! | |||
| 让众人知晓,我们……归来了! | |||
| 我们的目标,依旧是……点击榜,推荐榜,第一! | |||
| */ | |||
| private String title; | |||
| private String body; | |||
| public String getTitle() { | |||
| return title; | |||
| } | |||
| public void setTitle(String title) { | |||
| this.title = title; | |||
| } | |||
| public String getBody() { | |||
| return body; | |||
| } | |||
| public void setBody(String body) { | |||
| this.body = body; | |||
| } | |||
| } | |||
| @@ -1,52 +0,0 @@ | |||
| package com.yzx.webebook.model.bean; | |||
| import org.greenrobot.greendao.annotation.Entity; | |||
| import org.greenrobot.greendao.annotation.Id; | |||
| import org.greenrobot.greendao.annotation.Generated; | |||
| import org.greenrobot.greendao.annotation.Index; | |||
| @Entity | |||
| public class ChapterPageCount { | |||
| @Id | |||
| private String _id; // 本地书籍中,path 的 md5 值作为本地书籍的 id | |||
| private int total; | |||
| @Index | |||
| private String book_id; | |||
| @Generated(hash = 774780221) | |||
| public ChapterPageCount(String _id, int total, String book_id) { | |||
| this._id = _id; | |||
| this.total = total; | |||
| this.book_id = book_id; | |||
| } | |||
| @Generated(hash = 876465118) | |||
| public ChapterPageCount() { | |||
| } | |||
| public void setTotal(int total) { | |||
| this.total = total; | |||
| } | |||
| public void set_id(String _id) { | |||
| this._id = _id; | |||
| } | |||
| public void setBook_id(String book_id) { | |||
| this.book_id = book_id; | |||
| } | |||
| public int getTotal() { | |||
| return total; | |||
| } | |||
| public String get_id() { | |||
| return _id; | |||
| } | |||
| public String getBook_id() { | |||
| return book_id; | |||
| } | |||
| } | |||
| @@ -1,372 +0,0 @@ | |||
| package com.yzx.webebook.model.bean; | |||
| import android.os.Parcel; | |||
| import android.os.Parcelable; | |||
| import com.yzx.webebook.App; | |||
| import com.yzx.webebook.utils.StringUtils; | |||
| import org.greenrobot.greendao.DaoException; | |||
| import org.greenrobot.greendao.annotation.Entity; | |||
| import org.greenrobot.greendao.annotation.Generated; | |||
| import org.greenrobot.greendao.annotation.Id; | |||
| import org.greenrobot.greendao.annotation.ToMany; | |||
| import java.util.List; | |||
| import com.yzx.webebook.model.gen.DaoSession; | |||
| import com.yzx.webebook.model.gen.BookChapterBeanDao; | |||
| import com.yzx.webebook.model.gen.CollBookBeanDao; | |||
| /** | |||
| * Created by newbiechen on 17-5-8. | |||
| * 收藏的书籍 | |||
| */ | |||
| @Entity | |||
| public class CollBookBean implements Parcelable{ | |||
| public static final int STATUS_UNCACHE = 0; //未缓存 | |||
| public static final int STATUS_CACHING = 1; //正在缓存 | |||
| public static final int STATUS_CACHED = 2; //已经缓存 | |||
| /** | |||
| * _id : 53663ae356bdc93e49004474 | |||
| * title : 逍遥派 | |||
| * author : 白马出淤泥 | |||
| * shortIntro : 金庸武侠中有不少的神秘高手,书中或提起名字,或不曾提起,总之他们要么留下了绝世秘笈,要么就名震武林。 独孤九剑的创始者,独孤求败,他真的只创出九剑吗? 残本葵花... | |||
| * cover : /cover/149273897447137 | |||
| * hasCp : true | |||
| * latelyFollower : 60213 | |||
| * retentionRatio : 22.87 | |||
| * updated : 2017-05-07T18:24:34.720Z | |||
| * | |||
| * chaptersCount : 1660 | |||
| * lastChapter : 第1659章 朱长老 | |||
| */ | |||
| @Id | |||
| private String _id; // 本地书籍中,path 的 md5 值作为本地书籍的 id | |||
| private String title; | |||
| private String author; | |||
| private String shortIntro; | |||
| private String cover; // 在本地书籍中,该字段作为本地文件的路径 | |||
| private boolean hasCp; | |||
| private int latelyFollower; | |||
| private double retentionRatio; | |||
| //最新更新日期 | |||
| private String updated; | |||
| //最新阅读日期 | |||
| private String lastRead; | |||
| private int chaptersCount; | |||
| private String lastChapter; | |||
| //是否更新或未阅读 | |||
| private boolean isUpdate = true; | |||
| //是否是本地文件 | |||
| private boolean isLocal = false; | |||
| @ToMany(referencedJoinProperty = "bookId") | |||
| private List<BookChapterBean> bookChapterList; | |||
| /** Used to resolve relations */ | |||
| @Generated(hash = 2040040024) | |||
| private transient DaoSession daoSession; | |||
| /** Used for active entity operations. */ | |||
| @Generated(hash = 1552163441) | |||
| private transient CollBookBeanDao myDao; | |||
| @Generated(hash = 757968961) | |||
| public CollBookBean(String _id, String title, String author, String shortIntro, String cover, | |||
| boolean hasCp, int latelyFollower, double retentionRatio, String updated, String lastRead, | |||
| int chaptersCount, String lastChapter, boolean isUpdate, boolean isLocal) { | |||
| this._id = _id; | |||
| this.title = title; | |||
| this.author = author; | |||
| this.shortIntro = shortIntro; | |||
| this.cover = cover; | |||
| this.hasCp = hasCp; | |||
| this.latelyFollower = latelyFollower; | |||
| this.retentionRatio = retentionRatio; | |||
| this.updated = updated; | |||
| this.lastRead = lastRead; | |||
| this.chaptersCount = chaptersCount; | |||
| this.lastChapter = lastChapter; | |||
| this.isUpdate = isUpdate; | |||
| this.isLocal = isLocal; | |||
| } | |||
| public CollBookBean() { | |||
| } | |||
| public String get_id() { | |||
| return _id; | |||
| } | |||
| public void set_id(String _id) { | |||
| this._id = _id; | |||
| } | |||
| public String getTitle() { | |||
| return StringUtils.convertCC(title, App.Companion.getContext()); | |||
| } | |||
| public void setTitle(String title) { | |||
| this.title = title; | |||
| } | |||
| public String getAuthor() { | |||
| return StringUtils.convertCC(author, App.Companion.getContext()); | |||
| } | |||
| public void setAuthor(String author) { | |||
| this.author = author; | |||
| } | |||
| public String getShortIntro() { | |||
| return StringUtils.convertCC(shortIntro, App.Companion.getContext()); | |||
| } | |||
| public void setShortIntro(String shortIntro) { | |||
| this.shortIntro = shortIntro; | |||
| } | |||
| public String getCover() { | |||
| return StringUtils.convertCC(cover, App.Companion.getContext()); | |||
| } | |||
| public void setCover(String cover) { | |||
| this.cover = cover; | |||
| } | |||
| public boolean isHasCp() { | |||
| return hasCp; | |||
| } | |||
| public void setHasCp(boolean hasCp) { | |||
| this.hasCp = hasCp; | |||
| } | |||
| public int getLatelyFollower() { | |||
| return latelyFollower; | |||
| } | |||
| public void setLatelyFollower(int latelyFollower) { | |||
| this.latelyFollower = latelyFollower; | |||
| } | |||
| public double getRetentionRatio() { | |||
| return retentionRatio; | |||
| } | |||
| public void setRetentionRatio(double retentionRatio) { | |||
| this.retentionRatio = retentionRatio; | |||
| } | |||
| public String getUpdated() { | |||
| return StringUtils.convertCC(updated, App.Companion.getContext()); | |||
| } | |||
| public void setUpdated(String updated) { | |||
| this.updated = updated; | |||
| } | |||
| public int getChaptersCount() { | |||
| return chaptersCount; | |||
| } | |||
| public void setChaptersCount(int chaptersCount) { | |||
| this.chaptersCount = chaptersCount; | |||
| } | |||
| public String getLastChapter() { | |||
| return StringUtils.convertCC(lastChapter, App.Companion.getContext()); | |||
| } | |||
| public void setLastChapter(String lastChapter) { | |||
| this.lastChapter = lastChapter; | |||
| } | |||
| public boolean isUpdate() { | |||
| return isUpdate; | |||
| } | |||
| public void setUpdate(boolean update) { | |||
| isUpdate = update; | |||
| } | |||
| public boolean getHasCp() { | |||
| return this.hasCp; | |||
| } | |||
| public boolean getIsUpdate() { | |||
| return this.isUpdate; | |||
| } | |||
| public void setIsUpdate(boolean isUpdate) { | |||
| this.isUpdate = isUpdate; | |||
| } | |||
| public boolean isLocal() { | |||
| return isLocal; | |||
| } | |||
| public void setLocal(boolean local) { | |||
| isLocal = local; | |||
| } | |||
| public String getLastRead() { | |||
| return StringUtils.convertCC(lastRead, App.Companion.getContext()); | |||
| } | |||
| public void setLastRead(String lastRead) { | |||
| this.lastRead = lastRead; | |||
| } | |||
| public void setBookChapters(List<BookChapterBean> beans){ | |||
| bookChapterList = beans; | |||
| for (BookChapterBean bean : bookChapterList){ | |||
| bean.setBookId(get_id()); | |||
| } | |||
| } | |||
| public List<BookChapterBean> getBookChapters(){ | |||
| if (daoSession == null){ | |||
| return bookChapterList; | |||
| } | |||
| else { | |||
| return getBookChapterList(); | |||
| } | |||
| } | |||
| /** | |||
| * To-many relationship, resolved on first access (and after reset). | |||
| * Changes to to-many relations are not persisted, make changes to the target entity. | |||
| */ | |||
| @Generated(hash = 711740787) | |||
| public List<BookChapterBean> getBookChapterList() { | |||
| if (bookChapterList == null) { | |||
| final DaoSession daoSession = this.daoSession; | |||
| if (daoSession == null) { | |||
| throw new DaoException("Entity is detached from DAO context"); | |||
| } | |||
| BookChapterBeanDao targetDao = daoSession.getBookChapterBeanDao(); | |||
| List<BookChapterBean> bookChapterListNew = targetDao | |||
| ._queryCollBookBean_BookChapterList(_id); | |||
| synchronized (this) { | |||
| if (bookChapterList == null) { | |||
| bookChapterList = bookChapterListNew; | |||
| } | |||
| } | |||
| } | |||
| return bookChapterList; | |||
| } | |||
| /** Resets a to-many relationship, making the next get call to query for a fresh result. */ | |||
| @Generated(hash = 1077762221) | |||
| public synchronized void resetBookChapterList() { | |||
| bookChapterList = null; | |||
| } | |||
| /** | |||
| * Convenient call for {@link org.greenrobot.greendao.AbstractDao#delete(Object)}. | |||
| * Entity must attached to an entity context. | |||
| */ | |||
| @Generated(hash = 128553479) | |||
| public void delete() { | |||
| if (myDao == null) { | |||
| throw new DaoException("Entity is detached from DAO context"); | |||
| } | |||
| myDao.delete(this); | |||
| } | |||
| /** | |||
| * Convenient call for {@link org.greenrobot.greendao.AbstractDao#refresh(Object)}. | |||
| * Entity must attached to an entity context. | |||
| */ | |||
| @Generated(hash = 1942392019) | |||
| public void refresh() { | |||
| if (myDao == null) { | |||
| throw new DaoException("Entity is detached from DAO context"); | |||
| } | |||
| myDao.refresh(this); | |||
| } | |||
| /** | |||
| * Convenient call for {@link org.greenrobot.greendao.AbstractDao#update(Object)}. | |||
| * Entity must attached to an entity context. | |||
| */ | |||
| @Generated(hash = 713229351) | |||
| public void update() { | |||
| if (myDao == null) { | |||
| throw new DaoException("Entity is detached from DAO context"); | |||
| } | |||
| myDao.update(this); | |||
| } | |||
| public boolean getIsLocal() { | |||
| return this.isLocal; | |||
| } | |||
| public void setIsLocal(boolean isLocal) { | |||
| this.isLocal = isLocal; | |||
| } | |||
| @Override | |||
| public int describeContents() { | |||
| return 0; | |||
| } | |||
| @Override | |||
| public void writeToParcel(Parcel dest, int flags) { | |||
| dest.writeString(this._id); | |||
| dest.writeString(this.title); | |||
| dest.writeString(this.author); | |||
| dest.writeString(this.shortIntro); | |||
| dest.writeString(this.cover); | |||
| dest.writeByte(this.hasCp ? (byte) 1 : (byte) 0); | |||
| dest.writeInt(this.latelyFollower); | |||
| dest.writeDouble(this.retentionRatio); | |||
| dest.writeString(this.updated); | |||
| dest.writeString(this.lastRead); | |||
| dest.writeInt(this.chaptersCount); | |||
| dest.writeString(this.lastChapter); | |||
| dest.writeByte(this.isUpdate ? (byte) 1 : (byte) 0); | |||
| dest.writeByte(this.isLocal ? (byte) 1 : (byte) 0); | |||
| } | |||
| /** called by internal mechanisms, do not call yourself. */ | |||
| @Generated(hash = 159260324) | |||
| public void __setDaoSession(DaoSession daoSession) { | |||
| this.daoSession = daoSession; | |||
| myDao = daoSession != null ? daoSession.getCollBookBeanDao() : null; | |||
| } | |||
| protected CollBookBean(Parcel in) { | |||
| this._id = in.readString(); | |||
| this.title = in.readString(); | |||
| this.author = in.readString(); | |||
| this.shortIntro = in.readString(); | |||
| this.cover = in.readString(); | |||
| this.hasCp = in.readByte() != 0; | |||
| this.latelyFollower = in.readInt(); | |||
| this.retentionRatio = in.readDouble(); | |||
| this.updated = in.readString(); | |||
| this.lastRead = in.readString(); | |||
| this.chaptersCount = in.readInt(); | |||
| this.lastChapter = in.readString(); | |||
| this.isUpdate = in.readByte() != 0; | |||
| this.isLocal = in.readByte() != 0; | |||
| } | |||
| public static final Creator<CollBookBean> CREATOR = new Creator<CollBookBean>() { | |||
| @Override | |||
| public CollBookBean createFromParcel(Parcel source) { | |||
| return new CollBookBean(source); | |||
| } | |||
| @Override | |||
| public CollBookBean[] newArray(int size) { | |||
| return new CollBookBean[size]; | |||
| } | |||
| }; | |||
| } | |||
| @@ -1,81 +0,0 @@ | |||
| package com.yzx.webebook.model.bean; | |||
| /** | |||
| * Created by newbiechen on 17-4-29. | |||
| */ | |||
| public class CommentBean { | |||
| /** | |||
| * _id : 57fd69356b613e9d1e69febb | |||
| * content : 2000年 | |||
| * author : {"_id":"57b6794f138527405e83382c","avatar":"/avatar/bc/3f/bc3f0b58815e497b00dabb7a14476891","nickname":"孤独患者","activityAvatar":"","type":"normal","lv":6,"gender":"female"} | |||
| * floor : 7150 | |||
| * likeCount : 0 | |||
| * created : 2016-10-11T22:35:33.303Z | |||
| * replyTo : {"_id":"57caec937a142c2277757f2d","floor":7038,"author":{"_id":"576a96dd4cb19fa249303369","nickname":"刘"}} | |||
| */ | |||
| private String _id; | |||
| private String content; | |||
| private AuthorBean author; | |||
| private int floor; | |||
| private int likeCount; | |||
| private String created; | |||
| private ReplyToBean replyTo; | |||
| public String get_id() { | |||
| return _id; | |||
| } | |||
| public void set_id(String _id) { | |||
| this._id = _id; | |||
| } | |||
| public String getContent() { | |||
| return content; | |||
| } | |||
| public void setContent(String content) { | |||
| this.content = content; | |||
| } | |||
| public AuthorBean getAuthor() { | |||
| return author; | |||
| } | |||
| public void setAuthor(AuthorBean author) { | |||
| this.author = author; | |||
| } | |||
| public int getFloor() { | |||
| return floor; | |||
| } | |||
| public void setFloor(int floor) { | |||
| this.floor = floor; | |||
| } | |||
| public int getLikeCount() { | |||
| return likeCount; | |||
| } | |||
| public void setLikeCount(int likeCount) { | |||
| this.likeCount = likeCount; | |||
| } | |||
| public String getCreated() { | |||
| return created; | |||
| } | |||
| public void setCreated(String created) { | |||
| this.created = created; | |||
| } | |||
| public ReplyToBean getReplyTo() { | |||
| return replyTo; | |||
| } | |||
| public void setReplyTo(ReplyToBean replyTo) { | |||
| this.replyTo = replyTo; | |||
| } | |||
| } | |||
| @@ -1,31 +0,0 @@ | |||
| package com.yzx.webebook.model.bean; | |||
| import java.util.List; | |||
| /** | |||
| * Created by newbiechen on 17-4-29. | |||
| */ | |||
| public class DetailBean<T> { | |||
| private T detail; | |||
| private List<CommentBean> bestComments; | |||
| private List<CommentBean> comments; | |||
| public DetailBean(T details, List<CommentBean> bestComments, List<CommentBean> comments) { | |||
| this.detail = details; | |||
| this.bestComments = bestComments; | |||
| this.comments = comments; | |||
| } | |||
| public T getDetail() { | |||
| return detail; | |||
| } | |||
| public List<CommentBean> getBestComments() { | |||
| return bestComments; | |||
| } | |||
| public List<CommentBean> getComments() { | |||
| return comments; | |||
| } | |||
| } | |||
| @@ -1,212 +0,0 @@ | |||
| package com.yzx.webebook.model.bean; | |||
| import org.greenrobot.greendao.DaoException; | |||
| import org.greenrobot.greendao.annotation.Entity; | |||
| import org.greenrobot.greendao.annotation.Generated; | |||
| import org.greenrobot.greendao.annotation.Id; | |||
| import org.greenrobot.greendao.annotation.ToMany; | |||
| import java.util.List; | |||
| import com.yzx.webebook.model.gen.DaoSession; | |||
| import com.yzx.webebook.model.gen.BookChapterBeanDao; | |||
| import com.yzx.webebook.model.gen.DownloadTaskBeanDao; | |||
| /** | |||
| * Created by newbiechen on 17-5-11. | |||
| */ | |||
| @Entity | |||
| public class DownloadTaskBean { | |||
| public static final int STATUS_LOADING = 1; | |||
| public static final int STATUS_WAIT = 2; | |||
| public static final int STATUS_PAUSE = 3; | |||
| public static final int STATUS_ERROR = 4; | |||
| public static final int STATUS_FINISH = 5; | |||
| //任务名称 -> 名称唯一不重复 | |||
| @Id | |||
| private String taskName; | |||
| //所属的bookId(外健) | |||
| private String bookId; | |||
| @ToMany(referencedJoinProperty = "taskName") | |||
| private List<BookChapterBean> bookChapterList; | |||
| //章节的下载进度,默认为初始状态 | |||
| private int currentChapter = 0; | |||
| //最后的章节 | |||
| private int lastChapter = 0; | |||
| //状态:正在下载、下载完成、暂停、等待、下载错误。 | |||
| private volatile int status = STATUS_WAIT; | |||
| //总大小 -> (完成之后才会赋值) | |||
| private long size = 0; | |||
| /** Used to resolve relations */ | |||
| @Generated(hash = 2040040024) | |||
| private transient DaoSession daoSession; | |||
| /** Used for active entity operations. */ | |||
| @Generated(hash = 1584592296) | |||
| private transient DownloadTaskBeanDao myDao; | |||
| @Generated(hash = 597395122) | |||
| public DownloadTaskBean(String taskName, String bookId, int currentChapter, int lastChapter, | |||
| int status, long size) { | |||
| this.taskName = taskName; | |||
| this.bookId = bookId; | |||
| this.currentChapter = currentChapter; | |||
| this.lastChapter = lastChapter; | |||
| this.status = status; | |||
| this.size = size; | |||
| } | |||
| @Generated(hash = 2123101309) | |||
| public DownloadTaskBean() { | |||
| } | |||
| public String getBookId() { | |||
| return bookId; | |||
| } | |||
| public void setBookId(String bookId) { | |||
| this.bookId = bookId; | |||
| } | |||
| public String getTaskName() { | |||
| return taskName; | |||
| } | |||
| public void setTaskName(String taskName) { | |||
| this.taskName = taskName; | |||
| if (bookChapterList!=null){ | |||
| for (BookChapterBean bean : bookChapterList){ | |||
| bean.setTaskName(getTaskName()); | |||
| } | |||
| } | |||
| } | |||
| /** | |||
| * To-many relationship, resolved on first access (and after reset). | |||
| * Changes to to-many relations are not persisted, make changes to the target entity. | |||
| */ | |||
| @Generated(hash = 389263273) | |||
| public List<BookChapterBean> getBookChapterList() { | |||
| if (bookChapterList == null) { | |||
| final DaoSession daoSession = this.daoSession; | |||
| if (daoSession == null) { | |||
| throw new DaoException("Entity is detached from DAO context"); | |||
| } | |||
| BookChapterBeanDao targetDao = daoSession.getBookChapterBeanDao(); | |||
| List<BookChapterBean> bookChapterListNew = targetDao | |||
| ._queryDownloadTaskBean_BookChapterList(taskName); | |||
| synchronized (this) { | |||
| if (bookChapterList == null) { | |||
| bookChapterList = bookChapterListNew; | |||
| } | |||
| } | |||
| } | |||
| return bookChapterList; | |||
| } | |||
| /** | |||
| * 这才是真正的列表使用类。 | |||
| * | |||
| */ | |||
| public void setBookChapters(List<BookChapterBean> beans){ | |||
| bookChapterList = beans; | |||
| for (BookChapterBean bean : bookChapterList){ | |||
| bean.setTaskName(getTaskName()); | |||
| } | |||
| } | |||
| public List<BookChapterBean> getBookChapters(){ | |||
| if (daoSession == null){ | |||
| return bookChapterList; | |||
| } | |||
| else { | |||
| return getBookChapterList(); | |||
| } | |||
| } | |||
| public int getCurrentChapter() { | |||
| return currentChapter; | |||
| } | |||
| public void setCurrentChapter(int current) { | |||
| this.currentChapter = current; | |||
| } | |||
| public int getLastChapter() { | |||
| return lastChapter; | |||
| } | |||
| public void setLastChapter(int lastChapter) { | |||
| this.lastChapter = lastChapter; | |||
| } | |||
| //多线程访问的问题,所以需要同步机制 | |||
| public int getStatus() { | |||
| return status; | |||
| } | |||
| public void setStatus(int status){ | |||
| this.status = status; | |||
| } | |||
| public long getSize() { | |||
| return size; | |||
| } | |||
| public void setSize(long size) { | |||
| this.size = size; | |||
| } | |||
| /** Resets a to-many relationship, making the next get call to query for a fresh result. */ | |||
| @Generated(hash = 1077762221) | |||
| public synchronized void resetBookChapterList() { | |||
| bookChapterList = null; | |||
| } | |||
| /** | |||
| * Convenient call for {@link org.greenrobot.greendao.AbstractDao#delete(Object)}. | |||
| * Entity must attached to an entity context. | |||
| */ | |||
| @Generated(hash = 128553479) | |||
| public void delete() { | |||
| if (myDao == null) { | |||
| throw new DaoException("Entity is detached from DAO context"); | |||
| } | |||
| myDao.delete(this); | |||
| } | |||
| /** | |||
| * Convenient call for {@link org.greenrobot.greendao.AbstractDao#refresh(Object)}. | |||
| * Entity must attached to an entity context. | |||
| */ | |||
| @Generated(hash = 1942392019) | |||
| public void refresh() { | |||
| if (myDao == null) { | |||
| throw new DaoException("Entity is detached from DAO context"); | |||
| } | |||
| myDao.refresh(this); | |||
| } | |||
| /** | |||
| * Convenient call for {@link org.greenrobot.greendao.AbstractDao#update(Object)}. | |||
| * Entity must attached to an entity context. | |||
| */ | |||
| @Generated(hash = 713229351) | |||
| public void update() { | |||
| if (myDao == null) { | |||
| throw new DaoException("Entity is detached from DAO context"); | |||
| } | |||
| myDao.update(this); | |||
| } | |||
| /** called by internal mechanisms, do not call yourself. */ | |||
| @Generated(hash = 1923117869) | |||
| public void __setDaoSession(DaoSession daoSession) { | |||
| this.daoSession = daoSession; | |||
| myDao = daoSession != null ? daoSession.getDownloadTaskBeanDao() : null; | |||
| } | |||
| } | |||
| @@ -1,67 +0,0 @@ | |||
| package com.yzx.webebook.model.bean; | |||
| /** | |||
| * Created by newbiechen on 17-4-29. | |||
| */ | |||
| public class ReplyToBean { | |||
| /** | |||
| * _id : 57caec937a142c2277757f2d | |||
| * floor : 7038 | |||
| * author : {"_id":"576a96dd4cb19fa249303369","nickname":"刘"} | |||
| */ | |||
| private String _id; | |||
| private int floor; | |||
| private ReplyAuthorBean author; | |||
| public String get_id() { | |||
| return _id; | |||
| } | |||
| public void set_id(String _id) { | |||
| this._id = _id; | |||
| } | |||
| public int getFloor() { | |||
| return floor; | |||
| } | |||
| public void setFloor(int floor) { | |||
| this.floor = floor; | |||
| } | |||
| public ReplyAuthorBean getAuthor() { | |||
| return author; | |||
| } | |||
| public void setAuthor(ReplyAuthorBean author) { | |||
| this.author = author; | |||
| } | |||
| public static class ReplyAuthorBean { | |||
| /** | |||
| * _id : 576a96dd4cb19fa249303369 | |||
| * nickname : 刘 | |||
| */ | |||
| private String _id; | |||
| private String nickname; | |||
| public String get_id() { | |||
| return _id; | |||
| } | |||
| public void set_id(String _id) { | |||
| this._id = _id; | |||
| } | |||
| public String getNickname() { | |||
| return nickname; | |||
| } | |||
| public void setNickname(String nickname) { | |||
| this.nickname = nickname; | |||
| } | |||
| } | |||
| } | |||
| @@ -1,276 +0,0 @@ | |||
| package com.yzx.webebook.model.local; | |||
| import android.util.Log; | |||
| import com.yzx.webebook.model.bean.BookChapterBean; | |||
| import com.yzx.webebook.model.bean.BookRecordBean; | |||
| import com.yzx.webebook.model.bean.ChapterInfoBean; | |||
| import com.yzx.webebook.model.bean.CollBookBean; | |||
| import com.yzx.webebook.model.gen.BookChapterBeanDao; | |||
| import com.yzx.webebook.model.gen.BookRecordBeanDao; | |||
| import com.yzx.webebook.model.gen.CollBookBeanDao; | |||
| import com.yzx.webebook.model.gen.DaoSession; | |||
| import com.yzx.webebook.model.gen.DownloadTaskBeanDao; | |||
| import com.yzx.webebook.utils.BookManager; | |||
| import com.yzx.webebook.utils.Constant; | |||
| import com.yzx.webebook.utils.FileUtils; | |||
| import com.yzx.webebook.utils.IOUtils; | |||
| import java.io.BufferedReader; | |||
| import java.io.BufferedWriter; | |||
| import java.io.File; | |||
| import java.io.FileNotFoundException; | |||
| import java.io.FileReader; | |||
| import java.io.FileWriter; | |||
| import java.io.IOException; | |||
| import java.io.Reader; | |||
| import java.io.Writer; | |||
| import java.util.List; | |||
| import io.reactivex.Single; | |||
| import io.reactivex.SingleEmitter; | |||
| import io.reactivex.SingleOnSubscribe; | |||
| /** | |||
| * Created by newbiechen on 17-5-8. | |||
| * 存储关于书籍内容的信息(CollBook(收藏书籍),BookChapter(书籍列表),ChapterInfo(书籍章节),BookRecord(记录)) | |||
| */ | |||
| public class BookRepository { | |||
| private static final String TAG = "CollBookManager"; | |||
| private static volatile BookRepository sInstance; | |||
| private DaoSession mSession; | |||
| private CollBookBeanDao mCollBookDao; | |||
| private BookRepository(){ | |||
| mSession = DaoDbHelper.getInstance() | |||
| .getSession(); | |||
| mCollBookDao = mSession.getCollBookBeanDao(); | |||
| } | |||
| public static BookRepository getInstance(){ | |||
| if (sInstance == null){ | |||
| synchronized (BookRepository.class){ | |||
| if (sInstance == null){ | |||
| sInstance = new BookRepository(); | |||
| } | |||
| } | |||
| } | |||
| return sInstance; | |||
| } | |||
| //存储已收藏书籍 | |||
| public void saveCollBookWithAsync(CollBookBean bean){ | |||
| //启动异步存储 | |||
| mSession.startAsyncSession() | |||
| .runInTx( | |||
| () -> { | |||
| if (bean.getBookChapters() != null){ | |||
| // 存储BookChapterBean | |||
| mSession.getBookChapterBeanDao() | |||
| .insertOrReplaceInTx(bean.getBookChapters()); | |||
| } | |||
| //存储CollBook (确保先后顺序,否则出错) | |||
| mCollBookDao.insertOrReplace(bean); | |||
| } | |||
| ); | |||
| } | |||
| /** | |||
| * 异步存储。 | |||
| * 同时保存BookChapter | |||
| * @param beans | |||
| */ | |||
| public void saveCollBooksWithAsync(List<CollBookBean> beans){ | |||
| mSession.startAsyncSession() | |||
| .runInTx( | |||
| () -> { | |||
| for (CollBookBean bean : beans){ | |||
| if (bean.getBookChapters() != null){ | |||
| //存储BookChapterBean(需要修改,如果存在id相同的则无视) | |||
| mSession.getBookChapterBeanDao() | |||
| .insertOrReplaceInTx(bean.getBookChapters()); | |||
| } | |||
| } | |||
| //存储CollBook (确保先后顺序,否则出错) | |||
| mCollBookDao.insertOrReplaceInTx(beans); | |||
| } | |||
| ); | |||
| } | |||
| public void saveCollBook(CollBookBean bean){ | |||
| mCollBookDao.insertOrReplace(bean); | |||
| } | |||
| public void saveCollBooks(List<CollBookBean> beans){ | |||
| mCollBookDao.insertOrReplaceInTx(beans); | |||
| } | |||
| /** | |||
| * 异步存储BookChapter | |||
| * @param beans | |||
| */ | |||
| public void saveBookChaptersWithAsync(List<BookChapterBean> beans){ | |||
| mSession.startAsyncSession() | |||
| .runInTx( | |||
| () -> { | |||
| //存储BookChapterBean | |||
| mSession.getBookChapterBeanDao() | |||
| .insertOrReplaceInTx(beans); | |||
| Log.d(TAG, "saveBookChaptersWithAsync: "+"进行存储"); | |||
| } | |||
| ); | |||
| } | |||
| /** | |||
| * 存储章节 | |||
| * @param folderName | |||
| * @param fileName | |||
| * @param content | |||
| */ | |||
| public void saveChapterInfo(String folderName,String fileName,String content){ | |||
| File file = BookManager.getBookFile(folderName, fileName); | |||
| //获取流并存储 | |||
| Writer writer = null; | |||
| try { | |||
| writer = new BufferedWriter(new FileWriter(file)); | |||
| writer.write(content); | |||
| writer.flush(); | |||
| } catch (IOException e) { | |||
| e.printStackTrace(); | |||
| IOUtils.close(writer); | |||
| } | |||
| } | |||
| public void saveBookRecord(BookRecordBean bean){ | |||
| mSession.getBookRecordBeanDao() | |||
| .insertOrReplace(bean); | |||
| } | |||
| /*****************************get************************************************/ | |||
| public CollBookBean getCollBook(String bookId){ | |||
| CollBookBean bean = mCollBookDao.queryBuilder() | |||
| .where(CollBookBeanDao.Properties._id.eq(bookId)) | |||
| .unique(); | |||
| return bean; | |||
| } | |||
| public List<CollBookBean> getCollBooks(){ | |||
| return mCollBookDao | |||
| .queryBuilder() | |||
| .orderDesc(CollBookBeanDao.Properties.LastRead) | |||
| .list(); | |||
| } | |||
| //获取书籍列表 | |||
| public Single<List<BookChapterBean>> getBookChaptersInRx(String bookId){ | |||
| return Single.create(new SingleOnSubscribe<List<BookChapterBean>>() { | |||
| @Override | |||
| public void subscribe(SingleEmitter<List<BookChapterBean>> e) throws Exception { | |||
| List<BookChapterBean> beans = mSession | |||
| .getBookChapterBeanDao() | |||
| .queryBuilder() | |||
| .where(BookChapterBeanDao.Properties.BookId.eq(bookId)) | |||
| .list(); | |||
| e.onSuccess(beans); | |||
| } | |||
| }); | |||
| } | |||
| //获取阅读记录 | |||
| public BookRecordBean getBookRecord(String bookId){ | |||
| return mSession.getBookRecordBeanDao() | |||
| .queryBuilder() | |||
| .where(BookRecordBeanDao.Properties.BookId.eq(bookId)) | |||
| .unique(); | |||
| } | |||
| //TODO:需要进行获取编码并转换的问题 | |||
| public ChapterInfoBean getChapterInfoBean(String folderName, String fileName){ | |||
| File file = new File(Constant.BOOK_CACHE_PATH + folderName | |||
| + File.separator + fileName + FileUtils.SUFFIX_NB); | |||
| if (!file.exists()) return null; | |||
| Reader reader = null; | |||
| String str = null; | |||
| StringBuilder sb = new StringBuilder(); | |||
| try { | |||
| reader = new FileReader(file); | |||
| BufferedReader br = new BufferedReader(reader); | |||
| while ((str = br.readLine()) != null){ | |||
| sb.append(str); | |||
| } | |||
| } catch (FileNotFoundException e) { | |||
| e.printStackTrace(); | |||
| } catch (IOException e) { | |||
| e.printStackTrace(); | |||
| }finally { | |||
| IOUtils.close(reader); | |||
| } | |||
| ChapterInfoBean bean = new ChapterInfoBean(); | |||
| bean.setTitle(fileName); | |||
| bean.setBody(sb.toString()); | |||
| return bean; | |||
| } | |||
| /************************************************************/ | |||
| /************************************************************/ | |||
| public Single<Void> deleteCollBookInRx(CollBookBean bean) { | |||
| return Single.create(new SingleOnSubscribe<Void>() { | |||
| @Override | |||
| public void subscribe(SingleEmitter<Void> e) throws Exception { | |||
| //查看文本中是否存在删除的数据 | |||
| deleteBook(bean.get_id()); | |||
| //删除任务 | |||
| deleteDownloadTask(bean.get_id()); | |||
| //删除目录 | |||
| deleteBookChapter(bean.get_id()); | |||
| //删除CollBook | |||
| mCollBookDao.delete(bean); | |||
| e.onSuccess(new Void()); | |||
| } | |||
| }); | |||
| } | |||
| //这个需要用rx,进行删除 | |||
| public void deleteBookChapter(String bookId){ | |||
| mSession.getBookChapterBeanDao() | |||
| .queryBuilder() | |||
| .where(BookChapterBeanDao.Properties.BookId.eq(bookId)) | |||
| .buildDelete() | |||
| .executeDeleteWithoutDetachingEntities(); | |||
| } | |||
| public void deleteCollBook(CollBookBean collBook){ | |||
| mCollBookDao.delete(collBook); | |||
| } | |||
| //删除书籍 | |||
| public void deleteBook(String bookId){ | |||
| FileUtils.deleteFile(Constant.BOOK_CACHE_PATH+bookId); | |||
| } | |||
| public void deleteBookRecord(String id){ | |||
| mSession.getBookRecordBeanDao() | |||
| .queryBuilder() | |||
| .where(BookRecordBeanDao.Properties.BookId.eq(id)) | |||
| .buildDelete() | |||
| .executeDeleteWithoutDetachingEntities(); | |||
| } | |||
| //删除任务 | |||
| public void deleteDownloadTask(String bookId){ | |||
| mSession.getDownloadTaskBeanDao() | |||
| .queryBuilder() | |||
| .where(DownloadTaskBeanDao.Properties.BookId.eq(bookId)) | |||
| .buildDelete() | |||
| .executeDeleteWithoutDetachingEntities(); | |||
| } | |||
| public DaoSession getSession(){ | |||
| return mSession; | |||
| } | |||
| } | |||
| @@ -1,56 +0,0 @@ | |||
| package com.yzx.webebook.model.local; | |||
| import android.database.sqlite.SQLiteDatabase; | |||
| import com.yzx.webebook.App; | |||
| import com.yzx.webebook.model.gen.DaoMaster; | |||
| import com.yzx.webebook.model.gen.DaoSession; | |||
| /** | |||
| * Created by newbiechen on 17-4-26. | |||
| */ | |||
| public class DaoDbHelper { | |||
| private static final String DB_NAME = "IReader_DB"; | |||
| private static volatile DaoDbHelper sInstance; | |||
| private SQLiteDatabase mDb; | |||
| private DaoMaster mDaoMaster; | |||
| private DaoSession mSession; | |||
| private DaoDbHelper(){ | |||
| //封装数据库的创建、更新、删除 | |||
| DaoMaster.DevOpenHelper openHelper = new MyOpenHelper(App.Companion.getContext(),DB_NAME,null); | |||
| //获取数据库 | |||
| mDb = openHelper.getWritableDatabase(); | |||
| //封装数据库中表的创建、更新、删除 | |||
| mDaoMaster = new DaoMaster(mDb); //合起来就是对数据库的操作 | |||
| //对表操作的对象。 | |||
| mSession = mDaoMaster.newSession(); //可以认为是对数据的操作 | |||
| } | |||
| public static DaoDbHelper getInstance(){ | |||
| if (sInstance == null){ | |||
| synchronized (DaoDbHelper.class){ | |||
| if (sInstance == null){ | |||
| sInstance = new DaoDbHelper(); | |||
| } | |||
| } | |||
| } | |||
| return sInstance; | |||
| } | |||
| public DaoSession getSession(){ | |||
| return mSession; | |||
| } | |||
| public SQLiteDatabase getDatabase(){ | |||
| return mDb; | |||
| } | |||
| public DaoSession getNewSession(){ | |||
| return mDaoMaster.newSession(); | |||
| } | |||
| } | |||
| @@ -1,16 +0,0 @@ | |||
| package com.yzx.webebook.model.local; | |||
| import com.yzx.webebook.model.bean.AuthorBean; | |||
| import java.util.List; | |||
| /** | |||
| * Created by newbiechen on 17-4-28. | |||
| */ | |||
| public interface DeleteDbHelper { | |||
| void deleteAuthors(List<AuthorBean> beans); | |||
| void deleteAll(); | |||
| } | |||
| @@ -1,23 +0,0 @@ | |||
| package com.yzx.webebook.model.local; | |||
| import com.yzx.webebook.model.bean.AuthorBean; | |||
| import com.yzx.webebook.model.bean.DownloadTaskBean; | |||
| import java.util.List; | |||
| import io.reactivex.Single; | |||
| /** | |||
| * Created by newbiechen on 17-4-28. | |||
| */ | |||
| public interface GetDbHelper { | |||
| AuthorBean getAuthor(String id); | |||
| /******************************/ | |||
| List<DownloadTaskBean> getDownloadTaskList(); | |||
| } | |||
| @@ -1,116 +0,0 @@ | |||
| package com.yzx.webebook.model.local; | |||
| import com.google.gson.Gson; | |||
| import com.yzx.webebook.model.bean.AuthorBean; | |||
| import com.yzx.webebook.model.bean.BookCount; | |||
| import com.yzx.webebook.model.bean.ChapterPageCount; | |||
| import com.yzx.webebook.model.bean.DownloadTaskBean; | |||
| import com.yzx.webebook.model.gen.BookCountDao; | |||
| import com.yzx.webebook.model.gen.ChapterPageCountDao; | |||
| import com.yzx.webebook.model.gen.DaoSession; | |||
| import org.greenrobot.greendao.Property; | |||
| import org.greenrobot.greendao.query.Join; | |||
| import org.greenrobot.greendao.query.QueryBuilder; | |||
| import java.lang.reflect.Field; | |||
| import java.util.ArrayList; | |||
| import java.util.List; | |||
| import io.reactivex.Single; | |||
| import io.reactivex.SingleEmitter; | |||
| import io.reactivex.SingleOnSubscribe; | |||
| /** | |||
| * Created by newbiechen on 17-4-26. | |||
| */ | |||
| public class LocalRepository implements SaveDbHelper,GetDbHelper,DeleteDbHelper{ | |||
| private static final String TAG = "LocalRepository"; | |||
| private static final String DISTILLATE_ALL = "normal"; | |||
| private static final String DISTILLATE_BOUTIQUES = "distillate"; | |||
| private static volatile LocalRepository sInstance; | |||
| private DaoSession mSession; | |||
| private LocalRepository(){ | |||
| mSession = DaoDbHelper.getInstance().getSession(); | |||
| } | |||
| public static LocalRepository getInstance(){ | |||
| if (sInstance == null){ | |||
| synchronized (LocalRepository.class){ | |||
| if (sInstance == null){ | |||
| sInstance = new LocalRepository(); | |||
| } | |||
| } | |||
| } | |||
| return sInstance; | |||
| } | |||
| @Override | |||
| public void deleteAuthors(List<AuthorBean> beans) { | |||
| } | |||
| @Override | |||
| public void deleteAll() { | |||
| //清空全部数据。 | |||
| } | |||
| @Override | |||
| public AuthorBean getAuthor(String id) { | |||
| return null; | |||
| } | |||
| @Override | |||
| public List<DownloadTaskBean> getDownloadTaskList() { | |||
| return null; | |||
| } | |||
| @Override | |||
| public void saveAuthors(List<AuthorBean> beans) { | |||
| } | |||
| @Override | |||
| public void saveDownloadTask(DownloadTaskBean bean) { | |||
| } | |||
| @Override | |||
| public void saveBookCount(BookCount bookCount) { | |||
| mSession.getBookCountDao().insertOrReplaceInTx(bookCount); | |||
| } | |||
| @Override | |||
| public int getBookCount(String id) { | |||
| BookCount list = mSession.getBookCountDao() | |||
| .queryBuilder() | |||
| .where(BookCountDao.Properties._id.eq(id)) | |||
| .unique(); | |||
| if(list!=null){ | |||
| return list.getTotal(); | |||
| } | |||
| return 0; | |||
| } | |||
| @Override | |||
| public void saveChapterCount(List<ChapterPageCount> list) { | |||
| mSession.getChapterPageCountDao().insertOrReplaceInTx(list); | |||
| } | |||
| @Override | |||
| public List<ChapterPageCount> getChapterCount(String book_id) { | |||
| List<ChapterPageCount> list = mSession.getChapterPageCountDao() | |||
| .queryBuilder() | |||
| .where(ChapterPageCountDao.Properties.Book_id.eq(book_id)) | |||
| .list(); | |||
| if(list!=null && list.size()>0){ | |||
| return list; | |||
| } | |||
| return new ArrayList<ChapterPageCount>(); | |||
| } | |||
| } | |||
| @@ -1,34 +0,0 @@ | |||
| package com.yzx.webebook.model.local; | |||
| import android.content.Context; | |||
| import android.database.sqlite.SQLiteDatabase; | |||
| import com.yzx.webebook.model.gen.DaoMaster; | |||
| import com.yzx.webebook.model.local.update.Update2Helper; | |||
| import org.greenrobot.greendao.database.Database; | |||
| /** | |||
| * Created by newbiechen on 2017/10/9. | |||
| */ | |||
| public class MyOpenHelper extends DaoMaster.DevOpenHelper{ | |||
| public MyOpenHelper(Context context, String name, SQLiteDatabase.CursorFactory factory) { | |||
| super(context, name, factory); | |||
| } | |||
| @Override | |||
| public void onUpgrade(Database db, int oldVersion, int newVersion) { | |||
| // 跨版本更新策略 | |||
| switch (oldVersion){ | |||
| case 1: | |||
| // 暂无 1.0 | |||
| case 2: | |||
| // 更新数据到 3.0 | |||
| Update2Helper.getInstance().update(db); | |||
| default: | |||
| break; | |||
| } | |||
| } | |||
| } | |||
| @@ -1,134 +0,0 @@ | |||
| package com.yzx.webebook.model.local; | |||
| import com.yzx.webebook.utils.ScreenUtils; | |||
| import com.yzx.webebook.utils.SharedPreUtils; | |||
| import com.yzx.webebook.widget.page.PageMode; | |||
| import com.yzx.webebook.widget.page.PageStyle; | |||
| /** | |||
| * Created by newbiechen on 17-5-17. | |||
| * 阅读器的配置管理 | |||
| */ | |||
| public class ReadSettingManager { | |||
| /*************实在想不出什么好记的命名方式。。******************/ | |||
| public static final int READ_BG_DEFAULT = 0; | |||
| public static final int READ_BG_1 = 1; | |||
| public static final int READ_BG_2 = 2; | |||
| public static final int READ_BG_3 = 3; | |||
| public static final int READ_BG_4 = 4; | |||
| public static final int NIGHT_MODE = 5; | |||
| public static final String SHARED_READ_BG = "shared_read_bg"; | |||
| public static final String SHARED_READ_BRIGHTNESS = "shared_read_brightness"; | |||
| public static final String SHARED_READ_IS_BRIGHTNESS_AUTO = "shared_read_is_brightness_auto"; | |||
| public static final String SHARED_READ_TEXT_SIZE = "shared_read_text_size"; | |||
| public static final String SHARED_READ_IS_TEXT_DEFAULT = "shared_read_text_default"; | |||
| public static final String SHARED_READ_PAGE_MODE = "shared_read_mode"; | |||
| public static final String SHARED_READ_NIGHT_MODE = "shared_night_mode"; | |||
| public static final String SHARED_READ_VOLUME_TURN_PAGE = "shared_read_volume_turn_page"; | |||
| public static final String SHARED_READ_FULL_SCREEN = "shared_read_full_screen"; | |||
| public static final String SHARED_READ_CONVERT_TYPE = "shared_read_convert_type"; | |||
| private static volatile ReadSettingManager sInstance; | |||
| private SharedPreUtils sharedPreUtils; | |||
| public static ReadSettingManager getInstance() { | |||
| if (sInstance == null) { | |||
| synchronized (ReadSettingManager.class) { | |||
| if (sInstance == null) { | |||
| sInstance = new ReadSettingManager(); | |||
| } | |||
| } | |||
| } | |||
| return sInstance; | |||
| } | |||
| private ReadSettingManager() { | |||
| sharedPreUtils = SharedPreUtils.getInstance(); | |||
| } | |||
| public void setPageStyle(PageStyle pageStyle) { | |||
| sharedPreUtils.putInt(SHARED_READ_BG, pageStyle.ordinal()); | |||
| } | |||
| public void setBrightness(int progress) { | |||
| sharedPreUtils.putInt(SHARED_READ_BRIGHTNESS, progress); | |||
| } | |||
| public void setAutoBrightness(boolean isAuto) { | |||
| sharedPreUtils.putBoolean(SHARED_READ_IS_BRIGHTNESS_AUTO, isAuto); | |||
| } | |||
| public void setDefaultTextSize(boolean isDefault) { | |||
| sharedPreUtils.putBoolean(SHARED_READ_IS_TEXT_DEFAULT, isDefault); | |||
| } | |||
| public void setTextSize(int textSize) { | |||
| sharedPreUtils.putInt(SHARED_READ_TEXT_SIZE, textSize); | |||
| } | |||
| public void setPageMode(PageMode mode) { | |||
| sharedPreUtils.putInt(SHARED_READ_PAGE_MODE, mode.ordinal()); | |||
| } | |||
| public void setNightMode(boolean isNight) { | |||
| sharedPreUtils.putBoolean(SHARED_READ_NIGHT_MODE, isNight); | |||
| } | |||
| public int getBrightness() { | |||
| return sharedPreUtils.getInt(SHARED_READ_BRIGHTNESS, 40); | |||
| } | |||
| public boolean isBrightnessAuto() { | |||
| return sharedPreUtils.getBoolean(SHARED_READ_IS_BRIGHTNESS_AUTO, false); | |||
| } | |||
| public int getTextSize() { | |||
| return sharedPreUtils.getInt(SHARED_READ_TEXT_SIZE, ScreenUtils.spToPx(28)); | |||
| } | |||
| public boolean isDefaultTextSize() { | |||
| return sharedPreUtils.getBoolean(SHARED_READ_IS_TEXT_DEFAULT, false); | |||
| } | |||
| public PageMode getPageMode() { | |||
| int mode = sharedPreUtils.getInt(SHARED_READ_PAGE_MODE, PageMode.NONE.ordinal()); | |||
| return PageMode.values()[mode]; | |||
| } | |||
| public PageStyle getPageStyle() { | |||
| int style = sharedPreUtils.getInt(SHARED_READ_BG, PageStyle.BG_0.ordinal()); | |||
| return PageStyle.values()[style]; | |||
| } | |||
| public boolean isNightMode() { | |||
| return sharedPreUtils.getBoolean(SHARED_READ_NIGHT_MODE, false); | |||
| } | |||
| public void setVolumeTurnPage(boolean isTurn) { | |||
| sharedPreUtils.putBoolean(SHARED_READ_VOLUME_TURN_PAGE, isTurn); | |||
| } | |||
| public boolean isVolumeTurnPage() { | |||
| return sharedPreUtils.getBoolean(SHARED_READ_VOLUME_TURN_PAGE, false); | |||
| } | |||
| public void setFullScreen(boolean isFullScreen) { | |||
| sharedPreUtils.putBoolean(SHARED_READ_FULL_SCREEN, isFullScreen); | |||
| } | |||
| public boolean isFullScreen() { | |||
| return sharedPreUtils.getBoolean(SHARED_READ_FULL_SCREEN, false); | |||
| } | |||
| public void setConvertType(int convertType) { | |||
| sharedPreUtils.putInt(SHARED_READ_CONVERT_TYPE, convertType); | |||
| } | |||
| public int getConvertType() { | |||
| return sharedPreUtils.getInt(SHARED_READ_CONVERT_TYPE, 0); | |||
| } | |||
| } | |||
| @@ -1,28 +0,0 @@ | |||
| package com.yzx.webebook.model.local; | |||
| import com.yzx.webebook.model.bean.AuthorBean; | |||
| import com.yzx.webebook.model.bean.BookCount; | |||
| import com.yzx.webebook.model.bean.ChapterPageCount; | |||
| import com.yzx.webebook.model.bean.DownloadTaskBean; | |||
| import java.util.List; | |||
| /** | |||
| * Created by newbiechen on 17-4-28. | |||
| */ | |||
| public interface SaveDbHelper { | |||
| void saveAuthors(List<AuthorBean> beans); | |||
| /*************DownloadTask*********************/ | |||
| void saveDownloadTask(DownloadTaskBean bean); | |||
| void saveBookCount(BookCount bookCount); | |||
| int getBookCount(String id); | |||
| void saveChapterCount(List<ChapterPageCount> list); | |||
| List<ChapterPageCount> getChapterCount(String book_id); | |||
| } | |||
| @@ -1,8 +0,0 @@ | |||
| package com.yzx.webebook.model.local; | |||
| /** | |||
| * Created by newbiechen on 17-5-27. | |||
| */ | |||
| public final class Void { | |||
| } | |||
| @@ -1,207 +0,0 @@ | |||
| package com.yzx.webebook.model.local.update; | |||
| import android.database.Cursor; | |||
| import android.text.TextUtils; | |||
| import android.util.Log; | |||
| import org.greenrobot.greendao.AbstractDao; | |||
| import org.greenrobot.greendao.database.Database; | |||
| import org.greenrobot.greendao.internal.DaoConfig; | |||
| import java.lang.reflect.InvocationTargetException; | |||
| import java.lang.reflect.Method; | |||
| import java.util.ArrayList; | |||
| import java.util.Arrays; | |||
| import java.util.List; | |||
| /** | |||
| * Created by newbiechen on 2017/10/9. | |||
| * 数据库更新策略 | |||
| */ | |||
| public class MigrationHelper { | |||
| private static final String CONVERSION_CLASS_NOT_FOUND_EXCEPTION = "MIGRATION HELPER - CLASS DOESN'T MATCH WITH THE CURRENT PARAMETERS"; | |||
| private static MigrationHelper instance; | |||
| public static MigrationHelper getInstance() { | |||
| if (instance == null) { | |||
| instance = new MigrationHelper(); | |||
| } | |||
| return instance; | |||
| } | |||
| public void migrate(Database db, Class<? extends AbstractDao<?, ?>>... daoClasses) { | |||
| generateTempTables(db, daoClasses); | |||
| deleteOriginalTables(db, daoClasses); | |||
| createOrignalTables(db, daoClasses); | |||
| restoreData(db, daoClasses); | |||
| } | |||
| /** | |||
| * 生成临时列表 | |||
| * | |||
| * @param db | |||
| * @param daoClasses | |||
| */ | |||
| private void generateTempTables(Database db, Class<? extends AbstractDao<?, ?>>... daoClasses) { | |||
| for (int i = 0; i < daoClasses.length; i++) { | |||
| DaoConfig daoConfig = new DaoConfig(db, daoClasses[i]); | |||
| String divider = ""; | |||
| String tableName = daoConfig.tablename; | |||
| String tempTableName = daoConfig.tablename.concat("_TEMP"); | |||
| ArrayList<String> properties = new ArrayList<>(); | |||
| StringBuilder createTableStringBuilder = new StringBuilder(); | |||
| createTableStringBuilder.append("CREATE TABLE ").append(tempTableName).append(" ("); | |||
| for (int j = 0; j < daoConfig.properties.length; j++) { | |||
| String columnName = daoConfig.properties[j].columnName; | |||
| if (getColumns(db, tableName).contains(columnName)) { | |||
| properties.add(columnName); | |||
| String type = null; | |||
| try { | |||
| type = getTypeByClass(daoConfig.properties[j].type); | |||
| } catch (Exception exception) { | |||
| exception.printStackTrace(); | |||
| } | |||
| createTableStringBuilder.append(divider).append(columnName).append(" ").append(type); | |||
| if (daoConfig.properties[j].primaryKey) { | |||
| createTableStringBuilder.append(" PRIMARY KEY"); | |||
| } | |||
| divider = ","; | |||
| } | |||
| } | |||
| createTableStringBuilder.append(");"); | |||
| db.execSQL(createTableStringBuilder.toString()); | |||
| StringBuilder insertTableStringBuilder = new StringBuilder(); | |||
| insertTableStringBuilder.append("INSERT INTO ").append(tempTableName).append(" ("); | |||
| insertTableStringBuilder.append(TextUtils.join(",", properties)); | |||
| insertTableStringBuilder.append(") SELECT "); | |||
| insertTableStringBuilder.append(TextUtils.join(",", properties)); | |||
| insertTableStringBuilder.append(" FROM ").append(tableName).append(";"); | |||
| db.execSQL(insertTableStringBuilder.toString()); | |||
| } | |||
| } | |||
| /** | |||
| * 通过反射,删除要更新的表 | |||
| */ | |||
| private void deleteOriginalTables(Database db, Class<? extends AbstractDao<?, ?>>... daoClasses) { | |||
| for (Class<? extends AbstractDao<?, ?>> daoClass : daoClasses) { | |||
| try { | |||
| Method method = daoClass.getMethod("dropTable", Database.class, boolean.class); | |||
| method.invoke(null, db, true); | |||
| } catch (IllegalAccessException e) { | |||
| e.printStackTrace(); | |||
| } catch (InvocationTargetException e) { | |||
| e.printStackTrace(); | |||
| } catch (NoSuchMethodException e) { | |||
| e.printStackTrace(); | |||
| } | |||
| } | |||
| } | |||
| /** | |||
| * 通过反射,重新创建要更新的表 | |||
| */ | |||
| private void createOrignalTables(Database db, Class<? extends AbstractDao<?, ?>>... daoClasses) { | |||
| for (Class<? extends AbstractDao<?, ?>> daoClass : daoClasses) { | |||
| try { | |||
| Method method = daoClass.getMethod("createTable", Database.class, boolean.class); | |||
| method.invoke(null, db, false); | |||
| } catch (IllegalAccessException e) { | |||
| e.printStackTrace(); | |||
| } catch (InvocationTargetException e) { | |||
| e.printStackTrace(); | |||
| } catch (NoSuchMethodException e) { | |||
| e.printStackTrace(); | |||
| } | |||
| } | |||
| } | |||
| /** | |||
| * 存储新的数据库表 以及数据 | |||
| * | |||
| * @param db | |||
| * @param daoClasses | |||
| */ | |||
| private void restoreData(Database db, Class<? extends AbstractDao<?, ?>>... daoClasses) { | |||
| for (int i = 0; i < daoClasses.length; i++) { | |||
| DaoConfig daoConfig = new DaoConfig(db, daoClasses[i]); | |||
| String tableName = daoConfig.tablename; | |||
| String tempTableName = daoConfig.tablename.concat("_TEMP"); | |||
| ArrayList<String> properties = new ArrayList(); | |||
| for (int j = 0; j < daoConfig.properties.length; j++) { | |||
| String columnName = daoConfig.properties[j].columnName; | |||
| if (getColumns(db, tempTableName).contains(columnName)) { | |||
| properties.add(columnName); | |||
| } | |||
| } | |||
| StringBuilder insertTableStringBuilder = new StringBuilder(); | |||
| insertTableStringBuilder.append("INSERT INTO ").append(tableName).append(" ("); | |||
| insertTableStringBuilder.append(TextUtils.join(",", properties)); | |||
| insertTableStringBuilder.append(") SELECT "); | |||
| insertTableStringBuilder.append(TextUtils.join(",", properties)); | |||
| insertTableStringBuilder.append(" FROM ").append(tempTableName).append(";"); | |||
| StringBuilder dropTableStringBuilder = new StringBuilder(); | |||
| dropTableStringBuilder.append("DROP TABLE ").append(tempTableName); | |||
| db.execSQL(insertTableStringBuilder.toString()); | |||
| db.execSQL(dropTableStringBuilder.toString()); | |||
| } | |||
| } | |||
| private String getTypeByClass(Class<?> type) throws Exception { | |||
| if (type.equals(String.class)) { | |||
| return "TEXT"; | |||
| } | |||
| if (type.equals(Long.class) || type.equals(Integer.class) || type.equals(long.class)) { | |||
| return "INTEGER"; | |||
| } | |||
| if (type.equals(Boolean.class)) { | |||
| return "BOOLEAN"; | |||
| } | |||
| Exception exception = new Exception(CONVERSION_CLASS_NOT_FOUND_EXCEPTION.concat(" - Class: ").concat(type.toString())); | |||
| exception.printStackTrace(); | |||
| throw exception; | |||
| } | |||
| private List<String> getColumns(Database db, String tableName) { | |||
| List<String> columns = new ArrayList<>(); | |||
| Cursor cursor = null; | |||
| try { | |||
| cursor = db.rawQuery("SELECT * FROM " + tableName + " limit 1", null); | |||
| if (cursor != null) { | |||
| columns = new ArrayList<>(Arrays.asList(cursor.getColumnNames())); | |||
| } | |||
| } catch (Exception e) { | |||
| Log.v(tableName, e.getMessage(), e); | |||
| e.printStackTrace(); | |||
| } finally { | |||
| if (cursor != null) | |||
| cursor.close(); | |||
| } | |||
| return columns; | |||
| } | |||
| } | |||
| @@ -1,284 +0,0 @@ | |||
| package com.yzx.webebook.model.local.update; | |||
| import android.database.Cursor; | |||
| import android.text.TextUtils; | |||
| import android.util.Log; | |||
| import com.yzx.webebook.model.gen.BookChapterBeanDao; | |||
| import com.yzx.webebook.model.gen.CollBookBeanDao; | |||
| import com.yzx.webebook.utils.MD5Utils; | |||
| import org.greenrobot.greendao.AbstractDao; | |||
| import org.greenrobot.greendao.database.Database; | |||
| import org.greenrobot.greendao.internal.DaoConfig; | |||
| import java.lang.reflect.InvocationTargetException; | |||
| import java.lang.reflect.Method; | |||
| import java.util.ArrayList; | |||
| import java.util.Arrays; | |||
| import java.util.List; | |||
| /** | |||
| * Created by newbiechen on 2018/1/5. | |||
| * 由于 BookChapterBean 做了一次表的大更改,所以需要自定义更新。 | |||
| * 作用:将数据库2.0 升级到 3.0 | |||
| */ | |||
| public class Update2Helper { | |||
| private static final String TAG = "BookChapterHelper"; | |||
| private static final String CONVERSION_CLASS_NOT_FOUND_EXCEPTION = "MIGRATION HELPER - CLASS DOESN'T MATCH WITH THE CURRENT PARAMETERS"; | |||
| private static final String DIVIDER = ","; | |||
| private static final String QUOTE = "'%s'"; | |||
| private static Update2Helper instance; | |||
| public static Update2Helper getInstance() { | |||
| if (instance == null) { | |||
| instance = new Update2Helper(); | |||
| } | |||
| return instance; | |||
| } | |||
| public void update(Database db) { | |||
| updateCollBook(db); | |||
| updateBookChapter(db); | |||
| } | |||
| private void updateBookChapter(Database db) { | |||
| Class<? extends AbstractDao<?, ?>> bookChapterClass = BookChapterBeanDao.class; | |||
| generateTempTables(db, bookChapterClass); | |||
| deleteOriginalTables(db, bookChapterClass); | |||
| createOrignalTables(db, bookChapterClass); | |||
| restoreData(db, bookChapterClass); | |||
| } | |||
| private void updateCollBook(Database db) { | |||
| Class<? extends AbstractDao<?, ?>> collBookClass = CollBookBeanDao.class; | |||
| // 遍历查找本地文件,然后修改本地文件的数据 | |||
| DaoConfig daoConfig = new DaoConfig(db, collBookClass); | |||
| String tableName = daoConfig.tablename; | |||
| Cursor cursor = db.rawQuery("select _ID,IS_LOCAL from " + tableName, null); | |||
| String id = null; | |||
| String cover = null; | |||
| String isLocal = null; | |||
| StringBuilder updateSb = new StringBuilder(); | |||
| while (cursor.moveToNext()) { | |||
| cover = cursor.getString(0); | |||
| id = MD5Utils.strToMd5By16(cover); | |||
| isLocal = cursor.getString(1); | |||
| //如果是本地文件 | |||
| if (isLocal.equals("1")) { | |||
| // 数据更新 | |||
| updateSb.append("UPDATE " + tableName + " SET "); | |||
| updateSb.append("_ID=").append(String.format(QUOTE, id)).append(DIVIDER); | |||
| updateSb.append("COVER=").append(String.format(QUOTE, cover)).append(" "); | |||
| updateSb.append("WHERE _ID=").append(String.format(QUOTE,cover)).append(";"); | |||
| db.execSQL(updateSb.toString()); | |||
| updateSb.delete(0, updateSb.length()); | |||
| } | |||
| } | |||
| } | |||
| /** | |||
| * 生成临时列表 | |||
| * | |||
| * @param db | |||
| */ | |||
| private void generateTempTables(Database db, Class<? extends AbstractDao<?, ?>> bookChapterClass) { | |||
| // 解析 GreenDao,获取 table 名 | |||
| DaoConfig daoConfig = new DaoConfig(db, bookChapterClass); | |||
| String tableName = daoConfig.tablename; | |||
| // 创建临时 table 名。 | |||
| String tempTableName = daoConfig.tablename.concat("_TEMP"); | |||
| ArrayList<String> properties = new ArrayList<>(); | |||
| StringBuilder createTableStringBuilder = new StringBuilder(); | |||
| createTableStringBuilder.append("CREATE TABLE ").append(tempTableName).append(" ("); | |||
| // 新增的三个字段 | |||
| String ID = "ID"; | |||
| String START = "START"; | |||
| String END = "end"; | |||
| // 新建的 id 主键字段 | |||
| createTableStringBuilder.append(ID + " ").append("TEXT ").append("PRIMARY KEY"); | |||
| properties.add(ID); | |||
| // 获取符合新表的旧字段。 | |||
| for (int j = 0; j < daoConfig.properties.length; j++) { | |||
| String columnName = daoConfig.properties[j].columnName; | |||
| if (getColumns(db, tableName).contains(columnName)) { | |||
| properties.add(columnName); | |||
| String type = null; | |||
| try { | |||
| type = getTypeByClass(daoConfig.properties[j].type); | |||
| } catch (Exception exception) { | |||
| exception.printStackTrace(); | |||
| } | |||
| createTableStringBuilder.append(DIVIDER).append(columnName).append(" ").append(type); | |||
| } | |||
| } | |||
| // 新建的 START,和 END 字段。 | |||
| createTableStringBuilder.append(DIVIDER).append(START).append(" ").append("INTEGER"); | |||
| createTableStringBuilder.append(DIVIDER).append(END).append(" ").append("INTEGER"); | |||
| properties.add(START); | |||
| properties.add(END); | |||
| createTableStringBuilder.append(");"); | |||
| // 创建临时数据表 | |||
| db.execSQL(createTableStringBuilder.toString()); | |||
| StringBuilder insertTableStringBuilder = new StringBuilder(); | |||
| // 将 link 字段的文件的内容转换成 Id | |||
| Cursor cursor = db.rawQuery("select * from " + daoConfig.tablename, null); | |||
| String id = null; | |||
| String link = null; | |||
| String title = null; | |||
| String taskName = null; | |||
| String unreadble = null; | |||
| String bookId = null; | |||
| while (cursor.moveToNext()) { | |||
| link = cursor.getString(0); | |||
| id = MD5Utils.strToMd5By16(link); | |||
| title = cursor.getString(1); | |||
| taskName = cursor.getString(2); | |||
| unreadble = cursor.getString(4); | |||
| bookId = cursor.getString(3); | |||
| insertTableStringBuilder.append("INSERT INTO ").append(tempTableName).append(" ("); | |||
| insertTableStringBuilder.append(TextUtils.join(",", properties)); | |||
| insertTableStringBuilder.append(") VALUES ("); | |||
| insertTableStringBuilder.append(String.format(QUOTE, id)).append(DIVIDER); | |||
| insertTableStringBuilder.append(String.format(QUOTE, link)).append(DIVIDER); | |||
| insertTableStringBuilder.append(String.format(QUOTE, title)).append(DIVIDER); | |||
| insertTableStringBuilder.append(String.format(QUOTE, taskName)).append(DIVIDER); | |||
| insertTableStringBuilder.append(unreadble).append(DIVIDER); | |||
| insertTableStringBuilder.append(String.format(QUOTE, bookId)).append(DIVIDER); | |||
| insertTableStringBuilder.append("0").append(DIVIDER); | |||
| insertTableStringBuilder.append("0").append(");"); | |||
| db.execSQL(insertTableStringBuilder.toString()); | |||
| insertTableStringBuilder.delete(0, insertTableStringBuilder.length()); | |||
| } | |||
| } | |||
| /** | |||
| * 通过反射,删除要更新的表 | |||
| */ | |||
| private void deleteOriginalTables(Database db,Class<? extends AbstractDao<?, ?>> bookChapterClass) { | |||
| try { | |||
| Method method = bookChapterClass.getMethod("dropTable", Database.class, boolean.class); | |||
| method.invoke(null, db, true); | |||
| } catch (IllegalAccessException e) { | |||
| e.printStackTrace(); | |||
| } catch (InvocationTargetException e) { | |||
| e.printStackTrace(); | |||
| } catch (NoSuchMethodException e) { | |||
| e.printStackTrace(); | |||
| } | |||
| } | |||
| /** | |||
| * 通过反射,重新创建要更新的表 | |||
| */ | |||
| private void createOrignalTables(Database db,Class<? extends AbstractDao<?, ?>> bookChapterClass) { | |||
| try { | |||
| Method method = bookChapterClass.getMethod("createTable", Database.class, boolean.class); | |||
| method.invoke(null, db, false); | |||
| } catch (IllegalAccessException e) { | |||
| e.printStackTrace(); | |||
| } catch (InvocationTargetException e) { | |||
| e.printStackTrace(); | |||
| } catch (NoSuchMethodException e) { | |||
| e.printStackTrace(); | |||
| } | |||
| } | |||
| /** | |||
| * 存储新的数据库表 以及数据 | |||
| * | |||
| * @param db | |||
| */ | |||
| private void restoreData(Database db,Class<? extends AbstractDao<?, ?>> bookChapterClass) { | |||
| DaoConfig daoConfig = new DaoConfig(db, bookChapterClass); | |||
| String tableName = daoConfig.tablename; | |||
| String tempTableName = daoConfig.tablename.concat("_TEMP"); | |||
| ArrayList<String> properties = new ArrayList(); | |||
| for (int j = 0; j < daoConfig.properties.length; j++) { | |||
| String columnName = daoConfig.properties[j].columnName; | |||
| if (getColumns(db, tableName).contains(columnName)) { | |||
| properties.add(columnName); | |||
| } | |||
| } | |||
| StringBuilder insertTableStringBuilder = new StringBuilder(); | |||
| insertTableStringBuilder.append("INSERT INTO ").append(tableName).append(" ("); | |||
| insertTableStringBuilder.append(TextUtils.join(",", properties)); | |||
| insertTableStringBuilder.append(") SELECT "); | |||
| insertTableStringBuilder.append(TextUtils.join(",", properties)); | |||
| insertTableStringBuilder.append(" FROM ").append(tempTableName).append(";"); | |||
| Log.d(TAG, "restoreData: " + insertTableStringBuilder.toString()); | |||
| StringBuilder dropTableStringBuilder = new StringBuilder(); | |||
| dropTableStringBuilder.append("DROP TABLE ").append(tempTableName); | |||
| db.execSQL(insertTableStringBuilder.toString()); | |||
| db.execSQL(dropTableStringBuilder.toString()); | |||
| } | |||
| private String getTypeByClass(Class<?> type) throws Exception { | |||
| if (type.equals(String.class)) { | |||
| return "TEXT"; | |||
| } | |||
| if (type.equals(Long.class) || type.equals(Integer.class) || type.equals(long.class)) { | |||
| return "INTEGER"; | |||
| } | |||
| if (type.equals(boolean.class)) { | |||
| return "BOOLEAN"; | |||
| } | |||
| Exception exception = new Exception(CONVERSION_CLASS_NOT_FOUND_EXCEPTION.concat(" - Class: ").concat(type.toString())); | |||
| exception.printStackTrace(); | |||
| throw exception; | |||
| } | |||
| private List<String> getColumns(Database db, String tableName) { | |||
| List<String> columns = new ArrayList<>(); | |||
| Cursor cursor = null; | |||
| try { | |||
| cursor = db.rawQuery("SELECT * FROM " + tableName + " limit 1", null); | |||
| if (cursor != null) { | |||
| columns = new ArrayList<>(Arrays.asList(cursor.getColumnNames())); | |||
| } | |||
| } catch (Exception e) { | |||
| Log.v(tableName, e.getMessage(), e); | |||
| e.printStackTrace(); | |||
| } finally { | |||
| if (cursor != null) | |||
| cursor.close(); | |||
| } | |||
| return columns; | |||
| } | |||
| } | |||
| @@ -1,25 +0,0 @@ | |||
| package com.yzx.webebook.modules | |||
| import android.widget.Toast | |||
| import com.yzx.webebook.activity.WeexTestActivity | |||
| import org.apache.weex.annotation.JSMethod | |||
| import org.apache.weex.common.WXModule | |||
| import org.jetbrains.anko.startActivity | |||
| class ActivityWXModule : WXModule() { | |||
| @JSMethod(uiThread = true) | |||
| public fun navigateTo(url:String,params: String) { | |||
| // val intent = Intent(mWXSDKInstance.context, WeexTestActivity::class.java) | |||
| // intent.putExtra("url", url) | |||
| // intent.putExtra("params", params) | |||
| mWXSDKInstance.context.startActivity<WeexTestActivity>("url" to url,"params" to params) | |||
| } | |||
| @JSMethod(uiThread = true) | |||
| public fun toast(msg: String?) { | |||
| Toast.makeText(mWXSDKInstance.context, msg, Toast.LENGTH_SHORT).show() | |||
| } | |||
| } | |||
| @@ -1,211 +0,0 @@ | |||
| package com.yzx.webebook.presenter; | |||
| import android.util.Log; | |||
| import com.blankj.utilcode.util.FileIOUtils; | |||
| import com.blankj.utilcode.util.FileUtils; | |||
| import com.blankj.utilcode.util.LogUtils; | |||
| import com.blankj.utilcode.util.TimeUtils; | |||
| import com.blankj.utilcode.util.ToastUtils; | |||
| import com.google.gson.Gson; | |||
| import com.google.gson.reflect.TypeToken; | |||
| import com.lzy.okgo.OkGo; | |||
| import com.lzy.okgo.callback.FileCallback; | |||
| import com.lzy.okgo.callback.StringCallback; | |||
| import com.lzy.okgo.model.HttpHeaders; | |||
| import com.lzy.okgo.model.Response; | |||
| import com.yzx.webebook.config.Config; | |||
| import com.yzx.webebook.model.BaseBean; | |||
| import com.yzx.webebook.model.Book; | |||
| import com.yzx.webebook.model.Sections; | |||
| import com.yzx.webebook.model.User; | |||
| import com.yzx.webebook.model.Volumes; | |||
| import com.yzx.webebook.model.bean.CollBookBean; | |||
| import com.yzx.webebook.model.local.BookRepository; | |||
| import com.yzx.webebook.presenter.base.BasePresenter; | |||
| import com.yzx.webebook.widget.page.TxtChapter; | |||
| import org.jetbrains.annotations.NotNull; | |||
| import java.io.File; | |||
| import java.util.ArrayList; | |||
| import java.util.List; | |||
| public class ReadPresenter extends BasePresenter<ReadView> { | |||
| static String NOTE_FOLDER_DIR = "/mnt/sdcard/ebook/book/"; | |||
| public ReadPresenter(@NotNull ReadView view) { | |||
| super(view); | |||
| } | |||
| public void getReadProgress(String bookId,String readTaskId){ | |||
| User user = User.Companion.getUser(); | |||
| String url = Config.INSTANCE.getBASE_URL() + "/parent/readTask/getBookWarehouseContent"; | |||
| HttpHeaders headers = new HttpHeaders(); | |||
| headers.put("phone", user.getPhone()); | |||
| headers.put("token", user.getToken()); | |||
| OkGo.<String>post(url) | |||
| .tag(this) | |||
| .params("id", bookId) | |||
| .params("read_task_id", readTaskId) | |||
| .headers(headers) | |||
| .execute(new StringCallback() { | |||
| @Override | |||
| public void onSuccess(Response<String> response) { | |||
| Gson gson = new Gson(); | |||
| BaseBean<Book> bean = gson.fromJson(response.body(), new TypeToken<BaseBean<Book>>() { | |||
| }.getType()); | |||
| getMView().onProgressSuccess(bean.getData().getRead_progress()); | |||
| } | |||
| @Override | |||
| public void onError(Response<String> response) { | |||
| super.onError(response); | |||
| } | |||
| }); | |||
| } | |||
| public void loadCategory(String bookTaskId) { | |||
| User user = User.Companion.getUser(); | |||
| String localId = user.getUser_id() + "_" + bookTaskId; | |||
| CollBookBean collBook = BookRepository.getInstance().getCollBook(localId); | |||
| if (collBook != null) { | |||
| getMView().showCategory(localId); | |||
| } else { | |||
| String url = Config.INSTANCE.getBASE_URL() + "/parent/readTask/getBookWarehouseContent"; | |||
| HttpHeaders headers = new HttpHeaders(); | |||
| headers.put("phone", user.getPhone()); | |||
| headers.put("token", user.getToken()); | |||
| OkGo.<String>post(url) | |||
| .tag(this) | |||
| .params("id", bookTaskId) | |||
| .headers(headers) | |||
| .execute(new StringCallback() { | |||
| @Override | |||
| public void onSuccess(Response<String> response) { | |||
| Log.d("ReadActivity", "onSuccess: " + response.body()); | |||
| Gson gson = new Gson(); | |||
| BaseBean<Book> bean = gson.fromJson(response.body(), new TypeToken<BaseBean<Book>>() { | |||
| }.getType()); | |||
| if ("txt".equals(bean.getData().getFile_type()) || "pdf".equals(bean.getData().getFile_type().toLowerCase())) { | |||
| downloadBook(bean.getData(), bookTaskId); | |||
| } else { | |||
| Book book = bean.getData(); | |||
| StringBuffer builder = new StringBuffer() ; | |||
| if (book.getVolumes().size() > 0) { | |||
| for (Volumes volume : book.getVolumes()) { | |||
| builder.append("----------"); | |||
| builder.append("\r\n"); | |||
| for (Sections section : volume.getSections()) { | |||
| builder.append(section.getTitle()); | |||
| builder.append("\r\n"); | |||
| builder.append(section.getContent()); | |||
| builder.append("\r\n"); | |||
| } | |||
| } | |||
| } | |||
| LogUtils.d(builder); | |||
| LogUtils.d(builder.toString()); | |||
| String filePath = NOTE_FOLDER_DIR + user.getUser_id() + "_" + bookTaskId + ".txt"; | |||
| boolean success = FileUtils.createOrExistsFile(filePath); | |||
| boolean whiteSuccess = FileIOUtils.writeFileFromString(new File(filePath),builder.toString()); | |||
| if(success && whiteSuccess){ | |||
| CollBookBean bookBean = new CollBookBean(); | |||
| String localId = user.getUser_id() + "_" + bookTaskId; | |||
| bookBean.set_id(localId); | |||
| bookBean.setAuthor(book.getAuthor()); | |||
| bookBean.setTitle(book.getBook_name()); | |||
| bookBean.setShortIntro(book.getRead_requires()); | |||
| bookBean.setLastChapter("开始阅读"); | |||
| bookBean.setUpdate(true); | |||
| bookBean.setIsLocal(true); | |||
| bookBean.setLastRead(TimeUtils.getNowString()); | |||
| bookBean.setUpdated(TimeUtils.getNowString()); | |||
| bookBean.setCover(filePath); | |||
| List<CollBookBean> list = new ArrayList<CollBookBean>(); | |||
| list.add(bookBean); | |||
| BookRepository.getInstance() | |||
| .saveCollBooks(list); | |||
| getMView().showCategory(localId); | |||
| }else{ | |||
| ToastUtils.showLong("书籍信息读取失败!"); | |||
| } | |||
| } | |||
| } | |||
| @Override | |||
| public void onError(Response<String> response) { | |||
| super.onError(response); | |||
| } | |||
| }); | |||
| } | |||
| } | |||
| private void downloadBook(Book data, String bookTaskId) { | |||
| User user = User.Companion.getUser(); | |||
| OkGo.<File>get("https://" + data.getBook_file_identity() + ".oa.qbjjyyun.net/edufile/download?uniqueKey=" + data.getBook_file_id()) | |||
| .tag(this) | |||
| .execute(new FileCallback(NOTE_FOLDER_DIR, user.getUser_id() + "_" + data.getBook_name() + "." + data.getFile_type()) { | |||
| @Override | |||
| public void onSuccess(Response<File> response) { | |||
| File file = response.body(); | |||
| CollBookBean bookBean = new CollBookBean(); | |||
| String localId = user.getUser_id() + "_" + bookTaskId; | |||
| bookBean.set_id(localId); | |||
| bookBean.setAuthor(data.getAuthor()); | |||
| bookBean.setTitle(data.getBook_name()); | |||
| bookBean.setShortIntro(data.getRead_requires()); | |||
| bookBean.setLastChapter("开始阅读"); | |||
| bookBean.setUpdate(true); | |||
| bookBean.setIsLocal(true); | |||
| bookBean.setLastRead(TimeUtils.getNowString()); | |||
| bookBean.setUpdated(TimeUtils.getNowString()); | |||
| bookBean.setCover(file.getAbsolutePath()); | |||
| List<CollBookBean> list = new ArrayList<CollBookBean>(); | |||
| list.add(bookBean); | |||
| BookRepository.getInstance() | |||
| .saveCollBooks(list); | |||
| getMView().showCategory(localId); | |||
| } | |||
| }); | |||
| } | |||
| public void loadChapter(String bookId, List<TxtChapter> bookChapterList) { | |||
| } | |||
| public void updateReadProgress(String bookId,String readTaskId,String progress){ | |||
| User user = User.Companion.getUser(); | |||
| String url = Config.INSTANCE.getBASE_URL() + "/parent/readTask/updateReadProgress"; | |||
| HttpHeaders headers = new HttpHeaders(); | |||
| headers.put("phone", user.getPhone()); | |||
| headers.put("token", user.getToken()); | |||
| OkGo.<String>post(url) | |||
| .tag(this) | |||
| .params("id", bookId) | |||
| .params("read_task_id", readTaskId) | |||
| .params("read_progress", progress) | |||
| .headers(headers) | |||
| .execute(new StringCallback() { | |||
| @Override | |||
| public void onSuccess(Response<String> response) { | |||
| } | |||
| @Override | |||
| public void onError(Response<String> response) { | |||
| super.onError(response); | |||
| } | |||
| }); | |||
| } | |||
| } | |||
| @@ -1,15 +0,0 @@ | |||
| package com.yzx.webebook.presenter; | |||
| import com.yzx.webebook.model.bean.BookChapterBean; | |||
| import com.yzx.webebook.presenter.base.IView; | |||
| import java.util.List; | |||
| public interface ReadView extends IView { | |||
| void showCategory(String localId); | |||
| void finishChapter(); | |||
| void errorChapter(); | |||
| void onProgressSuccess(float progress); | |||
| } | |||
| @@ -1,16 +0,0 @@ | |||
| package com.yzx.webebook.utils; | |||
| import android.app.Application; | |||
| public class AppInstance { | |||
| private static Application sApplication; | |||
| public static void init(Application application) { | |||
| sApplication = application; | |||
| } | |||
| public static Application get() { | |||
| return sApplication; | |||
| } | |||
| } | |||
| @@ -1,221 +0,0 @@ | |||
| package com.yzx.webebook.utils; | |||
| import java.io.File; | |||
| import java.lang.ref.WeakReference; | |||
| import java.util.HashMap; | |||
| import java.util.Map; | |||
| /** | |||
| * Created by newbiechen on 17-5-20. | |||
| * 处理书籍的工具类,配合PageFactory使用 | |||
| * 已弃用, | |||
| */ | |||
| public class BookManager{ | |||
| private static final String TAG = "BookManager"; | |||
| private String chapterName; | |||
| private String bookId; | |||
| private long chapterLen; | |||
| private long position; | |||
| private Map<String, Cache> cacheMap = new HashMap<>(); | |||
| private static volatile BookManager sInstance; | |||
| public static BookManager getInstance(){ | |||
| if (sInstance == null){ | |||
| synchronized (BookManager.class){ | |||
| if (sInstance == null){ | |||
| sInstance = new BookManager(); | |||
| } | |||
| } | |||
| } | |||
| return sInstance; | |||
| } | |||
| public boolean openChapter(String bookId,String chapterName){ | |||
| return openChapter(bookId,chapterName,0); | |||
| } | |||
| public boolean openChapter(String bookId,String chapterName,long position){ | |||
| //如果文件不存在,则打开失败 | |||
| File file = new File(Constant.BOOK_CACHE_PATH + bookId | |||
| + File.separator + chapterName + FileUtils.SUFFIX_NB); | |||
| if (!file.exists()){ | |||
| return false; | |||
| } | |||
| this.bookId = bookId; | |||
| this.chapterName = chapterName; | |||
| this.position = position; | |||
| createCache(); | |||
| return true; | |||
| } | |||
| private void createCache(){ | |||
| //创建Cache | |||
| if (!cacheMap.containsKey(chapterName)){ | |||
| Cache cache = new Cache(); | |||
| File file = getBookFile(bookId, chapterName); | |||
| //TODO:数据加载默认utf-8(以后会增加判断),FileUtils采用Reader获取数据的,可能用byte会更好一点 | |||
| char[] array = FileUtils.getFileContent(file).toCharArray(); | |||
| WeakReference<char[]> charReference = new WeakReference<char[]>(array); | |||
| cache.size = array.length; | |||
| cache.data = charReference; | |||
| cacheMap.put(chapterName, cache); | |||
| chapterLen = cache.size; | |||
| } | |||
| else { | |||
| chapterLen = cacheMap.get(chapterName).getSize(); | |||
| } | |||
| } | |||
| public void setPosition(long position){ | |||
| this.position = position; | |||
| } | |||
| public long getPosition(){ | |||
| return position; | |||
| } | |||
| //获取上一段 | |||
| public String getPrevPara(){ | |||
| //首先判断是否Position已经达到起始位置,已经越界 | |||
| if (position < 0){ | |||
| return null; | |||
| } | |||
| //初始化从后向前获取的起始点,终止点,文本 | |||
| int end = (int)position; | |||
| int begin = end; | |||
| char[] array = getContent(); | |||
| while (begin >= 0) { //判断指针是否达到章节的起始位置 | |||
| char character = array[begin]; //获取当前指针下的字符 | |||
| //判断当前字符是否为换行,如果为换行,就代表获取到了一个段落,并退出。 | |||
| //有可能发生初始指针指的就是换行符的情况。 | |||
| if ((character+"").equals("\n") && begin != end) { | |||
| position = begin; | |||
| //当当前指针指向换行符的时候向后退一步 | |||
| begin++; | |||
| break; | |||
| } | |||
| //向前进一步 | |||
| begin--; | |||
| } | |||
| //最后end获取到段落的起始点,begin是段落的终止点。 | |||
| //当越界的时候,保证begin在章节内 | |||
| if (begin < 0){ | |||
| begin = 0;//在章节内 | |||
| position = -1; //越界 | |||
| } | |||
| int size = end+1 - begin; | |||
| return new String(array,begin,size); | |||
| } | |||
| //获取下一段 | |||
| public String getNextPara(){ | |||
| //首先判断是否Position已经达到终点位置 | |||
| if (position >= chapterLen){ | |||
| return null; | |||
| } | |||
| //初始化起始点,终止点。 | |||
| int begin = (int)position; | |||
| int end = begin; | |||
| char[] array = getContent(); | |||
| while (end < chapterLen) { //判断指针是否在章节的末尾位置 | |||
| char character = array[end]; //获取当前指针下的字符 | |||
| //判断当前字符是否为换行,如果为换行,就代表获取到了一个段落,并退出。 | |||
| //有可能发生初始指针指的就是换行符的情况。 | |||
| //这里当遇到\n的时候,不需要回退 | |||
| if ((character+"").equals("\n") && begin != end){ | |||
| ++end;//指向下一字段 | |||
| position = end; | |||
| break; | |||
| } | |||
| //指向下一字段 | |||
| end++; | |||
| } | |||
| //所要获取的字段的长度 | |||
| int size = end - begin; | |||
| return new String(array,begin,size); | |||
| } | |||
| //获取章节的内容 | |||
| public char[] getContent() { | |||
| if (cacheMap.size() == 0){ | |||
| return new char[1]; | |||
| } | |||
| char[] block = cacheMap.get(chapterName).getData().get(); | |||
| if (block == null) { | |||
| File file = getBookFile(bookId, chapterName); | |||
| block = FileUtils.getFileContent(file).toCharArray(); | |||
| Cache cache = cacheMap.get(chapterName); | |||
| cache.data = new WeakReference<char[]>(block); | |||
| } | |||
| return block; | |||
| } | |||
| public long getChapterLen(){ | |||
| return chapterLen; | |||
| } | |||
| public void clear(){ | |||
| cacheMap.clear(); | |||
| position = 0; | |||
| chapterLen = 0; | |||
| } | |||
| /** | |||
| * 创建或获取存储文件 | |||
| * @param folderName | |||
| * @param fileName | |||
| * @return | |||
| */ | |||
| public static File getBookFile(String folderName, String fileName){ | |||
| return FileUtils.getFile(Constant.BOOK_CACHE_PATH + folderName | |||
| + File.separator + fileName + FileUtils.SUFFIX_NB); | |||
| } | |||
| public static long getBookSize(String folderName){ | |||
| return FileUtils.getDirSize(FileUtils | |||
| .getFolder(Constant.BOOK_CACHE_PATH + folderName)); | |||
| } | |||
| /** | |||
| * 根据文件名判断是否被缓存过 (因为可能数据库显示被缓存过,但是文件中却没有的情况,所以需要根据文件判断是否被缓存 | |||
| * 过) | |||
| * @param folderName : bookId | |||
| * @param fileName: chapterName | |||
| * @return | |||
| */ | |||
| public static boolean isChapterCached(String folderName, String fileName){ | |||
| File file = new File(Constant.BOOK_CACHE_PATH + folderName | |||
| + File.separator + fileName + FileUtils.SUFFIX_NB); | |||
| return file.exists(); | |||
| } | |||
| public class Cache { | |||
| private long size; | |||
| private WeakReference<char[]> data; | |||
| public WeakReference<char[]> getData() { | |||
| return data; | |||
| } | |||
| public void setData(WeakReference<char[]> data) { | |||
| this.data = data; | |||
| } | |||
| public long getSize() { | |||
| return size; | |||
| } | |||
| public void setSize(long size) { | |||
| this.size = size; | |||
| } | |||
| } | |||
| } | |||
| @@ -1,108 +0,0 @@ | |||
| package com.yzx.webebook.utils; | |||
| import android.app.Activity; | |||
| import android.content.ContentResolver; | |||
| import android.provider.Settings; | |||
| import android.util.Log; | |||
| import android.view.WindowManager; | |||
| /** | |||
| * Created by newbiechen on 17-5-19. | |||
| * 调节亮度的工具类 | |||
| */ | |||
| public class BrightnessUtils { | |||
| private static final String TAG = "BrightnessUtils"; | |||
| /** | |||
| * 判断是否开启了自动亮度调节 | |||
| */ | |||
| public static boolean isAutoBrightness(Activity activity) { | |||
| boolean isAuto = false; | |||
| try { | |||
| isAuto = Settings.System.getInt(activity.getContentResolver(), | |||
| Settings.System.SCREEN_BRIGHTNESS_MODE) == Settings.System.SCREEN_BRIGHTNESS_MODE_AUTOMATIC; | |||
| } catch (Settings.SettingNotFoundException e){ | |||
| e.printStackTrace(); | |||
| } | |||
| return isAuto; | |||
| } | |||
| /** | |||
| * 获取屏幕的亮度 | |||
| * 系统亮度模式中,自动模式与手动模式获取到的系统亮度的值不同 | |||
| */ | |||
| public static int getScreenBrightness(Activity activity) { | |||
| if(isAutoBrightness(activity)){ | |||
| return getAutoScreenBrightness(activity); | |||
| }else{ | |||
| return getManualScreenBrightness(activity); | |||
| } | |||
| } | |||
| /** | |||
| * 获取手动模式下的屏幕亮度 | |||
| * @return value:0~255 | |||
| */ | |||
| public static int getManualScreenBrightness(Activity activity) { | |||
| int nowBrightnessValue = 0; | |||
| ContentResolver resolver = activity.getContentResolver(); | |||
| try { | |||
| nowBrightnessValue = Settings.System.getInt(resolver, Settings.System.SCREEN_BRIGHTNESS); | |||
| } catch (Exception e) { | |||
| e.printStackTrace(); | |||
| } | |||
| return nowBrightnessValue; | |||
| } | |||
| /** | |||
| * 获取自动模式下的屏幕亮度 | |||
| * @return value:0~255 | |||
| */ | |||
| public static int getAutoScreenBrightness(Activity activity) { | |||
| float nowBrightnessValue = 0; | |||
| //获取自动调节下的亮度范围在 0~1 之间 | |||
| ContentResolver resolver = activity.getContentResolver(); | |||
| try { | |||
| nowBrightnessValue = Settings.System.getFloat(resolver, Settings.System.SCREEN_BRIGHTNESS); | |||
| Log.d(TAG, "getAutoScreenBrightness: " + nowBrightnessValue); | |||
| } catch (Exception e) { | |||
| e.printStackTrace(); | |||
| } | |||
| //转换范围为 (0~255) | |||
| float fValue = nowBrightnessValue * 225.0f; | |||
| Log.d(TAG,"brightness: " + fValue); | |||
| return (int)fValue; | |||
| } | |||
| /** | |||
| * 设置亮度:通过设置 Windows 的 screenBrightness 来修改当前 Windows 的亮度 | |||
| * lp.screenBrightness:参数范围为 0~1 | |||
| */ | |||
| public static void setBrightness(Activity activity, int brightness) { | |||
| try{ | |||
| WindowManager.LayoutParams lp = activity.getWindow().getAttributes(); | |||
| //将 0~255 范围内的数据,转换为 0~1 | |||
| lp.screenBrightness = Float.valueOf(brightness) * (1f / 255f); | |||
| Log.d(TAG, "lp.screenBrightness == " + lp.screenBrightness); | |||
| activity.getWindow().setAttributes(lp); | |||
| }catch(Exception ex){ | |||
| ex.printStackTrace(); | |||
| } | |||
| } | |||
| /** | |||
| * 获取当前系统的亮度 | |||
| * @param activity | |||
| */ | |||
| public static void setDefaultBrightness(Activity activity) { | |||
| try { | |||
| WindowManager.LayoutParams lp = activity.getWindow().getAttributes(); | |||
| lp.screenBrightness = WindowManager.LayoutParams.BRIGHTNESS_OVERRIDE_NONE; | |||
| activity.getWindow().setAttributes(lp); | |||
| } catch (Exception ex) { | |||
| ex.printStackTrace(); | |||
| } | |||
| } | |||
| } | |||
| @@ -1,22 +0,0 @@ | |||
| package com.yzx.webebook.utils; | |||
| /** | |||
| * 编码类型 | |||
| */ | |||
| public enum Charset { | |||
| UTF8("UTF-8"), | |||
| UTF16LE("UTF-16LE"), | |||
| UTF16BE("UTF-16BE"), | |||
| GBK("GBK"); | |||
| private String mName; | |||
| public static final byte BLANK = 0x0a; | |||
| private Charset(String name) { | |||
| mName = name; | |||
| } | |||
| public String getName() { | |||
| return mName; | |||
| } | |||
| } | |||
| @@ -1,101 +0,0 @@ | |||
| package com.yzx.webebook.utils; | |||
| import androidx.annotation.StringDef; | |||
| import java.io.File; | |||
| import java.lang.annotation.Retention; | |||
| import java.lang.annotation.RetentionPolicy; | |||
| import java.util.HashMap; | |||
| import java.util.Map; | |||
| /** | |||
| * Created by newbiechen on 17-4-16. | |||
| */ | |||
| public class Constant { | |||
| /*SharedPreference*/ | |||
| public static final String SHARED_SEX = "sex"; | |||
| public static final String SHARED_SAVE_BOOK_SORT = "book_sort"; | |||
| public static final String SHARED_SAVE_BILLBOARD = "billboard"; | |||
| public static final String SHARED_CONVERT_TYPE = "convert_type"; | |||
| public static final String SEX_BOY = "boy"; | |||
| public static final String SEX_GIRL = "girl"; | |||
| /*URL_BASE*/ | |||
| public static final String API_BASE_URL = "http://api.zhuishushenqi.com"; | |||
| public static final String IMG_BASE_URL = "http://statics.zhuishushenqi.com"; | |||
| //book type | |||
| public static final String BOOK_TYPE_COMMENT = "normal"; | |||
| public static final String BOOK_TYPE_VOTE = "vote"; | |||
| //book state | |||
| public static final String BOOK_STATE_NORMAL = "normal"; | |||
| public static final String BOOK_STATE_DISTILLATE = "distillate"; | |||
| //Book Date Convert Format | |||
| public static final String FORMAT_BOOK_DATE = "yyyy-MM-dd'T'HH:mm:ss"; | |||
| public static final String FORMAT_TIME = "HH:mm"; | |||
| public static final String FORMAT_FILE_DATE = "yyyy-MM-dd"; | |||
| //RxBus | |||
| public static final int MSG_SELECTOR = 1; | |||
| //BookCachePath (因为getCachePath引用了Context,所以必须是静态变量,不能够是静态常量) | |||
| public static String BOOK_CACHE_PATH = FileUtils.getCachePath()+File.separator | |||
| + "book_cache"+ File.separator ; | |||
| //文件阅读记录保存的路径 | |||
| public static String BOOK_RECORD_PATH = FileUtils.getCachePath() + File.separator | |||
| + "book_record" + File.separator; | |||
| //BookType | |||
| @StringDef({ | |||
| BookType.ALL, | |||
| BookType.XHQH, | |||
| BookType.WXXX, | |||
| BookType.DSYN, | |||
| BookType.LSJS, | |||
| BookType.YXJJ, | |||
| BookType.KHLY, | |||
| BookType.CYJK, | |||
| BookType.HMZC, | |||
| BookType.XDYQ, | |||
| BookType.GDYQ, | |||
| BookType.HXYQ, | |||
| BookType.DMTR | |||
| }) | |||
| @Retention(RetentionPolicy.SOURCE) | |||
| public @interface BookType { | |||
| String ALL = "all"; | |||
| String XHQH = "xhqh"; | |||
| String WXXX = "wxxx"; | |||
| String DSYN = "dsyn"; | |||
| String LSJS = "lsjs"; | |||
| String YXJJ = "yxjj"; | |||
| String KHLY = "khly"; | |||
| String CYJK = "cyjk"; | |||
| String HMZC = "hmzc"; | |||
| String XDYQ = "xdyq"; | |||
| String GDYQ = "gdyq"; | |||
| String HXYQ = "hxyq"; | |||
| String DMTR = "dmtr"; | |||
| } | |||
| public static Map<String, String> bookType = new HashMap<String, String>() {{ | |||
| put("qt", "其他"); | |||
| put(BookType.XHQH, "玄幻奇幻"); | |||
| put(BookType.WXXX, "武侠仙侠"); | |||
| put(BookType.DSYN, "都市异能"); | |||
| put(BookType.LSJS, "历史军事"); | |||
| put(BookType.YXJJ, "游戏竞技"); | |||
| put(BookType.KHLY, "科幻灵异"); | |||
| put(BookType.CYJK, "穿越架空"); | |||
| put(BookType.HMZC, "豪门总裁"); | |||
| put(BookType.XDYQ, "现代言情"); | |||
| put(BookType.GDYQ, "古代言情"); | |||
| put(BookType.HXYQ, "幻想言情"); | |||
| put(BookType.DMTR, "耽美同人"); | |||
| }}; | |||
| } | |||
| @@ -1,49 +0,0 @@ | |||
| package com.yzx.webebook.utils; | |||
| import java.io.File; | |||
| import java.util.List; | |||
| /** | |||
| * Created by newbiechen on 17-5-28. | |||
| */ | |||
| public class FileStack { | |||
| private Node node = null; | |||
| private int count = 0; | |||
| public void push(FileSnapshot fileSnapshot){ | |||
| if (fileSnapshot == null) return; | |||
| Node fileNode = new Node(); | |||
| fileNode.fileSnapshot = fileSnapshot; | |||
| fileNode.next = node; | |||
| node = fileNode; | |||
| ++count; | |||
| } | |||
| public FileSnapshot pop(){ | |||
| Node fileNode = node; | |||
| if (fileNode == null) return null; | |||
| FileSnapshot fileSnapshot = fileNode.fileSnapshot; | |||
| node = fileNode.next; | |||
| --count; | |||
| return fileSnapshot; | |||
| } | |||
| public int getSize(){ | |||
| return count; | |||
| } | |||
| //节点 | |||
| public class Node { | |||
| FileSnapshot fileSnapshot; | |||
| Node next; | |||
| } | |||
| //文件快照 | |||
| public static class FileSnapshot{ | |||
| public String filePath; | |||
| public List<File> files; | |||
| public int scrollOffset; | |||
| } | |||
| } | |||
| @@ -1,328 +0,0 @@ | |||
| package com.yzx.webebook.utils; | |||
| import android.os.Environment; | |||
| import android.util.Log; | |||
| import com.yzx.webebook.App; | |||
| import java.io.BufferedInputStream; | |||
| import java.io.BufferedReader; | |||
| import java.io.File; | |||
| import java.io.FileInputStream; | |||
| import java.io.FileNotFoundException; | |||
| import java.io.FileReader; | |||
| import java.io.IOException; | |||
| import java.io.RandomAccessFile; | |||
| import java.io.Reader; | |||
| import java.text.DecimalFormat; | |||
| import java.util.ArrayList; | |||
| import java.util.List; | |||
| import io.reactivex.Single; | |||
| import io.reactivex.SingleEmitter; | |||
| import io.reactivex.SingleOnSubscribe; | |||
| /** | |||
| * Created by newbiechen on 17-5-11. | |||
| */ | |||
| public class FileUtils { | |||
| //采用自己的格式去设置文件,防止文件被系统文件查询到 | |||
| public static final String SUFFIX_NB = ".nb"; | |||
| public static final String SUFFIX_TXT = ".txt"; | |||
| public static final String SUFFIX_EPUB = ".epub"; | |||
| public static final String SUFFIX_PDF = ".pdf"; | |||
| //获取文件夹 | |||
| public static File getFolder(String filePath){ | |||
| File file = new File(filePath); | |||
| //如果文件夹不存在,就创建它 | |||
| if (!file.exists()){ | |||
| file.mkdirs(); | |||
| } | |||
| return file; | |||
| } | |||
| //获取文件 | |||
| public static synchronized File getFile(String filePath){ | |||
| File file = new File(filePath); | |||
| try { | |||
| if (!file.exists()){ | |||
| //创建父类文件夹 | |||
| getFolder(file.getParent()); | |||
| //创建文件 | |||
| file.createNewFile(); | |||
| } | |||
| } catch (IOException e) { | |||
| e.printStackTrace(); | |||
| } | |||
| return file; | |||
| } | |||
| //获取Cache文件夹 | |||
| public static String getCachePath(){ | |||
| if (isSdCardExist()){ | |||
| return App.Companion.getContext() | |||
| .getExternalCacheDir() | |||
| .getAbsolutePath(); | |||
| } | |||
| else{ | |||
| return App.Companion.getContext() | |||
| .getCacheDir() | |||
| .getAbsolutePath(); | |||
| } | |||
| } | |||
| public static long getDirSize(File file){ | |||
| //判断文件是否存在 | |||
| if (file.exists()) { | |||
| //如果是目录则递归计算其内容的总大小 | |||
| if (file.isDirectory()) { | |||
| File[] children = file.listFiles(); | |||
| long size = 0; | |||
| for (File f : children) | |||
| size += getDirSize(f); | |||
| return size; | |||
| } else { | |||
| return file.length(); | |||
| } | |||
| } else { | |||
| return 0; | |||
| } | |||
| } | |||
| public static String getFileSize(long size) { | |||
| if (size <= 0) return "0"; | |||
| final String[] units = new String[]{"b", "kb", "M", "G", "T"}; | |||
| //计算单位的,原理是利用lg,公式是 lg(1024^n) = nlg(1024),最后 nlg(1024)/lg(1024) = n。 | |||
| int digitGroups = (int) (Math.log10(size) / Math.log10(1024)); | |||
| //计算原理是,size/单位值。单位值指的是:比如说b = 1024,KB = 1024^2 | |||
| return new DecimalFormat("#,##0.##").format(size / Math.pow(1024, digitGroups)) + " " + units[digitGroups]; | |||
| } | |||
| /** | |||
| * 本来是获取File的内容的。但是为了解决文本缩进、换行的问题 | |||
| * 这个方法就是专门用来获取书籍的... | |||
| * | |||
| * 应该放在BookRepository中。。。 | |||
| * @param file | |||
| * @return | |||
| */ | |||
| public static String getFileContent(File file){ | |||
| Reader reader = null; | |||
| String str = null; | |||
| StringBuilder sb = new StringBuilder(); | |||
| try { | |||
| reader = new FileReader(file); | |||
| BufferedReader br = new BufferedReader(reader); | |||
| while ((str = br.readLine()) != null){ | |||
| //过滤空语句 | |||
| if (!str.equals("")){ | |||
| //由于sb会自动过滤\n,所以需要加上去 | |||
| sb.append(" "+str+"\n"); | |||
| } | |||
| } | |||
| } catch (FileNotFoundException e) { | |||
| e.printStackTrace(); | |||
| } catch (IOException e) { | |||
| e.printStackTrace(); | |||
| }finally { | |||
| IOUtils.close(reader); | |||
| } | |||
| return sb.toString(); | |||
| } | |||
| //判断是否挂载了SD卡 | |||
| public static boolean isSdCardExist(){ | |||
| if (Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState())){ | |||
| return true; | |||
| } | |||
| return false; | |||
| } | |||
| //递归删除文件夹下的数据 | |||
| public static synchronized void deleteFile(String filePath){ | |||
| File file = new File(filePath); | |||
| if (!file.exists()) return; | |||
| if (file.isDirectory()){ | |||
| File[] files = file.listFiles(); | |||
| for (File subFile : files){ | |||
| String path = subFile.getPath(); | |||
| deleteFile(path); | |||
| } | |||
| } | |||
| //删除文件 | |||
| file.delete(); | |||
| } | |||
| //由于递归的耗时问题,取巧只遍历内部三层 | |||
| //获取txt文件 | |||
| public static List<File> getTxtFiles(String filePath,int layer){ | |||
| List txtFiles = new ArrayList(); | |||
| File file = new File(filePath); | |||
| //如果层级为 3,则直接返回 | |||
| if (layer == 3){ | |||
| return txtFiles; | |||
| } | |||
| //获取文件夹 | |||
| File[] dirs = file.listFiles( | |||
| pathname -> { | |||
| if (pathname.isDirectory() && !pathname.getName().startsWith(".")) { | |||
| return true; | |||
| } | |||
| //获取txt文件 | |||
| else if(pathname.getName().endsWith(".txt")){ | |||
| txtFiles.add(pathname); | |||
| return false; | |||
| } | |||
| else{ | |||
| return false; | |||
| } | |||
| } | |||
| ); | |||
| //遍历文件夹 | |||
| for (File dir : dirs){ | |||
| //递归遍历txt文件 | |||
| txtFiles.addAll(getTxtFiles(dir.getPath(),layer + 1)); | |||
| } | |||
| return txtFiles; | |||
| } | |||
| //由于遍历比较耗时 | |||
| public static Single<List<File>> getSDTxtFile(){ | |||
| //外部存储卡路径 | |||
| String rootPath = Environment.getExternalStorageDirectory().getPath(); | |||
| return Single.create(new SingleOnSubscribe<List<File>>() { | |||
| @Override | |||
| public void subscribe(SingleEmitter<List<File>> e) throws Exception { | |||
| List<File> files = getTxtFiles(rootPath,0); | |||
| e.onSuccess(files); | |||
| } | |||
| }); | |||
| } | |||
| //获取文件的编码格式 | |||
| public static Charset getCharset(String fileName) { | |||
| BufferedInputStream bis = null; | |||
| Charset charset = Charset.GBK; | |||
| byte[] first3Bytes = new byte[3]; | |||
| try { | |||
| boolean checked = false; | |||
| bis = new BufferedInputStream(new FileInputStream(fileName)); | |||
| bis.mark(0); | |||
| int read = bis.read(first3Bytes, 0, 3); | |||
| if (read == -1) | |||
| return charset; | |||
| if (first3Bytes[0] == (byte) 0xEF | |||
| && first3Bytes[1] == (byte) 0xBB | |||
| && first3Bytes[2] == (byte) 0xBF) { | |||
| charset = Charset.UTF8; | |||
| checked = true; | |||
| } | |||
| /* | |||
| * 不支持 UTF16LE 和 UTF16BE | |||
| else if (first3Bytes[0] == (byte) 0xFF && first3Bytes[1] == (byte) 0xFE) { | |||
| charset = Charset.UTF16LE; | |||
| checked = true; | |||
| } else if (first3Bytes[0] == (byte) 0xFE | |||
| && first3Bytes[1] == (byte) 0xFF) { | |||
| charset = Charset.UTF16BE; | |||
| checked = true; | |||
| } else */ | |||
| bis.mark(0); | |||
| if (!checked) { | |||
| while ((read = bis.read()) != -1) { | |||
| if (read >= 0xF0) | |||
| break; | |||
| if (0x80 <= read && read <= 0xBF) // 单独出现BF以下的,也算是GBK | |||
| break; | |||
| if (0xC0 <= read && read <= 0xDF) { | |||
| read = bis.read(); | |||
| if (0x80 <= read && read <= 0xBF) // 双字节 (0xC0 - 0xDF) | |||
| // (0x80 - 0xBF),也可能在GB编码内 | |||
| continue; | |||
| else | |||
| break; | |||
| } else if (0xE0 <= read && read <= 0xEF) {// 也有可能出错,但是几率较小 | |||
| read = bis.read(); | |||
| if (0x80 <= read && read <= 0xBF) { | |||
| read = bis.read(); | |||
| if (0x80 <= read && read <= 0xBF) { | |||
| charset = Charset.UTF8; | |||
| break; | |||
| } else | |||
| break; | |||
| } else | |||
| break; | |||
| } | |||
| } | |||
| } | |||
| } catch (Exception e) { | |||
| e.printStackTrace(); | |||
| } finally { | |||
| IOUtils.close(bis); | |||
| } | |||
| return charset; | |||
| } | |||
| // 将字符串写入到文本文件中 | |||
| public static String writeTxtToFile(String strcontent, String filePath, String fileName) { | |||
| //生成文件夹之后,再生成文件,不然会出错 | |||
| makeFilePath(filePath, fileName); | |||
| String strFilePath = filePath + fileName; | |||
| // 每次写入时,都换行写 | |||
| String strContent = strcontent + "\r\n"; | |||
| try { | |||
| File file = new File(strFilePath); | |||
| if (!file.exists()) { | |||
| Log.d("TestFile", "Create the file:" + strFilePath); | |||
| file.getParentFile().mkdirs(); | |||
| file.createNewFile(); | |||
| } | |||
| RandomAccessFile raf = new RandomAccessFile(file, "rwd"); | |||
| raf.seek(file.length()); | |||
| raf.write(strContent.getBytes()); | |||
| raf.close(); | |||
| return strFilePath; | |||
| } catch (Exception e) { | |||
| Log.e("TestFile", "Error on write File:" + e); | |||
| return ""; | |||
| } | |||
| } | |||
| //生成文件 | |||
| public static File makeFilePath(String filePath, String fileName) { | |||
| File file = null; | |||
| makeRootDirectory(filePath); | |||
| try { | |||
| file = new File(filePath + fileName); | |||
| if (!file.exists()) { | |||
| file.createNewFile(); | |||
| } | |||
| } catch (Exception e) { | |||
| e.printStackTrace(); | |||
| } | |||
| return file; | |||
| } | |||
| //生成文件夹 | |||
| public static void makeRootDirectory(String filePath) { | |||
| File file = null; | |||
| try { | |||
| file = new File(filePath); | |||
| if (!file.exists()) { | |||
| file.mkdir(); | |||
| } | |||
| } catch (Exception e) { | |||
| Log.i("error:", e + ""); | |||
| } | |||
| } | |||
| } | |||
| @@ -1,58 +0,0 @@ | |||
| package com.yzx.webebook.utils; | |||
| import com.google.gson.Gson; | |||
| import com.google.gson.JsonArray; | |||
| import com.google.gson.JsonElement; | |||
| import com.google.gson.JsonParser; | |||
| import java.util.ArrayList; | |||
| import java.util.List; | |||
| /** | |||
| * Created by andrew on 2016/8/15 0015. | |||
| */ | |||
| public class GsonHelper { | |||
| public static String toJson(Object src){ | |||
| try { | |||
| return new Gson().toJson(src); | |||
| } catch (Exception e){ | |||
| e.printStackTrace(); | |||
| } | |||
| return null; | |||
| } | |||
| public static <T> T fromJson(String json, Class<T> clazz) { | |||
| try { | |||
| return new Gson().fromJson(json, clazz); | |||
| } catch (Exception e){ | |||
| e.printStackTrace(); | |||
| } | |||
| return null; | |||
| } | |||
| public static <T> List<T> fromJsonArray(String json, Class<T> clazz) { | |||
| try { | |||
| List<T> lst = new ArrayList<T>(); | |||
| JsonArray array = new JsonParser().parse(json).getAsJsonArray(); | |||
| for(final JsonElement elem : array){ | |||
| lst.add(new Gson().fromJson(elem, clazz)); | |||
| } | |||
| return lst; | |||
| } catch (Exception e){ | |||
| e.printStackTrace(); | |||
| } | |||
| return null; | |||
| } | |||
| public static <T> T fromJsonObject(String json, Class<T> clazz) { | |||
| try { | |||
| JsonElement elem = new JsonParser().parse(json).getAsJsonObject(); | |||
| return new Gson().fromJson(elem, clazz); | |||
| } catch (Exception e){ | |||
| e.printStackTrace(); | |||
| } | |||
| return null; | |||
| } | |||
| } | |||
| @@ -1,21 +0,0 @@ | |||
| package com.yzx.webebook.utils; | |||
| import java.io.Closeable; | |||
| import java.io.IOException; | |||
| /** | |||
| * Created by newbiechen on 17-5-11. | |||
| */ | |||
| public class IOUtils { | |||
| public static void close(Closeable closeable){ | |||
| if (closeable == null) return; | |||
| try { | |||
| closeable.close(); | |||
| } catch (IOException e) { | |||
| e.printStackTrace(); | |||
| //close error | |||
| } | |||
| } | |||
| } | |||
| @@ -1,2 +0,0 @@ | |||
| package com.yzx.webebook.utils | |||
| @@ -1,204 +0,0 @@ | |||
| package com.yzx.webebook.utils; | |||
| import android.text.TextUtils; | |||
| import java.util.ArrayList; | |||
| import java.util.List; | |||
| /** | |||
| * List Utils | |||
| * | |||
| * @author andrew 2015-9-2 | |||
| */ | |||
| public class ListUtils { | |||
| /** default join separator **/ | |||
| public static final String DEFAULT_JOIN_SEPARATOR = ","; | |||
| private ListUtils() { | |||
| throw new AssertionError(); | |||
| } | |||
| /** | |||
| * get size of list | |||
| * | |||
| * <pre> | |||
| * getSize(null) = 0; | |||
| * getSize({}) = 0; | |||
| * getSize({1}) = 1; | |||
| * </pre> | |||
| * | |||
| * @param <V> | |||
| * @param sourceList | |||
| * @return if list is null or empty, return 0, else return {@link List#size()}. | |||
| */ | |||
| public static <V> int getSize(List<V> sourceList) { | |||
| return sourceList == null ? 0 : sourceList.size(); | |||
| } | |||
| /** | |||
| * is null or its size is 0 | |||
| * | |||
| * <pre> | |||
| * isEmpty(null) = true; | |||
| * isEmpty({}) = true; | |||
| * isEmpty({1}) = false; | |||
| * </pre> | |||
| * | |||
| * @param <V> | |||
| * @param sourceList | |||
| * @return if list is null or its size is 0, return true, else return false. | |||
| */ | |||
| public static <V> boolean isEmpty(List<V> sourceList) { | |||
| return (sourceList == null || sourceList.size() == 0); | |||
| } | |||
| /** | |||
| * join list to string, separator is "," | |||
| * | |||
| * <pre> | |||
| * join(null) = ""; | |||
| * join({}) = ""; | |||
| * join({a,b}) = "a,b"; | |||
| * </pre> | |||
| * | |||
| * @param list | |||
| * @return join list to string, separator is ",". if list is empty, return "" | |||
| */ | |||
| public static String join(List<String> list) { | |||
| return join(list, DEFAULT_JOIN_SEPARATOR); | |||
| } | |||
| /** | |||
| * join list to string | |||
| * | |||
| * <pre> | |||
| * join(null, '#') = ""; | |||
| * join({}, '#') = ""; | |||
| * join({a,b,c}, ' ') = "abc"; | |||
| * join({a,b,c}, '#') = "a#b#c"; | |||
| * </pre> | |||
| * | |||
| * @param list | |||
| * @param separator | |||
| * @return join list to string. if list is empty, return "" | |||
| */ | |||
| public static String join(List<String> list, char separator) { | |||
| return join(list, new String(new char[] {separator})); | |||
| } | |||
| /** | |||
| * join list to string. if separator is null, use {@link #DEFAULT_JOIN_SEPARATOR} | |||
| * | |||
| * <pre> | |||
| * join(null, "#") = ""; | |||
| * join({}, "#$") = ""; | |||
| * join({a,b,c}, null) = "a,b,c"; | |||
| * join({a,b,c}, "") = "abc"; | |||
| * join({a,b,c}, "#") = "a#b#c"; | |||
| * join({a,b,c}, "#$") = "a#$b#$c"; | |||
| * </pre> | |||
| * | |||
| * @param list | |||
| * @param separator | |||
| * @return join list to string with separator. if list is empty, return "" | |||
| */ | |||
| public static String join(List<String> list, String separator) { | |||
| return list == null ? "" : TextUtils.join(separator, list); | |||
| } | |||
| /** | |||
| * add distinct entry to list | |||
| * | |||
| * @param <V> | |||
| * @param sourceList | |||
| * @param entry | |||
| * @return if entry already exist in sourceList, return false, else add it and return true. | |||
| */ | |||
| public static <V> boolean addDistinctEntry(List<V> sourceList, V entry) { | |||
| return (sourceList != null && !sourceList.contains(entry)) ? sourceList.add(entry) : false; | |||
| } | |||
| /** | |||
| * add all distinct entry to list1 from list2 | |||
| * | |||
| * @param <V> | |||
| * @param sourceList | |||
| * @param entryList | |||
| * @return the count of entries be added | |||
| */ | |||
| public static <V> int addDistinctList(List<V> sourceList, List<V> entryList) { | |||
| if (sourceList == null || isEmpty(entryList)) { | |||
| return 0; | |||
| } | |||
| int sourceCount = sourceList.size(); | |||
| for (V entry : entryList) { | |||
| if (!sourceList.contains(entry)) { | |||
| sourceList.add(entry); | |||
| } | |||
| } | |||
| return sourceList.size() - sourceCount; | |||
| } | |||
| /** | |||
| * remove duplicate entries in list | |||
| * | |||
| * @param <V> | |||
| * @param sourceList | |||
| * @return the count of entries be removed | |||
| */ | |||
| public static <V> int distinctList(List<V> sourceList) { | |||
| if (isEmpty(sourceList)) { | |||
| return 0; | |||
| } | |||
| int sourceCount = sourceList.size(); | |||
| int sourceListSize = sourceList.size(); | |||
| for (int i = 0; i < sourceListSize; i++) { | |||
| for (int j = (i + 1); j < sourceListSize; j++) { | |||
| if (sourceList.get(i).equals(sourceList.get(j))) { | |||
| sourceList.remove(j); | |||
| sourceListSize = sourceList.size(); | |||
| j--; | |||
| } | |||
| } | |||
| } | |||
| return sourceCount - sourceList.size(); | |||
| } | |||
| /** | |||
| * add not null entry to list | |||
| * | |||
| * @param sourceList | |||
| * @param value | |||
| * @return <ul> | |||
| * <li>if sourceList is null, return false</li> | |||
| * <li>if value is null, return false</li> | |||
| * <li>return {@link List#add(Object)}</li> | |||
| * </ul> | |||
| */ | |||
| public static <V> boolean addListNotNullValue(List<V> sourceList, V value) { | |||
| return (sourceList != null && value != null) ? sourceList.add(value) : false; | |||
| } | |||
| /** | |||
| * invert list | |||
| * | |||
| * @param <V> | |||
| * @param sourceList | |||
| * @return | |||
| */ | |||
| public static <V> List<V> invertList(List<V> sourceList) { | |||
| if (isEmpty(sourceList)) { | |||
| return sourceList; | |||
| } | |||
| List<V> invertList = new ArrayList<V>(sourceList.size()); | |||
| for (int i = sourceList.size() - 1; i >= 0; i--) { | |||
| invertList.add(sourceList.get(i)); | |||
| } | |||
| return invertList; | |||
| } | |||
| } | |||
| @@ -1,222 +0,0 @@ | |||
| package com.yzx.webebook.utils; | |||
| import android.content.Context; | |||
| import android.os.Environment; | |||
| import android.util.Log; | |||
| import com.yzx.webebook.App; | |||
| import java.io.BufferedWriter; | |||
| import java.io.File; | |||
| import java.io.FileWriter; | |||
| import java.io.IOException; | |||
| import java.text.SimpleDateFormat; | |||
| import java.util.Calendar; | |||
| import java.util.Date; | |||
| /** | |||
| * Created by newbiechen on 17-4-27. | |||
| */ | |||
| public class LogUtils { | |||
| private static Boolean LOG_SWITCH = true; // 日志文件总开关 | |||
| private static Boolean LOG_TO_FILE = false; // 日志写入文件开关 | |||
| private static String LOG_TAG = "IReader"; // 默认的tag | |||
| private static char LOG_TYPE = 'v';// 输入日志类型,v代表输出所有信息,w则只输出警告... | |||
| private static int LOG_SAVE_DAYS = 7;// sd卡中日志文件的最多保存天数 | |||
| private final static SimpleDateFormat LOG_FORMAT = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");// 日志的输出格式 | |||
| private final static SimpleDateFormat FILE_SUFFIX = new SimpleDateFormat("yyyy-MM-dd");// 日志文件格式 | |||
| private static String LOG_FILE_PATH; // 日志文件保存路径 | |||
| private static String LOG_FILE_NAME;// 日志文件保存名称 | |||
| public static void init(Context context) { // 在Application中初始化 | |||
| LOG_FILE_PATH = Environment.getExternalStorageDirectory().getPath() + File.separator + App.Companion.getContext().getPackageName(); | |||
| LOG_FILE_NAME = "Log"; | |||
| } | |||
| /**************************** | |||
| * Warn | |||
| *********************************/ | |||
| public static void w(Object msg) { | |||
| w(LOG_TAG, msg); | |||
| } | |||
| public static void w(String tag, Object msg) { | |||
| w(tag, msg, null); | |||
| } | |||
| public static void w(String tag, Object msg, Throwable tr) { | |||
| if (msg == null) return; | |||
| log(tag, msg.toString(), tr, 'w'); | |||
| } | |||
| /*************************** | |||
| * Error | |||
| ********************************/ | |||
| public static void e(Object msg) { | |||
| e(LOG_TAG, msg); | |||
| } | |||
| public static void e(String tag, Object msg) { | |||
| e(tag, msg, null); | |||
| } | |||
| public static void e(String tag, Object msg, Throwable tr) { | |||
| if (msg == null) return; | |||
| log(tag, msg.toString(), tr, 'e'); | |||
| } | |||
| /*************************** | |||
| * Debug | |||
| ********************************/ | |||
| public static void d(Object msg) { | |||
| d(LOG_TAG, msg); | |||
| } | |||
| public static void d(String tag, Object msg) {// 调试信息 | |||
| d(tag, msg, null); | |||
| } | |||
| public static void d(String tag, Object msg, Throwable tr) { | |||
| if (msg == null) return; | |||
| log(tag, msg.toString(), tr, 'd'); | |||
| } | |||
| /**************************** | |||
| * Info | |||
| *********************************/ | |||
| public static void i(Object msg) { | |||
| i(LOG_TAG, msg); | |||
| } | |||
| public static void i(String tag, Object msg) { | |||
| i(tag, msg, null); | |||
| } | |||
| public static void i(String tag, Object msg, Throwable tr) { | |||
| if (msg == null) return; | |||
| log(tag, msg.toString(), tr, 'i'); | |||
| } | |||
| /************************** | |||
| * Verbose | |||
| ********************************/ | |||
| public static void v(Object msg) { | |||
| v(LOG_TAG, msg); | |||
| } | |||
| public static void v(String tag, Object msg) { | |||
| v(tag, msg, null); | |||
| } | |||
| public static void v(String tag, Object msg, Throwable tr) { | |||
| if (msg == null) return; | |||
| log(tag, msg.toString(), tr, 'v'); | |||
| } | |||
| /** | |||
| * 根据tag, msg和等级,输出日志 | |||
| * | |||
| * @param tag | |||
| * @param msg | |||
| * @param level | |||
| */ | |||
| private static void log(String tag, String msg, Throwable tr, char level) { | |||
| if (tag == null || msg == null || tr == null) return; | |||
| if (LOG_SWITCH) { | |||
| if ('e' == level && ('e' == LOG_TYPE || 'v' == LOG_TYPE)) { // 输出错误信息 | |||
| Log.e(tag, createMessage(msg), tr); | |||
| } else if ('w' == level && ('w' == LOG_TYPE || 'v' == LOG_TYPE)) { | |||
| Log.w(tag, createMessage(msg), tr); | |||
| } else if ('d' == level && ('d' == LOG_TYPE || 'v' == LOG_TYPE)) { | |||
| Log.d(tag, createMessage(msg), tr); | |||
| } else if ('i' == level && ('d' == LOG_TYPE || 'v' == LOG_TYPE)) { | |||
| Log.i(tag, createMessage(msg), tr); | |||
| } else { | |||
| Log.v(tag, createMessage(msg), tr); | |||
| } | |||
| if (LOG_TO_FILE) | |||
| log2File(String.valueOf(level), tag, msg + tr == null ? "" : "\n" + Log.getStackTraceString(tr)); | |||
| } | |||
| } | |||
| private static String getFunctionName() { | |||
| StackTraceElement[] sts = Thread.currentThread().getStackTrace(); | |||
| if (sts == null) { | |||
| return null; | |||
| } | |||
| for (StackTraceElement st : sts) { | |||
| if (st.isNativeMethod()) { | |||
| continue; | |||
| } | |||
| if (st.getClassName().equals(Thread.class.getName())) { | |||
| continue; | |||
| } | |||
| if (st.getFileName().equals("LogUtils.java")) { | |||
| continue; | |||
| } | |||
| return "[" + Thread.currentThread().getName() + "(" | |||
| + Thread.currentThread().getId() + "): " + st.getFileName() | |||
| + ":" + st.getLineNumber() + "]"; | |||
| } | |||
| return null; | |||
| } | |||
| private static String createMessage(String msg) { | |||
| String functionName = getFunctionName(); | |||
| String message = (functionName == null ? msg | |||
| : (functionName + " - " + msg)); | |||
| return message; | |||
| } | |||
| /** | |||
| * 打开日志文件并写入日志 | |||
| * | |||
| * @return | |||
| **/ | |||
| private synchronized static void log2File(String mylogtype, String tag, String text) { | |||
| Date nowtime = new Date(); | |||
| String date = FILE_SUFFIX.format(nowtime); | |||
| String dateLogContent = LOG_FORMAT.format(nowtime) + ":" + mylogtype + ":" + tag + ":" + text; // 日志输出格式 | |||
| File destDir = new File(LOG_FILE_PATH); | |||
| if (!destDir.exists()) { | |||
| destDir.mkdirs(); | |||
| } | |||
| File file = new File(LOG_FILE_PATH, LOG_FILE_NAME + date); | |||
| try { | |||
| FileWriter filerWriter = new FileWriter(file, true); | |||
| BufferedWriter bufWriter = new BufferedWriter(filerWriter); | |||
| bufWriter.write(dateLogContent); | |||
| bufWriter.newLine(); | |||
| bufWriter.close(); | |||
| filerWriter.close(); | |||
| } catch (IOException e) { | |||
| e.printStackTrace(); | |||
| } | |||
| } | |||
| /** | |||
| * 删除指定的日志文件 | |||
| */ | |||
| public static void delFile() {// 删除日志文件 | |||
| String needDelFiel = FILE_SUFFIX.format(getDateBefore()); | |||
| File file = new File(LOG_FILE_PATH, needDelFiel + LOG_FILE_NAME); | |||
| if (file.exists()) { | |||
| file.delete(); | |||
| } | |||
| } | |||
| /** | |||
| * 得到LOG_SAVE_DAYS天前的日期 | |||
| * | |||
| * @return | |||
| */ | |||
| private static Date getDateBefore() { | |||
| Date nowtime = new Date(); | |||
| Calendar now = Calendar.getInstance(); | |||
| now.setTime(nowtime); | |||
| now.set(Calendar.DATE, now.get(Calendar.DATE) - LOG_SAVE_DAYS); | |||
| return now.getTime(); | |||
| } | |||
| } | |||
| @@ -1,43 +0,0 @@ | |||
| package com.yzx.webebook.utils; | |||
| /** | |||
| * Created by newbiechen on 2018/1/1. | |||
| */ | |||
| import java.security.MessageDigest; | |||
| import java.security.NoSuchAlgorithmException; | |||
| /** | |||
| *@Description: 将字符串转化为MD5 | |||
| */ | |||
| public class MD5Utils { | |||
| public static String strToMd5By32(String str){ | |||
| String reStr = null; | |||
| try { | |||
| MessageDigest md5 = MessageDigest.getInstance("MD5"); | |||
| byte[] bytes = md5.digest(str.getBytes()); | |||
| StringBuffer stringBuffer = new StringBuffer(); | |||
| for (byte b : bytes){ | |||
| int bt = b&0xff; | |||
| if (bt < 16){ | |||
| stringBuffer.append(0); | |||
| } | |||
| stringBuffer.append(Integer.toHexString(bt)); | |||
| } | |||
| reStr = stringBuffer.toString(); | |||
| } catch (NoSuchAlgorithmException e) { | |||
| e.printStackTrace(); | |||
| } | |||
| return reStr; | |||
| } | |||
| public static String strToMd5By16(String str){ | |||
| String reStr = strToMd5By32(str); | |||
| if (reStr != null){ | |||
| reStr = reStr.substring(8, 24); | |||
| } | |||
| return reStr; | |||
| } | |||
| } | |||
| @@ -1,63 +0,0 @@ | |||
| package com.yzx.webebook.utils; | |||
| import android.content.Context; | |||
| import android.net.ConnectivityManager; | |||
| import android.net.NetworkInfo; | |||
| import com.yzx.webebook.App; | |||
| /** | |||
| * Created by newbiechen on 17-5-11. | |||
| */ | |||
| public class NetworkUtils { | |||
| /** | |||
| * 获取活动网络信息 | |||
| * @return NetworkInfo | |||
| */ | |||
| public static NetworkInfo getNetworkInfo(){ | |||
| ConnectivityManager cm = (ConnectivityManager) App.Companion | |||
| .getContext() | |||
| .getSystemService(Context.CONNECTIVITY_SERVICE); | |||
| return cm.getActiveNetworkInfo(); | |||
| } | |||
| /** | |||
| * 网络是否可用 | |||
| * @return | |||
| */ | |||
| public static boolean isAvailable(){ | |||
| NetworkInfo info = getNetworkInfo(); | |||
| return info != null && info.isAvailable(); | |||
| } | |||
| /** | |||
| * 网络是否连接 | |||
| * @return | |||
| */ | |||
| public static boolean isConnected(){ | |||
| NetworkInfo info = getNetworkInfo(); | |||
| return info != null && info.isConnected(); | |||
| } | |||
| /** | |||
| * 判断wifi是否连接状态 | |||
| * <p>需添加权限 {@code <uses-permission android:name="android.permission | |||
| * .ACCESS_NETWORK_STATE"/>}</p> | |||
| * | |||
| * @param context 上下文 | |||
| * @return {@code true}: 连接<br>{@code false}: 未连接 | |||
| */ | |||
| public static boolean isWifiConnected(Context context) { | |||
| ConnectivityManager cm = (ConnectivityManager) context | |||
| .getSystemService(Context.CONNECTIVITY_SERVICE); | |||
| return cm != null && cm.getActiveNetworkInfo() != null | |||
| && cm.getActiveNetworkInfo().getType() == ConnectivityManager.TYPE_WIFI; | |||
| } | |||
| } | |||
| @@ -1,34 +0,0 @@ | |||
| package com.yzx.webebook.utils; | |||
| import android.content.Context; | |||
| import android.content.pm.PackageManager; | |||
| import androidx.core.content.ContextCompat; | |||
| /** | |||
| * Created by newbiechen on 2017/10/8. | |||
| */ | |||
| public class PermissionsChecker { | |||
| private final Context mContext; | |||
| public PermissionsChecker(Context context) { | |||
| mContext = context.getApplicationContext(); | |||
| } | |||
| // 判断权限集合 | |||
| public boolean lacksPermissions(String... permissions) { | |||
| for (String permission : permissions) { | |||
| if (lacksPermission(permission)) { | |||
| return true; | |||
| } | |||
| } | |||
| return false; | |||
| } | |||
| // 判断是否缺少权限 | |||
| private boolean lacksPermission(String permission) { | |||
| return ContextCompat.checkSelfPermission(mContext, permission) == | |||
| PackageManager.PERMISSION_DENIED; | |||
| } | |||
| } | |||
| @@ -1,60 +0,0 @@ | |||
| package com.yzx.webebook.utils; | |||
| import com.yzx.webebook.model.bean.CommentBean; | |||
| import com.yzx.webebook.model.bean.DetailBean; | |||
| import java.util.List; | |||
| import io.reactivex.Observable; | |||
| import io.reactivex.ObservableSource; | |||
| import io.reactivex.Single; | |||
| import io.reactivex.SingleSource; | |||
| import io.reactivex.android.schedulers.AndroidSchedulers; | |||
| import io.reactivex.functions.Function3; | |||
| import io.reactivex.schedulers.Schedulers; | |||
| /** | |||
| * Created by newbiechen on 17-4-29. | |||
| */ | |||
| public class RxUtils { | |||
| public static <T> SingleSource<T> toSimpleSingle(Single<T> upstream){ | |||
| return upstream.subscribeOn(Schedulers.io()) | |||
| .observeOn(AndroidSchedulers.mainThread()); | |||
| } | |||
| public static <T> ObservableSource<T> toSimpleSingle(Observable<T> upstream){ | |||
| return upstream.subscribeOn(Schedulers.io()) | |||
| .observeOn(AndroidSchedulers.mainThread()); | |||
| } | |||
| public static <T,R> TwoTuple<T,R> twoTuple(T first,R second){ | |||
| return new TwoTuple<T, R>(first, second); | |||
| } | |||
| public static <T> Single<DetailBean<T>> toCommentDetail(Single<T> detailSingle, | |||
| Single<List<CommentBean>> bestCommentsSingle, | |||
| Single<List<CommentBean>> commentsSingle){ | |||
| return Single.zip(detailSingle, bestCommentsSingle, commentsSingle, | |||
| new Function3<T, List<CommentBean>, List<CommentBean>, DetailBean<T>>() { | |||
| @Override | |||
| public DetailBean<T> apply(T t, List<CommentBean> commentBeen, | |||
| List<CommentBean> commentBeen2) throws Exception { | |||
| return new DetailBean<T>(t,commentBeen,commentBeen2); | |||
| } | |||
| }); | |||
| } | |||
| public static class TwoTuple<A, B> { | |||
| public final A first; | |||
| public final B second; | |||
| public TwoTuple(A a, B b) { | |||
| this.first = a; | |||
| this.second = b; | |||
| } | |||
| } | |||
| } | |||
| @@ -1,127 +0,0 @@ | |||
| package com.yzx.webebook.utils; | |||
| import android.content.res.Resources; | |||
| import android.util.DisplayMetrics; | |||
| import android.util.TypedValue; | |||
| import android.view.View; | |||
| import androidx.appcompat.app.AppCompatActivity; | |||
| import com.yzx.webebook.App; | |||
| import java.lang.reflect.Method; | |||
| /** | |||
| * Created by newbiechen on 17-5-1. | |||
| */ | |||
| public class ScreenUtils { | |||
| public static int dpToPx(int dp) { | |||
| DisplayMetrics metrics = getDisplayMetrics(); | |||
| return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp, metrics); | |||
| } | |||
| public static int pxToDp(int px) { | |||
| DisplayMetrics metrics = getDisplayMetrics(); | |||
| return (int) (px / metrics.density); | |||
| } | |||
| public static int spToPx(int sp) { | |||
| DisplayMetrics metrics = getDisplayMetrics(); | |||
| return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, sp, metrics); | |||
| } | |||
| public static int pxToSp(int px) { | |||
| DisplayMetrics metrics = getDisplayMetrics(); | |||
| return (int) (px / metrics.scaledDensity); | |||
| } | |||
| /** | |||
| * 获取手机显示App区域的大小(头部导航栏+ActionBar+根布局),不包括虚拟按钮 | |||
| * | |||
| * @return | |||
| */ | |||
| public static int[] getAppSize() { | |||
| int[] size = new int[2]; | |||
| DisplayMetrics metrics = getDisplayMetrics(); | |||
| size[0] = metrics.widthPixels; | |||
| size[1] = metrics.heightPixels; | |||
| return size; | |||
| } | |||
| /** | |||
| * 获取整个手机屏幕的大小(包括虚拟按钮) | |||
| * 必须在onWindowFocus方法之后使用 | |||
| * | |||
| * @param activity | |||
| * @return | |||
| */ | |||
| public static int[] getScreenSize(AppCompatActivity activity) { | |||
| int[] size = new int[2]; | |||
| View decorView = activity.getWindow().getDecorView(); | |||
| size[0] = decorView.getWidth(); | |||
| size[1] = decorView.getHeight(); | |||
| return size; | |||
| } | |||
| /** | |||
| * 获取导航栏的高度 | |||
| * | |||
| * @return | |||
| */ | |||
| public static int getStatusBarHeight() { | |||
| Resources resources = App.Companion.getContext().getResources(); | |||
| int resourceId = resources.getIdentifier("status_bar_height", "dimen", "android"); | |||
| return resources.getDimensionPixelSize(resourceId); | |||
| } | |||
| /** | |||
| * 获取虚拟按键的高度 | |||
| * | |||
| * @return | |||
| */ | |||
| public static int getNavigationBarHeight() { | |||
| int navigationBarHeight = 0; | |||
| Resources rs = App.Companion.getContext().getResources(); | |||
| int id = rs.getIdentifier("navigation_bar_height", "dimen", "android"); | |||
| if (id > 0 && hasNavigationBar()) { | |||
| navigationBarHeight = rs.getDimensionPixelSize(id); | |||
| } | |||
| return navigationBarHeight; | |||
| } | |||
| /** | |||
| * 是否存在虚拟按键 | |||
| * | |||
| * @return | |||
| */ | |||
| private static boolean hasNavigationBar() { | |||
| boolean hasNavigationBar = false; | |||
| Resources rs = App.Companion.getContext().getResources(); | |||
| int id = rs.getIdentifier("config_showNavigationBar", "bool", "android"); | |||
| if (id > 0) { | |||
| hasNavigationBar = rs.getBoolean(id); | |||
| } | |||
| try { | |||
| Class systemPropertiesClass = Class.forName("android.os.SystemProperties"); | |||
| Method m = systemPropertiesClass.getMethod("get", String.class); | |||
| String navBarOverride = (String) m.invoke(systemPropertiesClass, "qemu.hw.mainkeys"); | |||
| if ("1".equals(navBarOverride)) { | |||
| hasNavigationBar = false; | |||
| } else if ("0".equals(navBarOverride)) { | |||
| hasNavigationBar = true; | |||
| } | |||
| } catch (Exception e) { | |||
| } | |||
| return hasNavigationBar; | |||
| } | |||
| public static DisplayMetrics getDisplayMetrics() { | |||
| DisplayMetrics metrics = App.Companion | |||
| .getContext() | |||
| .getResources() | |||
| .getDisplayMetrics(); | |||
| return metrics; | |||
| } | |||
| } | |||
| @@ -1,61 +0,0 @@ | |||
| package com.yzx.webebook.utils; | |||
| import android.content.Context; | |||
| import android.content.SharedPreferences; | |||
| import com.yzx.webebook.App; | |||
| /** | |||
| * Created by newbiechen on 17-4-16. | |||
| */ | |||
| public class SharedPreUtils { | |||
| private static final String SHARED_NAME = "IReader_pref"; | |||
| private static SharedPreUtils sInstance; | |||
| private SharedPreferences sharedReadable; | |||
| private SharedPreferences.Editor sharedWritable; | |||
| private SharedPreUtils(){ | |||
| sharedReadable = App.Companion.getContext() | |||
| .getSharedPreferences(SHARED_NAME, Context.MODE_MULTI_PROCESS); | |||
| sharedWritable = sharedReadable.edit(); | |||
| } | |||
| public static SharedPreUtils getInstance(){ | |||
| if(sInstance == null){ | |||
| synchronized (SharedPreUtils.class){ | |||
| if (sInstance == null){ | |||
| sInstance = new SharedPreUtils(); | |||
| } | |||
| } | |||
| } | |||
| return sInstance; | |||
| } | |||
| public String getString(String key){ | |||
| return sharedReadable.getString(key,""); | |||
| } | |||
| public void putString(String key,String value){ | |||
| sharedWritable.putString(key,value); | |||
| sharedWritable.commit(); | |||
| } | |||
| public void putInt(String key,int value){ | |||
| sharedWritable.putInt(key, value); | |||
| sharedWritable.commit(); | |||
| } | |||
| public void putBoolean(String key,boolean value){ | |||
| sharedWritable.putBoolean(key, value); | |||
| sharedWritable.commit(); | |||
| } | |||
| public int getInt(String key,int def){ | |||
| return sharedReadable.getInt(key, def); | |||
| } | |||
| public boolean getBoolean(String key,boolean def){ | |||
| return sharedReadable.getBoolean(key, def); | |||
| } | |||
| } | |||
| @@ -1,190 +0,0 @@ | |||
| package com.yzx.webebook.utils; | |||
| import android.content.Context; | |||
| import androidx.annotation.StringRes; | |||
| import com.yzx.webebook.App; | |||
| import java.text.DateFormat; | |||
| import java.text.ParseException; | |||
| import java.text.SimpleDateFormat; | |||
| import java.util.Calendar; | |||
| import java.util.Date; | |||
| //import com.zqc.opencc.android.lib.ChineseConverter; | |||
| //import com.zqc.opencc.android.lib.ConversionType; | |||
| /** | |||
| * Created by newbiechen on 17-4-22. | |||
| * 对文字操作的工具类 | |||
| */ | |||
| public class StringUtils { | |||
| private static final String TAG = "StringUtils"; | |||
| private static final int HOUR_OF_DAY = 24; | |||
| private static final int DAY_OF_YESTERDAY = 2; | |||
| private static final int TIME_UNIT = 60; | |||
| //将时间转换成日期 | |||
| public static String dateConvert(long time,String pattern){ | |||
| Date date = new Date(time); | |||
| SimpleDateFormat format = new SimpleDateFormat(pattern); | |||
| return format.format(date); | |||
| } | |||
| //将日期转换成昨天、今天、明天 | |||
| public static String dateConvert(String source,String pattern){ | |||
| DateFormat format = new SimpleDateFormat(pattern); | |||
| Calendar calendar = Calendar.getInstance(); | |||
| try { | |||
| Date date = format.parse(source); | |||
| long curTime = calendar.getTimeInMillis(); | |||
| calendar.setTime(date); | |||
| //将MISC 转换成 sec | |||
| long difSec = Math.abs((curTime - date.getTime())/1000); | |||
| long difMin = difSec/60; | |||
| long difHour = difMin/60; | |||
| long difDate = difHour/60; | |||
| int oldHour = calendar.get(Calendar.HOUR); | |||
| //如果没有时间 | |||
| if (oldHour == 0){ | |||
| //比日期:昨天今天和明天 | |||
| if (difDate == 0){ | |||
| return "今天"; | |||
| } | |||
| else if (difDate < DAY_OF_YESTERDAY){ | |||
| return "昨天"; | |||
| } | |||
| else { | |||
| DateFormat convertFormat = new SimpleDateFormat("yyyy-MM-dd"); | |||
| String value = convertFormat.format(date); | |||
| return value; | |||
| } | |||
| } | |||
| if (difSec < TIME_UNIT){ | |||
| return difSec+"秒前"; | |||
| } | |||
| else if (difMin < TIME_UNIT){ | |||
| return difMin+"分钟前"; | |||
| } | |||
| else if (difHour < HOUR_OF_DAY){ | |||
| return difHour+"小时前"; | |||
| } | |||
| else if (difDate < DAY_OF_YESTERDAY){ | |||
| return "昨天"; | |||
| } | |||
| else { | |||
| DateFormat convertFormat = new SimpleDateFormat("yyyy-MM-dd"); | |||
| String value = convertFormat.format(date); | |||
| return value; | |||
| } | |||
| } catch (ParseException e) { | |||
| e.printStackTrace(); | |||
| } | |||
| return ""; | |||
| } | |||
| public static String toFirstCapital(String str){ | |||
| return str.substring(0,1).toUpperCase()+str.substring(1); | |||
| } | |||
| public static String getString(@StringRes int id){ | |||
| return App.Companion.getContext().getResources().getString(id); | |||
| } | |||
| public static String getString(@StringRes int id, Object... formatArgs){ | |||
| return App.Companion.getContext().getResources().getString(id,formatArgs); | |||
| } | |||
| /** | |||
| * 将文本中的半角字符,转换成全角字符 | |||
| * @param input | |||
| * @return | |||
| */ | |||
| public static String halfToFull(String input) | |||
| { | |||
| char[] c = input.toCharArray(); | |||
| for (int i = 0; i< c.length; i++) | |||
| { | |||
| if (c[i] == 32) //半角空格 | |||
| { | |||
| c[i] = (char) 12288; | |||
| continue; | |||
| } | |||
| //根据实际情况,过滤不需要转换的符号 | |||
| //if (c[i] == 46) //半角点号,不转换 | |||
| // continue; | |||
| if (c[i]> 32 && c[i]< 127) //其他符号都转换为全角 | |||
| c[i] = (char) (c[i] + 65248); | |||
| } | |||
| return new String(c); | |||
| } | |||
| //功能:字符串全角转换为半角 | |||
| public static String fullToHalf(String input) | |||
| { | |||
| char[] c = input.toCharArray(); | |||
| for (int i = 0; i< c.length; i++) | |||
| { | |||
| if (c[i] == 12288) //全角空格 | |||
| { | |||
| c[i] = (char) 32; | |||
| continue; | |||
| } | |||
| if (c[i]> 65280&& c[i]< 65375) | |||
| c[i] = (char) (c[i] - 65248); | |||
| } | |||
| return new String(c); | |||
| } | |||
| //繁簡轉換 | |||
| public static String convertCC(String input, Context context) | |||
| { | |||
| // ConversionType currentConversionType = ConversionType.S2TWP; | |||
| // int convertType = SharedPreUtils.getInstance().getInt(SHARED_READ_CONVERT_TYPE, 0); | |||
| // | |||
| // if (input.length() == 0) | |||
| // return ""; | |||
| // | |||
| // switch (convertType) { | |||
| // case 1: | |||
| // currentConversionType = ConversionType.TW2SP; | |||
| // break; | |||
| // case 2: | |||
| // currentConversionType = ConversionType.S2HK; | |||
| // break; | |||
| // case 3: | |||
| // currentConversionType = ConversionType.S2T; | |||
| // break; | |||
| // case 4: | |||
| // currentConversionType = ConversionType.S2TW; | |||
| // break; | |||
| // case 5: | |||
| // currentConversionType = ConversionType.S2TWP; | |||
| // break; | |||
| // case 6: | |||
| // currentConversionType = ConversionType.T2HK; | |||
| // break; | |||
| // case 7: | |||
| // currentConversionType = ConversionType.T2S; | |||
| // break; | |||
| // case 8: | |||
| // currentConversionType = ConversionType.T2TW; | |||
| // break; | |||
| // case 9: | |||
| // currentConversionType = ConversionType.TW2S; | |||
| // break; | |||
| // case 10: | |||
| // currentConversionType = ConversionType.HK2S; | |||
| // break; | |||
| // } | |||
| // return (convertType != 0)?ChineseConverter.convert(input, currentConversionType, context):input; | |||
| return input; | |||
| } | |||
| } | |||
| @@ -1,162 +0,0 @@ | |||
| package com.yzx.webebook.utils; | |||
| import android.app.Activity; | |||
| import android.os.Build; | |||
| import android.view.View; | |||
| import android.view.WindowManager; | |||
| /** | |||
| * Created by newbiechen on 17-5-16. | |||
| * 基于 Android 4.4 | |||
| * | |||
| * 主要参数说明: | |||
| * | |||
| * SYSTEM_UI_FLAG_FULLSCREEN : 隐藏StatusBar | |||
| * SYSTEM_UI_FLAG_HIDE_NAVIGATION : 隐藏NavigationBar | |||
| * SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN: 视图扩展到StatusBar的位置,并且StatusBar不消失。 | |||
| * 这里需要一些处理,一般是将StatusBar设置为全透明或者半透明。之后还需要使用fitSystemWindows=防止视图扩展到Status | |||
| * Bar上面(会在StatusBar上加一层View,该View可被移动) | |||
| * SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION: 视图扩展到NavigationBar的位置 | |||
| * SYSTEM_UI_FLAG_LAYOUT_STABLE:稳定效果 | |||
| * SYSTEM_UI_FLAG_IMMERSIVE_STICKY:保证点击任意位置不会退出 | |||
| * | |||
| * 可设置特效说明: | |||
| * 1. 全屏特效 | |||
| * 2. 全屏点击不退出特效 | |||
| * 3. 注意在19 <=sdk <=21 时候,必须通过Window设置透明栏 | |||
| */ | |||
| public class SystemBarUtils { | |||
| private static final int UNSTABLE_STATUS = View.SYSTEM_UI_FLAG_FULLSCREEN; | |||
| private static final int UNSTABLE_NAV = View.SYSTEM_UI_FLAG_HIDE_NAVIGATION; | |||
| private static final int STABLE_STATUS = View.SYSTEM_UI_FLAG_FULLSCREEN | | |||
| View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | | |||
| View.SYSTEM_UI_FLAG_LAYOUT_STABLE | | |||
| View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY; | |||
| private static final int STABLE_NAV = View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | | |||
| View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION | | |||
| View.SYSTEM_UI_FLAG_LAYOUT_STABLE | | |||
| View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY; | |||
| private static final int EXPAND_STATUS = View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | |||
| | View.SYSTEM_UI_FLAG_LAYOUT_STABLE; | |||
| private static final int EXPAND_NAV = View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION | |||
| | View.SYSTEM_UI_FLAG_LAYOUT_STABLE; | |||
| //设置隐藏StatusBar(点击任意地方会恢复) | |||
| public static void hideUnStableStatusBar(Activity activity){ | |||
| //App全屏,隐藏StatusBar | |||
| setFlag(activity,UNSTABLE_STATUS); | |||
| } | |||
| public static void showUnStableStatusBar(Activity activity){ | |||
| clearFlag(activity,UNSTABLE_STATUS); | |||
| } | |||
| //隐藏NavigationBar(点击任意地方会恢复) | |||
| public static void hideUnStableNavBar(Activity activity){ | |||
| setFlag(activity,UNSTABLE_NAV); | |||
| } | |||
| public static void showUnStableNavBar(Activity activity){ | |||
| clearFlag(activity,UNSTABLE_NAV); | |||
| } | |||
| public static void hideStableStatusBar(Activity activity){ | |||
| //App全屏,隐藏StatusBar | |||
| setFlag(activity,STABLE_STATUS); | |||
| } | |||
| public static void showStableStatusBar(Activity activity){ | |||
| clearFlag(activity,STABLE_STATUS); | |||
| } | |||
| public static void hideStableNavBar(Activity activity){ | |||
| //App全屏,隐藏StatusBar | |||
| setFlag(activity,STABLE_NAV); | |||
| } | |||
| public static void showStableNavBar(Activity activity){ | |||
| clearFlag(activity,STABLE_NAV); | |||
| } | |||
| /** | |||
| * 视图扩充到StatusBar | |||
| */ | |||
| public static void expandStatusBar(Activity activity){ | |||
| setFlag(activity, EXPAND_STATUS); | |||
| } | |||
| /** | |||
| * 视图扩充到NavBar | |||
| * @param activity | |||
| */ | |||
| public static void expandNavBar(Activity activity){ | |||
| setFlag(activity, EXPAND_NAV); | |||
| } | |||
| public static void transparentStatusBar(Activity activity){ | |||
| if (Build.VERSION.SDK_INT >= 21){ | |||
| expandStatusBar(activity); | |||
| activity.getWindow() | |||
| .setStatusBarColor(activity.getResources().getColor(android.R.color.transparent)); | |||
| } | |||
| else if (Build.VERSION.SDK_INT >= 19){ | |||
| WindowManager.LayoutParams attrs = activity.getWindow().getAttributes(); | |||
| attrs.flags = (WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS | attrs.flags); | |||
| activity.getWindow().setAttributes(attrs); | |||
| } | |||
| } | |||
| public static void transparentNavBar(Activity activity){ | |||
| if (Build.VERSION.SDK_INT >= 21){ | |||
| expandNavBar(activity); | |||
| //下面这个方法在sdk:21以上才有 | |||
| activity.getWindow() | |||
| .setNavigationBarColor(activity.getResources().getColor(android.R.color.transparent)); | |||
| } | |||
| } | |||
| public static void setFlag(Activity activity, int flag){ | |||
| if (Build.VERSION.SDK_INT >= 19){ | |||
| View decorView = activity.getWindow().getDecorView(); | |||
| int option = decorView.getSystemUiVisibility() | flag; | |||
| decorView.setSystemUiVisibility(option); | |||
| } | |||
| } | |||
| //取消flag | |||
| public static void clearFlag(Activity activity, int flag){ | |||
| if (Build.VERSION.SDK_INT >= 19){ | |||
| View decorView = activity.getWindow().getDecorView(); | |||
| int option = decorView.getSystemUiVisibility() & (~flag); | |||
| decorView.setSystemUiVisibility(option); | |||
| } | |||
| } | |||
| public static void setToggleFlag(Activity activity, int option){ | |||
| if (Build.VERSION.SDK_INT >= 19){ | |||
| if (isFlagUsed(activity,option)){ | |||
| clearFlag(activity,option); | |||
| } | |||
| else { | |||
| setFlag(activity,option); | |||
| } | |||
| } | |||
| } | |||
| /** | |||
| * @param activity | |||
| * @return flag是否已被使用 | |||
| */ | |||
| public static boolean isFlagUsed(Activity activity, int flag) { | |||
| int currentFlag = activity.getWindow().getDecorView().getSystemUiVisibility(); | |||
| if((currentFlag & flag) | |||
| == flag) { | |||
| return true; | |||
| }else { | |||
| return false; | |||
| } | |||
| } | |||
| } | |||
| @@ -1,17 +0,0 @@ | |||
| package com.yzx.webebook.utils; | |||
| import android.widget.Toast; | |||
| import com.yzx.webebook.App; | |||
| /** | |||
| * Created by newbiechen on 17-5-11. | |||
| */ | |||
| public class ToastUtils { | |||
| public static void show(String msg){ | |||
| Toast.makeText(App.Companion.getContext(), msg, Toast.LENGTH_SHORT).show(); | |||
| } | |||
| } | |||
| @@ -1,31 +0,0 @@ | |||
| package com.yzx.webebook.utils.media; | |||
| import android.content.Context; | |||
| import android.os.Bundle; | |||
| import androidx.loader.content.CursorLoader; | |||
| /** | |||
| * Created by newbiechen on 2018/1/14. | |||
| */ | |||
| public class LoaderCreator { | |||
| public static final int ALL_BOOK_FILE = 1; | |||
| public static CursorLoader create(Context context, int id, Bundle bundle) { | |||
| LocalFileLoader loader = null; | |||
| switch (id){ | |||
| case ALL_BOOK_FILE: | |||
| loader = new LocalFileLoader(context); | |||
| break; | |||
| default: | |||
| loader = null; | |||
| break; | |||
| } | |||
| if (loader != null) { | |||
| return loader; | |||
| } | |||
| throw new IllegalArgumentException("The id of Loader is invalid!"); | |||
| } | |||
| } | |||
| @@ -1,137 +0,0 @@ | |||
| package com.yzx.webebook.utils.media; | |||
| import android.content.Context; | |||
| import android.database.Cursor; | |||
| import android.net.Uri; | |||
| import android.provider.MediaStore; | |||
| import android.text.TextUtils; | |||
| import androidx.annotation.NonNull; | |||
| import androidx.loader.content.CursorLoader; | |||
| import java.io.File; | |||
| import java.sql.Blob; | |||
| import java.util.ArrayList; | |||
| import java.util.List; | |||
| /** | |||
| * Created by newbiechen on 2018/1/14. | |||
| */ | |||
| public class LocalFileLoader extends CursorLoader { | |||
| private static final String TAG = "LocalFileLoader"; | |||
| private static final Uri FILE_URI = Uri.parse("content://media/external/file"); | |||
| private static final String SELECTION = MediaStore.Files.FileColumns.DATA + " like ?"; | |||
| private static final String SEARCH_TYPE = "%.txt"; | |||
| private static final String SORT_ORDER = MediaStore.Files.FileColumns.DISPLAY_NAME + " DESC"; | |||
| private static final String[] FILE_PROJECTION = { | |||
| MediaStore.Files.FileColumns.DATA, | |||
| MediaStore.Files.FileColumns.DISPLAY_NAME | |||
| }; | |||
| public LocalFileLoader(Context context) { | |||
| super(context); | |||
| initLoader(); | |||
| } | |||
| /** | |||
| * 为 Cursor 设置默认参数 | |||
| */ | |||
| private void initLoader() { | |||
| setUri(FILE_URI); | |||
| setProjection(FILE_PROJECTION); | |||
| setSelection(SELECTION); | |||
| setSelectionArgs(new String[]{SEARCH_TYPE}); | |||
| setSortOrder(SORT_ORDER); | |||
| } | |||
| public void parseData(Cursor cursor, final MediaStoreHelper.MediaResultCallback resultCallback) { | |||
| List<File> files = new ArrayList<>(); | |||
| // 判断是否存在数据 | |||
| if (cursor == null) { | |||
| // TODO:当媒体库没有数据的时候,需要做相应的处理 | |||
| // 暂时直接返回空数据 | |||
| resultCallback.onResultCallback(files); | |||
| return; | |||
| } | |||
| // 重复使用Loader时,需要重置cursor的position; | |||
| cursor.moveToPosition(-1); | |||
| while (cursor.moveToNext()) { | |||
| String path; | |||
| path = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Files.FileColumns.DATA)); | |||
| // 路径无效 | |||
| if (TextUtils.isEmpty(path)) { | |||
| continue; | |||
| } else { | |||
| File file = new File(path); | |||
| if (file.isDirectory() || !file.exists()){ | |||
| continue; | |||
| } | |||
| else { | |||
| files.add(file); | |||
| } | |||
| } | |||
| } | |||
| if (resultCallback != null) { | |||
| resultCallback.onResultCallback(files); | |||
| } | |||
| } | |||
| /** | |||
| * 从Cursor中读取对应columnName的值 | |||
| * | |||
| * @param cursor | |||
| * @param columnName | |||
| * @param defaultValue | |||
| * @return 当columnName无效时返回默认值; | |||
| */ | |||
| protected Object getValueFromCursor(@NonNull Cursor cursor, String columnName, Object defaultValue) { | |||
| try { | |||
| int index = cursor.getColumnIndexOrThrow(columnName); | |||
| int type = cursor.getType(index); | |||
| switch (type) { | |||
| case Cursor.FIELD_TYPE_STRING: | |||
| // TO SOLVE:某些手机的数据库将数值类型存为String类型 | |||
| String value = cursor.getString(index); | |||
| try { | |||
| if (defaultValue instanceof String) { | |||
| return value; | |||
| } else if (defaultValue instanceof Long) { | |||
| return Long.valueOf(value); | |||
| } else if (defaultValue instanceof Integer) { | |||
| return Integer.valueOf(value); | |||
| } else if (defaultValue instanceof Double) { | |||
| return Double.valueOf(value); | |||
| } else if (defaultValue instanceof Float) { | |||
| return Float.valueOf(value); | |||
| } | |||
| } catch (NumberFormatException e) { | |||
| return defaultValue; | |||
| } | |||
| case Cursor.FIELD_TYPE_INTEGER: | |||
| if (defaultValue instanceof Long) { | |||
| return cursor.getLong(index); | |||
| } else if (defaultValue instanceof Integer) { | |||
| return cursor.getInt(index); | |||
| } | |||
| case Cursor.FIELD_TYPE_FLOAT: | |||
| if (defaultValue instanceof Float) { | |||
| return cursor.getFloat(index); | |||
| } else if (defaultValue instanceof Double) { | |||
| return cursor.getDouble(index); | |||
| } | |||
| case Cursor.FIELD_TYPE_BLOB: | |||
| if (defaultValue instanceof Blob) { | |||
| return cursor.getBlob(index); | |||
| } | |||
| case Cursor.FIELD_TYPE_NULL: | |||
| default: | |||
| return defaultValue; | |||
| } | |||
| } catch (IllegalArgumentException e) { | |||
| return defaultValue; | |||
| } | |||
| } | |||
| } | |||