Initial commit: 91dj android client dev_1.0.0

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
谢宇宁
2026-10-08 11:37:25 +07:00
co-authored by Claude Opus 5.5
commit 97dd6a739a
1262 changed files with 119813 additions and 0 deletions
+318
View File
@@ -0,0 +1,318 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="com.xvproject">
<!-- release 包只用 main manifest,INTERNET 必须在这里声明;
否则 release 无网络权限,启动选线 host lookup errno=7,弹"线路检测失败" -->
<uses-permission android:name="android.permission.INTERNET"/>
<application
android:label="91短剧"
android:name=".JPApplication"
android:icon="@mipmap/ic_launcher"
android:usesCleartextTraffic="true"
android:largeHeap="true"
android:hardwareAccelerated="true"
android:extractNativeLibs="true"
android:requestLegacyExternalStorage="true">
<activity
android:name=".MainActivity"
android:exported="true"
android:launchMode="singleTop"
android:theme="@style/LaunchTheme"
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
android:hardwareAccelerated="true"
android:windowSoftInputMode="adjustResize">
<!-- Specifies an Android theme to apply to this Activity as soon as
the Android process has started. This theme is visible to the user
while the Flutter UI initializes. After that, this theme continues
to determine the Window background behind the Flutter UI. -->
<meta-data
android:name="io.flutter.embedding.android.NormalTheme"
android:resource="@style/NormalTheme"
/>
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
<activity-alias
android:name=".lld"
android:targetActivity=".MainActivity"
android:label="91短剧"
android:enabled="false"
android:icon="@mipmap/ic_launcher"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity-alias>
<activity-alias
android:name=".aiyinyue"
android:targetActivity=".MainActivity"
android:label="爱音乐"
android:enabled="false"
android:icon="@mipmap/icon_1"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity-alias>
<activity-alias
android:name=".aiyuedu"
android:targetActivity=".MainActivity"
android:label="爱阅读"
android:enabled="false"
android:icon="@mipmap/icon_2"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity-alias>
<activity-alias
android:name=".alipay"
android:targetActivity=".MainActivity"
android:label="支付宝"
android:enabled="false"
android:icon="@mipmap/icon_3"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity-alias>
<activity-alias
android:name=".bilibili"
android:targetActivity=".MainActivity"
android:label="哔哩哔哩"
android:enabled="false"
android:icon="@mipmap/icon_4"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity-alias>
<activity-alias
android:name=".binggandazhuozhan"
android:targetActivity=".MainActivity"
android:label="金铲铲之战"
android:enabled="false"
android:icon="@mipmap/icon_5"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity-alias>
<activity-alias
android:name=".meisijiejian"
android:targetActivity=".MainActivity"
android:label="美食借鉴"
android:enabled="false"
android:icon="@mipmap/icon_6"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity-alias>
<activity-alias
android:name=".myworld"
android:targetActivity=".MainActivity"
android:label="我的世界"
android:enabled="false"
android:icon="@mipmap/icon_7"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity-alias>
<activity-alias
android:name=".shenxuanzhizhan"
android:targetActivity=".MainActivity"
android:label="神选之战"
android:enabled="false"
android:icon="@mipmap/icon_8"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity-alias>
<activity-alias
android:name=".shuixinwuxian"
android:targetActivity=".MainActivity"
android:label="随心无线"
android:enabled="false"
android:icon="@mipmap/icon_9"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity-alias>
<activity-alias
android:name=".texuanxiaoshuo"
android:targetActivity=".MainActivity"
android:label="特轩小说"
android:enabled="false"
android:icon="@mipmap/icon_10"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity-alias>
<activity-alias
android:name=".tiantianmajiang"
android:targetActivity=".MainActivity"
android:label="天天麻将"
android:enabled="false"
android:icon="@mipmap/icon_11"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity-alias>
<activity-alias
android:name=".tuyou"
android:targetActivity=".MainActivity"
android:label="途游"
android:enabled="false"
android:icon="@mipmap/icon_12"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity-alias>
<activity-alias
android:name=".weichat"
android:targetActivity=".MainActivity"
android:label="微信"
android:enabled="false"
android:icon="@mipmap/icon_13"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity-alias>
<activity-alias
android:name=".wendao"
android:targetActivity=".MainActivity"
android:label="问道"
android:enabled="false"
android:icon="@mipmap/icon_14"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity-alias>
<activity-alias
android:name=".yinyutusujiao"
android:targetActivity=".MainActivity"
android:label="英语图书角"
android:enabled="false"
android:icon="@mipmap/icon_15"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity-alias>
<activity-alias
android:name=".icon_16"
android:targetActivity=".MainActivity"
android:label="91短剧"
android:enabled="false"
android:icon="@mipmap/icon_16"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity-alias>
<activity-alias
android:name=".icon_17"
android:targetActivity=".MainActivity"
android:label="91短剧"
android:enabled="false"
android:icon="@mipmap/icon_17"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity-alias>
<activity-alias
android:name=".icon_18"
android:targetActivity=".MainActivity"
android:label="91短剧"
android:enabled="false"
android:icon="@mipmap/icon_18"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity-alias>
<provider
android:name="androidx.core.content.FileProvider"
android:authorities="${applicationId}.fileprovider"
android:exported="false"
android:grantUriPermissions="true"
tools:replace="android:authorities">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/totalfilepath"
tools:replace="android:resource" />
</provider>
<provider
android:name="com.pichillilorenzo.flutter_inappwebview_android.InAppWebViewFileProvider"
android:authorities="${applicationId}.flutter_inappwebview_android.fileprovider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/provider_paths" />
</provider>
<!-- Don't delete the meta-data below.
This is used by the Flutter tool to generate GeneratedPluginRegistrant.java -->
<meta-data
android:name="flutterEmbedding"
android:value="2" />
</application>
</manifest>
@@ -0,0 +1,104 @@
package io.flutter.plugins;
import android.media.MediaMetadataRetriever;
import android.text.TextUtils;
import java.io.FileInputStream;
/// 本地视频文件信息:时长 / 分辨率 / 比例 / 高度 / 比特率
/// 注:MediaMetadataRetriever 持有 native 资源,每次用完必须 release,否则多次调用后取不到任何信息
public class JPFileUtils {
/**
* 获取视频时长(秒)
*/
public static int getVideoDuration(String filePath) {
String ms = extract(filePath, MediaMetadataRetriever.METADATA_KEY_DURATION);
if (TextUtils.isEmpty(ms) || !TextUtils.isDigitsOnly(ms)) return 0;
return Integer.parseInt(ms) / 1000;
}
/**
* 获取视频分辨率,格式 "宽*高",取不到返回空串
*/
public static String getVideoResolution(String filePath) {
int[] size = videoSize(filePath);
return size[0] > 0 && size[1] > 0 ? size[0] + "*" + size[1] : "";
}
/**
* 获取视频宽高比
*/
public static String getVideoRatio(String filePath) {
int[] size = videoSize(filePath);
if (size[0] <= 0 || size[1] <= 0) return "0";
return String.valueOf((float) size[0] / size[1]);
}
/**
* 获取视频高度
*/
public static String getVideoHeight(String filePath) {
int[] size = videoSize(filePath);
if (size[0] <= 0 || size[1] <= 0) return "0";
return String.valueOf(size[1]);
}
/**
* 获取比特率
*/
public static String getVideoBitrate(String filePath) {
String bitrate = extract(filePath, MediaMetadataRetriever.METADATA_KEY_BITRATE);
return TextUtils.isEmpty(bitrate) ? "0" : bitrate;
}
/**
* 取单个 metadata;用 FD 而非路径设源,避开部分机型对中文/特殊字符路径的兼容问题
*/
private static String extract(String filePath, int key) {
if (TextUtils.isEmpty(filePath)) return null;
MediaMetadataRetriever mmr = new MediaMetadataRetriever();
try (FileInputStream in = new FileInputStream(filePath)) {
mmr.setDataSource(in.getFD());
return mmr.extractMetadata(key);
} catch (Exception e) {
return null;
} finally {
release(mmr);
}
}
/**
* 视频宽高,取不到返回 {0,0}。宽高一次打开取完,避免为了宽和高开两次文件
*/
private static int[] videoSize(String filePath) {
int[] empty = {0, 0};
if (TextUtils.isEmpty(filePath)) return empty;
MediaMetadataRetriever mmr = new MediaMetadataRetriever();
try (FileInputStream in = new FileInputStream(filePath)) {
mmr.setDataSource(in.getFD());
int width = parseInt(mmr.extractMetadata(MediaMetadataRetriever.METADATA_KEY_VIDEO_WIDTH));
int height = parseInt(mmr.extractMetadata(MediaMetadataRetriever.METADATA_KEY_VIDEO_HEIGHT));
return new int[]{width, height};
} catch (Exception e) {
return empty;
} finally {
release(mmr);
}
}
private static int parseInt(String value) {
try {
return Integer.parseInt(value);
} catch (Exception e) {
return 0;
}
}
private static void release(MediaMetadataRetriever mmr) {
try {
mmr.release();
} catch (Exception ignored) {
}
}
}
@@ -0,0 +1,96 @@
package io.flutter.plugins;
import android.app.Activity;
import android.content.Context;
import android.media.MediaCodecInfo;
import android.media.MediaCodecList;
import android.media.MediaFormat;
import android.os.Build;
import com.meituan.android.walle.WalleChannelReader;
import io.flutter.embedding.android.FlutterActivity;
import io.flutter.embedding.engine.FlutterEngine;
import io.flutter.plugin.common.MethodCall;
import io.flutter.plugin.common.MethodChannel;
/// 本地插件:设备号 / 视频文件信息 / 渠道号 / H265 硬解能力
public class JPNativePlugin implements MethodChannel.MethodCallHandler {
private static final String CHANNEL = "com.yinse/device";
private final Activity activity;
private JPNativePlugin(Activity activity) {
this.activity = activity;
}
/// 注册
public static void registerWith(FlutterActivity flutterActivity, FlutterEngine engine) {
MethodChannel channel = new MethodChannel(engine.getDartExecutor().getBinaryMessenger(), CHANNEL);
channel.setMethodCallHandler(new JPNativePlugin(flutterActivity));
}
/// 调用
@Override
public void onMethodCall(MethodCall call, MethodChannel.Result result) {
switch (call.method) {
case "getVideoDuration":
result.success(JPFileUtils.getVideoDuration(call.argument("filePath")));
break;
case "getVideoResolution":
result.success(JPFileUtils.getVideoResolution(call.argument("filePath")));
break;
case "getVideoRatio":
result.success(JPFileUtils.getVideoRatio(call.argument("filePath")));
break;
case "getVideoHeight":
result.success(JPFileUtils.getVideoHeight(call.argument("filePath")));
break;
case "getVideoBitrate":
result.success(JPFileUtils.getVideoBitrate(call.argument("filePath")));
break;
case "getChannel": // 获取android 渠道的东西
result.success(getChannel(activity));
break;
case "isH265HardwareSupported":
result.success(isHevcHardwareSupported());
break;
default:
// 不回 result 的话 Dart 那边的 Future 永远不完成
result.notImplemented();
}
}
/// 获取渠道号
public static String getChannel(Context context) {
return WalleChannelReader.getChannel(context);
}
/// 本机是否**硬解** H.265(HEVC)。只认硬解:软解(google/c2.android)当不支持,回落 264。
/// 查询编解码器能力,任何异常都按不支持处理。
private static boolean isHevcHardwareSupported() {
try {
MediaCodecList list = new MediaCodecList(MediaCodecList.REGULAR_CODECS);
for (MediaCodecInfo info : list.getCodecInfos()) {
if (info.isEncoder() || !supportsHevc(info)) continue;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
if (info.isHardwareAccelerated()) return true; // API29+ 直接问硬解
} else {
String name = info.getName().toLowerCase(); // 旧版本靠名字排除软解
if (!name.startsWith("omx.google.") && !name.startsWith("c2.android.")) return true;
}
}
} catch (Exception e) {
return false;
}
return false;
}
private static boolean supportsHevc(MediaCodecInfo info) {
for (String type : info.getSupportedTypes()) {
if (type.equalsIgnoreCase(MediaFormat.MIMETYPE_VIDEO_HEVC)) return true;
}
return false;
}
}
@@ -0,0 +1,5 @@
package com.xvproject
import io.flutter.app.FlutterApplication
class JPApplication : FlutterApplication()
@@ -0,0 +1,77 @@
package com.xvproject
import android.annotation.SuppressLint
import android.app.ActivityManager
import android.content.ComponentName
import android.content.Intent
import android.content.pm.PackageManager
import io.flutter.embedding.android.FlutterActivity
import io.flutter.embedding.engine.FlutterEngine
import io.flutter.plugin.common.MethodChannel
import io.flutter.plugins.JPNativePlugin
class MainActivity : FlutterActivity() {
override fun configureFlutterEngine(flutterEngine: FlutterEngine) {
super.configureFlutterEngine(flutterEngine)
JPNativePlugin.registerWith(this, flutterEngine)
MethodChannel(flutterEngine.dartExecutor.binaryMessenger, CHANNEL)
.setMethodCallHandler { call, result ->
when (call.method) {
METHOD_CHANGE_ICON -> {
val index = call.argument<Int>(ARG_ICON_INDEX) ?: -1
ICON_ALIASES.getOrNull(index)?.let { switchIcon("$ALIAS_PACKAGE.$it") }
result.success(true)
}
// 不回 result 的话 Dart 那边的 Future 永远不完成
else -> result.notImplemented()
}
}
}
/// 切换启动图标:禁用当前入口 + 启用目标 alias,再杀掉桌面进程让图标立刻刷新
private fun switchIcon(alias: String) {
val pm = packageManager
pm.setComponentEnabledSetting(
componentName,
PackageManager.COMPONENT_ENABLED_STATE_DISABLED, PackageManager.DONT_KILL_APP
)
pm.setComponentEnabledSetting(
ComponentName(this, alias),
PackageManager.COMPONENT_ENABLED_STATE_ENABLED, PackageManager.DONT_KILL_APP
)
restartLauncher(pm)
}
/// 杀掉桌面进程,强制它重读图标
@SuppressLint("ServiceCast")
private fun restartLauncher(pm: PackageManager) {
val am = getSystemService(ACTIVITY_SERVICE) as ActivityManager
val intent = Intent(Intent.ACTION_MAIN)
.addCategory(Intent.CATEGORY_HOME)
.addCategory(Intent.CATEGORY_DEFAULT)
for (info in pm.queryIntentActivities(intent, 0)) {
am.killBackgroundProcesses(info.activityInfo?.packageName ?: continue)
}
}
companion object {
//这个跟flutter的通道名称保持一致
private const val CHANNEL = "com.yinse/request"
private const val METHOD_CHANGE_ICON = "changeIcon"
private const val ARG_ICON_INDEX = "iconIndex"
/// 图标 alias 所在包名:AndroidManifest 里 activity-alias 写的是相对名(manifest package=com.xvproject),
/// 与 applicationId 不同,不能用 packageName 拼
private const val ALIAS_PACKAGE = "com.xvproject"
/// 下标即 Flutter 传来的 iconIndex,顺序必须与 manifest 里 activity-alias 的声明顺序一致
private val ICON_ALIASES = listOf(
"lld", "aiyinyue", "aiyuedu", "alipay", "bilibili", "binggandazhuozhan",
"meisijiejian", "myworld", "shenxuanzhizhan", "shuixinwuxian", "texuanxiaoshuo",
"tiantianmajiang", "tuyou", "weichat", "wendao", "yinyutusujiao",
"icon_16", "icon_17", "icon_18", //清明 / 端午 / 劳动
)
}
}
@@ -0,0 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Modify this file to customize your launch splash screen -->
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="?android:colorBackground" />
<!-- You can insert your own image assets here -->
<!-- <item>
<bitmap
android:gravity="center"
android:src="@mipmap/launch_image" />
</item> -->
</layer-list>
@@ -0,0 +1,74 @@
<?xml version="1.0" encoding="utf-8"?>
<vector
android:height="108dp"
android:width="108dp"
android:viewportHeight="108"
android:viewportWidth="108"
xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="#3DDC84"
android:pathData="M0,0h108v108h-108z"/>
<path android:fillColor="#00000000" android:pathData="M9,0L9,108"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M19,0L19,108"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M29,0L29,108"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M39,0L39,108"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M49,0L49,108"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M59,0L59,108"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M69,0L69,108"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M79,0L79,108"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M89,0L89,108"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M99,0L99,108"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M0,9L108,9"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M0,19L108,19"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M0,29L108,29"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M0,39L108,39"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M0,49L108,49"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M0,59L108,59"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M0,69L108,69"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M0,79L108,79"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M0,89L108,89"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M0,99L108,99"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M19,29L89,29"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M19,39L89,39"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M19,49L89,49"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M19,59L89,59"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M19,69L89,69"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M19,79L89,79"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M29,19L29,89"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M39,19L39,89"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M49,19L49,89"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M59,19L59,89"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M69,19L69,89"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M79,19L79,89"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
</vector>
@@ -0,0 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Modify this file to customize your launch splash screen -->
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@android:color/white" />
<!-- You can insert your own image assets here -->
<!-- <item>
<bitmap
android:gravity="center"
android:src="@mipmap/launch_image" />
</item> -->
</layer-list>
@@ -0,0 +1,13 @@
<?xml version="1.0" encoding="utf-8"?><!-- Modify this file to customize your launch splash screen -->
<layer-list xmlns:android="http://schemas.android.com/apk/res/android"
android:opacity="opaque">
<item android:gravity="center">
<bitmap
android:gravity="center_horizontal"
android:mipMap="true"
android:src="@mipmap/ic_splash_bg" />
</item>
</layer-list>
Binary file not shown.

After

Width:  |  Height:  |  Size: 50 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 103 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB

@@ -0,0 +1,18 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<!-- Theme applied to the Android Window while the process is starting when the OS's Dark Mode setting is on -->
<style name="LaunchTheme" parent="@android:style/Theme.Black.NoTitleBar">
<!-- Show a splash screen on the activity. Automatically removed when
the Flutter engine draws its first frame -->
<item name="android:windowBackground">@drawable/launch_background</item>
</style>
<!-- Theme applied to the Android Window as soon as the process has started.
This theme determines the color of the Android Window while your
Flutter UI initializes, as well as behind your Flutter UI while its
running.
This Theme is only used starting with V2 of Flutter's Android embedding. -->
<style name="NormalTheme" parent="@android:style/Theme.Black.NoTitleBar">
<item name="android:windowBackground">?android:colorBackground</item>
</style>
</resources>
@@ -0,0 +1,19 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="LaunchTheme" parent="@android:style/Theme.Black.NoTitleBar">
<item name="android:windowBackground">@drawable/launch_bg</item>
<item name="android:colorPrimary">#12131C</item>
<item name="colorPrimaryDark">#12131C</item>
<item name="colorAccent">#12131C</item>
<item name="android:windowNoTitle">true</item>
<item name="windowActionBar">false</item>
</style>
<!-- Flutter UI 初始化时及运行时的窗口背景;缺失会导致浅色模式下窗口透明 -->
<style name="NormalTheme" parent="@android:style/Theme.Black.NoTitleBar">
<item name="android:windowBackground">?android:colorBackground</item>
</style>
</resources>
@@ -0,0 +1,23 @@
<paths>
<external-path
name="external-path"
path="." />
<external-cache-path
name="external-cache-path"
path="." />
<external-files-path
name="external-files-path"
path="." />
<files-path
name="files_path"
path="." />
<cache-path
name="cache-path"
path="." />
<root-path
name="name"
path="." />
<external-path
name="external_storage_root"
path="." />
</paths>