fetch太慢去除历史提交记录
52
.github/ISSUE_TEMPLATE/01-bugReport.md
vendored
Normal file
@ -0,0 +1,52 @@
|
||||
---
|
||||
name: "[BUG] 问题提交模板"
|
||||
about: 请从符号">"后面开始填写内容,填写内容可以参考 https://github.com/gedoor/legado/issues/505
|
||||
title: "[BUG] "
|
||||
labels: 'BUG'
|
||||
assignees: ''
|
||||
---
|
||||
|
||||
|
||||
### 机型(如Redmi K30 Pro)
|
||||
>
|
||||
|
||||
|
||||
### 安卓版本(如Android 7.1.1)
|
||||
>
|
||||
|
||||
|
||||
### 阅读Legdao版本(我的-关于-版本,如3.20.112220)
|
||||
>
|
||||
|
||||
### 网络环境(移动,联通,电信,移动宽带,联通宽带,电信宽带,等等..)
|
||||
>
|
||||
|
||||
|
||||
### 问题描述(简要描述发生的问题)
|
||||
>
|
||||
|
||||
|
||||
### 使用书源(填写URL或者JSON)
|
||||
>
|
||||
|
||||
|
||||
```json
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
```
|
||||
|
||||
### 复现步骤(详细描述导致问题产生的操作步骤,如果能稳定复现)
|
||||
>
|
||||
|
||||
|
||||
|
||||
|
||||
### 日志提交(问题截图或者日志)
|
||||
>
|
||||
|
||||
|
||||
|
19
.github/ISSUE_TEMPLATE/02-featureRequest.md
vendored
Normal file
@ -0,0 +1,19 @@
|
||||
---
|
||||
name: "[FeatureRequest] 功能请求模板"
|
||||
about: 提交你希望能够在阅读中增加的功能
|
||||
title: "[Feature Request] "
|
||||
labels: '需求'
|
||||
assignees: ''
|
||||
---
|
||||
|
||||
### 功能描述(请清晰的、详细的描述你想要的功能)
|
||||
>
|
||||
|
||||
### 期望实现方式(阅读应该如何实现该功能)
|
||||
>
|
||||
|
||||
### 附加信息(其他的与功能相关的附加信息)
|
||||
>
|
||||
|
||||
### 效果演示(可以手绘一些草图,或者提供可借鉴的图片)
|
||||
>
|
98
.github/scripts/lzy_web.py
vendored
Normal file
@ -0,0 +1,98 @@
|
||||
import requests, os, datetime, sys
|
||||
|
||||
# Cookie 中 phpdisk_info 的值
|
||||
cookie_phpdisk_info = os.environ.get('phpdisk_info')
|
||||
# Cookie 中 ylogin 的值
|
||||
cookie_ylogin = os.environ.get('ylogin')
|
||||
|
||||
# 请求头
|
||||
headers = {
|
||||
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.72 Safari/537.36 Edg/89.0.774.45',
|
||||
'Accept-Language': 'zh-CN,zh;q=0.9',
|
||||
'Referer': 'https://pc.woozooo.com/account.php?action=login'
|
||||
}
|
||||
|
||||
# 小饼干
|
||||
cookie = {
|
||||
'ylogin': cookie_ylogin,
|
||||
'phpdisk_info': cookie_phpdisk_info
|
||||
}
|
||||
|
||||
|
||||
# 日志打印
|
||||
def log(msg):
|
||||
utc_time = datetime.datetime.utcnow()
|
||||
china_time = utc_time + datetime.timedelta(hours=8)
|
||||
print(f"[{china_time.strftime('%Y.%m.%d %H:%M:%S')}] {msg}")
|
||||
|
||||
|
||||
# 检查是否已登录
|
||||
def login_by_cookie():
|
||||
url_account = "https://pc.woozooo.com/account.php"
|
||||
if cookie['phpdisk_info'] is None:
|
||||
log('ERROR: 请指定 Cookie 中 phpdisk_info 的值!')
|
||||
return False
|
||||
if cookie['ylogin'] is None:
|
||||
log('ERROR: 请指定 Cookie 中 ylogin 的值!')
|
||||
return False
|
||||
res = requests.get(url_account, headers=headers, cookies=cookie, verify=True)
|
||||
if '网盘用户登录' in res.text:
|
||||
log('ERROR: 登录失败,请更新Cookie')
|
||||
return False
|
||||
else:
|
||||
log('登录成功')
|
||||
return True
|
||||
|
||||
|
||||
# 上传文件
|
||||
def upload_file(file_dir, folder_id):
|
||||
file_name = os.path.basename(file_dir)
|
||||
url_upload = "https://up.woozooo.com/fileup.php"
|
||||
headers['Referer'] = f'https://up.woozooo.com/mydisk.php?item=files&action=index&u={cookie_ylogin}'
|
||||
post_data = {
|
||||
"task": "1",
|
||||
"folder_id": folder_id,
|
||||
"id": "WU_FILE_0",
|
||||
"name": file_name,
|
||||
}
|
||||
files = {'upload_file': (file_name, open(file_dir, "rb"), 'application/octet-stream')}
|
||||
res = requests.post(url_upload, data=post_data, files=files, headers=headers, cookies=cookie, timeout=120).json()
|
||||
log(f"{file_dir} -> {res['info']}")
|
||||
return res['zt'] == 1
|
||||
|
||||
|
||||
# 上传文件夹内的文件
|
||||
def upload_folder(folder_dir, folder_id):
|
||||
file_list = sorted(os.listdir(folder_dir), reverse=True)
|
||||
for file in file_list:
|
||||
path = os.path.join(folder_dir, file)
|
||||
if os.path.isfile(path):
|
||||
upload_file(path, folder_id)
|
||||
else:
|
||||
upload_folder(path, folder_id)
|
||||
|
||||
|
||||
# 上传
|
||||
def upload(dir, folder_id):
|
||||
if dir is None:
|
||||
log('ERROR: 请指定上传的文件路径')
|
||||
return
|
||||
if folder_id is None:
|
||||
log('ERROR: 请指定蓝奏云的文件夹id')
|
||||
return
|
||||
if os.path.isfile(dir):
|
||||
upload_file(dir, str(folder_id))
|
||||
else:
|
||||
upload_folder(dir, str(folder_id))
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
argv = sys.argv[1:]
|
||||
if len(argv) != 2:
|
||||
log('ERROR: 参数错误,请以这种格式重新尝试\npython lzy_web.py 需上传的路径 蓝奏云文件夹id')
|
||||
# 需上传的路径
|
||||
upload_path = argv[0]
|
||||
# 蓝奏云文件夹id
|
||||
lzy_folder_id = argv[1]
|
||||
if login_by_cookie():
|
||||
upload(upload_path, lzy_folder_id)
|
47
.github/scripts/tg_bot.py
vendored
Normal file
@ -0,0 +1,47 @@
|
||||
import os, sys, telebot
|
||||
|
||||
# 上传文件
|
||||
def upload_file(tb, chat_id, file_dir):
|
||||
doc = open(file_dir, 'rb')
|
||||
tb.send_document(chat_id, doc)
|
||||
|
||||
# 上传文件夹内的文件
|
||||
def upload_folder(tb, chat_id, folder_dir):
|
||||
file_list = sorted(os.listdir(folder_dir))
|
||||
for file in file_list:
|
||||
path = os.path.join(folder_dir, file)
|
||||
if os.path.isfile(path):
|
||||
upload_file(tb, chat_id, path)
|
||||
else:
|
||||
upload_folder(tb, chat_id, path)
|
||||
|
||||
# 上传
|
||||
def upload(tb, chat_id, dir):
|
||||
if tb is None:
|
||||
log('ERROR: 输入正确的token')
|
||||
return
|
||||
if chat_id is None:
|
||||
log('ERROR: 输入正确的chat_id')
|
||||
return
|
||||
if dir is None:
|
||||
log('ERROR: 请指定上传的文件路径')
|
||||
return
|
||||
if os.path.isfile(dir):
|
||||
upload_file(tb, chat_id, dir)
|
||||
else:
|
||||
upload_folder(tb, chat_id, dir)
|
||||
|
||||
if __name__ == '__main__':
|
||||
argv = sys.argv[1:]
|
||||
if len(argv) != 3:
|
||||
log('ERROR: 参数错误,请以这种格式重新尝试\npython tg_bot.py $token $chat_id 待上传的路径')
|
||||
# Token
|
||||
TOKEN = argv[0]
|
||||
# chat_id
|
||||
chat_id = argv[1]
|
||||
# 待上传文件的路径
|
||||
upload_path = argv[2]
|
||||
#创建连接
|
||||
tb = telebot.TeleBot(TOKEN)
|
||||
#开始上传
|
||||
upload(tb, chat_id, upload_path)
|
32
.github/workflows/autoupdatefork.yml
vendored
Normal file
@ -0,0 +1,32 @@
|
||||
#更新fork
|
||||
name: update fork
|
||||
|
||||
on:
|
||||
schedule:
|
||||
- cron: '0 16 * * *' #设置定时任务
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
if: ${{ github.event.repository.owner.id == github.event.sender.id && github.actor != 'gedoor' }}
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- name: Install git
|
||||
run: |
|
||||
sudo apt-get update
|
||||
sudo apt-get -y install git
|
||||
- name: Set env
|
||||
run: |
|
||||
git config --global user.email "github-actions@github.com"
|
||||
git config --global user.name "github-actions"
|
||||
- name: Update fork
|
||||
run: |
|
||||
git remote add upstream https://github.com/gedoor/legado.git
|
||||
git remote -v
|
||||
git fetch upstream
|
||||
git checkout master
|
||||
git merge upstream/master
|
||||
git push origin master
|
BIN
.github/workflows/legado.jks
vendored
Normal file
99
.github/workflows/release.yml
vendored
Normal file
@ -0,0 +1,99 @@
|
||||
name: Build and Release
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
paths:
|
||||
- 'CHANGELOG.md'
|
||||
# schedule:
|
||||
# - cron: '0 4 * * *'
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
env:
|
||||
# 登录蓝奏云后在控制台运行document.cookie
|
||||
ylogin: ${{ secrets.LANZOU_ID }}
|
||||
phpdisk_info: ${{ secrets.LANZOU_PSD }}
|
||||
# 蓝奏云里的文件夹ID(阅读3测试版:2670621)
|
||||
LANZOU_FOLDER_ID: 'b0f7pt4ja'
|
||||
# 是否上传到artifact
|
||||
UPLOAD_ARTIFACT: 'true'
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- uses: actions/cache@v2
|
||||
with:
|
||||
path: |
|
||||
~/.gradle/caches
|
||||
~/.gradle/wrapper
|
||||
key: ${{ runner.os }}-legado-${{ hashFiles('**/updateLog.md') }}-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-legado-${{ hashFiles('**/updateLog.md') }}-
|
||||
- name: Release Apk Sign
|
||||
run: |
|
||||
echo "给apk增加签名"
|
||||
cp $GITHUB_WORKSPACE/.github/workflows/legado.jks $GITHUB_WORKSPACE/app/legado.jks
|
||||
sed '$a\RELEASE_STORE_FILE=./legado.jks' $GITHUB_WORKSPACE/gradle.properties -i
|
||||
sed '$a\RELEASE_KEY_ALIAS=legado' $GITHUB_WORKSPACE/gradle.properties -i
|
||||
sed '$a\RELEASE_STORE_PASSWORD=gedoor_legado' $GITHUB_WORKSPACE/gradle.properties -i
|
||||
sed '$a\RELEASE_KEY_PASSWORD=gedoor_legado' $GITHUB_WORKSPACE/gradle.properties -i
|
||||
- name: Unify Version Name
|
||||
run: |
|
||||
echo "统一版本号"
|
||||
VERSION=$(date -d "8 hour" -u +3.%y.%m%d%H)
|
||||
echo "RELEASE_VERSION=$VERSION" >> $GITHUB_ENV
|
||||
sed "/def version/c def version = \"$VERSION\"" $GITHUB_WORKSPACE/app/build.gradle -i
|
||||
- name: Build With Gradle
|
||||
run: |
|
||||
echo "开始进行release构建"
|
||||
chmod +x gradlew
|
||||
./gradlew assembleRelease --build-cache --parallel
|
||||
- name: Organize the Files
|
||||
run: |
|
||||
mkdir -p ${{ github.workspace }}/apk/
|
||||
cp -rf ${{ github.workspace }}/app/build/outputs/apk/*/*/*.apk ${{ github.workspace }}/apk/
|
||||
- name: Upload App To Artifact
|
||||
if: ${{ env.UPLOAD_ARTIFACT != 'false' }}
|
||||
uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: legado apk
|
||||
path: ${{ github.workspace }}/apk/*.apk
|
||||
- name: Upload App To Lanzou
|
||||
if: ${{ env.ylogin }}
|
||||
run: |
|
||||
path="$GITHUB_WORKSPACE/apk/"
|
||||
python3 $GITHUB_WORKSPACE/.github/scripts/lzy_web.py "$path" "$LANZOU_FOLDER_ID"
|
||||
echo "[$(date -u -d '+8 hour' '+%Y.%m.%d %H:%M:%S')] 分享链接: https://kunfei.lanzoux.com/b0f7pt4ja"
|
||||
- name: Release
|
||||
uses: softprops/action-gh-release@59c3b4891632ff9a897f99a91d7bc557467a3a22
|
||||
with:
|
||||
name: legado_app_${{ env.RELEASE_VERSION }}
|
||||
tag_name: ${{ env.RELEASE_VERSION }}
|
||||
body_path: ${{ github.workspace }}/CHANGELOG.md
|
||||
draft: false
|
||||
prerelease: false
|
||||
files: ${{ github.workspace }}/apk/*.apk
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
- name: Push Assets To "release" Branch
|
||||
run: |
|
||||
cd $GITHUB_WORKSPACE/apk || exit 1
|
||||
git init
|
||||
git config --local user.name "github-actions[bot]"
|
||||
git config --local user.email "41898282+github-actions[bot]@users.noreply.github.com"
|
||||
git checkout -b release
|
||||
git add *.apk
|
||||
git commit -m "${{ env.RELEASE_VERSION }}"
|
||||
git remote add origin "https://${{ github.actor }}:${{ secrets.GITHUB_TOKEN }}@github.com/${{ github.repository }}"
|
||||
git push -f -u origin release
|
||||
- name: Purge Jsdelivr Cache
|
||||
run: |
|
||||
result=$(curl -s https://purge.jsdelivr.net/gh/${{ github.repository }}@release/)
|
||||
if echo $result |grep -q 'success.*true'; then
|
||||
echo "jsdelivr缓存更新成功"
|
||||
else
|
||||
echo $result
|
||||
fi
|
161
.github/workflows/test.yml
vendored
Normal file
@ -0,0 +1,161 @@
|
||||
name: Test Build
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
prepare:
|
||||
runs-on: ubuntu-latest
|
||||
outputs:
|
||||
version: ${{ steps.set-ver.outputs.version }}
|
||||
versionL: ${{ steps.set-ver.outputs.versionL }}
|
||||
lanzou: ${{ steps.check.outputs.lanzou }}
|
||||
telegram: ${{ steps.check.outputs.telegram }}
|
||||
steps:
|
||||
- id: set-ver
|
||||
run: |
|
||||
echo "::set-output name=version::$(date -d "8 hour" -u +3.%y.%m%d%H)"
|
||||
echo "::set-output name=versionL::$(date -d "8 hour" -u +3.%y.%m%d%H%M)"
|
||||
- id: check
|
||||
run: |
|
||||
if [ ${{ secrets.LANZOU_ID }} ]; then
|
||||
echo "::set-output name=lanzou::yes"
|
||||
fi
|
||||
if [ ${{ secrets.BOT_TOKEN }} ]; then
|
||||
echo "::set-output name=telegram::yes"
|
||||
fi
|
||||
|
||||
build:
|
||||
needs: prepare
|
||||
strategy:
|
||||
matrix:
|
||||
product: [app, google]
|
||||
type: [release, releaseA]
|
||||
fail-fast: false
|
||||
runs-on: ubuntu-latest
|
||||
env:
|
||||
product: ${{ matrix.product }}
|
||||
type: ${{ matrix.type }}
|
||||
VERSION: ${{ needs.prepare.outputs.version }}
|
||||
VERSIONL: ${{ needs.prepare.outputs.versionL }}
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- uses: actions/cache@v2
|
||||
with:
|
||||
path: |
|
||||
~/.gradle/caches
|
||||
~/.gradle/wrapper
|
||||
key: ${{ runner.os }}-legado-${{ hashFiles('**/updateLog.md') }}-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-legado-${{ hashFiles('**/updateLog.md') }}-
|
||||
- name: Clear 18PlusList.txt
|
||||
run: |
|
||||
echo "清空18PlusList.txt"
|
||||
echo "">$GITHUB_WORKSPACE/app/src/main/assets/18PlusList.txt
|
||||
- name: Release Apk Sign
|
||||
run: |
|
||||
echo "给apk增加签名"
|
||||
cp $GITHUB_WORKSPACE/.github/workflows/legado.jks $GITHUB_WORKSPACE/app/legado.jks
|
||||
sed '$a\RELEASE_STORE_FILE=./legado.jks' $GITHUB_WORKSPACE/gradle.properties -i
|
||||
sed '$a\RELEASE_KEY_ALIAS=legado' $GITHUB_WORKSPACE/gradle.properties -i
|
||||
sed '$a\RELEASE_STORE_PASSWORD=gedoor_legado' $GITHUB_WORKSPACE/gradle.properties -i
|
||||
sed '$a\RELEASE_KEY_PASSWORD=gedoor_legado' $GITHUB_WORKSPACE/gradle.properties -i
|
||||
- name: Build With Gradle
|
||||
run: |
|
||||
if [ ${{ env.type }} == 'release' ]; then
|
||||
typeName="原包名"
|
||||
else
|
||||
typeName="共存"
|
||||
sed "s/'.release'/'.releaseA'/" $GITHUB_WORKSPACE/app/build.gradle -i
|
||||
sed 's/.release/.releaseA/' $GITHUB_WORKSPACE/app/google-services.json -i
|
||||
fi
|
||||
echo "统一版本号"
|
||||
sed "/def version/c def version = \"${{ env.VERSION }}\"" $GITHUB_WORKSPACE/app/build.gradle -i
|
||||
echo "开始${{ env.product }}$typeName构建"
|
||||
chmod +x gradlew
|
||||
./gradlew assemble${{ env.product }}release --build-cache --parallel --daemon --warning-mode all
|
||||
echo "修改文件名"
|
||||
mkdir -p ${{ github.workspace }}/apk/
|
||||
for file in `ls ${{ github.workspace }}/app/build/outputs/apk/*/*/*.apk`; do
|
||||
mv "$file" ${{ github.workspace }}/apk/legado_${{ env.product }}_${{ env.VERSIONL }}_$typeName.apk
|
||||
done
|
||||
- name: Upload App To Artifact
|
||||
uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: legado.${{ env.product }}.${{ env.type }}
|
||||
path: ${{ github.workspace }}/apk/*.apk
|
||||
|
||||
lanzou:
|
||||
needs: [prepare, build]
|
||||
if: ${{ needs.prepare.outputs.lanzou }}
|
||||
runs-on: ubuntu-latest
|
||||
env:
|
||||
# 登录蓝奏云后在控制台运行document.cookie
|
||||
ylogin: ${{ secrets.LANZOU_ID }}
|
||||
phpdisk_info: ${{ secrets.LANZOU_PSD }}
|
||||
# 蓝奏云里的文件夹ID(阅读3测试版:2670621)
|
||||
LANZOU_FOLDER_ID: '2670621'
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/download-artifact@v2
|
||||
with:
|
||||
path: apk/
|
||||
- working-directory: apk/
|
||||
run: mv */*.apk . ;rm -rf */
|
||||
- name: Upload To Lanzou
|
||||
continue-on-error: true
|
||||
run: |
|
||||
path="$GITHUB_WORKSPACE/apk/"
|
||||
python3 $GITHUB_WORKSPACE/.github/scripts/lzy_web.py "$path" "$LANZOU_FOLDER_ID"
|
||||
echo "[$(date -u -d '+8 hour' '+%Y.%m.%d %H:%M:%S')] 分享链接: https://kunfei.lanzoux.com/b0f810h4b"
|
||||
|
||||
test_Branch:
|
||||
needs: [prepare, build]
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/download-artifact@v2
|
||||
with:
|
||||
path: apk/
|
||||
- working-directory: apk/
|
||||
run: mv */*.apk . ;rm -rf */
|
||||
- name: Push To "test" Branch
|
||||
run: |
|
||||
cd $GITHUB_WORKSPACE/apk
|
||||
git init
|
||||
git config --local user.name "github-actions[bot]"
|
||||
git config --local user.email "41898282+github-actions[bot]@users.noreply.github.com"
|
||||
git checkout -b test
|
||||
git add *.apk
|
||||
git commit -m "${{ needs.prepare.outputs.versionL }}"
|
||||
git remote add origin "https://${{ github.actor }}:${{ secrets.GITHUB_TOKEN }}@github.com/${{ github.repository }}"
|
||||
git push -f -u origin test
|
||||
|
||||
telegram:
|
||||
needs: [prepare, build]
|
||||
if: ${{ needs.prepare.outputs.telegram }}
|
||||
runs-on: ubuntu-latest
|
||||
env:
|
||||
CHANNEL_ID: ${{ secrets.CHANNEL_ID }}
|
||||
BOT_TOKEN: ${{ secrets.BOT_TOKEN }}
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/download-artifact@v2
|
||||
with:
|
||||
path: apk/
|
||||
- working-directory: apk/
|
||||
run: |
|
||||
for file in `ls */*.apk`; do
|
||||
mv "$file" "$(echo "$file"|sed -e 's#.*\/##g' -e "s/_/ /g" -e 's/legado/阅读/')"
|
||||
done
|
||||
rm -rf */
|
||||
- name: Post to channel
|
||||
run: |
|
||||
pip install pyTelegramBotAPI
|
||||
path="$GITHUB_WORKSPACE/apk/"
|
||||
python3 $GITHUB_WORKSPACE/.github/scripts/tg_bot.py "$BOT_TOKEN" "$CHANNEL_ID" "$path"
|
14
.gitignore
vendored
Normal file
@ -0,0 +1,14 @@
|
||||
*.iml
|
||||
.gradle
|
||||
/local.properties
|
||||
.DS_Store
|
||||
/build
|
||||
/captures
|
||||
.externalNativeBuild
|
||||
/release
|
||||
/tmp
|
||||
node_modules/
|
||||
/app/app
|
||||
/app/google
|
||||
/app/gradle.properties
|
||||
package-lock.json
|
14
.idea/.gitignore
vendored
Normal file
@ -0,0 +1,14 @@
|
||||
# Default ignored files
|
||||
/shelf/
|
||||
/workspace.xml
|
||||
# Datasource local storage ignored files
|
||||
/dataSources/
|
||||
/dataSources.local.xml
|
||||
# Editor-based HTTP Client requests
|
||||
/httpRequests/
|
||||
# Custom ignored
|
||||
/caches/
|
||||
/dictionaries/
|
||||
/modules/
|
||||
/libraries/
|
||||
/*.xml
|
125
.idea/codeStyles/Project.xml
Normal file
@ -0,0 +1,125 @@
|
||||
<component name="ProjectCodeStyleConfiguration">
|
||||
<code_scheme name="Project" version="173">
|
||||
<JetCodeStyleSettings>
|
||||
<option name="CODE_STYLE_DEFAULTS" value="KOTLIN_OFFICIAL" />
|
||||
</JetCodeStyleSettings>
|
||||
<codeStyleSettings language="XML">
|
||||
<indentOptions>
|
||||
<option name="CONTINUATION_INDENT_SIZE" value="4" />
|
||||
</indentOptions>
|
||||
<arrangement>
|
||||
<rules>
|
||||
<section>
|
||||
<rule>
|
||||
<match>
|
||||
<AND>
|
||||
<NAME>xmlns:android</NAME>
|
||||
<XML_ATTRIBUTE />
|
||||
<XML_NAMESPACE>^$</XML_NAMESPACE>
|
||||
</AND>
|
||||
</match>
|
||||
</rule>
|
||||
</section>
|
||||
<section>
|
||||
<rule>
|
||||
<match>
|
||||
<AND>
|
||||
<NAME>xmlns:.*</NAME>
|
||||
<XML_ATTRIBUTE />
|
||||
<XML_NAMESPACE>^$</XML_NAMESPACE>
|
||||
</AND>
|
||||
</match>
|
||||
<order>BY_NAME</order>
|
||||
</rule>
|
||||
</section>
|
||||
<section>
|
||||
<rule>
|
||||
<match>
|
||||
<AND>
|
||||
<NAME>.*:id</NAME>
|
||||
<XML_ATTRIBUTE />
|
||||
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
|
||||
</AND>
|
||||
</match>
|
||||
</rule>
|
||||
</section>
|
||||
<section>
|
||||
<rule>
|
||||
<match>
|
||||
<AND>
|
||||
<NAME>.*:name</NAME>
|
||||
<XML_ATTRIBUTE />
|
||||
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
|
||||
</AND>
|
||||
</match>
|
||||
</rule>
|
||||
</section>
|
||||
<section>
|
||||
<rule>
|
||||
<match>
|
||||
<AND>
|
||||
<NAME>name</NAME>
|
||||
<XML_ATTRIBUTE />
|
||||
<XML_NAMESPACE>^$</XML_NAMESPACE>
|
||||
</AND>
|
||||
</match>
|
||||
</rule>
|
||||
</section>
|
||||
<section>
|
||||
<rule>
|
||||
<match>
|
||||
<AND>
|
||||
<NAME>style</NAME>
|
||||
<XML_ATTRIBUTE />
|
||||
<XML_NAMESPACE>^$</XML_NAMESPACE>
|
||||
</AND>
|
||||
</match>
|
||||
</rule>
|
||||
</section>
|
||||
<section>
|
||||
<rule>
|
||||
<match>
|
||||
<AND>
|
||||
<NAME>.*</NAME>
|
||||
<XML_ATTRIBUTE />
|
||||
<XML_NAMESPACE>^$</XML_NAMESPACE>
|
||||
</AND>
|
||||
</match>
|
||||
<order>BY_NAME</order>
|
||||
</rule>
|
||||
</section>
|
||||
<section>
|
||||
<rule>
|
||||
<match>
|
||||
<AND>
|
||||
<NAME>.*</NAME>
|
||||
<XML_ATTRIBUTE />
|
||||
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
|
||||
</AND>
|
||||
</match>
|
||||
<order>ANDROID_ATTRIBUTE_ORDER</order>
|
||||
</rule>
|
||||
</section>
|
||||
<section>
|
||||
<rule>
|
||||
<match>
|
||||
<AND>
|
||||
<NAME>.*</NAME>
|
||||
<XML_ATTRIBUTE />
|
||||
<XML_NAMESPACE>.*</XML_NAMESPACE>
|
||||
</AND>
|
||||
</match>
|
||||
<order>BY_NAME</order>
|
||||
</rule>
|
||||
</section>
|
||||
</rules>
|
||||
</arrangement>
|
||||
</codeStyleSettings>
|
||||
<codeStyleSettings language="kotlin">
|
||||
<option name="CODE_STYLE_DEFAULTS" value="KOTLIN_OFFICIAL" />
|
||||
<indentOptions>
|
||||
<option name="CONTINUATION_INDENT_SIZE" value="4" />
|
||||
</indentOptions>
|
||||
</codeStyleSettings>
|
||||
</code_scheme>
|
||||
</component>
|
5
.idea/codeStyles/codeStyleConfig.xml
Normal file
@ -0,0 +1,5 @@
|
||||
<component name="ProjectCodeStyleConfiguration">
|
||||
<state>
|
||||
<option name="USE_PER_PROJECT_SETTINGS" value="true" />
|
||||
</state>
|
||||
</component>
|
20
.idea/inspectionProfiles/Project_Default.xml
Normal file
@ -0,0 +1,20 @@
|
||||
<component name="InspectionProjectProfileManager">
|
||||
<profile version="1.0">
|
||||
<option name="myName" value="Project Default" />
|
||||
<inspection_tool class="ConstantConditions" enabled="true" level="WARNING" enabled_by_default="true">
|
||||
<option name="SUGGEST_NULLABLE_ANNOTATIONS" value="false" />
|
||||
<option name="DONT_REPORT_TRUE_ASSERT_STATEMENTS" value="false" />
|
||||
</inspection_tool>
|
||||
<inspection_tool class="HtmlUnknownAttribute" enabled="true" level="WARNING" enabled_by_default="true">
|
||||
<option name="myValues">
|
||||
<value>
|
||||
<list size="1">
|
||||
<item index="0" class="java.lang.String" itemvalue="name" />
|
||||
</list>
|
||||
</value>
|
||||
</option>
|
||||
<option name="myCustomValuesEnabled" value="true" />
|
||||
</inspection_tool>
|
||||
<inspection_tool class="NonAsciiCharacters" enabled="false" level="WARNING" enabled_by_default="false" />
|
||||
</profile>
|
||||
</component>
|
6
.idea/inspectionProfiles/profiles_settings.xml
Normal file
@ -0,0 +1,6 @@
|
||||
<component name="InspectionProjectProfileManager">
|
||||
<settings>
|
||||
<option name="USE_PROJECT_PROFILE" value="false" />
|
||||
<version value="1.0" />
|
||||
</settings>
|
||||
</component>
|
4
CHANGELOG.md
Normal file
@ -0,0 +1,4 @@
|
||||
**2021/08/09**
|
||||
|
||||
1. 修复选择文字不能选择单个文字的bug
|
||||
2.
|
674
LICENSE
Normal file
@ -0,0 +1,674 @@
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 3, 29 June 2007
|
||||
|
||||
Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
The GNU General Public License is a free, copyleft license for
|
||||
software and other kinds of works.
|
||||
|
||||
The licenses for most software and other practical works are designed
|
||||
to take away your freedom to share and change the works. By contrast,
|
||||
the GNU General Public License is intended to guarantee your freedom to
|
||||
share and change all versions of a program--to make sure it remains free
|
||||
software for all its users. We, the Free Software Foundation, use the
|
||||
GNU General Public License for most of our software; it applies also to
|
||||
any other work released this way by its authors. You can apply it to
|
||||
your programs, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Our General Public Licenses are designed to make sure that you
|
||||
have the freedom to distribute copies of free software (and charge for
|
||||
them if you wish), that you receive source code or can get it if you
|
||||
want it, that you can change the software or use pieces of it in new
|
||||
free programs, and that you know you can do these things.
|
||||
|
||||
To protect your rights, we need to prevent others from denying you
|
||||
these rights or asking you to surrender the rights. Therefore, you have
|
||||
certain responsibilities if you distribute copies of the software, or if
|
||||
you modify it: responsibilities to respect the freedom of others.
|
||||
|
||||
For example, if you distribute copies of such a program, whether
|
||||
gratis or for a fee, you must pass on to the recipients the same
|
||||
freedoms that you received. You must make sure that they, too, receive
|
||||
or can get the source code. And you must show them these terms so they
|
||||
know their rights.
|
||||
|
||||
Developers that use the GNU GPL protect your rights with two steps:
|
||||
(1) assert copyright on the software, and (2) offer you this License
|
||||
giving you legal permission to copy, distribute and/or modify it.
|
||||
|
||||
For the developers' and authors' protection, the GPL clearly explains
|
||||
that there is no warranty for this free software. For both users' and
|
||||
authors' sake, the GPL requires that modified versions be marked as
|
||||
changed, so that their problems will not be attributed erroneously to
|
||||
authors of previous versions.
|
||||
|
||||
Some devices are designed to deny users access to install or run
|
||||
modified versions of the software inside them, although the manufacturer
|
||||
can do so. This is fundamentally incompatible with the aim of
|
||||
protecting users' freedom to change the software. The systematic
|
||||
pattern of such abuse occurs in the area of products for individuals to
|
||||
use, which is precisely where it is most unacceptable. Therefore, we
|
||||
have designed this version of the GPL to prohibit the practice for those
|
||||
products. If such problems arise substantially in other domains, we
|
||||
stand ready to extend this provision to those domains in future versions
|
||||
of the GPL, as needed to protect the freedom of users.
|
||||
|
||||
Finally, every program is threatened constantly by software patents.
|
||||
States should not allow patents to restrict development and use of
|
||||
software on general-purpose computers, but in those that do, we wish to
|
||||
avoid the special danger that patents applied to a free program could
|
||||
make it effectively proprietary. To prevent this, the GPL assures that
|
||||
patents cannot be used to render the program non-free.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
TERMS AND CONDITIONS
|
||||
|
||||
0. Definitions.
|
||||
|
||||
"This License" refers to version 3 of the GNU General Public License.
|
||||
|
||||
"Copyright" also means copyright-like laws that apply to other kinds of
|
||||
works, such as semiconductor masks.
|
||||
|
||||
"The Program" refers to any copyrightable work licensed under this
|
||||
License. Each licensee is addressed as "you". "Licensees" and
|
||||
"recipients" may be individuals or organizations.
|
||||
|
||||
To "modify" a work means to copy from or adapt all or part of the work
|
||||
in a fashion requiring copyright permission, other than the making of an
|
||||
exact copy. The resulting work is called a "modified version" of the
|
||||
earlier work or a work "based on" the earlier work.
|
||||
|
||||
A "covered work" means either the unmodified Program or a work based
|
||||
on the Program.
|
||||
|
||||
To "propagate" a work means to do anything with it that, without
|
||||
permission, would make you directly or secondarily liable for
|
||||
infringement under applicable copyright law, except executing it on a
|
||||
computer or modifying a private copy. Propagation includes copying,
|
||||
distribution (with or without modification), making available to the
|
||||
public, and in some countries other activities as well.
|
||||
|
||||
To "convey" a work means any kind of propagation that enables other
|
||||
parties to make or receive copies. Mere interaction with a user through
|
||||
a computer network, with no transfer of a copy, is not conveying.
|
||||
|
||||
An interactive user interface displays "Appropriate Legal Notices"
|
||||
to the extent that it includes a convenient and prominently visible
|
||||
feature that (1) displays an appropriate copyright notice, and (2)
|
||||
tells the user that there is no warranty for the work (except to the
|
||||
extent that warranties are provided), that licensees may convey the
|
||||
work under this License, and how to view a copy of this License. If
|
||||
the interface presents a list of user commands or options, such as a
|
||||
menu, a prominent item in the list meets this criterion.
|
||||
|
||||
1. Source Code.
|
||||
|
||||
The "source code" for a work means the preferred form of the work
|
||||
for making modifications to it. "Object code" means any non-source
|
||||
form of a work.
|
||||
|
||||
A "Standard Interface" means an interface that either is an official
|
||||
standard defined by a recognized standards body, or, in the case of
|
||||
interfaces specified for a particular programming language, one that
|
||||
is widely used among developers working in that language.
|
||||
|
||||
The "System Libraries" of an executable work include anything, other
|
||||
than the work as a whole, that (a) is included in the normal form of
|
||||
packaging a Major Component, but which is not part of that Major
|
||||
Component, and (b) serves only to enable use of the work with that
|
||||
Major Component, or to implement a Standard Interface for which an
|
||||
implementation is available to the public in source code form. A
|
||||
"Major Component", in this context, means a major essential component
|
||||
(kernel, window system, and so on) of the specific operating system
|
||||
(if any) on which the executable work runs, or a compiler used to
|
||||
produce the work, or an object code interpreter used to run it.
|
||||
|
||||
The "Corresponding Source" for a work in object code form means all
|
||||
the source code needed to generate, install, and (for an executable
|
||||
work) run the object code and to modify the work, including scripts to
|
||||
control those activities. However, it does not include the work's
|
||||
System Libraries, or general-purpose tools or generally available free
|
||||
programs which are used unmodified in performing those activities but
|
||||
which are not part of the work. For example, Corresponding Source
|
||||
includes interface definition files associated with source files for
|
||||
the work, and the source code for shared libraries and dynamically
|
||||
linked subprograms that the work is specifically designed to require,
|
||||
such as by intimate data communication or control flow between those
|
||||
subprograms and other parts of the work.
|
||||
|
||||
The Corresponding Source need not include anything that users
|
||||
can regenerate automatically from other parts of the Corresponding
|
||||
Source.
|
||||
|
||||
The Corresponding Source for a work in source code form is that
|
||||
same work.
|
||||
|
||||
2. Basic Permissions.
|
||||
|
||||
All rights granted under this License are granted for the term of
|
||||
copyright on the Program, and are irrevocable provided the stated
|
||||
conditions are met. This License explicitly affirms your unlimited
|
||||
permission to run the unmodified Program. The output from running a
|
||||
covered work is covered by this License only if the output, given its
|
||||
content, constitutes a covered work. This License acknowledges your
|
||||
rights of fair use or other equivalent, as provided by copyright law.
|
||||
|
||||
You may make, run and propagate covered works that you do not
|
||||
convey, without conditions so long as your license otherwise remains
|
||||
in force. You may convey covered works to others for the sole purpose
|
||||
of having them make modifications exclusively for you, or provide you
|
||||
with facilities for running those works, provided that you comply with
|
||||
the terms of this License in conveying all material for which you do
|
||||
not control copyright. Those thus making or running the covered works
|
||||
for you must do so exclusively on your behalf, under your direction
|
||||
and control, on terms that prohibit them from making any copies of
|
||||
your copyrighted material outside their relationship with you.
|
||||
|
||||
Conveying under any other circumstances is permitted solely under
|
||||
the conditions stated below. Sublicensing is not allowed; section 10
|
||||
makes it unnecessary.
|
||||
|
||||
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
|
||||
|
||||
No covered work shall be deemed part of an effective technological
|
||||
measure under any applicable law fulfilling obligations under article
|
||||
11 of the WIPO copyright treaty adopted on 20 December 1996, or
|
||||
similar laws prohibiting or restricting circumvention of such
|
||||
measures.
|
||||
|
||||
When you convey a covered work, you waive any legal power to forbid
|
||||
circumvention of technological measures to the extent such circumvention
|
||||
is effected by exercising rights under this License with respect to
|
||||
the covered work, and you disclaim any intention to limit operation or
|
||||
modification of the work as a means of enforcing, against the work's
|
||||
users, your or third parties' legal rights to forbid circumvention of
|
||||
technological measures.
|
||||
|
||||
4. Conveying Verbatim Copies.
|
||||
|
||||
You may convey verbatim copies of the Program's source code as you
|
||||
receive it, in any medium, provided that you conspicuously and
|
||||
appropriately publish on each copy an appropriate copyright notice;
|
||||
keep intact all notices stating that this License and any
|
||||
non-permissive terms added in accord with section 7 apply to the code;
|
||||
keep intact all notices of the absence of any warranty; and give all
|
||||
recipients a copy of this License along with the Program.
|
||||
|
||||
You may charge any price or no price for each copy that you convey,
|
||||
and you may offer support or warranty protection for a fee.
|
||||
|
||||
5. Conveying Modified Source Versions.
|
||||
|
||||
You may convey a work based on the Program, or the modifications to
|
||||
produce it from the Program, in the form of source code under the
|
||||
terms of section 4, provided that you also meet all of these conditions:
|
||||
|
||||
a) The work must carry prominent notices stating that you modified
|
||||
it, and giving a relevant date.
|
||||
|
||||
b) The work must carry prominent notices stating that it is
|
||||
released under this License and any conditions added under section
|
||||
7. This requirement modifies the requirement in section 4 to
|
||||
"keep intact all notices".
|
||||
|
||||
c) You must license the entire work, as a whole, under this
|
||||
License to anyone who comes into possession of a copy. This
|
||||
License will therefore apply, along with any applicable section 7
|
||||
additional terms, to the whole of the work, and all its parts,
|
||||
regardless of how they are packaged. This License gives no
|
||||
permission to license the work in any other way, but it does not
|
||||
invalidate such permission if you have separately received it.
|
||||
|
||||
d) If the work has interactive user interfaces, each must display
|
||||
Appropriate Legal Notices; however, if the Program has interactive
|
||||
interfaces that do not display Appropriate Legal Notices, your
|
||||
work need not make them do so.
|
||||
|
||||
A compilation of a covered work with other separate and independent
|
||||
works, which are not by their nature extensions of the covered work,
|
||||
and which are not combined with it such as to form a larger program,
|
||||
in or on a volume of a storage or distribution medium, is called an
|
||||
"aggregate" if the compilation and its resulting copyright are not
|
||||
used to limit the access or legal rights of the compilation's users
|
||||
beyond what the individual works permit. Inclusion of a covered work
|
||||
in an aggregate does not cause this License to apply to the other
|
||||
parts of the aggregate.
|
||||
|
||||
6. Conveying Non-Source Forms.
|
||||
|
||||
You may convey a covered work in object code form under the terms
|
||||
of sections 4 and 5, provided that you also convey the
|
||||
machine-readable Corresponding Source under the terms of this License,
|
||||
in one of these ways:
|
||||
|
||||
a) Convey the object code in, or embodied in, a physical product
|
||||
(including a physical distribution medium), accompanied by the
|
||||
Corresponding Source fixed on a durable physical medium
|
||||
customarily used for software interchange.
|
||||
|
||||
b) Convey the object code in, or embodied in, a physical product
|
||||
(including a physical distribution medium), accompanied by a
|
||||
written offer, valid for at least three years and valid for as
|
||||
long as you offer spare parts or customer support for that product
|
||||
model, to give anyone who possesses the object code either (1) a
|
||||
copy of the Corresponding Source for all the software in the
|
||||
product that is covered by this License, on a durable physical
|
||||
medium customarily used for software interchange, for a price no
|
||||
more than your reasonable cost of physically performing this
|
||||
conveying of source, or (2) access to copy the
|
||||
Corresponding Source from a network server at no charge.
|
||||
|
||||
c) Convey individual copies of the object code with a copy of the
|
||||
written offer to provide the Corresponding Source. This
|
||||
alternative is allowed only occasionally and noncommercially, and
|
||||
only if you received the object code with such an offer, in accord
|
||||
with subsection 6b.
|
||||
|
||||
d) Convey the object code by offering access from a designated
|
||||
place (gratis or for a charge), and offer equivalent access to the
|
||||
Corresponding Source in the same way through the same place at no
|
||||
further charge. You need not require recipients to copy the
|
||||
Corresponding Source along with the object code. If the place to
|
||||
copy the object code is a network server, the Corresponding Source
|
||||
may be on a different server (operated by you or a third party)
|
||||
that supports equivalent copying facilities, provided you maintain
|
||||
clear directions next to the object code saying where to find the
|
||||
Corresponding Source. Regardless of what server hosts the
|
||||
Corresponding Source, you remain obligated to ensure that it is
|
||||
available for as long as needed to satisfy these requirements.
|
||||
|
||||
e) Convey the object code using peer-to-peer transmission, provided
|
||||
you inform other peers where the object code and Corresponding
|
||||
Source of the work are being offered to the general public at no
|
||||
charge under subsection 6d.
|
||||
|
||||
A separable portion of the object code, whose source code is excluded
|
||||
from the Corresponding Source as a System Library, need not be
|
||||
included in conveying the object code work.
|
||||
|
||||
A "User Product" is either (1) a "consumer product", which means any
|
||||
tangible personal property which is normally used for personal, family,
|
||||
or household purposes, or (2) anything designed or sold for incorporation
|
||||
into a dwelling. In determining whether a product is a consumer product,
|
||||
doubtful cases shall be resolved in favor of coverage. For a particular
|
||||
product received by a particular user, "normally used" refers to a
|
||||
typical or common use of that class of product, regardless of the status
|
||||
of the particular user or of the way in which the particular user
|
||||
actually uses, or expects or is expected to use, the product. A product
|
||||
is a consumer product regardless of whether the product has substantial
|
||||
commercial, industrial or non-consumer uses, unless such uses represent
|
||||
the only significant mode of use of the product.
|
||||
|
||||
"Installation Information" for a User Product means any methods,
|
||||
procedures, authorization keys, or other information required to install
|
||||
and execute modified versions of a covered work in that User Product from
|
||||
a modified version of its Corresponding Source. The information must
|
||||
suffice to ensure that the continued functioning of the modified object
|
||||
code is in no case prevented or interfered with solely because
|
||||
modification has been made.
|
||||
|
||||
If you convey an object code work under this section in, or with, or
|
||||
specifically for use in, a User Product, and the conveying occurs as
|
||||
part of a transaction in which the right of possession and use of the
|
||||
User Product is transferred to the recipient in perpetuity or for a
|
||||
fixed term (regardless of how the transaction is characterized), the
|
||||
Corresponding Source conveyed under this section must be accompanied
|
||||
by the Installation Information. But this requirement does not apply
|
||||
if neither you nor any third party retains the ability to install
|
||||
modified object code on the User Product (for example, the work has
|
||||
been installed in ROM).
|
||||
|
||||
The requirement to provide Installation Information does not include a
|
||||
requirement to continue to provide support service, warranty, or updates
|
||||
for a work that has been modified or installed by the recipient, or for
|
||||
the User Product in which it has been modified or installed. Access to a
|
||||
network may be denied when the modification itself materially and
|
||||
adversely affects the operation of the network or violates the rules and
|
||||
protocols for communication across the network.
|
||||
|
||||
Corresponding Source conveyed, and Installation Information provided,
|
||||
in accord with this section must be in a format that is publicly
|
||||
documented (and with an implementation available to the public in
|
||||
source code form), and must require no special password or key for
|
||||
unpacking, reading or copying.
|
||||
|
||||
7. Additional Terms.
|
||||
|
||||
"Additional permissions" are terms that supplement the terms of this
|
||||
License by making exceptions from one or more of its conditions.
|
||||
Additional permissions that are applicable to the entire Program shall
|
||||
be treated as though they were included in this License, to the extent
|
||||
that they are valid under applicable law. If additional permissions
|
||||
apply only to part of the Program, that part may be used separately
|
||||
under those permissions, but the entire Program remains governed by
|
||||
this License without regard to the additional permissions.
|
||||
|
||||
When you convey a copy of a covered work, you may at your option
|
||||
remove any additional permissions from that copy, or from any part of
|
||||
it. (Additional permissions may be written to require their own
|
||||
removal in certain cases when you modify the work.) You may place
|
||||
additional permissions on material, added by you to a covered work,
|
||||
for which you have or can give appropriate copyright permission.
|
||||
|
||||
Notwithstanding any other provision of this License, for material you
|
||||
add to a covered work, you may (if authorized by the copyright holders of
|
||||
that material) supplement the terms of this License with terms:
|
||||
|
||||
a) Disclaiming warranty or limiting liability differently from the
|
||||
terms of sections 15 and 16 of this License; or
|
||||
|
||||
b) Requiring preservation of specified reasonable legal notices or
|
||||
author attributions in that material or in the Appropriate Legal
|
||||
Notices displayed by works containing it; or
|
||||
|
||||
c) Prohibiting misrepresentation of the origin of that material, or
|
||||
requiring that modified versions of such material be marked in
|
||||
reasonable ways as different from the original version; or
|
||||
|
||||
d) Limiting the use for publicity purposes of names of licensors or
|
||||
authors of the material; or
|
||||
|
||||
e) Declining to grant rights under trademark law for use of some
|
||||
trade names, trademarks, or service marks; or
|
||||
|
||||
f) Requiring indemnification of licensors and authors of that
|
||||
material by anyone who conveys the material (or modified versions of
|
||||
it) with contractual assumptions of liability to the recipient, for
|
||||
any liability that these contractual assumptions directly impose on
|
||||
those licensors and authors.
|
||||
|
||||
All other non-permissive additional terms are considered "further
|
||||
restrictions" within the meaning of section 10. If the Program as you
|
||||
received it, or any part of it, contains a notice stating that it is
|
||||
governed by this License along with a term that is a further
|
||||
restriction, you may remove that term. If a license document contains
|
||||
a further restriction but permits relicensing or conveying under this
|
||||
License, you may add to a covered work material governed by the terms
|
||||
of that license document, provided that the further restriction does
|
||||
not survive such relicensing or conveying.
|
||||
|
||||
If you add terms to a covered work in accord with this section, you
|
||||
must place, in the relevant source files, a statement of the
|
||||
additional terms that apply to those files, or a notice indicating
|
||||
where to find the applicable terms.
|
||||
|
||||
Additional terms, permissive or non-permissive, may be stated in the
|
||||
form of a separately written license, or stated as exceptions;
|
||||
the above requirements apply either way.
|
||||
|
||||
8. Termination.
|
||||
|
||||
You may not propagate or modify a covered work except as expressly
|
||||
provided under this License. Any attempt otherwise to propagate or
|
||||
modify it is void, and will automatically terminate your rights under
|
||||
this License (including any patent licenses granted under the third
|
||||
paragraph of section 11).
|
||||
|
||||
However, if you cease all violation of this License, then your
|
||||
license from a particular copyright holder is reinstated (a)
|
||||
provisionally, unless and until the copyright holder explicitly and
|
||||
finally terminates your license, and (b) permanently, if the copyright
|
||||
holder fails to notify you of the violation by some reasonable means
|
||||
prior to 60 days after the cessation.
|
||||
|
||||
Moreover, your license from a particular copyright holder is
|
||||
reinstated permanently if the copyright holder notifies you of the
|
||||
violation by some reasonable means, this is the first time you have
|
||||
received notice of violation of this License (for any work) from that
|
||||
copyright holder, and you cure the violation prior to 30 days after
|
||||
your receipt of the notice.
|
||||
|
||||
Termination of your rights under this section does not terminate the
|
||||
licenses of parties who have received copies or rights from you under
|
||||
this License. If your rights have been terminated and not permanently
|
||||
reinstated, you do not qualify to receive new licenses for the same
|
||||
material under section 10.
|
||||
|
||||
9. Acceptance Not Required for Having Copies.
|
||||
|
||||
You are not required to accept this License in order to receive or
|
||||
run a copy of the Program. Ancillary propagation of a covered work
|
||||
occurring solely as a consequence of using peer-to-peer transmission
|
||||
to receive a copy likewise does not require acceptance. However,
|
||||
nothing other than this License grants you permission to propagate or
|
||||
modify any covered work. These actions infringe copyright if you do
|
||||
not accept this License. Therefore, by modifying or propagating a
|
||||
covered work, you indicate your acceptance of this License to do so.
|
||||
|
||||
10. Automatic Licensing of Downstream Recipients.
|
||||
|
||||
Each time you convey a covered work, the recipient automatically
|
||||
receives a license from the original licensors, to run, modify and
|
||||
propagate that work, subject to this License. You are not responsible
|
||||
for enforcing compliance by third parties with this License.
|
||||
|
||||
An "entity transaction" is a transaction transferring control of an
|
||||
organization, or substantially all assets of one, or subdividing an
|
||||
organization, or merging organizations. If propagation of a covered
|
||||
work results from an entity transaction, each party to that
|
||||
transaction who receives a copy of the work also receives whatever
|
||||
licenses to the work the party's predecessor in interest had or could
|
||||
give under the previous paragraph, plus a right to possession of the
|
||||
Corresponding Source of the work from the predecessor in interest, if
|
||||
the predecessor has it or can get it with reasonable efforts.
|
||||
|
||||
You may not impose any further restrictions on the exercise of the
|
||||
rights granted or affirmed under this License. For example, you may
|
||||
not impose a license fee, royalty, or other charge for exercise of
|
||||
rights granted under this License, and you may not initiate litigation
|
||||
(including a cross-claim or counterclaim in a lawsuit) alleging that
|
||||
any patent claim is infringed by making, using, selling, offering for
|
||||
sale, or importing the Program or any portion of it.
|
||||
|
||||
11. Patents.
|
||||
|
||||
A "contributor" is a copyright holder who authorizes use under this
|
||||
License of the Program or a work on which the Program is based. The
|
||||
work thus licensed is called the contributor's "contributor version".
|
||||
|
||||
A contributor's "essential patent claims" are all patent claims
|
||||
owned or controlled by the contributor, whether already acquired or
|
||||
hereafter acquired, that would be infringed by some manner, permitted
|
||||
by this License, of making, using, or selling its contributor version,
|
||||
but do not include claims that would be infringed only as a
|
||||
consequence of further modification of the contributor version. For
|
||||
purposes of this definition, "control" includes the right to grant
|
||||
patent sublicenses in a manner consistent with the requirements of
|
||||
this License.
|
||||
|
||||
Each contributor grants you a non-exclusive, worldwide, royalty-free
|
||||
patent license under the contributor's essential patent claims, to
|
||||
make, use, sell, offer for sale, import and otherwise run, modify and
|
||||
propagate the contents of its contributor version.
|
||||
|
||||
In the following three paragraphs, a "patent license" is any express
|
||||
agreement or commitment, however denominated, not to enforce a patent
|
||||
(such as an express permission to practice a patent or covenant not to
|
||||
sue for patent infringement). To "grant" such a patent license to a
|
||||
party means to make such an agreement or commitment not to enforce a
|
||||
patent against the party.
|
||||
|
||||
If you convey a covered work, knowingly relying on a patent license,
|
||||
and the Corresponding Source of the work is not available for anyone
|
||||
to copy, free of charge and under the terms of this License, through a
|
||||
publicly available network server or other readily accessible means,
|
||||
then you must either (1) cause the Corresponding Source to be so
|
||||
available, or (2) arrange to deprive yourself of the benefit of the
|
||||
patent license for this particular work, or (3) arrange, in a manner
|
||||
consistent with the requirements of this License, to extend the patent
|
||||
license to downstream recipients. "Knowingly relying" means you have
|
||||
actual knowledge that, but for the patent license, your conveying the
|
||||
covered work in a country, or your recipient's use of the covered work
|
||||
in a country, would infringe one or more identifiable patents in that
|
||||
country that you have reason to believe are valid.
|
||||
|
||||
If, pursuant to or in connection with a single transaction or
|
||||
arrangement, you convey, or propagate by procuring conveyance of, a
|
||||
covered work, and grant a patent license to some of the parties
|
||||
receiving the covered work authorizing them to use, propagate, modify
|
||||
or convey a specific copy of the covered work, then the patent license
|
||||
you grant is automatically extended to all recipients of the covered
|
||||
work and works based on it.
|
||||
|
||||
A patent license is "discriminatory" if it does not include within
|
||||
the scope of its coverage, prohibits the exercise of, or is
|
||||
conditioned on the non-exercise of one or more of the rights that are
|
||||
specifically granted under this License. You may not convey a covered
|
||||
work if you are a party to an arrangement with a third party that is
|
||||
in the business of distributing software, under which you make payment
|
||||
to the third party based on the extent of your activity of conveying
|
||||
the work, and under which the third party grants, to any of the
|
||||
parties who would receive the covered work from you, a discriminatory
|
||||
patent license (a) in connection with copies of the covered work
|
||||
conveyed by you (or copies made from those copies), or (b) primarily
|
||||
for and in connection with specific products or compilations that
|
||||
contain the covered work, unless you entered into that arrangement,
|
||||
or that patent license was granted, prior to 28 March 2007.
|
||||
|
||||
Nothing in this License shall be construed as excluding or limiting
|
||||
any implied license or other defenses to infringement that may
|
||||
otherwise be available to you under applicable patent law.
|
||||
|
||||
12. No Surrender of Others' Freedom.
|
||||
|
||||
If conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot convey a
|
||||
covered work so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you may
|
||||
not convey it at all. For example, if you agree to terms that obligate you
|
||||
to collect a royalty for further conveying from those to whom you convey
|
||||
the Program, the only way you could satisfy both those terms and this
|
||||
License would be to refrain entirely from conveying the Program.
|
||||
|
||||
13. Use with the GNU Affero General Public License.
|
||||
|
||||
Notwithstanding any other provision of this License, you have
|
||||
permission to link or combine any covered work with a work licensed
|
||||
under version 3 of the GNU Affero General Public License into a single
|
||||
combined work, and to convey the resulting work. The terms of this
|
||||
License will continue to apply to the part which is the covered work,
|
||||
but the special requirements of the GNU Affero General Public License,
|
||||
section 13, concerning interaction through a network will apply to the
|
||||
combination as such.
|
||||
|
||||
14. Revised Versions of this License.
|
||||
|
||||
The Free Software Foundation may publish revised and/or new versions of
|
||||
the GNU General Public License from time to time. Such new versions will
|
||||
be similar in spirit to the present version, but may differ in detail to
|
||||
address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the
|
||||
Program specifies that a certain numbered version of the GNU General
|
||||
Public License "or any later version" applies to it, you have the
|
||||
option of following the terms and conditions either of that numbered
|
||||
version or of any later version published by the Free Software
|
||||
Foundation. If the Program does not specify a version number of the
|
||||
GNU General Public License, you may choose any version ever published
|
||||
by the Free Software Foundation.
|
||||
|
||||
If the Program specifies that a proxy can decide which future
|
||||
versions of the GNU General Public License can be used, that proxy's
|
||||
public statement of acceptance of a version permanently authorizes you
|
||||
to choose that version for the Program.
|
||||
|
||||
Later license versions may give you additional or different
|
||||
permissions. However, no additional obligations are imposed on any
|
||||
author or copyright holder as a result of your choosing to follow a
|
||||
later version.
|
||||
|
||||
15. Disclaimer of Warranty.
|
||||
|
||||
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
|
||||
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
|
||||
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
|
||||
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
|
||||
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
|
||||
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
|
||||
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
|
||||
|
||||
16. Limitation of Liability.
|
||||
|
||||
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
|
||||
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
|
||||
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
|
||||
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
|
||||
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
|
||||
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
|
||||
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
|
||||
SUCH DAMAGES.
|
||||
|
||||
17. Interpretation of Sections 15 and 16.
|
||||
|
||||
If the disclaimer of warranty and limitation of liability provided
|
||||
above cannot be given local legal effect according to their terms,
|
||||
reviewing courts shall apply local law that most closely approximates
|
||||
an absolute waiver of all civil liability in connection with the
|
||||
Program, unless a warranty or assumption of liability accompanies a
|
||||
copy of the Program in return for a fee.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest
|
||||
possible use to the public, the best way to achieve this is to make it
|
||||
free software which everyone can redistribute and change under these terms.
|
||||
|
||||
To do so, attach the following notices to the program. It is safest
|
||||
to attach them to the start of each source file to most effectively
|
||||
state the exclusion of warranty; and each file should have at least
|
||||
the "copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the program's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If the program does terminal interaction, make it output a short
|
||||
notice like this when it starts in an interactive mode:
|
||||
|
||||
<program> Copyright (C) <year> <name of author>
|
||||
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under certain conditions; type `show c' for details.
|
||||
|
||||
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||
parts of the General Public License. Of course, your program's commands
|
||||
might be different; for a GUI interface, you would use an "about box".
|
||||
|
||||
You should also get your employer (if you work as a programmer) or school,
|
||||
if any, to sign a "copyright disclaimer" for the program, if necessary.
|
||||
For more information on this, and how to apply and follow the GNU GPL, see
|
||||
<https://www.gnu.org/licenses/>.
|
||||
|
||||
The GNU General Public License does not permit incorporating your program
|
||||
into proprietary programs. If your program is a subroutine library, you
|
||||
may consider it more useful to permit linking proprietary applications with
|
||||
the library. If this is what you want to do, use the GNU Lesser General
|
||||
Public License instead of this License. But first, please read
|
||||
<https://www.gnu.org/licenses/why-not-lgpl.html>.
|
130
README.md
Normal file
@ -0,0 +1,130 @@
|
||||
[![icon_android](https://github.com/gedoor/gedoor.github.io/blob/master/images/icon_android.png)](https://play.google.com/store/apps/details?id=io.legado.play.release)
|
||||
<a href="https://data.newrank.cn/m/s.html?s=NykyOzI9MS5LNQ%3D%3D" target="_blank">
|
||||
<img src="https://img.shields.io/badge/-微信关注“开源阅读”公众号-orange.svg" alt="#" align="right">
|
||||
</a>
|
||||
|
||||
<div align="center">
|
||||
<img width="125" height="125" src="https://github.com/gedoor/legado/raw/master/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png" alt="legado"/>
|
||||
|
||||
Legado / 开源阅读
|
||||
<br>
|
||||
<a href="https://gedoor.github.io" target="_blank">gedoor.github.io</a> / <a href="https://www.legado.top/" target="_blank">legado.top</a>
|
||||
<br>
|
||||
Legado is a free and open source novel reader for Android.
|
||||
</div>
|
||||
|
||||
[![](https://img.shields.io/badge/-Contents:-696969.svg)](#contents) [![](https://img.shields.io/badge/-Function-F5F5F5.svg)](#Function-主要功能-) [![](https://img.shields.io/badge/-Download-F5F5F5.svg)](#Download-下载-) [![](https://img.shields.io/badge/-Community-F5F5F5.svg)](#Community-交流社区-) [![](https://img.shields.io/badge/-API-F5F5F5.svg)](#API-) [![](https://img.shields.io/badge/-Other-F5F5F5.svg)](#Other-其他-) [![](https://img.shields.io/badge/-Grateful-F5F5F5.svg)](#Grateful-感谢-) [![](https://img.shields.io/badge/-Interface-F5F5F5.svg)](#Interface-界面-)
|
||||
|
||||
>新用户?
|
||||
>
|
||||
>软件不提供内容,需要您自己手动添加,例如导入书源等。
|
||||
>看看 [官方帮助文档](https://www.yuque.com/legado/wiki),也许里面就有你要的答案。
|
||||
|
||||
# Function-主要功能 [![](https://img.shields.io/badge/-Function-F5F5F5.svg)](#Function-主要功能-)
|
||||
<details><summary>English</summary>
|
||||
1. Online reading from a variety of sources.<br>
|
||||
2. Local reading of downloaded content.<br>
|
||||
3. A configurable reader with multiple viewers, reading directions and other settings. <br>
|
||||
4. Categories to organize your library.<br>
|
||||
5. Light and dark themes.<br>
|
||||
6. Schedule updating your library for new chapters.<br>
|
||||
7. read offline or to your desired cloud service
|
||||
</details>
|
||||
|
||||
<details><summary>中文</summary>
|
||||
1.自定义书源,自己设置规则,抓取网页数据,规则简单易懂,软件内有规则说明。<br>
|
||||
2.列表书架,网格书架自由切换。<br>
|
||||
3.书源规则支持搜索及发现,所有找书看书功能全部自定义,找书更方便。<br>
|
||||
4.订阅内容,可以订阅想看的任何内容,看你想看<br>
|
||||
5.支持替换净化,去除广告替换内容很方便。<br>
|
||||
6.支持本地TXT、EPUB阅读,手动浏览,智能扫描。<br>
|
||||
7.支持高度自定义阅读界面,切换字体、颜色、背景、行距、段距、加粗、简繁转换等。<br>
|
||||
8.支持多种翻页模式,覆盖、仿真、滑动、滚动等。<br>
|
||||
9.软件开源,持续优化,无广告。
|
||||
</details>
|
||||
|
||||
<a href="#readme">
|
||||
<img src="https://img.shields.io/badge/-返回顶部-orange.svg" alt="#" align="right">
|
||||
</a>
|
||||
|
||||
# Download-下载 [![](https://img.shields.io/badge/-Download-F5F5F5.svg)](#Download-下载-)
|
||||
#### Android-安卓
|
||||
* [Releases](https://github.com/gedoor/legado/releases/latest)
|
||||
* [Google play - $1.99](https://play.google.com/store/apps/details?id=io.legado.play.release)
|
||||
* [Coolapk](https://www.coolapk.com/apk/io.legado.app.release)
|
||||
* [Jsdelivr](https://cdn.jsdelivr.net/gh/gedoor/legado@release/)
|
||||
* [\#Beta](https://kunfei.lanzoui.com/b0f810h4b)
|
||||
|
||||
|
||||
#### IOS-苹果
|
||||
* 准备中(No release) - [Github](https://github.com/gedoor/YueDuFlutter)
|
||||
|
||||
<a href="#readme">
|
||||
<img src="https://img.shields.io/badge/-返回顶部-orange.svg" alt="#" align="right">
|
||||
</a>
|
||||
|
||||
# Community-交流社区 [![](https://img.shields.io/badge/-Community-F5F5F5.svg)](#Community-交流社区-)
|
||||
|
||||
#### Telegram
|
||||
[![Telegram-group](https://img.shields.io/badge/Telegram-%E7%BE%A4%E7%BB%84-blue)](https://t.me/yueduguanfang) [![Telegram-channel](https://img.shields.io/badge/Telegram-%E9%A2%91%E9%81%93-blue)](https://t.me/legado_channels)
|
||||
|
||||
#### Discord
|
||||
[![Discord](https://img.shields.io/discord/560731361414086666?color=%235865f2&label=Discord)](https://discord.gg/VtUfRyzRXn)
|
||||
|
||||
#### Other
|
||||
https://www.yuque.com/legado/wiki/community
|
||||
|
||||
<a href="#readme">
|
||||
<img src="https://img.shields.io/badge/-返回顶部-orange.svg" alt="#" align="right">
|
||||
</a>
|
||||
|
||||
# API [![](https://img.shields.io/badge/-API-F5F5F5.svg)](#API-)
|
||||
* 阅读3.0 提供了2种方式的API:`Web方式`和`Content Provider方式`。您可以在[这里](api.md)根据需要自行调用。
|
||||
* 可通过url唤起阅读进行一键导入,url格式: legado://import/{path}?src={url}
|
||||
* path类型: bookSource,rssSource,replaceRule,textTocRule,httpTTS,theme,readConfig
|
||||
* path类型解释: 书源,订阅源,替换规则,本地txt小说目录规则,在线朗读引擎,主题,阅读排版
|
||||
|
||||
<a href="#readme">
|
||||
<img src="https://img.shields.io/badge/-返回顶部-orange.svg" alt="#" align="right">
|
||||
</a>
|
||||
|
||||
# Other-其他 [![](https://img.shields.io/badge/-Other-F5F5F5.svg)](#Other-其他-)
|
||||
##### 免责声明
|
||||
https://gedoor.github.io/about.html
|
||||
##### 阅读3.0
|
||||
* [书源规则](https://alanskycn.gitee.io/teachme)
|
||||
* [更新日志](/app/src/main/assets/updateLog.md)
|
||||
* [帮助文档](/app/src/main/assets/help/appHelp.md)
|
||||
* [web端](https://github.com/celetor/web-yuedu3)
|
||||
|
||||
<a href="#readme">
|
||||
<img src="https://img.shields.io/badge/-返回顶部-orange.svg" alt="#" align="right">
|
||||
</a>
|
||||
|
||||
# Grateful-感谢 [![](https://img.shields.io/badge/-Grateful-F5F5F5.svg)](#Grateful-感谢-)
|
||||
> * org.jsoup:jsoup
|
||||
> * cn.wanghaomiao:JsoupXpath
|
||||
> * com.jayway.jsonpath:json-path
|
||||
> * com.github.gedoor:rhino-android
|
||||
> * com.squareup.okhttp3:okhttp
|
||||
> * com.github.bumptech.glide:glide
|
||||
> * org.nanohttpd:nanohttpd
|
||||
> * org.nanohttpd:nanohttpd-websocket
|
||||
> * cn.bingoogolapple:bga-qrcode-zxing
|
||||
> * com.jaredrummler:colorpicker
|
||||
> * org.apache.commons:commons-text
|
||||
> * io.noties.markwon:core
|
||||
> * io.noties.markwon:image-glide
|
||||
> * com.hankcs:hanlp
|
||||
> * com.positiondev.epublib:epublib-core
|
||||
<a href="#readme">
|
||||
<img src="https://img.shields.io/badge/-返回顶部-orange.svg" alt="#" align="right">
|
||||
</a>
|
||||
|
||||
# Interface-界面 [![](https://img.shields.io/badge/-Interface-F5F5F5.svg)](#Interface-界面-)
|
||||
<img src="https://github.com/gedoor/gedoor.github.io/blob/master/images/%E9%98%85%E8%AF%BB%E7%AE%80%E4%BB%8B1.jpg" width="270"><img src="https://github.com/gedoor/gedoor.github.io/blob/master/images/%E9%98%85%E8%AF%BB%E7%AE%80%E4%BB%8B2.jpg" width="270"><img src="https://github.com/gedoor/gedoor.github.io/blob/master/images/%E9%98%85%E8%AF%BB%E7%AE%80%E4%BB%8B3.jpg" width="270">
|
||||
<img src="https://github.com/gedoor/gedoor.github.io/blob/master/images/%E9%98%85%E8%AF%BB%E7%AE%80%E4%BB%8B4.jpg" width="270"><img src="https://github.com/gedoor/gedoor.github.io/blob/master/images/%E9%98%85%E8%AF%BB%E7%AE%80%E4%BB%8B5.jpg" width="270"><img src="https://github.com/gedoor/gedoor.github.io/blob/master/images/%E9%98%85%E8%AF%BB%E7%AE%80%E4%BB%8B6.jpg" width="270">
|
||||
|
||||
<a href="#readme">
|
||||
<img src="https://img.shields.io/badge/-返回顶部-orange.svg" alt="#" align="right">
|
||||
</a>
|
194
api.md
Normal file
@ -0,0 +1,194 @@
|
||||
# 阅读API
|
||||
## 对于Web的配置
|
||||
您需要先在设置中启用"Web 服务"。
|
||||
## 使用
|
||||
### Web
|
||||
以下说明假设您的操作在本机进行,且开放端口为1234。
|
||||
如果您要从远程计算机访问[阅读](),请将`127.0.0.1`替换成手机IP。
|
||||
#### 插入单个书源
|
||||
```
|
||||
URL = http://127.0.0.1:1234/saveSource
|
||||
Method = POST
|
||||
```
|
||||
|
||||
请求BODY内容为`JSON`字符串,
|
||||
格式参考[这个文件](https://github.com/gedoor/legado/blob/master/app/src/main/java/io/legado/app/data/entities/BookSource.kt)
|
||||
|
||||
#### 插入多个书源or订阅源
|
||||
|
||||
```
|
||||
URL = http://127.0.0.1:1234/saveBookSources
|
||||
URL = http://127.0.0.1:1234/saveRssSources
|
||||
Method = POST
|
||||
```
|
||||
|
||||
请求BODY内容为`JSON`字符串,
|
||||
格式参考[这个文件](https://github.com/gedoor/legado/blob/master/app/src/main/java/io/legado/app/data/entities/BookSource.kt),**为数组格式**。
|
||||
|
||||
#### 获取书源
|
||||
|
||||
```
|
||||
URL = http://127.0.0.1:1234/getBookSource?url=xxx
|
||||
URL = http://127.0.0.1:1234/getRssSource?url=xxx
|
||||
Method = GET
|
||||
```
|
||||
|
||||
#### 获取所有书源or订阅源
|
||||
|
||||
```
|
||||
URL = http://127.0.0.1:1234/getBookSources
|
||||
URL = http://127.0.0.1:1234/getRssSources
|
||||
Method = GET
|
||||
```
|
||||
|
||||
#### 删除多个书源or订阅源
|
||||
|
||||
```
|
||||
URL = http://127.0.0.1:1234/deleteBookSources
|
||||
URL = http://127.0.0.1:1234/deleteRssSources
|
||||
Method = POST
|
||||
```
|
||||
|
||||
请求BODY内容为`JSON`字符串,
|
||||
格式参考[这个文件](https://github.com/gedoor/legado/blob/master/app/src/main/java/io/legado/app/data/entities/BookSource.kt),**为数组格式**。
|
||||
|
||||
#### 插入书籍
|
||||
```
|
||||
URL = http://127.0.0.1:1234/saveBook
|
||||
Method = POST
|
||||
```
|
||||
|
||||
请求BODY内容为`JSON`字符串,
|
||||
格式参考[这个文件](https://github.com/gedoor/legado/blob/master/app/src/main/java/io/legado/app/data/entities/Book.kt)。
|
||||
|
||||
#### 获取所有书籍
|
||||
```
|
||||
URL = http://127.0.0.1:1234/getBookshelf
|
||||
Method = GET
|
||||
```
|
||||
|
||||
获取APP内的所有书籍。
|
||||
|
||||
#### 获取书籍章节列表
|
||||
```
|
||||
URL = http://127.0.0.1:1234/getChapterList?url=xxx
|
||||
Method = GET
|
||||
```
|
||||
|
||||
获取指定图书的章节列表。
|
||||
|
||||
#### 获取书籍内容
|
||||
```
|
||||
URL = http://127.0.0.1:1234/getBookContent?url=xxx&index=1
|
||||
Method = GET
|
||||
```
|
||||
获取指定图书的第`index`章节的文本内容。
|
||||
|
||||
#### 获取封面
|
||||
```
|
||||
URL = http://127.0.0.1:1234/cover?path=xxxxx
|
||||
Method = GET
|
||||
```
|
||||
|
||||
|
||||
### Content Provider
|
||||
* 需声明`io.legado.READ_WRITE`权限
|
||||
* `providerHost`为`包名.readerProvider`, 如`io.legado.app.release.readerProvider`,不同包的地址不同,防止冲突安装失败
|
||||
* 以下出现的`providerHost`请自行替换
|
||||
|
||||
#### 插入单个书源or订阅源
|
||||
|
||||
```
|
||||
URL = content://providerHost/bookSource/insert
|
||||
URL = content://providerHost/rssSource/insert
|
||||
Method = insert
|
||||
```
|
||||
|
||||
创建`Key="json"`的`ContentValues`,内容为`JSON`字符串,
|
||||
格式参考[这个文件](https://github.com/gedoor/legado/blob/master/app/src/main/java/io/legado/app/data/entities/BookSource.kt)
|
||||
|
||||
#### 插入多个书源or订阅源
|
||||
|
||||
```
|
||||
URL = content://providerHost/bookSources/insert
|
||||
URL = content://providerHost/rssSources/insert
|
||||
Method = insert
|
||||
```
|
||||
|
||||
创建`Key="json"`的`ContentValues`,内容为`JSON`字符串,
|
||||
格式参考[这个文件](https://github.com/gedoor/legado/blob/master/app/src/main/java/io/legado/app/data/entities/BookSource.kt),**为数组格式**。
|
||||
|
||||
#### 获取书源or订阅源
|
||||
|
||||
```
|
||||
URL = content://providerHost/bookSource/query?url=xxx
|
||||
URL = content://providerHost/rssSource/query?url=xxx
|
||||
Method = query
|
||||
```
|
||||
|
||||
获取指定URL对应的书源信息。
|
||||
用`Cursor.getString(0)`取出返回结果。
|
||||
|
||||
#### 获取所有书源or订阅源
|
||||
|
||||
```
|
||||
URL = content://providerHost/bookSources/query
|
||||
URL = content://providerHost/rssSources/query
|
||||
Method = query
|
||||
```
|
||||
|
||||
获取APP内的所有书源。
|
||||
用`Cursor.getString(0)`取出返回结果。
|
||||
|
||||
#### 删除多个书源or订阅源
|
||||
|
||||
```
|
||||
URL = content://providerHost/bookSources/delete
|
||||
URL = content://providerHost/rssSources/delete
|
||||
Method = delete
|
||||
```
|
||||
|
||||
创建`Key="json"`的`ContentValues`,内容为`JSON`字符串,
|
||||
格式参考[这个文件](https://github.com/gedoor/legado/blob/master/app/src/main/java/io/legado/app/data/entities/BookSource.kt),**为数组格式**。
|
||||
|
||||
#### 插入书籍
|
||||
```
|
||||
URL = content://providerHost/book/insert
|
||||
Method = insert
|
||||
```
|
||||
|
||||
创建`Key="json"`的`ContentValues`,内容为`JSON`字符串,
|
||||
格式参考[这个文件](https://github.com/gedoor/legado/blob/master/app/src/main/java/io/legado/app/data/entities/Book.kt)。
|
||||
|
||||
#### 获取所有书籍
|
||||
```
|
||||
URL = content://providerHost/books/query
|
||||
Method = query
|
||||
```
|
||||
|
||||
获取APP内的所有书籍。
|
||||
用`Cursor.getString(0)`取出返回结果。
|
||||
|
||||
#### 获取书籍章节列表
|
||||
```
|
||||
URL = content://providerHost/book/chapter/query?url=xxx
|
||||
Method = query
|
||||
```
|
||||
|
||||
获取指定图书的章节列表。
|
||||
用`Cursor.getString(0)`取出返回结果。
|
||||
|
||||
#### 获取书籍内容
|
||||
|
||||
```
|
||||
URL = content://providerHost/book/content/query?url=xxx&index=1
|
||||
Method = query
|
||||
```
|
||||
获取指定图书的第`index`章节的文本内容。
|
||||
用`Cursor.getString(0)`取出返回结果。
|
||||
|
||||
#### 获取封面
|
||||
```
|
||||
URL = content://providerHost/book/cover/query?path=xxxx
|
||||
Method = query
|
||||
```
|
2
app/.gitignore
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
/build
|
||||
/so
|
227
app/build.gradle
Normal file
@ -0,0 +1,227 @@
|
||||
apply plugin: 'com.android.application'
|
||||
apply plugin: 'kotlin-android'
|
||||
apply plugin: 'kotlin-parcelize'
|
||||
apply plugin: 'kotlin-kapt'
|
||||
apply plugin: 'de.timfreiheit.resourceplaceholders'
|
||||
apply from: 'download.gradle'
|
||||
|
||||
static def releaseTime() {
|
||||
return new Date().format("yy.MMddHH", TimeZone.getTimeZone("GMT+8"))
|
||||
}
|
||||
|
||||
def name = "legado"
|
||||
def version = "3." + releaseTime()
|
||||
def gitCommits = Integer.parseInt('git rev-list --count HEAD'.execute([], project.rootDir).text.trim())
|
||||
|
||||
android {
|
||||
compileSdkVersion 32
|
||||
buildToolsVersion '32.0.0'
|
||||
kotlinOptions {
|
||||
jvmTarget = "11"
|
||||
}
|
||||
signingConfigs {
|
||||
if (project.hasProperty("RELEASE_STORE_FILE")) {
|
||||
myConfig {
|
||||
storeFile file(RELEASE_STORE_FILE)
|
||||
storePassword RELEASE_STORE_PASSWORD
|
||||
keyAlias RELEASE_KEY_ALIAS
|
||||
keyPassword RELEASE_KEY_PASSWORD
|
||||
v1SigningEnabled true
|
||||
v2SigningEnabled true
|
||||
}
|
||||
}
|
||||
}
|
||||
defaultConfig {
|
||||
applicationId "io.legado.app"
|
||||
minSdkVersion 21
|
||||
targetSdkVersion 32
|
||||
versionCode gitCommits
|
||||
versionName version
|
||||
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
||||
project.ext.set("archivesBaseName", name + "_" + version)
|
||||
multiDexEnabled true
|
||||
|
||||
javaCompileOptions {
|
||||
annotationProcessorOptions {
|
||||
arguments += [
|
||||
"room.incremental" : "true",
|
||||
"room.expandProjection": "true",
|
||||
"room.schemaLocation" : "$projectDir/schemas".toString()
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
buildFeatures {
|
||||
viewBinding true
|
||||
}
|
||||
buildTypes {
|
||||
release {
|
||||
buildConfigField "String", "Cronet_Version", "\"$CronetVersion\""
|
||||
if (project.hasProperty("RELEASE_STORE_FILE")) {
|
||||
signingConfig signingConfigs.myConfig
|
||||
}
|
||||
applicationIdSuffix '.release'
|
||||
|
||||
minifyEnabled false
|
||||
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
|
||||
}
|
||||
debug {
|
||||
buildConfigField "String", "Cronet_Version", "\"$CronetVersion\""
|
||||
if (project.hasProperty("RELEASE_STORE_FILE")) {
|
||||
signingConfig signingConfigs.myConfig
|
||||
}
|
||||
applicationIdSuffix '.debug'
|
||||
versionNameSuffix 'debug'
|
||||
minifyEnabled false
|
||||
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
|
||||
}
|
||||
android.applicationVariants.all { variant ->
|
||||
variant.outputs.all {
|
||||
def flavor = variant.productFlavors[0].name
|
||||
outputFileName = "${name}_${flavor}_${defaultConfig.versionName}.apk"
|
||||
}
|
||||
}
|
||||
}
|
||||
flavorDimensions "mode"
|
||||
productFlavors {
|
||||
app {
|
||||
dimension "mode"
|
||||
manifestPlaceholders = [APP_CHANNEL_VALUE: "app"]
|
||||
}
|
||||
google {
|
||||
dimension "mode"
|
||||
applicationId "io.legado.play"
|
||||
manifestPlaceholders = [APP_CHANNEL_VALUE: "google"]
|
||||
}
|
||||
}
|
||||
compileOptions {
|
||||
// Flag to enable support for the new language APIs
|
||||
coreLibraryDesugaringEnabled true
|
||||
// Sets Java compatibility to Java 11
|
||||
sourceCompatibility JavaVersion.VERSION_11
|
||||
targetCompatibility JavaVersion.VERSION_11
|
||||
}
|
||||
|
||||
sourceSets {
|
||||
// Adds exported schema location as test app assets.
|
||||
androidTest.assets.srcDirs += files("$projectDir/schemas".toString())
|
||||
}
|
||||
tasks.withType(JavaCompile) {
|
||||
//options.compilerArgs << "-Xlint:unchecked"
|
||||
}
|
||||
}
|
||||
|
||||
resourcePlaceholders {
|
||||
files = ['xml/shortcuts.xml']
|
||||
}
|
||||
|
||||
kapt {
|
||||
arguments {
|
||||
arg("room.schemaLocation", "$projectDir/schemas")
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
coreLibraryDesugaring('com.android.tools:desugar_jdk_libs:1.1.5')
|
||||
testImplementation('junit:junit:4.13.2')
|
||||
androidTestImplementation('androidx.test:runner:1.4.0')
|
||||
androidTestImplementation('androidx.test.espresso:espresso-core:3.4.0')
|
||||
implementation('androidx.multidex:multidex:2.0.1')
|
||||
//kotlin
|
||||
implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version")
|
||||
//Kotlin反射
|
||||
implementation("org.jetbrains.kotlin:kotlin-reflect:$kotlin_version")
|
||||
//协程
|
||||
def coroutines_version = '1.6.0'
|
||||
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:$coroutines_version")
|
||||
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-android:$coroutines_version")
|
||||
|
||||
//androidX
|
||||
implementation('androidx.core:core-ktx:1.7.0')
|
||||
implementation('androidx.appcompat:appcompat:1.4.0')
|
||||
implementation('androidx.activity:activity-ktx:1.4.0')
|
||||
implementation('androidx.fragment:fragment-ktx:1.4.0')
|
||||
implementation('androidx.preference:preference-ktx:1.1.1')
|
||||
implementation('androidx.constraintlayout:constraintlayout:2.1.2')
|
||||
implementation('androidx.swiperefreshlayout:swiperefreshlayout:1.1.0')
|
||||
implementation('androidx.viewpager2:viewpager2:1.0.0')
|
||||
implementation('com.google.android.material:material:1.4.0')
|
||||
implementation('com.google.android.flexbox:flexbox:3.0.0')
|
||||
implementation('com.google.code.gson:gson:2.8.9')
|
||||
implementation('androidx.webkit:webkit:1.4.0')
|
||||
|
||||
implementation('com.jakewharton.timber:timber:5.0.1')
|
||||
|
||||
//media
|
||||
implementation("androidx.media:media:1.4.3")
|
||||
def exoplayer_version = '2.16.1'
|
||||
implementation("com.google.android.exoplayer:exoplayer-core:$exoplayer_version")
|
||||
implementation("com.google.android.exoplayer:extension-okhttp:$exoplayer_version")
|
||||
|
||||
//Splitties
|
||||
def splitties_version = '3.0.0'
|
||||
implementation("com.louiscad.splitties:splitties-appctx:$splitties_version")
|
||||
implementation("com.louiscad.splitties:splitties-systemservices:$splitties_version")
|
||||
implementation("com.louiscad.splitties:splitties-views:$splitties_version")
|
||||
|
||||
//lifecycle
|
||||
def lifecycle_version = '2.4.0'
|
||||
implementation("androidx.lifecycle:lifecycle-common-java8:$lifecycle_version")
|
||||
|
||||
//room
|
||||
def room_version = '2.4.0'
|
||||
implementation("androidx.room:room-runtime:$room_version")
|
||||
implementation("androidx.room:room-ktx:$room_version")
|
||||
kapt("androidx.room:room-compiler:$room_version")
|
||||
testImplementation("androidx.room:room-testing:$room_version")
|
||||
|
||||
//liveEventBus
|
||||
implementation('io.github.jeremyliao:live-event-bus-x:1.8.0')
|
||||
|
||||
//规则相关
|
||||
implementation('org.jsoup:jsoup:1.14.3')
|
||||
implementation('com.jayway.jsonpath:json-path:2.6.0')
|
||||
implementation('cn.wanghaomiao:JsoupXpath:2.5.1')
|
||||
implementation(project(path: ':epublib'))
|
||||
|
||||
//JS rhino
|
||||
implementation('com.github.gedoor:rhino-android:1.6')
|
||||
|
||||
//网络
|
||||
implementation('com.squareup.okhttp3:okhttp:4.9.3')
|
||||
implementation(fileTree(dir: 'cronetlib', include: ['*.jar', '*.aar']))
|
||||
|
||||
//Glide
|
||||
implementation('com.github.bumptech.glide:glide:4.12.0')
|
||||
kapt('com.github.bumptech.glide:compiler:4.12.0')
|
||||
|
||||
//webServer
|
||||
def nanoHttpdVersion = "2.3.1"
|
||||
implementation("org.nanohttpd:nanohttpd:$nanoHttpdVersion")
|
||||
implementation("org.nanohttpd:nanohttpd-websocket:$nanoHttpdVersion")
|
||||
|
||||
//二维码
|
||||
implementation('com.github.jenly1314:zxing-lite:2.1.1')
|
||||
|
||||
//颜色选择
|
||||
implementation('com.jaredrummler:colorpicker:1.1.0')
|
||||
|
||||
//apache
|
||||
implementation('org.apache.commons:commons-text:1.9')
|
||||
|
||||
//MarkDown
|
||||
def markwonVersion = "4.6.2"
|
||||
implementation("io.noties.markwon:core:$markwonVersion")
|
||||
implementation("io.noties.markwon:image-glide:$markwonVersion")
|
||||
implementation("io.noties.markwon:ext-tables:$markwonVersion")
|
||||
implementation("io.noties.markwon:html:$markwonVersion")
|
||||
|
||||
//转换繁体
|
||||
implementation('com.github.liuyueyi.quick-chinese-transfer:quick-transfer-core:0.2.3')
|
||||
|
||||
//代码编辑com.github.AmrDeveloper:CodeView已集成到应用内
|
||||
//epubLib集成到应用内
|
||||
|
||||
// LeakCanary
|
||||
//debugImplementation 'com.squareup.leakcanary:leakcanary-android:2.7'
|
||||
}
|
BIN
app/cronetlib/cronet_api.jar
Normal file
BIN
app/cronetlib/cronet_impl_common_java.jar
Normal file
BIN
app/cronetlib/cronet_impl_native_java.jar
Normal file
BIN
app/cronetlib/cronet_impl_platform_java.jar
Normal file
110
app/download.gradle
Normal file
@ -0,0 +1,110 @@
|
||||
import java.security.MessageDigest
|
||||
|
||||
apply plugin: 'de.undercouch.download'
|
||||
|
||||
def BASE_PATH = "https://storage.googleapis.com/chromium-cronet/android/" + CronetVersion + "/Release/cronet/"
|
||||
def assetsDir = projectDir.toString() + "/src/main/assets"
|
||||
def libPath = projectDir.toString() + "/cronetlib"
|
||||
def soPath = projectDir.toString() + "/so"
|
||||
|
||||
/**
|
||||
* 从文件生成MD5
|
||||
* @param file
|
||||
* @return
|
||||
*/
|
||||
static def generateMD5(final file) {
|
||||
MessageDigest digest = MessageDigest.getInstance("MD5")
|
||||
file.withInputStream() { is ->
|
||||
byte[] buffer = new byte[1024]
|
||||
int numRead = 0
|
||||
while ((numRead = is.read(buffer)) > 0) {
|
||||
digest.update(buffer, 0, numRead)
|
||||
}
|
||||
}
|
||||
return String.format("%032x", new BigInteger(1, digest.digest())).toLowerCase()
|
||||
}
|
||||
|
||||
/**
|
||||
* 下载Cronet相关的jar
|
||||
*/
|
||||
task downloadJar(type: Download) {
|
||||
src([
|
||||
BASE_PATH + "cronet_api.jar",
|
||||
BASE_PATH + "cronet_impl_common_java.jar",
|
||||
BASE_PATH + "cronet_impl_native_java.jar",
|
||||
BASE_PATH + "cronet_impl_platform_java.jar",
|
||||
])
|
||||
dest libPath
|
||||
overwrite true
|
||||
onlyIfModified true
|
||||
}
|
||||
/**
|
||||
* 下载Cronet的arm64-v8a so
|
||||
*/
|
||||
task downloadARM64(type: Download) {
|
||||
src BASE_PATH + "libs/arm64-v8a/libcronet." + CronetVersion + ".so"
|
||||
dest soPath + "/arm64-v8a.so"
|
||||
overwrite true
|
||||
onlyIfModified true
|
||||
}
|
||||
/**
|
||||
* 下载Cronet的armeabi-v7a so
|
||||
*/
|
||||
task downloadARMv7(type: Download) {
|
||||
src BASE_PATH + "libs/armeabi-v7a/libcronet." + CronetVersion + ".so"
|
||||
dest soPath + "/armeabi-v7a.so"
|
||||
overwrite true
|
||||
onlyIfModified true
|
||||
}
|
||||
/**
|
||||
* 下载Cronet的x86_64 so
|
||||
*/
|
||||
task downloadX86_64(type: Download) {
|
||||
src BASE_PATH + "libs/x86_64/libcronet." + CronetVersion + ".so"
|
||||
dest soPath + "/x86_64.so"
|
||||
overwrite true
|
||||
onlyIfModified true
|
||||
}
|
||||
/**
|
||||
* 下载Cronet的x86 so
|
||||
*/
|
||||
task downloadX86(type: Download) {
|
||||
src BASE_PATH + "libs/x86/libcronet." + CronetVersion + ".so"
|
||||
dest soPath + "/x86.so"
|
||||
overwrite true
|
||||
onlyIfModified true
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新Cronet版本时执行这个task
|
||||
* 先更改gradle.properties 里面的版本号,然后再执行
|
||||
* gradlew app:downloadCronet
|
||||
*/
|
||||
task downloadCronet() {
|
||||
dependsOn downloadJar, downloadARM64, downloadARMv7, downloadX86_64, downloadX86
|
||||
|
||||
doLast {
|
||||
StringBuilder sb = new StringBuilder("{")
|
||||
def files = new File(soPath).listFiles()
|
||||
for (File file : files) {
|
||||
println file.name.replace(".so", "")
|
||||
sb.append("\"").append(file.name.replace(".so", "")).append("\":\"").append(generateMD5(file)).append("\",")
|
||||
}
|
||||
sb.append("\"version\":\"").append(CronetVersion).append("\"}")
|
||||
|
||||
println sb.toString()
|
||||
|
||||
println assetsDir
|
||||
def f1 = new File(assetsDir + "/cronet.json")
|
||||
if (!f1.exists()) {
|
||||
f1.parentFile.mkdirs()
|
||||
f1.createNewFile()
|
||||
}
|
||||
f1.text = sb.toString()
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
151
app/google-services.json
Normal file
@ -0,0 +1,151 @@
|
||||
{
|
||||
"project_info": {
|
||||
"project_number": "453392274790",
|
||||
"firebase_url": "https://legado-fca69.firebaseio.com",
|
||||
"project_id": "legado-fca69",
|
||||
"storage_bucket": "legado-fca69.appspot.com"
|
||||
},
|
||||
"client": [
|
||||
{
|
||||
"client_info": {
|
||||
"mobilesdk_app_id": "1:453392274790:android:c4eac14b1410eec5f624a7",
|
||||
"android_client_info": {
|
||||
"package_name": "io.legado.app.debug"
|
||||
}
|
||||
},
|
||||
"oauth_client": [
|
||||
{
|
||||
"client_id": "453392274790-hnbpatpce9hbjiggj76hgo7queu86atq.apps.googleusercontent.com",
|
||||
"client_type": 3
|
||||
}
|
||||
],
|
||||
"api_key": [
|
||||
{
|
||||
"current_key": "AIzaSyD90mfNLhA7cAzzI9SonpSz5mrF5BnmyJA"
|
||||
}
|
||||
],
|
||||
"services": {
|
||||
"appinvite_service": {
|
||||
"other_platform_oauth_client": [
|
||||
{
|
||||
"client_id": "453392274790-hnbpatpce9hbjiggj76hgo7queu86atq.apps.googleusercontent.com",
|
||||
"client_type": 3
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"client_info": {
|
||||
"mobilesdk_app_id": "1:453392274790:android:c1481c1c3d3f51eff624a7",
|
||||
"android_client_info": {
|
||||
"package_name": "io.legado.app.release"
|
||||
}
|
||||
},
|
||||
"oauth_client": [
|
||||
{
|
||||
"client_id": "453392274790-trrgennt5njr1lhil1sgtf0ogcgd38fo.apps.googleusercontent.com",
|
||||
"client_type": 1,
|
||||
"android_info": {
|
||||
"package_name": "io.legado.app.release",
|
||||
"certificate_hash": "fd67dba87b7b761631266f19ddde249054aac5c1"
|
||||
}
|
||||
},
|
||||
{
|
||||
"client_id": "453392274790-hnbpatpce9hbjiggj76hgo7queu86atq.apps.googleusercontent.com",
|
||||
"client_type": 3
|
||||
}
|
||||
],
|
||||
"api_key": [
|
||||
{
|
||||
"current_key": "AIzaSyD90mfNLhA7cAzzI9SonpSz5mrF5BnmyJA"
|
||||
}
|
||||
],
|
||||
"services": {
|
||||
"appinvite_service": {
|
||||
"other_platform_oauth_client": [
|
||||
{
|
||||
"client_id": "453392274790-hnbpatpce9hbjiggj76hgo7queu86atq.apps.googleusercontent.com",
|
||||
"client_type": 3
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"client_info": {
|
||||
"mobilesdk_app_id": "1:453392274790:android:b891abd2331577dff624a7",
|
||||
"android_client_info": {
|
||||
"package_name": "io.legado.play.release"
|
||||
}
|
||||
},
|
||||
"oauth_client": [
|
||||
{
|
||||
"client_id": "453392274790-f8sjn6ohs72rg1dvp0pdvk42nkq54p0k.apps.googleusercontent.com",
|
||||
"client_type": 1,
|
||||
"android_info": {
|
||||
"package_name": "io.legado.play.release",
|
||||
"certificate_hash": "00819ace9891386e535967cbafd6a88f3797bd5b"
|
||||
}
|
||||
},
|
||||
{
|
||||
"client_id": "453392274790-hnbpatpce9hbjiggj76hgo7queu86atq.apps.googleusercontent.com",
|
||||
"client_type": 3
|
||||
}
|
||||
],
|
||||
"api_key": [
|
||||
{
|
||||
"current_key": "AIzaSyD90mfNLhA7cAzzI9SonpSz5mrF5BnmyJA"
|
||||
}
|
||||
],
|
||||
"services": {
|
||||
"appinvite_service": {
|
||||
"other_platform_oauth_client": [
|
||||
{
|
||||
"client_id": "453392274790-hnbpatpce9hbjiggj76hgo7queu86atq.apps.googleusercontent.com",
|
||||
"client_type": 3
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"client_info": {
|
||||
"mobilesdk_app_id": "1:453392274790:android:b891abd2331577dff624a7",
|
||||
"android_client_info": {
|
||||
"package_name": "io.legado.play.debug"
|
||||
}
|
||||
},
|
||||
"oauth_client": [
|
||||
{
|
||||
"client_id": "453392274790-f8sjn6ohs72rg1dvp0pdvk42nkq54p0k.apps.googleusercontent.com",
|
||||
"client_type": 1,
|
||||
"android_info": {
|
||||
"package_name": "io.legado.play.debug",
|
||||
"certificate_hash": "00819ace9891386e535967cbafd6a88f3797bd5b"
|
||||
}
|
||||
},
|
||||
{
|
||||
"client_id": "453392274790-hnbpatpce9hbjiggj76hgo7queu86atq.apps.googleusercontent.com",
|
||||
"client_type": 3
|
||||
}
|
||||
],
|
||||
"api_key": [
|
||||
{
|
||||
"current_key": "AIzaSyD90mfNLhA7cAzzI9SonpSz5mrF5BnmyJA"
|
||||
}
|
||||
],
|
||||
"services": {
|
||||
"appinvite_service": {
|
||||
"other_platform_oauth_client": [
|
||||
{
|
||||
"client_id": "453392274790-hnbpatpce9hbjiggj76hgo7queu86atq.apps.googleusercontent.com",
|
||||
"client_type": 3
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"configuration_version": "1"
|
||||
}
|
231
app/proguard-rules.pro
vendored
Normal file
@ -0,0 +1,231 @@
|
||||
# Add project specific ProGuard rules here.
|
||||
# You can control the set of applied configuration files using the
|
||||
# proguardFiles setting in build.gradle.
|
||||
#
|
||||
# For more details, see
|
||||
# http://developer.android.com/guide/developing/tools/proguard.html
|
||||
|
||||
# If your project uses WebView with JS, uncomment the following
|
||||
# and specify the fully qualified class name to the JavaScript interface
|
||||
# class:
|
||||
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
|
||||
# public *;
|
||||
#}
|
||||
|
||||
# Uncomment this to preserve the line number information for
|
||||
# debugging stack traces.
|
||||
#-keepattributes SourceFile,LineNumberTable
|
||||
|
||||
# If you keep the line number information, uncomment this to
|
||||
# hide the original source file name.
|
||||
#-renamesourcefileattribute SourceFile
|
||||
# 混合时不使用大小写混合,混合后的类名为小写
|
||||
-dontusemixedcaseclassnames
|
||||
|
||||
# 指定不去忽略非公共库的类
|
||||
-dontskipnonpubliclibraryclasses
|
||||
|
||||
# 这句话能够使我们的项目混淆后产生映射文件
|
||||
# 包含有类名->混淆后类名的映射关系
|
||||
-verbose
|
||||
|
||||
# 指定不去忽略非公共库的类成员
|
||||
-dontskipnonpubliclibraryclassmembers
|
||||
|
||||
# 不做预校验,preverify是proguard的四个步骤之一,Android不需要preverify,去掉这一步能够加快混淆速度。
|
||||
-dontpreverify
|
||||
|
||||
# 保留Annotation不混淆
|
||||
-keepattributes *Annotation*,InnerClasses
|
||||
|
||||
# 避免混淆泛型
|
||||
-keepattributes Signature
|
||||
|
||||
# 抛出异常时保留代码行号
|
||||
-keepattributes SourceFile,LineNumberTable
|
||||
|
||||
# 指定混淆是采用的算法,后面的参数是一个过滤器
|
||||
# 这个过滤器是谷歌推荐的算法,一般不做更改
|
||||
-optimizations !code/simplification/cast,!field/*,!class/merging/*
|
||||
|
||||
|
||||
#############################################
|
||||
#
|
||||
# Android开发中一些需要保留的公共部分
|
||||
#
|
||||
#############################################
|
||||
# 屏蔽错误Unresolved class name
|
||||
#noinspection ShrinkerUnresolvedReference
|
||||
|
||||
# 保留我们使用的四大组件,自定义的Application等等这些类不被混淆
|
||||
# 因为这些子类都有可能被外部调用
|
||||
-keep public class * extends android.app.Activity
|
||||
-keep public class * extends android.app.Application
|
||||
-keep public class * extends android.app.Service
|
||||
-keep public class * extends android.content.BroadcastReceiver
|
||||
-keep public class * extends android.content.ContentProvider
|
||||
-keep public class * extends android.app.backup.BackupAgentHelper
|
||||
-keep public class * extends android.preference.Preference
|
||||
-keep public class * extends android.view.View
|
||||
|
||||
# 保留androidx下的所有类及其内部类
|
||||
-keep class androidx.** {*;}
|
||||
|
||||
# 保留继承的
|
||||
-keep public class * extends androidx.**
|
||||
|
||||
# 保留R下面的资源
|
||||
-keep class **.R$* {*;}
|
||||
|
||||
# 保留本地native方法不被混淆
|
||||
-keepclasseswithmembernames class * {
|
||||
native <methods>;
|
||||
}
|
||||
|
||||
# 保留在Activity中的方法参数是view的方法,
|
||||
# 这样以来我们在layout中写的onClick就不会被影响
|
||||
-keepclassmembers class * extends android.app.Activity{
|
||||
public void *(android.view.View);
|
||||
}
|
||||
|
||||
# 保留枚举类不被混淆
|
||||
-keepclassmembers enum * {
|
||||
public static **[] values();
|
||||
public static ** valueOf(java.lang.String);
|
||||
}
|
||||
|
||||
# 保留我们自定义控件(继承自View)不被混淆
|
||||
-keep public class * extends android.view.View{
|
||||
*** get*();
|
||||
void set*(***);
|
||||
public <init>(android.content.Context);
|
||||
public <init>(android.content.Context, android.util.AttributeSet);
|
||||
public <init>(android.content.Context, android.util.AttributeSet, int);
|
||||
}
|
||||
|
||||
# 保留Parcelable序列化类不被混淆
|
||||
-keep class * implements android.os.Parcelable {
|
||||
public static final android.os.Parcelable$Creator *;
|
||||
}
|
||||
|
||||
# 保留Serializable序列化的类不被混淆
|
||||
-keepclassmembers class * implements java.io.Serializable {
|
||||
static final long serialVersionUID;
|
||||
private static final java.io.ObjectStreamField[] serialPersistentFields;
|
||||
!static !transient <fields>;
|
||||
!private <fields>;
|
||||
!private <methods>;
|
||||
private void writeObject(java.io.ObjectOutputStream);
|
||||
private void readObject(java.io.ObjectInputStream);
|
||||
java.lang.Object writeReplace();
|
||||
java.lang.Object readResolve();
|
||||
}
|
||||
|
||||
# 对于带有回调函数的onXXEvent、**On*Listener的,不能被混淆
|
||||
-keepclassmembers class * {
|
||||
void *(**On*Event);
|
||||
void *(**On*Listener);
|
||||
}
|
||||
|
||||
# webView处理,项目中没有使用到webView忽略即可
|
||||
-keepclassmembers class * extends android.webkit.WebViewClient {
|
||||
public void *(android.webkit.WebView, java.lang.String);
|
||||
public void *(android.webkit.WebView, java.lang.String, android.graphics.Bitmap);
|
||||
public boolean *(android.webkit.WebView, java.lang.String);
|
||||
}
|
||||
|
||||
# 移除Log类打印各个等级日志的代码,打正式包的时候可以做为禁log使用,这里可以作为禁止log打印的功能使用
|
||||
# 记得proguard-android.txt中一定不要加-dontoptimize才起作用
|
||||
# 另外的一种实现方案是通过BuildConfig.DEBUG的变量来控制
|
||||
-assumenosideeffects class android.util.Log {
|
||||
public static int v(...);
|
||||
public static int i(...);
|
||||
public static int w(...);
|
||||
public static int d(...);
|
||||
public static int e(...);
|
||||
}
|
||||
|
||||
# 保持js引擎调用的java类
|
||||
-keep class **.analyzeRule.**{*;}
|
||||
# 保持web类
|
||||
-keep class **.web.**{*;}
|
||||
#数据类
|
||||
-keep class **.data.**{*;}
|
||||
|
||||
-dontwarn rx.**
|
||||
-dontwarn okio.**
|
||||
-dontwarn javax.annotation.**
|
||||
-dontwarn org.apache.log4j.lf5.viewer.**
|
||||
-dontnote org.apache.log4j.lf5.viewer.**
|
||||
-dontwarn freemarker.**
|
||||
-dontnote org.python.core.**
|
||||
-dontwarn com.hwangjr.rxbus.**
|
||||
-dontwarn okhttp3.**
|
||||
-dontwarn org.conscrypt.**
|
||||
-dontwarn com.jeremyliao.liveeventbus.**
|
||||
|
||||
-keep class com.google.gson.** { *; }
|
||||
-keep class com.ke.gson.** { *; }
|
||||
-keep class com.jeremyliao.liveeventbus.** { *; }
|
||||
-keep class okhttp3.**{*;}
|
||||
-keep class okio.**{*;}
|
||||
-keep class com.hwangjr.rxbus.**{*;}
|
||||
-keep class org.conscrypt.**{*;}
|
||||
-keep class android.support.**{*;}
|
||||
-keep class me.grantland.widget.**{*;}
|
||||
-keep class de.hdodenhof.circleimageview.**{*;}
|
||||
-keep class tyrant.explosionfield.**{*;}
|
||||
-keep class tyrantgit.explosionfield.**{*;}
|
||||
-keep class freemarker.**{*;}
|
||||
-keep class com.gyf.barlibrary.** {*;}
|
||||
##JSOUP
|
||||
-keep class org.jsoup.**{*;}
|
||||
-keep class **.xpath.**{*;}
|
||||
|
||||
-keep class org.slf4j.**{*;}
|
||||
-dontwarn org.slf4j.**
|
||||
|
||||
-keep class org.codehaus.**{*;}
|
||||
-dontwarn org.codehaus.**
|
||||
-keep class com.jayway.**{*;}
|
||||
-dontwarn com.jayway.**
|
||||
-keep class com.fasterxml.**{*;}
|
||||
|
||||
-keep class javax.swing.**{*;}
|
||||
-dontwarn javax.swing.**
|
||||
-keep class java.awt.**{*;}
|
||||
-dontwarn java.awt.**
|
||||
-keep class sun.misc.**{*;}
|
||||
-dontwarn sun.misc.**
|
||||
-keep class sun.reflect.**{*;}
|
||||
-dontwarn sun.reflect.**
|
||||
|
||||
## Rhino
|
||||
-keep class javax.script.** { *; }
|
||||
-keep class com.sun.script.javascript.** { *; }
|
||||
-keep class org.mozilla.javascript.** { *; }
|
||||
|
||||
###EPUB
|
||||
-dontwarn nl.siegmann.epublib.**
|
||||
-dontwarn org.xmlpull.**
|
||||
-keep class nl.siegmann.epublib.**{*;}
|
||||
-keep class javax.xml.**{*;}
|
||||
-keep class org.xmlpull.**{*;}
|
||||
|
||||
-keep class org.simpleframework.**{*;}
|
||||
-dontwarn org.simpleframework.xml.**
|
||||
|
||||
-keepclassmembers class * {
|
||||
public <init> (org.json.JSONObject);
|
||||
}
|
||||
-keepclassmembers enum * {
|
||||
public static **[] values();
|
||||
public static ** valueOf(java.lang.String);
|
||||
}
|
||||
|
||||
|
||||
# Keep all of Cronet API as it's used by the Cronet module.
|
||||
-keep public class org.chromium.net.* {
|
||||
!private *;
|
||||
*;
|
||||
}
|
1022
app/schemas/io.legado.app.data.AppDatabase/1.json
Normal file
1176
app/schemas/io.legado.app.data.AppDatabase/10.json
Normal file
1182
app/schemas/io.legado.app.data.AppDatabase/11.json
Normal file
1188
app/schemas/io.legado.app.data.AppDatabase/12.json
Normal file
1194
app/schemas/io.legado.app.data.AppDatabase/13.json
Normal file
1194
app/schemas/io.legado.app.data.AppDatabase/14.json
Normal file
1200
app/schemas/io.legado.app.data.AppDatabase/15.json
Normal file
1226
app/schemas/io.legado.app.data.AppDatabase/16.json
Normal file
1226
app/schemas/io.legado.app.data.AppDatabase/17.json
Normal file
1258
app/schemas/io.legado.app.data.AppDatabase/18.json
Normal file
1265
app/schemas/io.legado.app.data.AppDatabase/19.json
Normal file
1028
app/schemas/io.legado.app.data.AppDatabase/2.json
Normal file
1271
app/schemas/io.legado.app.data.AppDatabase/20.json
Normal file
1283
app/schemas/io.legado.app.data.AppDatabase/21.json
Normal file
1277
app/schemas/io.legado.app.data.AppDatabase/22.json
Normal file
1283
app/schemas/io.legado.app.data.AppDatabase/23.json
Normal file
1324
app/schemas/io.legado.app.data.AppDatabase/24.json
Normal file
1368
app/schemas/io.legado.app.data.AppDatabase/25.json
Normal file
1392
app/schemas/io.legado.app.data.AppDatabase/26.json
Normal file
1392
app/schemas/io.legado.app.data.AppDatabase/27.json
Normal file
1404
app/schemas/io.legado.app.data.AppDatabase/28.json
Normal file
1410
app/schemas/io.legado.app.data.AppDatabase/29.json
Normal file
1036
app/schemas/io.legado.app.data.AppDatabase/3.json
Normal file
1485
app/schemas/io.legado.app.data.AppDatabase/30.json
Normal file
1422
app/schemas/io.legado.app.data.AppDatabase/31.json
Normal file
1422
app/schemas/io.legado.app.data.AppDatabase/32.json
Normal file
1417
app/schemas/io.legado.app.data.AppDatabase/33.json
Normal file
1423
app/schemas/io.legado.app.data.AppDatabase/34.json
Normal file
1441
app/schemas/io.legado.app.data.AppDatabase/35.json
Normal file
1441
app/schemas/io.legado.app.data.AppDatabase/36.json
Normal file
1459
app/schemas/io.legado.app.data.AppDatabase/37.json
Normal file
1465
app/schemas/io.legado.app.data.AppDatabase/38.json
Normal file
1471
app/schemas/io.legado.app.data.AppDatabase/39.json
Normal file
1093
app/schemas/io.legado.app.data.AppDatabase/4.json
Normal file
1483
app/schemas/io.legado.app.data.AppDatabase/40.json
Normal file
1513
app/schemas/io.legado.app.data.AppDatabase/41.json
Normal file
1519
app/schemas/io.legado.app.data.AppDatabase/42.json
Normal file
1093
app/schemas/io.legado.app.data.AppDatabase/5.json
Normal file
1131
app/schemas/io.legado.app.data.AppDatabase/6.json
Normal file
1131
app/schemas/io.legado.app.data.AppDatabase/7.json
Normal file
1157
app/schemas/io.legado.app.data.AppDatabase/8.json
Normal file
1164
app/schemas/io.legado.app.data.AppDatabase/9.json
Normal file
@ -0,0 +1,26 @@
|
||||
package io.legado.app
|
||||
|
||||
import android.net.Uri
|
||||
import android.util.Log
|
||||
import androidx.test.InstrumentationRegistry
|
||||
import androidx.test.runner.AndroidJUnit4
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
|
||||
/**
|
||||
* Instrumented test, which will execute on an Android device.
|
||||
*
|
||||
* See [testing documentation](http://d.android.com/tools/testing).
|
||||
*/
|
||||
@RunWith(AndroidJUnit4::class)
|
||||
class ExampleInstrumentedTest {
|
||||
@Test
|
||||
fun testContentProvider() {
|
||||
// Context of the app under test.
|
||||
val appContext = InstrumentationRegistry.getTargetContext()
|
||||
Log.d("test",
|
||||
appContext.contentResolver.query(Uri.parse("content://io.legado.app.api.ReaderProvider/sources/query"),null,null,null,null)
|
||||
!!.getString(0)
|
||||
)
|
||||
}
|
||||
}
|
50
app/src/androidTest/java/io/legado/app/MigrationTest.kt
Normal file
@ -0,0 +1,50 @@
|
||||
package io.legado.app
|
||||
|
||||
import androidx.room.Room
|
||||
import androidx.room.migration.Migration
|
||||
import androidx.room.testing.MigrationTestHelper
|
||||
import androidx.sqlite.db.framework.FrameworkSQLiteOpenHelperFactory
|
||||
import androidx.test.platform.app.InstrumentationRegistry
|
||||
import androidx.test.runner.AndroidJUnit4
|
||||
import io.legado.app.data.AppDatabase
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
import java.io.IOException
|
||||
|
||||
@RunWith(AndroidJUnit4::class)
|
||||
class MigrationTest {
|
||||
private val TEST_DB = "migration-test"
|
||||
|
||||
private val ALL_MIGRATIONS = arrayOf<Migration>(
|
||||
|
||||
)
|
||||
|
||||
@Rule
|
||||
val helper: MigrationTestHelper = MigrationTestHelper(
|
||||
InstrumentationRegistry.getInstrumentation(),
|
||||
AppDatabase::class.java.canonicalName,
|
||||
FrameworkSQLiteOpenHelperFactory()
|
||||
)
|
||||
|
||||
@Test
|
||||
@Throws(IOException::class)
|
||||
fun migrateAll() {
|
||||
// Create earliest version of the database.
|
||||
helper.createDatabase(TEST_DB, 30).apply {
|
||||
close()
|
||||
}
|
||||
|
||||
// Open latest version of the database. Room will validate the schema
|
||||
// once all migrations execute.
|
||||
Room.databaseBuilder(
|
||||
InstrumentationRegistry.getInstrumentation().targetContext,
|
||||
AppDatabase::class.java,
|
||||
TEST_DB
|
||||
).addMigrations(*ALL_MIGRATIONS)
|
||||
.build().apply {
|
||||
openHelper.writableDatabase
|
||||
close()
|
||||
}
|
||||
}
|
||||
}
|
4
app/src/debug/res/values-zh/strings.xml
Normal file
@ -0,0 +1,4 @@
|
||||
<resources>
|
||||
<string name="app_name">阅读·D</string>
|
||||
<string name="receiving_shared_label">阅读·D·搜索</string>
|
||||
</resources>
|
4
app/src/debug/res/values/strings.xml
Normal file
@ -0,0 +1,4 @@
|
||||
<resources>
|
||||
<string name="app_name">legado·D</string>
|
||||
<string name="receiving_shared_label">legado·D·search</string>
|
||||
</resources>
|
6
app/src/google/res/values-zh-rCN/strings.xml
Normal file
@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
|
||||
<string name="app_name">阅读Pro</string>
|
||||
|
||||
</resources>
|
6
app/src/google/res/values-zh-rHK/strings.xml
Normal file
@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
|
||||
<string name="app_name">閱讀Pro</string>
|
||||
|
||||
</resources>
|
6
app/src/google/res/values-zh-rTW/strings.xml
Normal file
@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
|
||||
<string name="app_name">閱讀Pro</string>
|
||||
|
||||
</resources>
|
6
app/src/google/res/values/strings.xml
Normal file
@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
|
||||
<string name="app_name">legadoPro</string>
|
||||
|
||||
</resources>
|
465
app/src/main/AndroidManifest.xml
Normal file
@ -0,0 +1,465 @@
|
||||
<?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="io.legado.app">
|
||||
|
||||
<uses-permission android:name="android.permission.INTERNET" />
|
||||
<uses-permission android:name="android.permission.ACCESS_MEDIA_LOCATION" />
|
||||
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
|
||||
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
|
||||
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
|
||||
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />
|
||||
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
|
||||
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
|
||||
<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" />
|
||||
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
|
||||
<uses-permission android:name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS" />
|
||||
<uses-permission android:name="android.permission.DOWNLOAD_WITHOUT_NOTIFICATION" />
|
||||
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
|
||||
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
|
||||
<uses-permission
|
||||
android:name="android.permission.WRITE_EXTERNAL_STORAGE"
|
||||
tools:ignore="ScopedStorage" />
|
||||
|
||||
<application
|
||||
android:name=".App"
|
||||
android:allowBackup="true"
|
||||
android:icon="@mipmap/ic_launcher"
|
||||
android:label="@string/app_name"
|
||||
android:networkSecurityConfig="@xml/network_security_config"
|
||||
android:requestLegacyExternalStorage="true"
|
||||
android:supportsRtl="true"
|
||||
android:theme="@style/AppTheme.Light"
|
||||
tools:ignore="AllowBackup,GoogleAppIndexingWarning,UnusedAttribute">
|
||||
<!-- 主入口 -->
|
||||
<activity
|
||||
android:name=".ui.welcome.WelcomeActivity"
|
||||
android:exported="true">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
|
||||
<category android:name="android.intent.category.LAUNCHER" />
|
||||
</intent-filter>
|
||||
|
||||
<meta-data
|
||||
android:name="android.app.shortcuts"
|
||||
android:launchMode="singleTask"
|
||||
android:resource="@xml/shortcuts" />
|
||||
</activity>
|
||||
<!-- 图标1 -->
|
||||
<activity
|
||||
android:name=".ui.welcome.Launcher1"
|
||||
android:enabled="false"
|
||||
android:exported="true"
|
||||
android:icon="@mipmap/launcher1">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
|
||||
<category android:name="android.intent.category.LAUNCHER" />
|
||||
</intent-filter>
|
||||
|
||||
<meta-data
|
||||
android:name="android.app.shortcuts"
|
||||
android:launchMode="singleTask"
|
||||
android:resource="@xml/shortcuts" />
|
||||
</activity>
|
||||
<!-- 图标2 -->
|
||||
<activity
|
||||
android:name=".ui.welcome.Launcher2"
|
||||
android:enabled="false"
|
||||
android:exported="true"
|
||||
android:icon="@mipmap/launcher2">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
|
||||
<category android:name="android.intent.category.LAUNCHER" />
|
||||
</intent-filter>
|
||||
|
||||
<meta-data
|
||||
android:name="android.app.shortcuts"
|
||||
android:launchMode="singleTask"
|
||||
android:resource="@xml/shortcuts" />
|
||||
</activity>
|
||||
<!-- 图标3 -->
|
||||
<activity
|
||||
android:name=".ui.welcome.Launcher3"
|
||||
android:enabled="false"
|
||||
android:exported="true"
|
||||
android:icon="@mipmap/launcher3">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
|
||||
<category android:name="android.intent.category.LAUNCHER" />
|
||||
</intent-filter>
|
||||
|
||||
<meta-data
|
||||
android:name="android.app.shortcuts"
|
||||
android:launchMode="singleTask"
|
||||
android:resource="@xml/shortcuts" />
|
||||
</activity>
|
||||
<!-- 图标4 -->
|
||||
<activity
|
||||
android:name=".ui.welcome.Launcher4"
|
||||
android:enabled="false"
|
||||
android:exported="true"
|
||||
android:icon="@mipmap/launcher4">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
|
||||
<category android:name="android.intent.category.LAUNCHER" />
|
||||
</intent-filter>
|
||||
|
||||
<meta-data
|
||||
android:name="android.app.shortcuts"
|
||||
android:launchMode="singleTask"
|
||||
android:resource="@xml/shortcuts" />
|
||||
</activity>
|
||||
<!-- 图标5 -->
|
||||
<activity
|
||||
android:name=".ui.welcome.Launcher5"
|
||||
android:enabled="false"
|
||||
android:exported="true"
|
||||
android:icon="@mipmap/launcher5">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
|
||||
<category android:name="android.intent.category.LAUNCHER" />
|
||||
</intent-filter>
|
||||
|
||||
<meta-data
|
||||
android:name="android.app.shortcuts"
|
||||
android:launchMode="singleTask"
|
||||
android:resource="@xml/shortcuts" />
|
||||
</activity>
|
||||
<!-- 图标6 -->
|
||||
<activity
|
||||
android:name=".ui.welcome.Launcher6"
|
||||
android:enabled="false"
|
||||
android:exported="true"
|
||||
android:icon="@mipmap/launcher6">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
|
||||
<category android:name="android.intent.category.LAUNCHER" />
|
||||
</intent-filter>
|
||||
|
||||
<meta-data
|
||||
android:name="android.app.shortcuts"
|
||||
android:launchMode="singleTask"
|
||||
android:resource="@xml/shortcuts" />
|
||||
</activity>
|
||||
<!-- 主界面 -->
|
||||
<activity
|
||||
android:name=".ui.main.MainActivity"
|
||||
android:alwaysRetainTaskState="true"
|
||||
android:launchMode="singleTask" />
|
||||
<!-- 阅读界面 -->
|
||||
<activity
|
||||
android:name=".ui.book.read.ReadBookActivity"
|
||||
android:configChanges="locale|keyboardHidden|orientation|screenSize|smallestScreenSize|screenLayout"
|
||||
android:exported="true"
|
||||
android:launchMode="singleTask">
|
||||
<intent-filter>
|
||||
<action android:name="com.samsung.android.support.REMOTE_ACTION" />
|
||||
</intent-filter>
|
||||
|
||||
<meta-data
|
||||
android:name="com.samsung.android.support.REMOTE_ACTION"
|
||||
android:resource="@xml/spen_remote_actions" />
|
||||
</activity>
|
||||
<!-- 书籍详情页 -->
|
||||
<activity
|
||||
android:name=".ui.book.info.BookInfoActivity"
|
||||
android:launchMode="singleTop" />
|
||||
<!-- 书籍信息编辑 -->
|
||||
<activity
|
||||
android:name=".ui.book.info.edit.BookInfoEditActivity"
|
||||
android:launchMode="singleTask" />
|
||||
<!-- 音频播放界面 -->
|
||||
<activity
|
||||
android:name="io.legado.app.ui.book.audio.AudioPlayActivity"
|
||||
android:launchMode="singleTask" />
|
||||
<!-- 授权界面 -->
|
||||
<activity
|
||||
android:name="io.legado.app.lib.permission.PermissionActivity"
|
||||
android:theme="@style/Activity.Permission" />
|
||||
<!-- 二维码扫描 -->
|
||||
<activity
|
||||
android:name=".ui.qrcode.QrCodeActivity"
|
||||
android:launchMode="singleTask" />
|
||||
<!-- 规则订阅 -->
|
||||
<activity
|
||||
android:name=".ui.rss.subscription.RuleSubActivity"
|
||||
android:launchMode="singleTask" />
|
||||
<!-- 书源编辑 -->
|
||||
<activity
|
||||
android:name=".ui.book.source.edit.BookSourceEditActivity"
|
||||
android:configChanges="locale|keyboardHidden|orientation|screenSize|smallestScreenSize|screenLayout"
|
||||
android:launchMode="singleTask"
|
||||
android:windowSoftInputMode="adjustResize|stateHidden" />
|
||||
<!-- 订阅源编辑 -->
|
||||
<activity
|
||||
android:name=".ui.rss.source.edit.RssSourceEditActivity"
|
||||
android:configChanges="locale|keyboardHidden|orientation|screenSize|smallestScreenSize|screenLayout"
|
||||
android:launchMode="singleTask"
|
||||
android:windowSoftInputMode="adjustResize|stateHidden" />
|
||||
<!-- 书源编辑 -->
|
||||
<activity
|
||||
android:name=".ui.replace.edit.ReplaceEditActivity"
|
||||
android:configChanges="locale|keyboardHidden|orientation|screenSize|smallestScreenSize|screenLayout"
|
||||
android:launchMode="singleTask"
|
||||
android:windowSoftInputMode="adjustResize|stateHidden" />
|
||||
<!-- 配置界面 -->
|
||||
<activity
|
||||
android:name=".ui.config.ConfigActivity"
|
||||
android:launchMode="singleTask" />
|
||||
<!-- 搜索界面 -->
|
||||
<activity
|
||||
android:name=".ui.book.search.SearchActivity"
|
||||
android:launchMode="standard" />
|
||||
<!-- 关于界面 -->
|
||||
<activity
|
||||
android:name=".ui.about.AboutActivity"
|
||||
android:launchMode="singleTask"
|
||||
android:screenOrientation="behind" />
|
||||
<!-- 捐赠界面 -->
|
||||
<activity
|
||||
android:name=".ui.about.DonateActivity"
|
||||
android:launchMode="singleTask"
|
||||
android:screenOrientation="behind" />
|
||||
<!-- 书源管理 -->
|
||||
<activity
|
||||
android:name=".ui.book.source.manage.BookSourceActivity"
|
||||
android:launchMode="singleTop"
|
||||
android:screenOrientation="behind" />
|
||||
<!-- 订阅源管理 -->
|
||||
<activity
|
||||
android:name=".ui.rss.source.manage.RssSourceActivity"
|
||||
android:launchMode="singleTop"
|
||||
android:screenOrientation="behind" />
|
||||
<!-- txt目录规则管理 -->
|
||||
<activity
|
||||
android:name=".ui.book.local.rule.TxtTocRuleActivity"
|
||||
android:launchMode="singleTop"
|
||||
android:screenOrientation="behind" />
|
||||
<!-- 替换规则界面 -->
|
||||
<activity
|
||||
android:name=".ui.replace.ReplaceRuleActivity"
|
||||
android:launchMode="singleTop"
|
||||
android:screenOrientation="behind" />
|
||||
<!-- 书籍管理 -->
|
||||
<activity
|
||||
android:name=".ui.book.arrange.ArrangeBookActivity"
|
||||
android:launchMode="singleTop"
|
||||
android:screenOrientation="behind" />
|
||||
<!-- 书源调试 -->
|
||||
<activity
|
||||
android:name=".ui.book.source.debug.BookSourceDebugActivity"
|
||||
android:launchMode="singleTop"
|
||||
android:screenOrientation="behind" />
|
||||
<!-- 目录 -->
|
||||
<activity
|
||||
android:name=".ui.book.toc.TocActivity"
|
||||
android:launchMode="singleTop"
|
||||
android:screenOrientation="behind" />
|
||||
<!-- 正文搜索 -->
|
||||
<activity
|
||||
android:name=".ui.book.searchContent.SearchContentActivity"
|
||||
android:launchMode="singleTop"
|
||||
android:screenOrientation="behind" />
|
||||
<!-- RSS条目 -->
|
||||
<activity
|
||||
android:name=".ui.rss.article.RssSortActivity"
|
||||
android:launchMode="singleTop" />
|
||||
<!-- RSS阅读 -->
|
||||
<activity
|
||||
android:name=".ui.rss.read.ReadRssActivity"
|
||||
android:configChanges="orientation|screenSize"
|
||||
android:hardwareAccelerated="true"
|
||||
android:launchMode="singleTop" />
|
||||
<!-- 导入书籍 -->
|
||||
<activity
|
||||
android:name=".ui.book.local.ImportBookActivity"
|
||||
android:launchMode="singleTop" />
|
||||
<!-- 发现界面 -->
|
||||
<activity
|
||||
android:name=".ui.book.explore.ExploreShowActivity"
|
||||
android:launchMode="singleTop" />
|
||||
<!-- 订阅源调试 -->
|
||||
<activity
|
||||
android:name=".ui.rss.source.debug.RssSourceDebugActivity"
|
||||
android:launchMode="singleTop" />
|
||||
<!-- Rss收藏 -->
|
||||
<activity
|
||||
android:name=".ui.rss.favorites.RssFavoritesActivity"
|
||||
android:launchMode="singleTop" />
|
||||
<!-- 缓存界面 -->
|
||||
<activity
|
||||
android:name=".ui.book.cache.CacheActivity"
|
||||
android:launchMode="singleTop" />
|
||||
<!-- WebView界面 -->
|
||||
<activity
|
||||
android:name=".ui.browser.WebViewActivity"
|
||||
android:launchMode="standard" />
|
||||
<!-- 书源登录 -->
|
||||
<activity
|
||||
android:name="io.legado.app.ui.login.SourceLoginActivity"
|
||||
android:configChanges="orientation|screenSize"
|
||||
android:hardwareAccelerated="true"
|
||||
android:theme="@style/AppTheme.Transparent" />
|
||||
<!-- 阅读记录 -->
|
||||
<activity
|
||||
android:name=".ui.about.ReadRecordActivity"
|
||||
android:configChanges="orientation|screenSize"
|
||||
android:hardwareAccelerated="true" />
|
||||
<!-- 选择文件 -->
|
||||
<activity
|
||||
android:name=".ui.document.HandleFileActivity"
|
||||
android:configChanges="orientation|screenSize"
|
||||
android:hardwareAccelerated="true"
|
||||
android:theme="@style/AppTheme.Transparent" />
|
||||
<!-- 文字处理 -->
|
||||
<activity
|
||||
android:name=".receiver.SharedReceiverActivity"
|
||||
android:exported="true"
|
||||
android:label="@string/receiving_shared_label"
|
||||
android:theme="@style/AppTheme.Transparent">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.PROCESS_TEXT" />
|
||||
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
|
||||
<data android:mimeType="text/plain" />
|
||||
</intent-filter>
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.SEND" />
|
||||
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
|
||||
<data android:mimeType="text/plain" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
<!-- 一键导入 -->
|
||||
<activity
|
||||
android:name=".ui.association.OnLineImportActivity"
|
||||
android:configChanges="locale|keyboardHidden|orientation|screenSize|smallestScreenSize|screenLayout"
|
||||
android:exported="true"
|
||||
android:theme="@style/AppTheme.Transparent">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.VIEW" />
|
||||
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
<category android:name="android.intent.category.BROWSABLE" />
|
||||
|
||||
<data android:scheme="legado" />
|
||||
<data android:scheme="yuedu" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
<!-- 打开文件 -->
|
||||
<activity
|
||||
android:name=".ui.association.FileAssociationActivity"
|
||||
android:exported="true"
|
||||
android:launchMode="singleTop"
|
||||
android:theme="@style/AppTheme.Transparent">
|
||||
<!-- VIEW (Open with) action -->
|
||||
<!-- Works when an app knows the media type of a file, e.g. Gmail or Chrome. -->
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.VIEW" />
|
||||
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
<category android:name="android.intent.category.BROWSABLE" />
|
||||
|
||||
<data android:scheme="app" />
|
||||
<data android:scheme="content" />
|
||||
<data android:scheme="file" />
|
||||
<!-- text -->
|
||||
<data android:mimeType="text/plain" />
|
||||
<!-- json -->
|
||||
<data android:mimeType="application/json" />
|
||||
<!-- EPUB -->
|
||||
<data android:mimeType="application/epub+zip" />
|
||||
</intent-filter>
|
||||
<!-- Works when an app doesn't know the media type, e.g. Dropbox -->
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.VIEW" />
|
||||
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
<category android:name="android.intent.category.BROWSABLE" />
|
||||
|
||||
<data android:host="*" />
|
||||
|
||||
<data android:scheme="app" />
|
||||
<data android:scheme="content" />
|
||||
<data android:scheme="file" />
|
||||
<!-- This media type is necessary, otherwise it won't match on the file extension -->
|
||||
<data android:mimeType="*/*" />
|
||||
<!--TXT-->
|
||||
<data android:pathPattern=".*\\.txt" />
|
||||
<data android:pathPattern=".*\\.TXT" />
|
||||
<!--JSON-->
|
||||
<data android:pathPattern=".*\\.json" />
|
||||
<data android:pathPattern=".*\\.JSON" />
|
||||
<!-- EPUB -->
|
||||
<data android:pathPattern=".*\\.epub" />
|
||||
<data android:pathPattern=".*\\.EPUB" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
|
||||
<service android:name=".service.CheckSourceService" />
|
||||
<service android:name=".service.CacheBookService" />
|
||||
<service android:name=".service.WebService" />
|
||||
<service
|
||||
android:name=".service.WebTileService"
|
||||
android:exported="true"
|
||||
android:icon="@drawable/ic_web_service_noti"
|
||||
android:label="legado Web Service"
|
||||
android:permission="android.permission.BIND_QUICK_SETTINGS_TILE">
|
||||
<intent-filter>
|
||||
<action android:name="android.service.quicksettings.action.QS_TILE" />
|
||||
</intent-filter>
|
||||
</service>
|
||||
<service android:name=".service.TTSReadAloudService" />
|
||||
<service android:name=".service.HttpReadAloudService" />
|
||||
<service android:name=".service.AudioPlayService" />
|
||||
<service android:name=".service.DownloadService" />
|
||||
|
||||
<receiver
|
||||
android:name=".receiver.MediaButtonReceiver"
|
||||
android:exported="true">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MEDIA_BUTTON" />
|
||||
</intent-filter>
|
||||
</receiver>
|
||||
|
||||
<provider
|
||||
android:name=".api.ReaderProvider"
|
||||
android:authorities="${applicationId}.readerProvider"
|
||||
android:enabled="true"
|
||||
android:exported="true"
|
||||
tools:ignore="ExportedContentProvider" />
|
||||
<provider
|
||||
android:name="androidx.core.content.FileProvider"
|
||||
android:authorities="${applicationId}.fileProvider"
|
||||
android:exported="false"
|
||||
android:grantUriPermissions="true">
|
||||
<meta-data
|
||||
android:name="android.support.FILE_PROVIDER_PATHS"
|
||||
android:resource="@xml/file_paths" />
|
||||
</provider>
|
||||
|
||||
<meta-data
|
||||
android:name="channel"
|
||||
android:value="${APP_CHANNEL_VALUE}" />
|
||||
</application>
|
||||
|
||||
<queries>
|
||||
<intent>
|
||||
<action android:name="android.intent.action.TTS_SERVICE" />
|
||||
</intent>
|
||||
<intent>
|
||||
<action android:name="android.intent.action.PROCESS_TEXT" />
|
||||
<data android:mimeType="text/plain" />
|
||||
</intent>
|
||||
</queries>
|
||||
|
||||
</manifest>
|
284
app/src/main/assets/18PlusList.txt
Normal file
@ -0,0 +1,284 @@
|
||||
OGN5dS5jb20=
|
||||
c2cwMC54eXo=
|
||||
aXRyYWZmaWNuZXQuY29t
|
||||
eGlhb3FpYW5nNTIw
|
||||
MTIzeGlhb3FpYW5n
|
||||
eGlhb3FpYW5neHM=
|
||||
eGlhb3FpYW5nNTIw
|
||||
MzM1eHM=
|
||||
eGN4czk=
|
||||
eGN4czUyMA==
|
||||
c2h1YmFvYW4=
|
||||
c2h1YmFvd2FuZzEyMw==
|
||||
c2h1YmFvYW4=
|
||||
aGFpdGFuZzEyMw==
|
||||
eXV6aGFpd3VsYQ==
|
||||
cG8xOA==
|
||||
Ymwtbm92ZWw=
|
||||
NXRucw==
|
||||
c2hhb3NodWdl
|
||||
amluamlzaHV3dQ==
|
||||
NDJ3Zw==
|
||||
eWlxdXNodQ==
|
||||
c2h1YmFvd2FuZzEyMw==
|
||||
M2hlYmFv
|
||||
MzNoZWJhbw==
|
||||
bHVvcWl1enc=
|
||||
bXlzaHVnZQ==
|
||||
c3NzeHN3
|
||||
eWl0ZQ==
|
||||
Y3Vpd2VpanV1
|
||||
Y3Vpd2VpanV4cw==
|
||||
Y3Vpd2VpanV4
|
||||
eGlhb3FpYW5nd3g=
|
||||
YXN6dw==
|
||||
YXN6dzY=
|
||||
c2FuaGFveHM=
|
||||
ODdzaHV3dQ==
|
||||
NDh3eA==
|
||||
bG9uZ3Rlbmcy
|
||||
NnF3eA==
|
||||
bG9uZ3Rlbmd4cw==
|
||||
aGF4ZHU=
|
||||
M3R3eA==
|
||||
aGF4d3g1
|
||||
NjZsZXdlbg==
|
||||
eGJhbnpodQ==
|
||||
aGR5cA==
|
||||
ZHliejk=
|
||||
ZGl5aWJhbnpodTk=
|
||||
ZGl5aWJhbnpodQ==
|
||||
ZGl5aWJhbnpodTc=
|
||||
YnoyMjI=
|
||||
d29kZWFwaTAwMQ==
|
||||
dGFuZ3poZWthbg==
|
||||
YmF4aWFueHM=
|
||||
eGlhb3NodW9zaGVuemhhbg==
|
||||
ZGFtb2tl
|
||||
emh3ZW5wZw==
|
||||
eXV6aGFpZ2U=
|
||||
d21wOA==
|
||||
OXhpYW53ZW4=
|
||||
bmFucmVudmlw
|
||||
cmV5b28=
|
||||
eWZ4aWFvc2h1b2U=
|
||||
c2Fuaml1enc=
|
||||
N3Fpbmc3
|
||||
cWR4aWFvc2h1bw==
|
||||
Y2hpbmVzZXpq
|
||||
MzlzaHViYW8=
|
||||
a3l4czU=
|
||||
NTZtcw==
|
||||
bml1c2hh
|
||||
bWt4czY=
|
||||
MjIyMjJ4cw==
|
||||
OTVkdXNodQ==
|
||||
YmFuemh1MjI=
|
||||
d3JsdHh0
|
||||
dHVkb3V0eHQ=
|
||||
cm5neHM=
|
||||
OTl3ZW5rdQ==
|
||||
bGFvc2lqaXhz
|
||||
ZnVzaHV6aGFpMQ==
|
||||
cG8xOA==
|
||||
czUyMTc=
|
||||
c2FuaGFveHM=
|
||||
NTJrc2h1
|
||||
NDhyeA==
|
||||
ZWNub3ZlbA==
|
||||
bGllaHVvenc=
|
||||
eGlhb3FpYW5nd3g=
|
||||
NTJrc2h1
|
||||
NDh3eA==
|
||||
NTJrc2h1
|
||||
MDB1aQ==
|
||||
MDFieg==
|
||||
c2h1YmFvMQ==
|
||||
ZG54aWFvc2h1b2E=
|
||||
am5zaHViYQ==
|
||||
MThzaHV3dQ==
|
||||
bGV4cw==
|
||||
MzM1eHM=
|
||||
dXB1
|
||||
ZnVndW9kdQ==
|
||||
ODB0eHQ=
|
||||
YWFyZWFk
|
||||
eWlkdWR1MQ==
|
||||
YmFuemh1d2FuZw==
|
||||
cWloYW9xaWhhbw==
|
||||
OHhpYW54cw==
|
||||
amluamlzaHV3dQ==
|
||||
d21wOA==
|
||||
ZXl1c2h1d3U=
|
||||
NTB4c2Y=
|
||||
aGF4d3g1
|
||||
cG93YW5qdWFu
|
||||
d2luMTBjaXR5
|
||||
eWV5ZXhzdw==
|
||||
bXlzaHVnZQ==
|
||||
eGlhbmd0eHN3
|
||||
Y3Vpd2VpanV4
|
||||
MzY2eHN3
|
||||
aHVheXVld2Vua3U=
|
||||
eW91ZGlhbmxlbg==
|
||||
c291Nzg=
|
||||
bGFucm91Mg==
|
||||
cXFib29r
|
||||
eW91d3V4cw==
|
||||
cnVpbGlzYWxl
|
||||
MzY1bXd3
|
||||
ZnV3ZW5o
|
||||
bGVzYmw=
|
||||
YXd1Ym9vaw==
|
||||
bGl5dXhpYW5nMjAyMA==
|
||||
OTJwb3Bv
|
||||
ZnVzaHV0dWFu
|
||||
ODhkYW5tZWk=
|
||||
ZG14cw==
|
||||
eXVsaW56aGFueWU=
|
||||
M2hlYmFv
|
||||
eGd1YWd1YXhz
|
||||
ZGl5aWJhbnpodTY=
|
||||
aXJlYWR4cw==
|
||||
c2h1YmFvOTY=
|
||||
ZGl5aWJhbnpodTU1NQ==
|
||||
c2Fuaml1enc=
|
||||
N3Fpbmc3
|
||||
NjZsZXdlbg==
|
||||
a3l4czU=
|
||||
MjIyMjJ4cw==
|
||||
c2hhb3NodWdl
|
||||
amlsaW41NQ==
|
||||
bWt4czY=
|
||||
amluc2h1bG91
|
||||
eGlhbndhbmdz
|
||||
eWlkdWR1
|
||||
cWR0eHQ=
|
||||
MTZib29rMQ==
|
||||
am1zaHV3dQ==
|
||||
MzY2eHN3
|
||||
ZHliejk=
|
||||
c2hvdWRhOA==
|
||||
ZnlxMTg=
|
||||
eWlzaHVn
|
||||
eXV6aGFpd3VsYQ==
|
||||
MTFiYW56aHU=
|
||||
MTIzeGlhb3FpYW5n
|
||||
ZGl5aWJhbnpodTk=
|
||||
ZGl5aWJhbnpodQ==
|
||||
MzY2eHN3
|
||||
ODdzaHV3dQ==
|
||||
NnF3eA==
|
||||
emhlbmh1bnhpYW9zaHVv
|
||||
bG9uZ3Rlbmc1Mg==
|
||||
eGlueGluZ3hpYW5nemhpZmE=
|
||||
ZHliejk=
|
||||
ZHVvemhla2Fu
|
||||
MTIzeGlhb3FpYW5n
|
||||
MzM1eHM=
|
||||
am1zaHV3dQ==
|
||||
c2hhb3NodWdl
|
||||
bGF3ZW54cw==
|
||||
cnVzaHV3dQ==
|
||||
MzY2eHN3
|
||||
NTB4c2Y=
|
||||
bGV3ZW41NQ==
|
||||
aGFpdGFuZzEyMw==
|
||||
aGViYW81MjA=
|
||||
bHVvcWl1enc=
|
||||
c3NzeHN3
|
||||
c2h1c2h1d3V4cw==
|
||||
cm5neHM=
|
||||
cWR4aWFvc2h1bw==
|
||||
dHl1ZQ==
|
||||
Y2hlNDM=
|
||||
bG9uZ3Rlbmcy
|
||||
amZ5eHNo
|
||||
aGV0dTI=
|
||||
bGFvc2lqaXhz
|
||||
bG9uZ3Rlbmd4cw==
|
||||
bGllaHVvenc=
|
||||
c2h1YmFvYW4=
|
||||
eHNodW9zaHVv
|
||||
NTIxZGFubWVp
|
||||
YmFuemh1MjI=
|
||||
cWtzaHU=
|
||||
eWZ4aWFvc2h1b2U=
|
||||
a3lnc28=
|
||||
c2h1bG91YmE=
|
||||
NXRucw==
|
||||
N3Fpbmc3
|
||||
bWlhb2R1NQ==
|
||||
eXVzaHV3ZW4=
|
||||
YWFyZWFk
|
||||
cXRzaHU=
|
||||
MTdzaHV3dQ==
|
||||
c2h1YmFvMnM=
|
||||
YnowMDE=
|
||||
ZGFtb2dl
|
||||
MTMxdGI=
|
||||
aXhpYW9z
|
||||
bXlzaHVnZQ==
|
||||
OXhpYW53ZW4=
|
||||
ZHVvemhla2Fu
|
||||
MTIwdw==
|
||||
c2h1c2h1d3U1MjA=
|
||||
c2h1YmFvMnM=
|
||||
YWd4c3c=
|
||||
OTR4c3c=
|
||||
cG8xOA==
|
||||
eWFvY2hpeHM=
|
||||
eGlhb3FpYW5neHM=
|
||||
Ym9va2Js
|
||||
c2Fuaml1eHM=
|
||||
d29kZXNodWJhbw==
|
||||
em9uZ2NhaXhpYW9zaHVvMg==
|
||||
OWI4OTEzOTRkZjVi
|
||||
MThub3ZlbA==
|
||||
YWFib29r
|
||||
YjF0eHQ=
|
||||
eXVjYWl6dw==
|
||||
Yzl0eHQ=
|
||||
ZGl5aWJhbnpodTU1NQ==
|
||||
MzBtYw==
|
||||
eGlueXVzaHV3dQ==
|
||||
c2h1YmFvd2FuZzEyMw==
|
||||
YWd4cw==
|
||||
YmlxdWdlbmw=
|
||||
c2hpcWlzaHV3dQ==
|
||||
c2lsdWtl
|
||||
ZGl5aWJhbnpodTg=
|
||||
ZGl5aWJhbnpodTk=
|
||||
aGV0dW54cw==
|
||||
OTl3ZW5rdQ==
|
||||
aGFpdGFuZ3NodXd1
|
||||
OTd5ZA==
|
||||
eXV6aGFpd3UxMQ==
|
||||
Y3Vpd2VpanV4cw==
|
||||
Y2JpcXU=
|
||||
NTIxZGFubWVp
|
||||
c2h1YmFvMzM=
|
||||
c2FuaGFvMQ==
|
||||
dGlhbm1lbmd3ZW5rdQ==
|
||||
eXVzaHV3dTUyMA==
|
||||
c2h1YmFvMjIy
|
||||
c2h1YmFvd2FuZzEyMw==
|
||||
eXVib29r
|
||||
Y2JpcXU=
|
||||
MWxld2Vu
|
||||
MTV4c3c=
|
||||
eG5jd3h3
|
||||
c2h1YmFvd2FuZzEyMw==
|
||||
c2FuaGFveHM=
|
||||
eXV3YW5nc2hl
|
||||
YmlxdXRz
|
||||
bGFtZWl4cw==
|
||||
eGJhbnpodQ==
|
||||
cWR4aWFvc2h1bw==
|
||||
bWh0bGE=
|
||||
OTl3ZW5rdQ==
|
||||
eGlhb3FpYW5nNTIw
|
||||
dGlhbm1lbmd3ZW5rdQ==
|
||||
YWlmdXNodQ==
|
||||
bWlhb2R1NQ==
|
||||
bWlmZW5neHM=
|
BIN
app/src/main/assets/bg/午后沙滩.jpg
Normal file
After Width: | Height: | Size: 46 KiB |
BIN
app/src/main/assets/bg/宁静夜色.jpg
Normal file
After Width: | Height: | Size: 38 KiB |
BIN
app/src/main/assets/bg/山水墨影.jpg
Normal file
After Width: | Height: | Size: 39 KiB |
BIN
app/src/main/assets/bg/山水画.jpg
Normal file
After Width: | Height: | Size: 20 KiB |
BIN
app/src/main/assets/bg/护眼漫绿.jpg
Normal file
After Width: | Height: | Size: 112 KiB |
BIN
app/src/main/assets/bg/新羊皮纸.jpg
Normal file
After Width: | Height: | Size: 42 KiB |
BIN
app/src/main/assets/bg/明媚倾城.jpg
Normal file
After Width: | Height: | Size: 65 KiB |
BIN
app/src/main/assets/bg/深宫魅影.jpg
Normal file
After Width: | Height: | Size: 49 KiB |
BIN
app/src/main/assets/bg/清新时光.jpg
Normal file
After Width: | Height: | Size: 42 KiB |
BIN
app/src/main/assets/bg/羊皮纸1.jpg
Normal file
After Width: | Height: | Size: 246 KiB |
BIN
app/src/main/assets/bg/羊皮纸2.jpg
Normal file
After Width: | Height: | Size: 312 KiB |
BIN
app/src/main/assets/bg/羊皮纸3.jpg
Normal file
After Width: | Height: | Size: 124 KiB |
BIN
app/src/main/assets/bg/羊皮纸4.jpg
Normal file
After Width: | Height: | Size: 132 KiB |
BIN
app/src/main/assets/bg/边彩画布.jpg
Normal file
After Width: | Height: | Size: 287 KiB |
1
app/src/main/assets/cronet.json
Normal file
@ -0,0 +1 @@
|
||||
{"arm64-v8a":"690c212d9bbad4b09b9e1ba450b273bb","armeabi-v7a":"4dbb88e5229abef7d84138218772f872","x86":"3f2421e040147da48abb07cfc6c7c87e","x86_64":"730a71ef4f03a27d1c8c8a77e7d09ff5","version":"96.0.4664.104"}
|
48
app/src/main/assets/defaultData/bookSources.json
Normal file
@ -0,0 +1,48 @@
|
||||
[
|
||||
{
|
||||
"bookSourceComment": "",
|
||||
"bookSourceGroup": "听书",
|
||||
"bookSourceName": "消消乐听书",
|
||||
"bookSourceType": 1,
|
||||
"bookSourceUrl": "https://www.kaixin7days.com",
|
||||
"customOrder": 0,
|
||||
"enabled": true,
|
||||
"enabledExplore": true,
|
||||
"exploreUrl": "@js:var header = JSON.parsesource.getLoginHeader()\nvar json = ''\nvar j = null\nif (header != null) {\n json = java.connect('https://www.kaixin7days.com/book-service/bookMgt/getBookCategroy,{\"method\":\"POST\",\"body\":{}}', header).body()\n j = JSON.parse(json)\n}\nif (j == null || j.statusCode != 200) {\n json = java.connect('https://www.kaixin7days.com/visitorLogin,{\"method\":\"POST\", \"body\":{} }').body()\n j = JSON.parse(json)\n var accessToken = {\n Authorization: 'Bearer ' + j.content.accessToken\n }\n header = JSON.stringify(accessToken)\n source.putLoginHeader(header)\n json = java.connect('https://www.kaixin7days.com/book-service/bookMgt/getBookCategroy,{\"method\":\"POST\",\"body\":{} }', header).body()\n j = JSON.parse(json)\n}\nvar fls = j.content\nvar fx = []\nfor (var i = 0; i < fls.length; i++) {\n fx.push({\n title: fls[i].categoryName,\n url: '/book-service/bookMgt/getAllBookByCategroyId,{\"method\":\"POST\",\"body\":{\"categoryIds\": \"' + fls[i].associationCategoryIDs + '\",\"pageNum\": {{page}},\"pageSize\": 100}}'\n })\n}\nJSON.stringify(fx)",
|
||||
"searchUrl": "https://www.kaixin7days.com/book-service/bookMgt/findBookName,{\"method\":\"POST\",\"body\":{\"title\": \"searchKey\",\"pageNum\": {{searchPage}},\"pageSize\": 100}}",
|
||||
"lastUpdateTime": 1630656684531,
|
||||
"loginCheckJs": "var strRes = result\nvar c = JSON.parse(result.body())\nif (c.statusCode == 301) {\n var loginInfo = source.getLoginInfo()\n var dl = null\n if (loginInfo) {\n dl = java.connect('https://www.kaixin7days.com/login,{\"method\":\"POST\",\"body\":' + loginInfo + '}').body()\n } else {\n dl = java.connect('https://www.kaixin7days.com/visitorLogin,{\"method\":\"POST\",\"body\":{}}').body()\n }\n c = JSON.parse(dl)\n var accessToken = {\n Authorization: \"Bearer \" + c.content.accessToken\n }\n var header = JSON.stringify(accessToken)\n source.putLoginHeader(header)\n strRes = java.connect(url, header)\n}\nstrRes",
|
||||
"loginUi": "[{\"name\": \"telephone\",\"type\": \"text\"},{\"name\": \"password\",\"type\": \"password\"},{\"name\": \"注册\",\"type\": \"button\",\"action\": \"http://www.yooike.com/xiaoshuo/#/register?title=%E6%B3%A8%E5%86%8C\"}]",
|
||||
"loginUrl": "var loginInfo = source.getLoginInfo()\nvar json = java.connect('https://www.kaixin7days.com/login,{\"method\":\"POST\",\"body\":' + loginInfo + '}').body()\nvar loginRes = JSON.parse(json)\nvar header = null\nif (loginRes.statusCode == 200) {\n var accessToken = {\n Authorization: \"Bearer \" + loginRes.content.accessToken\n }\n header = JSON.stringify(accessToken)\n source.putLoginHeader(header)\n}\nheader",
|
||||
"respondTime": 180000,
|
||||
"ruleBookInfo": {},
|
||||
"ruleContent": {
|
||||
"content": "",
|
||||
"payAction": "var header = JSON.parse(source.getLoginHeader()); var bookId = book.getVariableMap().get('bookId');var chapterId = java.get('chapterId');\n'http://www.shuidi.online/?name=' + book.getName() + '&type=2&cover=' + book.getCoverUrl() + '&chapterId=' + chapterId + '&chapter=203&allNumber=' + book.getTotalChapterNum() + '&bookId=' + bookId + '&chapterIds=' + chapterId + '&number=' + chapter.getIndex() + '&accessToken=' + header.Authorization.substring(7) + '#/pay'"
|
||||
},
|
||||
"ruleExplore": {
|
||||
"author": "$.author",
|
||||
"bookList": "$.content.content",
|
||||
"bookUrl": "$.id@js:java.put('bookId', result);'https://www.kaixin7days.com/book-service/bookMgt/getAllChapterByBookId,{ \"method\": \"POST\",\"body\": {\"bookId\": \"'+result+'\",\"pageNum\": \"1\",\"pageSize\": \"10000\"} }'",
|
||||
"coverUrl": "$.cover@js:var cover = JSON.parse(result);'https://www.shuidi.online/fileMgt/getPicture?filePath='+cover.storeFilePath",
|
||||
"intro": "$.desc",
|
||||
"lastChapter": "$.newestChapter",
|
||||
"name": "$.title"
|
||||
},
|
||||
"ruleSearch": {
|
||||
"author": "$.author",
|
||||
"bookList": "$.content.content",
|
||||
"bookUrl": "$.id@js:java.put('bookId', result);'https://www.kaixin7days.com/book-service/bookMgt/getAllChapterByBookId,{ \"method\": \"POST\",\"body\": {\"bookId\": \"'+result+'\",\"pageNum\": \"1\",\"pageSize\": \"10000\"} }'",
|
||||
"coverUrl": "$.cover@js:var cover = JSON.parse(result);'https://www.shuidi.online/fileMgt/getPicture?filePath='+cover.storeFilePath",
|
||||
"intro": "$.desc",
|
||||
"lastChapter": "$.newestChapter",
|
||||
"name": "$.title"
|
||||
},
|
||||
"ruleToc": {
|
||||
"chapterList": "$.content.content",
|
||||
"chapterName": "$.chapterTitle",
|
||||
"chapterUrl": "$.id@js:java.put('chapterId', result);'https://www.shuidi.online/fileMgt/getAudioByChapterId?bookId=' + java.get('bookId') + '&chapterId=' + result + \"&pageNum=1&pageSize=50&keyId={{var header = JSON.parse(source.getLoginHeader());var keyId = '1632746188011002';var ks = java.md5Encode(keyId + java.get('chapterId') + header.Authorization);keyId + '&keySecret=' + ks}\" + '}'"
|
||||
},
|
||||
"weight": 0
|
||||
}
|
||||
]
|
5
app/src/main/assets/defaultData/directLinkUpload.json
Normal file
@ -0,0 +1,5 @@
|
||||
{
|
||||
"UploadUrl": "http://sy.miaogongzi.cc/shuyuan,{\"method\":\"POST\",\"body\": {\"file\": \"fileRequest\"},\"type\": \"multipart/form-data\"}",
|
||||
"DownloadUrlRule": "$.data@js:if (result == '') \n '' \n else \n 'https://shuyuan.miaogongzi.cc/shuyuan/' + result",
|
||||
"summary": "有效期2天"
|
||||
}
|
30
app/src/main/assets/defaultData/httpTTS.json
Normal file
@ -0,0 +1,30 @@
|
||||
[
|
||||
{
|
||||
"id": -100,
|
||||
"name": "1.百度",
|
||||
"url": "http://tts.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{(speakSpeed + 5) / 10 + 4}}&per=4127&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=11&vol=5&aue=6&pit=3&_res_tag_=audio\"\n}",
|
||||
"contentType": "audio/wav"
|
||||
},
|
||||
{
|
||||
"id": -29,
|
||||
"name": "2.阿里云语音",
|
||||
"url": "https://nls-gateway.cn-shanghai.aliyuncs.com/stream/v1/tts,{\"method\": \"POST\",\"body\": {\"appkey\":\"{{source.getLoginInfoMap().get('AppKey')}}\",\"text\":\"{{speakText}}\",\"format\":\"mp3\",\"volume\":100,\"speech_rate\":{{String((speakSpeed) * 20 - 400)}} }}",
|
||||
"contentType": "audio/mpeg",
|
||||
"loginUrl": "var loginInfo = source.getLoginInfoMap();\nvar accessKeyId = loginInfo.get('AccessKeyId');\nvar accessKeySecret = loginInfo.get('AccessKeySecret');\nvar timestamp = java.timeFormatUTC(new Date().getTime(), \"yyyy-MM-dd'T'HH:mm:ss'Z'\", 0);\nvar aly = new JavaImporter(Packages.javax.crypto.Mac, Packages.javax.crypto.spec.SecretKeySpec, Packages.javax.xml.bind.DatatypeConverter, Packages.java.net.URLEncoder, Packages.java.lang.String, Packages.android.util.Base64);\nwith (aly) {\n function percentEncode(value) {\n return URLEncoder.encode(value, \"UTF-8\").replace(\"+\", \"%20\")\n .replace(\"*\", \"%2A\").replace(\"%7E\", \"~\")\n }\n\n function sign(stringToSign, accessKeySecret) {\n var mac = Mac.getInstance('HmacSHA1');\n mac.init(new SecretKeySpec(String(accessKeySecret + '&').getBytes(\"UTF-8\"), \"HmacSHA1\"));\n var signData = mac.doFinal(String(stringToSign).getBytes(\"UTF-8\"));\n var signBase64 = Base64.encodeToString(signData, Base64.NO_WRAP);\n var signUrlEncode = percentEncode(signBase64);\n return signUrlEncode;\n }\n}\nvar query = 'AccessKeyId=' + accessKeyId + '&Action=CreateToken&Format=JSON&RegionId=cn-shanghai&SignatureMethod=HMAC-SHA1&SignatureNonce=' + java.randomUUID() + '&SignatureVersion=1.0&Timestamp=' + percentEncode(timestamp) + '&Version=2019-02-28';\nvar signStr = sign('GET&' + percentEncode('/') + '&' + percentEncode(query), accessKeySecret);\nvar queryStringWithSign = \"Signature=\" + signStr + \"&\" + query;\nvar body = java.ajax('http://nls-meta.cn-shanghai.aliyuncs.com/?' + queryStringWithSign)\nvar res = JSON.parse(body)\nif (res.Message) {\n throw new Error(res.Message)\n}\nvar header = { \"X-NLS-Token\": res.Token.Id };\nsource.putLoginHeader(JSON.stringify(header))",
|
||||
"loginUi": [
|
||||
{
|
||||
"name": "AppKey",
|
||||
"type": "text"
|
||||
},
|
||||
{
|
||||
"name": "AccessKeyId",
|
||||
"type": "text"
|
||||
},
|
||||
{
|
||||
"name": "AccessKeySecret",
|
||||
"type": "text"
|
||||
}
|
||||
],
|
||||
"loginCheckJs": "var response = result;\nif (response.headers().get(\"Content-Type\") != \"audio/mpeg\") {\n var body = JSON.parse(response.body().string())\n if (body.status == 40000001) {\n source.login()\n java.getHeaderMap().putAll(source.getHeaderMap(true))\n response = java.getResponse()\n } else {\n throw body.message\n }\n}\nresponse"
|
||||
}
|
||||
]
|
107
app/src/main/assets/defaultData/readConfig.json
Normal file
@ -0,0 +1,107 @@
|
||||
[
|
||||
{
|
||||
"bgStr": "#ffc0edc6",
|
||||
"bgStrEInk": "#FFFFFF",
|
||||
"bgStrNight": "#000000",
|
||||
"bgType": 0,
|
||||
"bgTypeEInk": 0,
|
||||
"bgTypeNight": 0,
|
||||
"darkStatusIcon": true,
|
||||
"darkStatusIconEInk": true,
|
||||
"darkStatusIconNight": false,
|
||||
"footerMode": 0,
|
||||
"footerPaddingBottom": 10,
|
||||
"footerPaddingLeft": 13,
|
||||
"footerPaddingRight": 17,
|
||||
"footerPaddingTop": 0,
|
||||
"headerMode": 0,
|
||||
"headerPaddingBottom": 0,
|
||||
"headerPaddingLeft": 19,
|
||||
"headerPaddingRight": 16,
|
||||
"headerPaddingTop": 10,
|
||||
"letterSpacing": 0,
|
||||
"lineSpacingExtra": 10,
|
||||
"name": "微信读书",
|
||||
"paddingBottom": 4,
|
||||
"paddingLeft": 22,
|
||||
"paddingRight": 22,
|
||||
"paddingTop": 5,
|
||||
"pageAnim": 3,
|
||||
"pageAnimEInk": 3,
|
||||
"paragraphIndent": " ",
|
||||
"paragraphSpacing": 6,
|
||||
"showFooterLine": true,
|
||||
"showHeaderLine": true,
|
||||
"textBold": 0,
|
||||
"textColor": "#ff0b0b0b",
|
||||
"textColorEInk": "#000000",
|
||||
"textColorNight": "#ADADAD",
|
||||
"textSize": 24,
|
||||
"tipColor": -10461088,
|
||||
"tipFooterLeft": 7,
|
||||
"tipFooterMiddle": 0,
|
||||
"tipFooterRight": 6,
|
||||
"tipHeaderLeft": 1,
|
||||
"tipHeaderMiddle": 0,
|
||||
"tipHeaderRight": 2,
|
||||
"titleBottomSpacing": 0,
|
||||
"titleMode": 0,
|
||||
"titleSize": 4,
|
||||
"titleTopSpacing": 0
|
||||
},
|
||||
{
|
||||
"name": "预设1",
|
||||
"bgStr": "#FFFFFF",
|
||||
"bgStrNight": "#000000",
|
||||
"textColor": "#000000",
|
||||
"textColorNight": "#FFFFFF",
|
||||
"bgType": 0,
|
||||
"bgTypeNight": 0,
|
||||
"darkStatusIcon": true,
|
||||
"darkStatusIconNight": false
|
||||
},
|
||||
{
|
||||
"name": "预设2",
|
||||
"bgStr": "#DDC090",
|
||||
"bgStrNight": "#3C3F43",
|
||||
"textColor": "#3E3422",
|
||||
"textColorNight": "#DCDFE1",
|
||||
"bgType": 0,
|
||||
"bgTypeNight": 0,
|
||||
"darkStatusIcon": true,
|
||||
"darkStatusIconNight": false
|
||||
},
|
||||
{
|
||||
"name": "预设3",
|
||||
"bgStr": "#C2D8AA",
|
||||
"bgStrNight": "#3C3F43",
|
||||
"textColor": "#596C44",
|
||||
"textColorNight": "#88C16F",
|
||||
"bgType": 0,
|
||||
"bgTypeNight": 0,
|
||||
"darkStatusIcon": false,
|
||||
"darkStatusIconNight": false
|
||||
},
|
||||
{
|
||||
"name": "预设4",
|
||||
"bgStr": "#DBB8E2",
|
||||
"bgStrNight": "#3C3F43",
|
||||
"textColor": "#68516C",
|
||||
"textColorNight": "#F6AEAE",
|
||||
"bgType": 0,
|
||||
"bgTypeNight": 0,
|
||||
"darkStatusIcon": false,
|
||||
"darkStatusIconNight": false
|
||||
},
|
||||
{
|
||||
"name": "预设5",
|
||||
"bgStr": "#ABCEE0",
|
||||
"bgStrNight": "#3C3F43",
|
||||
"textColor": "#3D4C54",
|
||||
"textColorNight": "#90BFF5",
|
||||
"bgType": 0,
|
||||
"bgTypeNight": 0,
|
||||
"darkStatusIcon": false,
|
||||
"darkStatusIconNight": false
|
||||
}
|
||||
]
|
42
app/src/main/assets/defaultData/rssSources.json
Normal file
@ -0,0 +1,42 @@
|
||||
[
|
||||
{
|
||||
"customOrder": 1,
|
||||
"enableJs": true,
|
||||
"enabled": true,
|
||||
"singleUrl": true,
|
||||
"sourceGroup": "legado",
|
||||
"sourceIcon": "https://cdn.jsdelivr.net/gh/gedoor/legado@master/app/src/main/res/mipmap-hdpi/ic_launcher.png",
|
||||
"sourceName": "使用说明",
|
||||
"sourceUrl": "https://www.yuque.com/legado"
|
||||
},
|
||||
{
|
||||
"customOrder": 2,
|
||||
"enableJs": true,
|
||||
"enabled": true,
|
||||
"singleUrl": true,
|
||||
"sourceGroup": "legado",
|
||||
"sourceIcon": "http://mmbiz.qpic.cn/mmbiz_png/hpfMV8hEuL2eS6vnCxvTzoOiaCAibV6exBzJWq9xMic9xDg3YXAick87tsfafic0icRwkQ5ibV0bJ84JtSuxhPuEDVquA/0?wx_fmt=png",
|
||||
"sourceName": "小说拾遗",
|
||||
"sourceUrl": "snssdk1128://user/profile/562564899806367"
|
||||
},
|
||||
{
|
||||
"customOrder": 3,
|
||||
"enableJs": true,
|
||||
"enabled": true,
|
||||
"singleUrl": true,
|
||||
"sourceGroup": "legado",
|
||||
"sourceIcon": "https://Cloud.miaogongzi.site/images/icon.png",
|
||||
"sourceName": "Meow云",
|
||||
"sourceUrl": "https://pan.miaogongzi.net"
|
||||
},
|
||||
{
|
||||
"customOrder": 4,
|
||||
"enableJs": true,
|
||||
"enabled": true,
|
||||
"singleUrl": true,
|
||||
"sourceGroup": "legado",
|
||||
"sourceIcon": "https://cdn.jsdelivr.net/gh/gedoor/legado@master/app/src/main/res/mipmap-hdpi/ic_launcher.png",
|
||||
"sourceName": "烏雲净化",
|
||||
"sourceUrl": "https://www.lanzoux.com/b0bw8jwoh"
|
||||
}
|
||||
]
|
26
app/src/main/assets/defaultData/themeConfig.json
Normal file
@ -0,0 +1,26 @@
|
||||
[
|
||||
{
|
||||
"themeName": "典雅蓝",
|
||||
"isNightTheme": false,
|
||||
"primaryColor": "#03A9F4",
|
||||
"accentColor": "#AD1457",
|
||||
"backgroundColor": "#F5F5F5",
|
||||
"bottomBackground": "#EEEEEE"
|
||||
},
|
||||
{
|
||||
"themeName": "黑白",
|
||||
"isNightTheme": true,
|
||||
"primaryColor": "#303030",
|
||||
"accentColor": "#E0E0E0",
|
||||
"backgroundColor": "#424242",
|
||||
"bottomBackground": "#424242"
|
||||
},
|
||||
{
|
||||
"themeName": "A屏黑",
|
||||
"isNightTheme": true,
|
||||
"primaryColor": "#000000",
|
||||
"accentColor": "#FFFFFF",
|
||||
"backgroundColor": "#000000",
|
||||
"bottomBackground": "#000000"
|
||||
}
|
||||
]
|