1.多渠道打包
2.app更新页面
This commit is contained in:
@@ -4,9 +4,17 @@ plugins {
|
|||||||
|
|
||||||
}
|
}
|
||||||
android {
|
android {
|
||||||
|
// 1. 定义渠道维度(必须配置,否则报错)
|
||||||
|
flavorDimensions "environment"
|
||||||
|
|
||||||
|
|
||||||
namespace 'com.xscm.midi'
|
namespace 'com.xscm.midi'
|
||||||
compileSdk 35
|
compileSdk 35
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
defaultConfig {
|
defaultConfig {
|
||||||
applicationId "com.xscm.midi"
|
applicationId "com.xscm.midi"
|
||||||
minSdk 24
|
minSdk 24
|
||||||
@@ -19,7 +27,7 @@ android {
|
|||||||
ndk {
|
ndk {
|
||||||
//设置支持的so库
|
//设置支持的so库
|
||||||
// abiFilters 'arm64-v8a', 'armeabi','arm64'
|
// abiFilters 'arm64-v8a', 'armeabi','arm64'
|
||||||
abiFilters 'arm64-v8a','armeabi-v7a'
|
abiFilters 'arm64-v8a', 'armeabi-v7a'
|
||||||
}
|
}
|
||||||
|
|
||||||
javaCompileOptions {
|
javaCompileOptions {
|
||||||
@@ -30,12 +38,50 @@ android {
|
|||||||
]
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// 【默认图标占位符】后续会被渠道配置覆盖
|
||||||
|
manifestPlaceholders = [
|
||||||
|
icon: "@mipmap/ic_launcher_app" // 默认图标(main目录下的图标)
|
||||||
|
]
|
||||||
|
|
||||||
// signingConfig signingConfigs.release
|
// signingConfig signingConfigs.release
|
||||||
// proguardFiles 'proguard-rules.pro'
|
// proguardFiles 'proguard-rules.pro'
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 2. 配置测试版和正式版渠道
|
||||||
|
productFlavors {
|
||||||
|
// 正式版配置
|
||||||
|
releas {
|
||||||
|
dimension "environment"
|
||||||
|
// 正式版包名:使用基础包名(com.example.myapp)
|
||||||
|
applicationIdSuffix ""
|
||||||
|
|
||||||
|
// 【正式版应用名称】通过resValue动态生成string资源
|
||||||
|
resValue "string", "app_name", "秘地"
|
||||||
|
|
||||||
|
// 【正式版图标】替换manifest中的占位符(使用main目录下的正式图标)
|
||||||
|
manifestPlaceholders = [
|
||||||
|
appIcon: "@mipmap/ic_launcher_app" // 需在main/res/mipmap放置该图标
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
// 测试版配置
|
||||||
|
beta {
|
||||||
|
dimension "environment"
|
||||||
|
// 测试版包名:基础包名 + .beta(com.example.myapp.beta)
|
||||||
|
applicationIdSuffix ".beta"
|
||||||
|
// 测试版版本名:1.0-beta
|
||||||
|
versionNameSuffix "-beta"
|
||||||
|
|
||||||
|
// 【测试版应用名称】动态生成带标识的名称
|
||||||
|
resValue "string", "app_name", "秘地-测试版"
|
||||||
|
|
||||||
|
// 【测试版图标】替换为测试专用图标
|
||||||
|
manifestPlaceholders = [
|
||||||
|
appIcon: "@mipmap/ic_launcher_app_bat" // 需在main/res/mipmap放置该图标
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
signingConfigs {
|
signingConfigs {
|
||||||
|
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ isBuildModule=false
|
|||||||
android.injected.testOnly=false
|
android.injected.testOnly=false
|
||||||
|
|
||||||
APP_VERSION_NAME=1.1.3
|
APP_VERSION_NAME=1.1.3
|
||||||
APP_VERSION_CODE=166
|
APP_VERSION_CODE=165
|
||||||
|
|
||||||
org.gradle.jvm.toolchain.useLegacyAdapters=false
|
org.gradle.jvm.toolchain.useLegacyAdapters=false
|
||||||
#org.gradle.java.home=C\:\\Users\\qx\\.jdks\\ms-17.0.15
|
#org.gradle.java.home=C\:\\Users\\qx\\.jdks\\ms-17.0.15
|
||||||
|
|||||||
@@ -9,12 +9,14 @@ import androidx.annotation.NonNull;
|
|||||||
import android.text.Html;
|
import android.text.Html;
|
||||||
import android.text.TextUtils;
|
import android.text.TextUtils;
|
||||||
import android.text.method.ScrollingMovementMethod;
|
import android.text.method.ScrollingMovementMethod;
|
||||||
|
import android.util.Log;
|
||||||
import android.view.KeyEvent;
|
import android.view.KeyEvent;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.Window;
|
import android.view.Window;
|
||||||
import android.view.WindowManager;
|
import android.view.WindowManager;
|
||||||
|
|
||||||
import com.blankj.utilcode.util.AppUtils;
|
import com.blankj.utilcode.util.AppUtils;
|
||||||
|
import com.blankj.utilcode.util.LogUtils;
|
||||||
import com.blankj.utilcode.util.ScreenUtils;
|
import com.blankj.utilcode.util.ScreenUtils;
|
||||||
import com.blankj.utilcode.util.ToastUtils;
|
import com.blankj.utilcode.util.ToastUtils;
|
||||||
import com.xscm.moduleutil.R;
|
import com.xscm.moduleutil.R;
|
||||||
@@ -22,6 +24,7 @@ import com.xscm.moduleutil.bean.AppUpdateModel;
|
|||||||
import com.xscm.moduleutil.databinding.DialogAppUpdateBinding;
|
import com.xscm.moduleutil.databinding.DialogAppUpdateBinding;
|
||||||
import com.xscm.moduleutil.utils.DownloadListener;
|
import com.xscm.moduleutil.utils.DownloadListener;
|
||||||
import com.xscm.moduleutil.utils.DownloadUtil;
|
import com.xscm.moduleutil.utils.DownloadUtil;
|
||||||
|
import com.xscm.moduleutil.utils.TextViewUtils;
|
||||||
import com.xscm.moduleutil.utils.logger.Logger;
|
import com.xscm.moduleutil.utils.logger.Logger;
|
||||||
import com.xscm.moduleutil.widget.dialog.BaseDialog;
|
import com.xscm.moduleutil.widget.dialog.BaseDialog;
|
||||||
|
|
||||||
@@ -77,7 +80,11 @@ public class AppUpdateDialog extends BaseDialog<DialogAppUpdateBinding> implemen
|
|||||||
|
|
||||||
public void setAppUpdateModel(AppUpdateModel appUpdateModel) {
|
public void setAppUpdateModel(AppUpdateModel appUpdateModel) {
|
||||||
this.appUpdateModel = appUpdateModel;
|
this.appUpdateModel = appUpdateModel;
|
||||||
mBinding.tvContent.setText(TextUtils.isEmpty(appUpdateModel.getContent()) ? "修复旧版本已知bug" : Html.fromHtml(appUpdateModel.getContent()));
|
TextViewUtils.setHtmlText(mBinding.tvContent,appUpdateModel.getContent(),false);
|
||||||
|
//mBinding.tvContent.setText(TextUtils.isEmpty(appUpdateModel.getContent()) ? "修复旧版本已知bug" : Html.fromHtml(appUpdateModel.getContent()));
|
||||||
|
LogUtils.d("AppUpdateDialog", "setAppUpdateModel " + appUpdateModel.getContent().toString());
|
||||||
|
// mBinding.tvContent.setHtmlText(appUpdateModel.getContent());
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,171 @@
|
|||||||
|
package com.xscm.moduleutil.utils;
|
||||||
|
import android.graphics.Color;
|
||||||
|
import android.graphics.Typeface;
|
||||||
|
import android.os.Build;
|
||||||
|
import android.text.Html;
|
||||||
|
import android.text.Spannable;
|
||||||
|
import android.text.SpannableString;
|
||||||
|
import android.text.method.LinkMovementMethod;
|
||||||
|
import android.text.style.BackgroundColorSpan;
|
||||||
|
import android.text.style.ClickableSpan;
|
||||||
|
import android.text.style.ForegroundColorSpan;
|
||||||
|
import android.text.style.RelativeSizeSpan;
|
||||||
|
import android.text.style.StrikethroughSpan;
|
||||||
|
import android.text.style.StyleSpan;
|
||||||
|
import android.text.style.UnderlineSpan;
|
||||||
|
import android.view.View;
|
||||||
|
import android.widget.TextView;
|
||||||
|
|
||||||
|
import androidx.annotation.ColorInt;
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* TextView 富文本工具类(Java实现)
|
||||||
|
* 支持HTML解析、部分文本样式、点击事件等功能
|
||||||
|
*/
|
||||||
|
public class TextViewUtils {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 显示HTML格式文本
|
||||||
|
* @param textView 目标TextView
|
||||||
|
* @param htmlContent HTML内容字符串
|
||||||
|
*/
|
||||||
|
public static void setHtmlText(TextView textView, String htmlContent) {
|
||||||
|
setHtmlText(textView, htmlContent, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 显示HTML格式文本(可控制链接点击)
|
||||||
|
* @param textView 目标TextView
|
||||||
|
* @param htmlContent HTML内容字符串
|
||||||
|
* @param enableLinks 是否启用链接点击
|
||||||
|
*/
|
||||||
|
public static void setHtmlText(TextView textView, String htmlContent, boolean enableLinks) {
|
||||||
|
if (textView == null || htmlContent == null) return;
|
||||||
|
|
||||||
|
// 处理不同Android版本的HTML解析
|
||||||
|
CharSequence spannedText;
|
||||||
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
|
||||||
|
spannedText = Html.fromHtml(htmlContent, Html.FROM_HTML_MODE_COMPACT);
|
||||||
|
} else {
|
||||||
|
// 兼容Android N以下版本
|
||||||
|
spannedText = Html.fromHtml(htmlContent);
|
||||||
|
}
|
||||||
|
|
||||||
|
textView.setText(spannedText);
|
||||||
|
|
||||||
|
// 启用链接点击功能
|
||||||
|
if (enableLinks) {
|
||||||
|
textView.setMovementMethod(LinkMovementMethod.getInstance());
|
||||||
|
textView.setHighlightColor(Color.TRANSPARENT); // 去除点击高亮
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 给部分文本设置样式
|
||||||
|
* @param textView 目标TextView
|
||||||
|
* @param fullText 完整文本
|
||||||
|
* @param targetText 需要设置样式的子文本
|
||||||
|
* @param spans 样式集合(可传入多个)
|
||||||
|
*/
|
||||||
|
public static void setPartialStyle(TextView textView, String fullText,
|
||||||
|
String targetText, Object... spans) {
|
||||||
|
if (textView == null || fullText == null || targetText == null) return;
|
||||||
|
|
||||||
|
int startIndex = fullText.indexOf(targetText);
|
||||||
|
if (startIndex == -1) {
|
||||||
|
textView.setText(fullText);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int endIndex = startIndex + targetText.length();
|
||||||
|
SpannableString spannable = new SpannableString(fullText);
|
||||||
|
|
||||||
|
// 应用所有样式
|
||||||
|
for (Object span : spans) {
|
||||||
|
spannable.setSpan(span, startIndex, endIndex, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
|
||||||
|
}
|
||||||
|
|
||||||
|
textView.setText(spannable);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设置可点击文本
|
||||||
|
* @param textView 目标TextView
|
||||||
|
* @param fullText 完整文本
|
||||||
|
* @param clickText 可点击的子文本
|
||||||
|
* @param linkColor 链接颜色
|
||||||
|
* @param isUnderline 是否显示下划线
|
||||||
|
* @param listener 点击事件监听器
|
||||||
|
*/
|
||||||
|
public static void setClickableText(TextView textView, String fullText, String clickText,
|
||||||
|
@ColorInt int linkColor, boolean isUnderline,
|
||||||
|
OnClickableTextListener listener) {
|
||||||
|
if (textView == null || fullText == null || clickText == null || listener == null) return;
|
||||||
|
|
||||||
|
int startIndex = fullText.indexOf(clickText);
|
||||||
|
if (startIndex == -1) {
|
||||||
|
textView.setText(fullText);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int endIndex = startIndex + clickText.length();
|
||||||
|
SpannableString spannable = new SpannableString(fullText);
|
||||||
|
|
||||||
|
// 创建可点击样式
|
||||||
|
ClickableSpan clickableSpan = new ClickableSpan() {
|
||||||
|
@Override
|
||||||
|
public void onClick(@NonNull View widget) {
|
||||||
|
listener.onClick();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void updateDrawState(@NonNull android.text.TextPaint ds) {
|
||||||
|
super.updateDrawState(ds);
|
||||||
|
ds.setColor(linkColor);
|
||||||
|
ds.setUnderlineText(isUnderline);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
spannable.setSpan(clickableSpan, startIndex, endIndex, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
|
||||||
|
textView.setText(spannable);
|
||||||
|
textView.setMovementMethod(LinkMovementMethod.getInstance());
|
||||||
|
textView.setHighlightColor(Color.TRANSPARENT);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 快捷创建样式的工具方法
|
||||||
|
public static StyleSpan createBoldSpan() {
|
||||||
|
return new StyleSpan(Typeface.BOLD);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static StyleSpan createItalicSpan() {
|
||||||
|
return new StyleSpan(Typeface.ITALIC);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ForegroundColorSpan createTextColorSpan(@ColorInt int color) {
|
||||||
|
return new ForegroundColorSpan(color);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static BackgroundColorSpan createBgColorSpan(@ColorInt int color) {
|
||||||
|
return new BackgroundColorSpan(color);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static UnderlineSpan createUnderlineSpan() {
|
||||||
|
return new UnderlineSpan();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static StrikethroughSpan createStrikethroughSpan() {
|
||||||
|
return new StrikethroughSpan();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static RelativeSizeSpan createTextSizeSpan(float proportion) {
|
||||||
|
return new RelativeSizeSpan(proportion);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 可点击文本的监听器接口
|
||||||
|
*/
|
||||||
|
public interface OnClickableTextListener {
|
||||||
|
void onClick();
|
||||||
|
}
|
||||||
|
}
|
||||||
File diff suppressed because one or more lines are too long
@@ -332,7 +332,7 @@ public class MainActivity extends BaseMvpActivity<HomePresenter, ActivityMainBin
|
|||||||
mBinding.ivGuanbi.setOnClickListener(this);
|
mBinding.ivGuanbi.setOnClickListener(this);
|
||||||
mBinding.riv.setOnClickListener(this);
|
mBinding.riv.setOnClickListener(this);
|
||||||
mBinding.ivShouchl.setOnClickListener(this);
|
mBinding.ivShouchl.setOnClickListener(this);
|
||||||
//requestGpsPermissions();
|
requestGpsPermissions();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -572,9 +572,7 @@ public class MainActivity extends BaseMvpActivity<HomePresenter, ActivityMainBin
|
|||||||
PermissionX.init(this)
|
PermissionX.init(this)
|
||||||
// 请求精确位置权限(包含GPS定位能力)
|
// 请求精确位置权限(包含GPS定位能力)
|
||||||
.permissions(
|
.permissions(
|
||||||
Manifest.permission.ACCESS_FINE_LOCATION,
|
Manifest.permission.ACCESS_FINE_LOCATION
|
||||||
// 如需后台使用GPS,添加此权限(Android 10+)
|
|
||||||
Manifest.permission.ACCESS_BACKGROUND_LOCATION
|
|
||||||
)
|
)
|
||||||
// 权限请求结果回调
|
// 权限请求结果回调
|
||||||
.request(new RequestCallback() {
|
.request(new RequestCallback() {
|
||||||
|
|||||||
Reference in New Issue
Block a user