服务器备份与恢复

master
fengyuecanzhu 3 years ago
parent 59f950915a
commit 973d6552ce
  1. 4
      .idea/misc.xml
  2. 37
      app/src/main/java/xyz/fycz/myreader/model/storage/Backup.kt
  3. 49
      app/src/main/java/xyz/fycz/myreader/model/user/UserService2.kt
  4. 9
      app/src/main/java/xyz/fycz/myreader/ui/activity/LoginActivity.java
  5. 10
      app/src/main/java/xyz/fycz/myreader/ui/activity/RegisterActivity.java
  6. 124
      app/src/main/java/xyz/fycz/myreader/ui/fragment/MineFragment.java
  7. 59
      app/src/main/java/xyz/fycz/myreader/ui/presenter/BookcasePresenter.java
  8. 2
      app/src/main/java/xyz/fycz/myreader/util/help/JsExtensions.java
  9. 13
      app/src/main/java/xyz/fycz/myreader/util/utils/OkHttpUtils.java
  10. 26
      app/src/main/res/drawable/ic_restore.xml
  11. 2
      app/src/main/res/drawable/login_btn_selector.xml
  12. 67
      app/src/main/res/layout/fragment_mine.xml

@ -4,7 +4,9 @@
<option name="filePathToZoomLevelMap"> <option name="filePathToZoomLevelMap">
<map> <map>
<entry key="..\:/android/FYReader/app/src/main/res/drawable/ic_delete.xml" value="0.18518518518518517" /> <entry key="..\:/android/FYReader/app/src/main/res/drawable/ic_delete.xml" value="0.18518518518518517" />
<entry key="..\:/android/FYReader/app/src/main/res/drawable/ic_online_syn.xml" value="0.19074074074074074" />
<entry key="..\:/android/FYReader/app/src/main/res/drawable/ic_re_seg.xml" value="0.1962962962962963" /> <entry key="..\:/android/FYReader/app/src/main/res/drawable/ic_re_seg.xml" value="0.1962962962962963" />
<entry key="..\:/android/FYReader/app/src/main/res/drawable/ic_restore.xml" value="0.19074074074074074" />
<entry key="..\:/android/FYReader/app/src/main/res/drawable/ic_search_word.xml" value="0.21944444444444444" /> <entry key="..\:/android/FYReader/app/src/main/res/drawable/ic_search_word.xml" value="0.21944444444444444" />
<entry key="..\:/android/FYReader/app/src/main/res/drawable/login_btn_selector.xml" value="0.17777777777777778" /> <entry key="..\:/android/FYReader/app/src/main/res/drawable/login_btn_selector.xml" value="0.17777777777777778" />
<entry key="..\:/android/FYReader/app/src/main/res/drawable/selector_btn_add.xml" value="0.17777777777777778" /> <entry key="..\:/android/FYReader/app/src/main/res/drawable/selector_btn_add.xml" value="0.17777777777777778" />
@ -27,7 +29,7 @@
<entry key="..\:/android/FYReader/app/src/main/res/layout/fragment_file_category.xml" value="0.2318840579710145" /> <entry key="..\:/android/FYReader/app/src/main/res/layout/fragment_file_category.xml" value="0.2318840579710145" />
<entry key="..\:/android/FYReader/app/src/main/res/layout/fragment_find_book_2.xml" value="0.12132725430597771" /> <entry key="..\:/android/FYReader/app/src/main/res/layout/fragment_find_book_2.xml" value="0.12132725430597771" />
<entry key="..\:/android/FYReader/app/src/main/res/layout/fragment_local_source.xml" value="0.1947463768115942" /> <entry key="..\:/android/FYReader/app/src/main/res/layout/fragment_local_source.xml" value="0.1947463768115942" />
<entry key="..\:/android/FYReader/app/src/main/res/layout/fragment_mine.xml" value="0.176" /> <entry key="..\:/android/FYReader/app/src/main/res/layout/fragment_mine.xml" value="0.37037037037037035" />
<entry key="..\:/android/FYReader/app/src/main/res/layout/fragment_private_bookcase.xml" value="0.21195652173913043" /> <entry key="..\:/android/FYReader/app/src/main/res/layout/fragment_private_bookcase.xml" value="0.21195652173913043" />
<entry key="..\:/android/FYReader/app/src/main/res/layout/fragment_webdav_setting.xml" value="0.4" /> <entry key="..\:/android/FYReader/app/src/main/res/layout/fragment_webdav_setting.xml" value="0.4" />
<entry key="..\:/android/FYReader/app/src/main/res/layout/gridview_book_detailed_item.xml" value="0.1947463768115942" /> <entry key="..\:/android/FYReader/app/src/main/res/layout/gridview_book_detailed_item.xml" value="0.1947463768115942" />

@ -61,8 +61,27 @@ object Backup {
} }
fun backup(context: Context, path: String, callBack: CallBack?, isAuto: Boolean = false) { fun backup(context: Context, path: String, callBack: CallBack?, isAuto: Boolean = false) {
backup(context, path, isAuto).subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(object : MySingleObserver<Boolean>() {
override fun onSuccess(t: Boolean) {
callBack?.backupSuccess()
}
override fun onError(e: Throwable) {
e.printStackTrace()
callBack?.backupError(e.localizedMessage ?: "ERROR")
}
})
}
fun backup(
context: Context,
path: String,
isAuto: Boolean = false
): Single<Boolean> {
SharedPreUtils.getInstance().putLong("lastBackup", System.currentTimeMillis()) SharedPreUtils.getInstance().putLong("lastBackup", System.currentTimeMillis())
Single.create(SingleOnSubscribe<Boolean> { e -> return Single.create { e ->
BookService.getInstance().allBooks.let { BookService.getInstance().allBooks.let {
if (it.isNotEmpty()) { if (it.isNotEmpty()) {
val json = GSON.toJson(it) val json = GSON.toJson(it)
@ -153,18 +172,7 @@ object Backup {
copyBackup(path, isAuto) copyBackup(path, isAuto)
} }
e.onSuccess(true) e.onSuccess(true)
}).subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(object : MySingleObserver<Boolean>() {
override fun onSuccess(t: Boolean) {
callBack?.backupSuccess()
}
override fun onError(e: Throwable) {
e.printStackTrace()
callBack?.backupError(e.localizedMessage ?: "ERROR")
} }
})
} }
@Throws(Exception::class) @Throws(Exception::class)
@ -202,7 +210,10 @@ object Backup {
if (isAuto) { if (isAuto) {
val file = File(backupPath + File.separator + fileName) val file = File(backupPath + File.separator + fileName)
if (file.exists()) { if (file.exists()) {
file.copyTo(FileUtils.getFile(path + File.separator + "auto" + File.separator + fileName), true) file.copyTo(
FileUtils.getFile(path + File.separator + "auto" + File.separator + fileName),
true
)
} }
} else { } else {
val file = File(backupPath + File.separator + fileName) val file = File(backupPath + File.separator + fileName)

@ -1,12 +1,16 @@
package xyz.fycz.myreader.model.user package xyz.fycz.myreader.model.user
import io.reactivex.ObservableSource
import io.reactivex.Single import io.reactivex.Single
import io.reactivex.SingleOnSubscribe import io.reactivex.SingleOnSubscribe
import io.reactivex.SingleSource
import io.reactivex.functions.Function
import okhttp3.MediaType import okhttp3.MediaType
import okhttp3.RequestBody import okhttp3.RequestBody
import xyz.fycz.myreader.application.App import xyz.fycz.myreader.application.App
import xyz.fycz.myreader.common.APPCONST import xyz.fycz.myreader.common.APPCONST
import xyz.fycz.myreader.common.URLCONST import xyz.fycz.myreader.common.URLCONST
import xyz.fycz.myreader.entity.StrResponse
import xyz.fycz.myreader.model.storage.Backup import xyz.fycz.myreader.model.storage.Backup
import xyz.fycz.myreader.model.storage.Restore import xyz.fycz.myreader.model.storage.Restore
import xyz.fycz.myreader.model.storage.Restore.restore import xyz.fycz.myreader.model.storage.Restore.restore
@ -15,6 +19,7 @@ import xyz.fycz.myreader.util.utils.FileUtils
import xyz.fycz.myreader.util.utils.GSON import xyz.fycz.myreader.util.utils.GSON
import xyz.fycz.myreader.util.utils.OkHttpUtils import xyz.fycz.myreader.util.utils.OkHttpUtils
import xyz.fycz.myreader.util.utils.RxUtils import xyz.fycz.myreader.util.utils.RxUtils
import java.io.File
/** /**
* @author fengyue * @author fengyue
@ -91,14 +96,14 @@ object UserService2 {
} }
fun webBackup(user: User): Single<Result> { fun webBackup(user: User): Single<Result> {
return Single.create(SingleOnSubscribe<Result> { return Backup.backup(App.getmContext(), APPCONST.FILE_DIR + "webBackup/")
Backup.backup(App.getmContext(), APPCONST.FILE_DIR + "webBackup/", .flatMap(Function<Boolean, SingleSource<Result>> {
object : Backup.CallBack { Single.create {
override fun backupSuccess() {
val inputFile = FileUtils.getFile(APPCONST.FILE_DIR + "webBackup") val inputFile = FileUtils.getFile(APPCONST.FILE_DIR + "webBackup")
val zipFile = FileUtils.getFile(APPCONST.FILE_DIR + "webBackup.zip") val zipFile = FileUtils.getFile(APPCONST.FILE_DIR + "webBackup.zip")
//压缩文件 //压缩文件
ZipUtils.zipFile(inputFile, zipFile) ZipUtils.zipFile(inputFile, zipFile)
FileUtils.deleteFile(zipFile.absolutePath)
val ret = OkHttpUtils.upload( val ret = OkHttpUtils.upload(
URLCONST.USER_URL + "/do/bak?" + URLCONST.USER_URL + "/do/bak?" +
"username=${user.userName}" + "username=${user.userName}" +
@ -109,28 +114,30 @@ object UserService2 {
zipFile.delete() zipFile.delete()
it.onSuccess(GSON.fromJson(ret, Result::class.java)) it.onSuccess(GSON.fromJson(ret, Result::class.java))
} }
override fun backupError(msg: String) {
it.onError(Throwable(msg))
}
})
}).compose { RxUtils.toSimpleSingle(it) } }).compose { RxUtils.toSimpleSingle(it) }
} }
fun webRestore(user: User): Single<Result> { fun webRestore(user: User): Single<Result> {
return Single.create(SingleOnSubscribe<Result> { return Single.create(SingleOnSubscribe<Result> {
val zipFile = FileUtils.getFile(APPCONST.FILE_DIR + "webBackup.zip") val zipFile = FileUtils.getFile(APPCONST.FILE_DIR + "webBackup.zip")
val input = OkHttpUtils.getInputStream( val mediaType = MediaType.parse("application/x-www-form-urlencoded")
URLCONST.USER_URL + "/do/ret?" + val body = "username=${user.userName}" +
"username=${user.userName}" +
makeAuth() makeAuth()
val requestBody = RequestBody.create(mediaType, body)
val input = OkHttpUtils.getInputStream(
URLCONST.USER_URL + "/do/ret", requestBody
) )
if (FileUtils.writeFile(input.readBytes(), zipFile)) { val bytes = input.readBytes()
if (bytes.size < 50) {
it.onError(Throwable(String(bytes)))
return@SingleOnSubscribe
}
if (FileUtils.writeFile(bytes, zipFile)) {
ZipUtils.unzipFile(zipFile.absolutePath, APPCONST.FILE_DIR) ZipUtils.unzipFile(zipFile.absolutePath, APPCONST.FILE_DIR)
zipFile.delete()
restore(APPCONST.FILE_DIR + "webBackup/", object : Restore.CallBack { restore(APPCONST.FILE_DIR + "webBackup/", object : Restore.CallBack {
override fun restoreSuccess() { override fun restoreSuccess() {
zipFile.delete() FileUtils.deleteFile(zipFile.absolutePath)
it.onSuccess(Result(100, "成功从网络同步到本地")) it.onSuccess(Result(100, "成功从网络同步到本地"))
} }
@ -162,10 +169,20 @@ object UserService2 {
return FileUtils.readText(APPCONST.QQ_DATA_DIR + "user") return FileUtils.readText(APPCONST.QQ_DATA_DIR + "user")
} }
/**
* 判断是否登录
* @return
*/
fun isLogin(): Boolean {
val file = App.getApplication().getFileStreamPath("userConfig.fy")
return file.exists()
}
private fun makeAuth(): String { private fun makeAuth(): String {
return "&signal=" + AppInfoUtils.getSingInfo( return "&signal=" + AppInfoUtils.getSingInfo(
App.getmContext(), App.getmContext(),
App.getApplication().packageName, AppInfoUtils.SHA1 App.getApplication().packageName,
AppInfoUtils.SHA1
) + "&appVersion=" + App.getVersionCode() ) + "&appVersion=" + App.getVersionCode()
} }
} }

@ -1,12 +1,9 @@
package xyz.fycz.myreader.ui.activity; package xyz.fycz.myreader.ui.activity;
import android.annotation.SuppressLint;
import android.app.Activity; import android.app.Activity;
import android.content.Intent; import android.content.Intent;
import android.graphics.Bitmap; import android.graphics.Bitmap;
import android.os.Bundle; import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.text.Editable; import android.text.Editable;
import android.text.TextWatcher; import android.text.TextWatcher;
import android.view.MotionEvent; import android.view.MotionEvent;
@ -17,9 +14,6 @@ import androidx.annotation.NonNull;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import androidx.appcompat.widget.Toolbar; import androidx.appcompat.widget.Toolbar;
import java.util.HashMap;
import java.util.Map;
import io.reactivex.disposables.Disposable; import io.reactivex.disposables.Disposable;
import xyz.fycz.myreader.R; import xyz.fycz.myreader.R;
import xyz.fycz.myreader.base.BaseActivity; import xyz.fycz.myreader.base.BaseActivity;
@ -29,7 +23,6 @@ import xyz.fycz.myreader.common.APPCONST;
import xyz.fycz.myreader.databinding.ActivityLoginBinding; import xyz.fycz.myreader.databinding.ActivityLoginBinding;
import xyz.fycz.myreader.model.user.Result; import xyz.fycz.myreader.model.user.Result;
import xyz.fycz.myreader.model.user.User; import xyz.fycz.myreader.model.user.User;
import xyz.fycz.myreader.model.user.UserService;
import xyz.fycz.myreader.model.user.UserService2; import xyz.fycz.myreader.model.user.UserService2;
import xyz.fycz.myreader.ui.dialog.DialogCreator; import xyz.fycz.myreader.ui.dialog.DialogCreator;
import xyz.fycz.myreader.ui.dialog.LoadingDialog; import xyz.fycz.myreader.ui.dialog.LoadingDialog;
@ -37,9 +30,7 @@ import xyz.fycz.myreader.util.CodeUtil;
import xyz.fycz.myreader.util.CyptoUtils; import xyz.fycz.myreader.util.CyptoUtils;
import xyz.fycz.myreader.util.ToastUtils; import xyz.fycz.myreader.util.ToastUtils;
import xyz.fycz.myreader.util.utils.NetworkUtils; import xyz.fycz.myreader.util.utils.NetworkUtils;
import xyz.fycz.myreader.util.utils.ProgressUtils;
import xyz.fycz.myreader.util.utils.StringUtils; import xyz.fycz.myreader.util.utils.StringUtils;
import xyz.fycz.myreader.webapi.ResultCallback;
/** /**
* @author fengyue * @author fengyue

@ -1,21 +1,14 @@
package xyz.fycz.myreader.ui.activity; package xyz.fycz.myreader.ui.activity;
import android.annotation.SuppressLint;
import android.graphics.Bitmap; import android.graphics.Bitmap;
import android.os.Bundle; import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.text.Editable; import android.text.Editable;
import android.text.TextWatcher;
import android.text.method.LinkMovementMethod; import android.text.method.LinkMovementMethod;
import android.view.View; import android.view.View;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.appcompat.widget.Toolbar; import androidx.appcompat.widget.Toolbar;
import java.util.HashMap;
import java.util.Map;
import io.reactivex.disposables.Disposable; import io.reactivex.disposables.Disposable;
import xyz.fycz.myreader.R; import xyz.fycz.myreader.R;
import xyz.fycz.myreader.application.App; import xyz.fycz.myreader.application.App;
@ -26,16 +19,13 @@ import xyz.fycz.myreader.common.APPCONST;
import xyz.fycz.myreader.databinding.ActivityRegisterBinding; import xyz.fycz.myreader.databinding.ActivityRegisterBinding;
import xyz.fycz.myreader.model.user.Result; import xyz.fycz.myreader.model.user.Result;
import xyz.fycz.myreader.model.user.User; import xyz.fycz.myreader.model.user.User;
import xyz.fycz.myreader.model.user.UserService;
import xyz.fycz.myreader.model.user.UserService2; import xyz.fycz.myreader.model.user.UserService2;
import xyz.fycz.myreader.ui.dialog.DialogCreator; import xyz.fycz.myreader.ui.dialog.DialogCreator;
import xyz.fycz.myreader.ui.dialog.LoadingDialog; import xyz.fycz.myreader.ui.dialog.LoadingDialog;
import xyz.fycz.myreader.util.CodeUtil; import xyz.fycz.myreader.util.CodeUtil;
import xyz.fycz.myreader.util.CyptoUtils; import xyz.fycz.myreader.util.CyptoUtils;
import xyz.fycz.myreader.util.ToastUtils; import xyz.fycz.myreader.util.ToastUtils;
import xyz.fycz.myreader.util.utils.ProgressUtils;
import xyz.fycz.myreader.util.utils.StringUtils; import xyz.fycz.myreader.util.utils.StringUtils;
import xyz.fycz.myreader.webapi.ResultCallback;
/** /**
* @author fengyue * @author fengyue

@ -1,5 +1,7 @@
package xyz.fycz.myreader.ui.fragment; package xyz.fycz.myreader.ui.fragment;
import static android.app.Activity.RESULT_OK;
import android.annotation.SuppressLint; import android.annotation.SuppressLint;
import android.content.Intent; import android.content.Intent;
import android.os.Bundle; import android.os.Bundle;
@ -37,12 +39,11 @@ import xyz.fycz.myreader.databinding.FragmentMineBinding;
import xyz.fycz.myreader.entity.Setting; import xyz.fycz.myreader.entity.Setting;
import xyz.fycz.myreader.greendao.entity.Book; import xyz.fycz.myreader.greendao.entity.Book;
import xyz.fycz.myreader.greendao.service.BookService; import xyz.fycz.myreader.greendao.service.BookService;
import xyz.fycz.myreader.model.user.Result;
import xyz.fycz.myreader.model.user.User;
import xyz.fycz.myreader.model.user.UserService;
import xyz.fycz.myreader.model.storage.BackupRestoreUi; import xyz.fycz.myreader.model.storage.BackupRestoreUi;
import xyz.fycz.myreader.model.storage.Restore; import xyz.fycz.myreader.model.storage.Restore;
import xyz.fycz.myreader.model.storage.WebDavHelp; import xyz.fycz.myreader.model.storage.WebDavHelp;
import xyz.fycz.myreader.model.user.Result;
import xyz.fycz.myreader.model.user.User;
import xyz.fycz.myreader.model.user.UserService2; import xyz.fycz.myreader.model.user.UserService2;
import xyz.fycz.myreader.ui.activity.AboutActivity; import xyz.fycz.myreader.ui.activity.AboutActivity;
import xyz.fycz.myreader.ui.activity.AdSettingActivity; import xyz.fycz.myreader.ui.activity.AdSettingActivity;
@ -55,13 +56,9 @@ import xyz.fycz.myreader.ui.activity.MoreSettingActivity;
import xyz.fycz.myreader.ui.activity.ReadRecordActivity; import xyz.fycz.myreader.ui.activity.ReadRecordActivity;
import xyz.fycz.myreader.ui.dialog.DialogCreator; import xyz.fycz.myreader.ui.dialog.DialogCreator;
import xyz.fycz.myreader.ui.dialog.LoadingDialog; import xyz.fycz.myreader.ui.dialog.LoadingDialog;
import xyz.fycz.myreader.ui.dialog.MyAlertDialog;
import xyz.fycz.myreader.util.SharedPreUtils; import xyz.fycz.myreader.util.SharedPreUtils;
import xyz.fycz.myreader.util.ToastUtils; import xyz.fycz.myreader.util.ToastUtils;
import xyz.fycz.myreader.util.utils.NetworkUtils; import xyz.fycz.myreader.util.utils.NetworkUtils;
import xyz.fycz.myreader.webapi.ResultCallback;
import static android.app.Activity.RESULT_OK;
/** /**
* @author fengyue * @author fengyue
@ -164,6 +161,70 @@ public class MineFragment extends BaseFragment {
getActivity().startActivityForResult(intent, APPCONST.REQUEST_LOGIN); getActivity().startActivityForResult(intent, APPCONST.REQUEST_LOGIN);
} }
}); });
binding.mineRlSyn.setOnClickListener(v -> {
if (!isLogin) {
ToastUtils.showWarring("请先登录!");
Intent loginIntent = new Intent(getActivity(), LoginActivity.class);
getActivity().startActivityForResult(loginIntent, APPCONST.REQUEST_LOGIN);
return;
}
if (mSetting.isAutoSyn()) {
webSynMenu[2] = App.getmContext().getString(R.string.menu_backup_autoSyn) + "已开启";
} else {
webSynMenu[2] = App.getmContext().getString(R.string.menu_backup_autoSyn) + "已关闭";
}
/*MyAlertDialog.build(getContext())
.setTitle(getActivity().getString(R.string.menu_bookcase_syn))
.setItems(webSynMenu, (dialog, which) -> {
switch (which) {
case 0:
synBookcaseToWeb(false);
break;
case 1:
webRestore();
break;
case 2:
String tip = "";
if (mSetting.isAutoSyn()) {
mSetting.setAutoSyn(false);
tip = "每日自动同步已关闭!";
} else {
mSetting.setAutoSyn(true);
tip = "每日自动同步已开启!";
}
SysManager.saveSetting(mSetting);
ToastUtils.showSuccess(tip);
break;
}
})
.setNegativeButton(null, null)
.setPositiveButton(null, null)
.show();*/
BottomMenu.show("同步书架", webSynMenu)
.setOnMenuItemClickListener((dialog1, text, which) -> {
switch (which) {
case 0:
synBookcaseToWeb(false);
break;
case 1:
webRestore();
break;
case 2:
String tip = "";
if (mSetting.isAutoSyn()) {
mSetting.setAutoSyn(false);
tip = "每日自动同步已关闭!";
} else {
mSetting.setAutoSyn(true);
tip = "每日自动同步已开启!";
}
SysManager.saveSetting(mSetting);
ToastUtils.showSuccess(tip);
break;
}
return false;
}).setCancelButton(R.string.cancel);
});
binding.mineRlWebdav.setOnClickListener(v -> { binding.mineRlWebdav.setOnClickListener(v -> {
Intent intent = new Intent(getActivity(), MoreSettingActivity.class); Intent intent = new Intent(getActivity(), MoreSettingActivity.class);
@ -171,7 +232,7 @@ public class MineFragment extends BaseFragment {
startActivity(intent); startActivity(intent);
}); });
/*binding.mineRlSyn.setOnClickListener(v -> { binding.mineRlSynWebdav.setOnClickListener(v -> {
String account = SharedPreUtils.getInstance().getString("webdavAccount"); String account = SharedPreUtils.getInstance().getString("webdavAccount");
String password = SharedPreUtils.getInstance().getString("webdavPassword"); String password = SharedPreUtils.getInstance().getString("webdavPassword");
if (TextUtils.isEmpty(account) || TextUtils.isEmpty(password)) { if (TextUtils.isEmpty(account) || TextUtils.isEmpty(password)) {
@ -212,7 +273,7 @@ public class MineFragment extends BaseFragment {
} }
} }
}); });
});*/ });
binding.mineRlBookSource.setOnClickListener(v -> { binding.mineRlBookSource.setOnClickListener(v -> {
startActivity(new Intent(getContext(), BookSourceActivity.class)); startActivity(new Intent(getContext(), BookSourceActivity.class));
}); });
@ -247,46 +308,6 @@ public class MineFragment extends BaseFragment {
return false; return false;
}).setCancelButton(R.string.cancel); }).setCancelButton(R.string.cancel);
}); });
binding.mineRlSyn.setOnClickListener(v -> {
if (!isLogin) {
ToastUtils.showWarring("请先登录!");
Intent loginIntent = new Intent(getActivity(), LoginActivity.class);
getActivity().startActivityForResult(loginIntent, APPCONST.REQUEST_LOGIN);
return;
}
if (mSetting.isAutoSyn()) {
webSynMenu[2] = App.getmContext().getString(R.string.menu_backup_autoSyn) + "已开启";
} else {
webSynMenu[2] = App.getmContext().getString(R.string.menu_backup_autoSyn) + "已关闭";
}
MyAlertDialog.build(getContext())
.setTitle(getActivity().getString(R.string.menu_bookcase_syn))
.setItems(webSynMenu, (dialog, which) -> {
switch (which) {
case 0:
synBookcaseToWeb(false);
break;
case 1:
webRestore();
break;
case 2:
String tip = "";
if (mSetting.isAutoSyn()) {
mSetting.setAutoSyn(false);
tip = "每日自动同步已关闭!";
} else {
mSetting.setAutoSyn(true);
tip = "每日自动同步已开启!";
}
SysManager.saveSetting(mSetting);
ToastUtils.showSuccess(tip);
break;
}
})
.setNegativeButton(null, null)
.setPositiveButton(null, null)
.show();
});
binding.mineRlReadRecord.setOnClickListener(v -> { binding.mineRlReadRecord.setOnClickListener(v -> {
startActivity(new Intent(getContext(), ReadRecordActivity.class)); startActivity(new Intent(getContext(), ReadRecordActivity.class));
@ -524,7 +545,6 @@ public class MineFragment extends BaseFragment {
DialogCreator.createCommonDialog(getContext(), "确认同步吗?", "将书架从网络同步至本地会覆盖原有书架!", true, DialogCreator.createCommonDialog(getContext(), "确认同步吗?", "将书架从网络同步至本地会覆盖原有书架!", true,
(dialogInterface, i) -> { (dialogInterface, i) -> {
dialogInterface.dismiss(); dialogInterface.dismiss();
App.getApplication().newThread(() -> {
/*if (UserService.webRestore()) { /*if (UserService.webRestore()) {
mHandler.sendMessage(mHandler.obtainMessage(7)); mHandler.sendMessage(mHandler.obtainMessage(7));
// DialogCreator.createTipDialog(mMainActivity, // DialogCreator.createTipDialog(mMainActivity,
@ -562,11 +582,11 @@ public class MineFragment extends BaseFragment {
@Override @Override
public void onError(Throwable e) { public void onError(Throwable e) {
if (App.isDebug()) e.printStackTrace();
DialogCreator.createTipDialog(getContext(), "未找到同步文件,同步失败!\n" + e.getLocalizedMessage()); DialogCreator.createTipDialog(getContext(), "未找到同步文件,同步失败!\n" + e.getLocalizedMessage());
DialogCreator.createTipDialog(getContext(), "未找到同步文件,同步失败!\n" + e.getLocalizedMessage()); dialog.dismiss();
} }
}); });
});
}, (dialogInterface, i) -> dialogInterface.dismiss()); }, (dialogInterface, i) -> dialogInterface.dismiss());
} }

@ -1,19 +1,23 @@
package xyz.fycz.myreader.ui.presenter; package xyz.fycz.myreader.ui.presenter;
import static xyz.fycz.myreader.application.App.checkVersionByServer;
import android.Manifest; import android.Manifest;
import android.annotation.SuppressLint; import android.annotation.SuppressLint;
import android.app.Notification; import android.app.Notification;
import android.app.PendingIntent; import android.app.PendingIntent;
import android.content.*; import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.graphics.BitmapFactory; import android.graphics.BitmapFactory;
import android.os.Handler; import android.os.Handler;
import android.os.Message; import android.os.Message;
import android.view.Gravity; import android.view.Gravity;
import android.view.MenuItem; import android.view.MenuItem;
import android.view.View; import android.view.View;
import android.widget.PopupMenu; import android.widget.PopupMenu;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.GridLayoutManager; import androidx.recyclerview.widget.GridLayoutManager;
import androidx.recyclerview.widget.ItemTouchHelper; import androidx.recyclerview.widget.ItemTouchHelper;
import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.LinearLayoutManager;
@ -41,35 +45,38 @@ import xyz.fycz.myreader.application.App;
import xyz.fycz.myreader.application.SysManager; import xyz.fycz.myreader.application.SysManager;
import xyz.fycz.myreader.base.BasePresenter; import xyz.fycz.myreader.base.BasePresenter;
import xyz.fycz.myreader.base.observer.MyObserver; import xyz.fycz.myreader.base.observer.MyObserver;
import xyz.fycz.myreader.ui.adapter.helper.ItemTouchCallback; import xyz.fycz.myreader.base.observer.MySingleObserver;
import xyz.fycz.myreader.ui.dialog.BookGroupDialog;
import xyz.fycz.myreader.util.help.StringHelper;
import xyz.fycz.myreader.util.utils.RxUtils;
import xyz.fycz.myreader.webapi.ResultCallback;
import xyz.fycz.myreader.common.APPCONST; import xyz.fycz.myreader.common.APPCONST;
import xyz.fycz.myreader.greendao.entity.BookGroup;
import xyz.fycz.myreader.greendao.service.BookGroupService;
import xyz.fycz.myreader.model.user.UserService;
import xyz.fycz.myreader.ui.activity.*;
import xyz.fycz.myreader.webapi.crawler.base.ReadCrawler;
import xyz.fycz.myreader.webapi.crawler.ReadCrawlerUtil;
import xyz.fycz.myreader.ui.dialog.DialogCreator;
import xyz.fycz.myreader.entity.Setting; import xyz.fycz.myreader.entity.Setting;
import xyz.fycz.myreader.enums.BookcaseStyle; import xyz.fycz.myreader.enums.BookcaseStyle;
import xyz.fycz.myreader.greendao.entity.Book; import xyz.fycz.myreader.greendao.entity.Book;
import xyz.fycz.myreader.greendao.entity.BookGroup;
import xyz.fycz.myreader.greendao.entity.Chapter; import xyz.fycz.myreader.greendao.entity.Chapter;
import xyz.fycz.myreader.greendao.service.BookGroupService;
import xyz.fycz.myreader.greendao.service.BookService; import xyz.fycz.myreader.greendao.service.BookService;
import xyz.fycz.myreader.greendao.service.ChapterService; import xyz.fycz.myreader.greendao.service.ChapterService;
import xyz.fycz.myreader.model.user.Result;
import xyz.fycz.myreader.model.user.UserService2;
import xyz.fycz.myreader.ui.activity.FileSystemActivity;
import xyz.fycz.myreader.ui.activity.GroupManagerActivity;
import xyz.fycz.myreader.ui.activity.MainActivity;
import xyz.fycz.myreader.ui.activity.SearchBookActivity;
import xyz.fycz.myreader.ui.adapter.BookcaseAdapter; import xyz.fycz.myreader.ui.adapter.BookcaseAdapter;
import xyz.fycz.myreader.ui.adapter.BookcaseDetailedAdapter; import xyz.fycz.myreader.ui.adapter.BookcaseDetailedAdapter;
import xyz.fycz.myreader.ui.adapter.BookcaseDragAdapter; import xyz.fycz.myreader.ui.adapter.BookcaseDragAdapter;
import xyz.fycz.myreader.ui.adapter.helper.ItemTouchCallback;
import xyz.fycz.myreader.ui.dialog.BookGroupDialog;
import xyz.fycz.myreader.ui.dialog.DialogCreator;
import xyz.fycz.myreader.ui.fragment.BookcaseFragment; import xyz.fycz.myreader.ui.fragment.BookcaseFragment;
import xyz.fycz.myreader.util.*; import xyz.fycz.myreader.util.SharedPreUtils;
import xyz.fycz.myreader.util.ToastUtils;
import xyz.fycz.myreader.util.help.StringHelper;
import xyz.fycz.myreader.util.notification.NotificationUtil; import xyz.fycz.myreader.util.notification.NotificationUtil;
import xyz.fycz.myreader.util.utils.NetworkUtils; import xyz.fycz.myreader.util.utils.NetworkUtils;
import xyz.fycz.myreader.util.utils.RxUtils;
import xyz.fycz.myreader.webapi.BookApi; import xyz.fycz.myreader.webapi.BookApi;
import xyz.fycz.myreader.webapi.crawler.ReadCrawlerUtil;
import static xyz.fycz.myreader.application.App.checkVersionByServer; import xyz.fycz.myreader.webapi.crawler.base.ReadCrawler;
public class BookcasePresenter implements BasePresenter { public class BookcasePresenter implements BasePresenter {
@ -168,9 +175,9 @@ public class BookcasePresenter implements BasePresenter {
getData(); getData();
/*if (mSetting.isAutoSyn() && UserService.isLogin()) { if (mSetting.isAutoSyn() && UserService2.INSTANCE.isLogin()) {
synBookcaseToWeb(true); synBookcaseToWeb(true);
}*/ }
//设置是否启用内容视图拖动效果 //设置是否启用内容视图拖动效果
mBookcaseFragment.getSrlContent().setEnableHeaderTranslationContent(false); mBookcaseFragment.getSrlContent().setEnableHeaderTranslationContent(false);
@ -979,10 +986,15 @@ public class BookcasePresenter implements BasePresenter {
SharedPreUtils spb = SharedPreUtils.getInstance(); SharedPreUtils spb = SharedPreUtils.getInstance();
String synTime = spb.getString(mMainActivity.getString(R.string.synTime)); String synTime = spb.getString(mMainActivity.getString(R.string.synTime));
if (!nowTimeStr.equals(synTime) || !isAutoSyn) { if (!nowTimeStr.equals(synTime) || !isAutoSyn) {
UserService.webBackup(new ResultCallback() { UserService2.INSTANCE.webBackup(UserService2.INSTANCE.readConfig()).subscribe(new MySingleObserver<Result>() {
@Override @Override
public void onFinish(Object o, int code) { public void onSubscribe(Disposable d) {
if ((boolean) o) { mMainActivity.addDisposable(d);
}
@Override
public void onSuccess(@NonNull Result result) {
if (result.getCode() == 104) {
spb.putString(mMainActivity.getString(R.string.synTime), nowTimeStr); spb.putString(mMainActivity.getString(R.string.synTime), nowTimeStr);
if (!isAutoSyn) { if (!isAutoSyn) {
DialogCreator.createTipDialog(mMainActivity, "成功将书架同步至网络!"); DialogCreator.createTipDialog(mMainActivity, "成功将书架同步至网络!");
@ -993,9 +1005,8 @@ public class BookcasePresenter implements BasePresenter {
} }
} }
} }
@Override @Override
public void onError(Exception e) { public void onError(Throwable e) {
if (!isAutoSyn) { if (!isAutoSyn) {
DialogCreator.createTipDialog(mMainActivity, "同步失败,请重试!\n" + e.getLocalizedMessage()); DialogCreator.createTipDialog(mMainActivity, "同步失败,请重试!\n" + e.getLocalizedMessage());
} }

@ -35,6 +35,8 @@ import xyz.fycz.myreader.util.utils.StringUtils;
@Keep @Keep
@SuppressWarnings({"unused"}) @SuppressWarnings({"unused"})
public interface JsExtensions { public interface JsExtensions {
String TAG = JsExtensions.class.getSimpleName(); String TAG = JsExtensions.class.getSimpleName();

@ -142,8 +142,18 @@ public class OkHttpUtils {
} }
public static InputStream getInputStream(String url) throws IOException { public static InputStream getInputStream(String url) throws IOException {
return getInputStream(url, null);
}
public static InputStream getInputStream(String url, RequestBody body) throws IOException {
Request.Builder builder = new Request.Builder() Request.Builder builder = new Request.Builder()
.addHeader("user-agent", APPCONST.DEFAULT_USER_AGENT); .addHeader("user-agent", APPCONST.DEFAULT_USER_AGENT);
if (body != null) {
builder.post(body);
Log.d("HttpPost URl", url);
} else {
Log.d("HttpGet URl", url);
}
Request request = builder Request request = builder
.url(url) .url(url)
.build(); .build();
@ -331,7 +341,8 @@ public class OkHttpUtils {
OkHttpClient client = getOkHttpClient(); OkHttpClient client = getOkHttpClient();
RequestBody requestBody = new MultipartBody.Builder() RequestBody requestBody = new MultipartBody.Builder()
.setType(MultipartBody.FORM) .setType(MultipartBody.FORM)
.addFormDataPart("file", fileName, RequestBody.create(MediaType.parse("multipart/form-data"), new File(filePath))) .addFormDataPart("file", fileName,
RequestBody.create(MediaType.parse("multipart/form-data"), new File(filePath)))
.build(); .build();
Request request = new Request.Builder() Request request = new Request.Builder()

@ -0,0 +1,26 @@
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="#595757"
android:pathData="M18.807,13.043 C18.035,12.273,17.011,11.848,15.924,11.848 C14.876,11.848,13.893,12.25,13.134,12.966 L13.134,12.281 L11.847,12.281 L11.847,15.095 L12.49,15.095 L13.135,15.095 L14.908,15.095 L14.908,13.806 L14.128,13.806 C14.632,13.378,15.256,13.132,15.924,13.132 C16.668,13.132,17.369,13.425,17.896,13.952 C18.423,14.477,18.713,15.179,18.713,15.925 C18.713,16.667,18.423,17.366,17.896,17.896 C17.37,18.421,16.668,18.71,15.924,18.71 C15.178,18.71,14.479,18.421,13.949,17.896 C13.425,17.367,13.135,16.669,13.135,15.925 L11.848,15.925 C11.848,17.013,12.27,18.038,13.041,18.804 C13.81,19.576,14.834,20,15.924,20 C17.011,20,18.035,19.576,18.807,18.805 C19.576,18.037,20,17.012,20,15.926 C20,14.836,19.576,13.813,18.807,13.043 Z" />
<path
android:fillColor="#595757"
android:pathData="M5.287,5.625 C5.287,5.437,5.439,5.287,5.625,5.287 L16.412,5.287 C16.596,5.287,16.751,5.441,16.751,5.625 L16.751,11.02 L18.038,11.02 L18.038,5.625 C18.038,4.727,17.308,3.998,16.412,3.998 L5.625,3.998 C4.73,3.998,4,4.727,4,5.625 L4,18.377 C4,19.273,4.73,20.002,5.625,20.002 L11.018,20.002 L11.018,18.713 L5.625,18.713 C5.439,18.713,5.287,18.563,5.287,18.377 L5.287,18.039 L11.018,18.039 L11.018,16.754 L5.287,16.754 L5.287,5.625 Z" />
<path
android:fillColor="#595757"
android:pathData="M5.96,6.117 L7.247,6.117 L7.247,7.097 L5.96,7.097 L5.96,6.117 Z" />
<path
android:fillColor="#595757"
android:pathData="M14.789,6.117 L16.076,6.117 L16.076,7.097 L14.789,7.097 L14.789,6.117 Z" />
<path
android:fillColor="#595757"
android:pathData="M5.96,14.945 L7.247,14.945 L7.247,15.925 L5.96,15.925 L5.96,14.945 Z" />
<path
android:fillColor="#595757"
android:pathData="M11.473,11.475 L13.387,9.562 C13.65,9.988,13.809,10.484,13.809,11.02 L15.097,11.02 C15.097,10.128,14.801,9.309,14.312,8.637 L14.908,8.041 L13.996,7.133 L13.401,7.728 C12.729,7.24,11.91,6.944,11.018,6.944 C8.769,6.944,6.941,8.774,6.941,11.02 C6.941,13.268,8.77,15.096,11.018,15.096 L11.018,13.807 C9.48,13.807,8.228,12.557,8.228,11.02 C8.228,9.481,9.48,8.229,11.018,8.229 C11.554,8.229,12.051,8.388,12.476,8.652 L10.562,10.565 L11.473,11.475 Z" />
</vector>

@ -4,7 +4,7 @@
<item android:state_enabled="false"> <item android:state_enabled="false">
<shape android:shape="rectangle"> <shape android:shape="rectangle">
<corners android:radius="5dp"/> <corners android:radius="5dp"/>
<solid android:color="@color/textSecondary"/> <solid android:color="@color/textAssistSecondary"/>
</shape> </shape>
</item> </item>

@ -31,7 +31,7 @@
<RelativeLayout <RelativeLayout
android:id="@+id/mine_rl_user" android:id="@+id/mine_rl_user"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="60dp" android:layout_height="50dp"
android:paddingLeft="20dp" android:paddingLeft="20dp"
android:paddingRight="20dp" android:paddingRight="20dp"
android:background="@drawable/selector_common_bg"> android:background="@drawable/selector_common_bg">
@ -56,6 +56,35 @@
android:textSize="@dimen/text_medium_size" android:textSize="@dimen/text_medium_size"
android:text="登录/注册"/> android:text="登录/注册"/>
</RelativeLayout>
<RelativeLayout
android:id="@+id/mine_rl_syn"
android:layout_width="match_parent"
android:layout_height="50dp"
android:background="@drawable/selector_common_bg"
android:paddingLeft="20dp"
android:paddingRight="20dp">
<ImageView
android:id="@+id/iv_syn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentStart="true"
android:layout_centerVertical="true"
android:src="@drawable/ic_online_syn"
app:tint="@color/textPrimary" />
<TextView
android:id="@+id/tv_syn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_marginStart="15dp"
android:layout_toEndOf="@id/iv_syn"
android:text="@string/menu_bookcase_syn"
android:textColor="@color/textSecondary"
android:textSize="@dimen/text_normal_size" />
</RelativeLayout> </RelativeLayout>
<RelativeLayout <RelativeLayout
android:layout_width="match_parent" android:layout_width="match_parent"
@ -68,7 +97,7 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_alignParentStart="true" android:layout_alignParentStart="true"
android:layout_centerInParent="true" android:layout_centerInParent="true"
android:text="云服务" android:text="WebDav云服务"
android:textColor="@color/textPrimary" /> android:textColor="@color/textPrimary" />
</RelativeLayout> </RelativeLayout>
@ -76,7 +105,7 @@
<RelativeLayout <RelativeLayout
android:id="@+id/mine_rl_webdav" android:id="@+id/mine_rl_webdav"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="60dp" android:layout_height="50dp"
android:background="@drawable/selector_common_bg" android:background="@drawable/selector_common_bg"
android:paddingLeft="20dp" android:paddingLeft="20dp"
android:paddingRight="20dp"> android:paddingRight="20dp">
@ -104,30 +133,30 @@
</RelativeLayout> </RelativeLayout>
<RelativeLayout <RelativeLayout
android:id="@+id/mine_rl_syn" android:id="@+id/mine_rl_syn_webdav"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="60dp" android:layout_height="50dp"
android:background="@drawable/selector_common_bg" android:background="@drawable/selector_common_bg"
android:paddingLeft="20dp" android:paddingLeft="20dp"
android:paddingRight="20dp"> android:paddingRight="20dp">
<ImageView <ImageView
android:id="@+id/iv_syn" android:id="@+id/iv_syn_webdav"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_alignParentStart="true" android:layout_alignParentStart="true"
android:layout_centerVertical="true" android:layout_centerVertical="true"
android:src="@drawable/ic_online_syn" android:src="@drawable/ic_restore"
app:tint="@color/textPrimary" /> app:tint="@color/textPrimary" />
<TextView <TextView
android:id="@+id/tv_syn" android:id="@+id/tv_syn_webdav"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_centerVertical="true" android:layout_centerVertical="true"
android:layout_marginStart="15dp" android:layout_marginStart="15dp"
android:layout_toEndOf="@id/iv_syn" android:layout_toEndOf="@id/iv_syn_webdav"
android:text="@string/menu_bookcase_syn" android:text="@string/webdav_restore_tip"
android:textColor="@color/textSecondary" android:textColor="@color/textSecondary"
android:textSize="@dimen/text_normal_size" /> android:textSize="@dimen/text_normal_size" />
@ -152,7 +181,7 @@
<RelativeLayout <RelativeLayout
android:id="@+id/mine_rl_book_source" android:id="@+id/mine_rl_book_source"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="60dp" android:layout_height="50dp"
android:background="@drawable/selector_common_bg" android:background="@drawable/selector_common_bg"
android:paddingLeft="20dp" android:paddingLeft="20dp"
android:paddingRight="20dp"> android:paddingRight="20dp">
@ -182,7 +211,7 @@
<RelativeLayout <RelativeLayout
android:id="@+id/mine_rl_backup" android:id="@+id/mine_rl_backup"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="60dp" android:layout_height="50dp"
android:background="@drawable/selector_common_bg" android:background="@drawable/selector_common_bg"
android:paddingLeft="20dp" android:paddingLeft="20dp"
android:paddingRight="20dp"> android:paddingRight="20dp">
@ -211,7 +240,7 @@
<RelativeLayout <RelativeLayout
android:id="@+id/mine_rl_read_record" android:id="@+id/mine_rl_read_record"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="60dp" android:layout_height="50dp"
android:background="@drawable/selector_common_bg" android:background="@drawable/selector_common_bg"
android:paddingLeft="20dp" android:paddingLeft="20dp"
android:paddingRight="20dp"> android:paddingRight="20dp">
@ -257,7 +286,7 @@
<RelativeLayout <RelativeLayout
android:id="@+id/mine_rl_setting" android:id="@+id/mine_rl_setting"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="60dp" android:layout_height="50dp"
android:background="@drawable/selector_common_bg" android:background="@drawable/selector_common_bg"
android:paddingLeft="20dp" android:paddingLeft="20dp"
android:paddingRight="20dp"> android:paddingRight="20dp">
@ -287,7 +316,7 @@
<RelativeLayout <RelativeLayout
android:id="@+id/mine_rl_theme_mode" android:id="@+id/mine_rl_theme_mode"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="60dp" android:layout_height="50dp"
android:background="@drawable/selector_common_bg" android:background="@drawable/selector_common_bg"
android:paddingLeft="20dp" android:paddingLeft="20dp"
android:paddingRight="20dp"> android:paddingRight="20dp">
@ -327,7 +356,7 @@
android:id="@+id/mine_rl_ad_setting" android:id="@+id/mine_rl_ad_setting"
android:visibility="gone" android:visibility="gone"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="60dp" android:layout_height="50dp"
android:background="@drawable/selector_common_bg" android:background="@drawable/selector_common_bg"
android:paddingLeft="20dp" android:paddingLeft="20dp"
android:paddingRight="20dp"> android:paddingRight="20dp">
@ -374,7 +403,7 @@
<RelativeLayout <RelativeLayout
android:id="@+id/mine_rl_feedback" android:id="@+id/mine_rl_feedback"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="60dp" android:layout_height="50dp"
android:background="@drawable/selector_common_bg" android:background="@drawable/selector_common_bg"
android:paddingLeft="20dp" android:paddingLeft="20dp"
android:paddingRight="20dp"> android:paddingRight="20dp">
@ -404,7 +433,7 @@
<RelativeLayout <RelativeLayout
android:id="@+id/mine_rl_donate" android:id="@+id/mine_rl_donate"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="60dp" android:layout_height="50dp"
android:background="@drawable/selector_common_bg" android:background="@drawable/selector_common_bg"
android:paddingLeft="20dp" android:paddingLeft="20dp"
android:paddingRight="20dp"> android:paddingRight="20dp">
@ -433,7 +462,7 @@
<RelativeLayout <RelativeLayout
android:id="@+id/mine_rl_about" android:id="@+id/mine_rl_about"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="60dp" android:layout_height="50dp"
android:background="@drawable/selector_common_bg" android:background="@drawable/selector_common_bg"
android:paddingLeft="20dp" android:paddingLeft="20dp"
android:paddingRight="20dp"> android:paddingRight="20dp">

Loading…
Cancel
Save