diff --git a/FlycoTabLayoutZ_Lib/build.gradle b/FlycoTabLayoutZ_Lib/build.gradle index 6e30d02..ad47ed6 100644 --- a/FlycoTabLayoutZ_Lib/build.gradle +++ b/FlycoTabLayoutZ_Lib/build.gradle @@ -3,8 +3,9 @@ apply plugin: 'com.android.library' version = "1.3.3" android { + namespace "com.flyco.tablayout" + compileSdkVersion 28 - buildToolsVersion "28.0.3" defaultConfig { minSdkVersion 17 diff --git a/FlycoTabLayoutZ_Lib/src/main/AndroidManifest.xml b/FlycoTabLayoutZ_Lib/src/main/AndroidManifest.xml index 65a3365..e0a940b 100644 --- a/FlycoTabLayoutZ_Lib/src/main/AndroidManifest.xml +++ b/FlycoTabLayoutZ_Lib/src/main/AndroidManifest.xml @@ -1,3 +1 @@ - - + diff --git a/MDM_Run.bat b/MDM_Run.bat new file mode 100644 index 0000000..9bccb31 --- /dev/null +++ b/MDM_Run.bat @@ -0,0 +1,8 @@ +# Android Studio Panda 4 运行会报错 +# Couldn't terminate previous instance of app +# 1. 构建 APK +./gradlew :app:assembleDebug +# 2. 直接安装(不主动执行 am force-stop) +adb install -r -t app/build/outputs/apk/debug/app_debug.apk +# 3. 启动应用 powershell 可以用";"连接 +adb shell am start -n com.xwad.os/.activity.home.HomeActivity diff --git a/PhotoPreview/build.gradle b/PhotoPreview/build.gradle index 62e7b1b..e92ca9c 100644 --- a/PhotoPreview/build.gradle +++ b/PhotoPreview/build.gradle @@ -1,7 +1,10 @@ apply plugin: 'com.android.library' android { + namespace "com.wgw.photo.preview" + compileSdkVersion 29 + defaultConfig { minSdkVersion 23 targetSdkVersion 29 diff --git a/PhotoPreview/src/main/AndroidManifest.xml b/PhotoPreview/src/main/AndroidManifest.xml index 00e99bd..572ede9 100644 --- a/PhotoPreview/src/main/AndroidManifest.xml +++ b/PhotoPreview/src/main/AndroidManifest.xml @@ -1,2 +1 @@ - + diff --git a/PhotoPreview/src/main/java/com/wgw/photo/preview/PreviewDialogFragment.java b/PhotoPreview/src/main/java/com/wgw/photo/preview/PreviewDialogFragment.java index 6756ed7..276af86 100644 --- a/PhotoPreview/src/main/java/com/wgw/photo/preview/PreviewDialogFragment.java +++ b/PhotoPreview/src/main/java/com/wgw/photo/preview/PreviewDialogFragment.java @@ -20,24 +20,12 @@ import android.view.ViewGroup; import android.view.ViewParent; import android.view.ViewTreeObserver.OnGlobalLayoutListener; import android.view.Window; -import android.view.WindowInsets; -import android.view.WindowInsetsController; import android.view.WindowManager.LayoutParams; import android.widget.FrameLayout; import android.widget.ImageView; import android.widget.LinearLayout; import android.widget.TextView; -import com.wgw.photo.preview.PreloadImageView.DrawableLoadListener; -import com.wgw.photo.preview.interfaces.IFindThumbnailView; -import com.wgw.photo.preview.interfaces.OnDismissListener; -import com.wgw.photo.preview.util.SpannableString; -import com.wgw.photo.preview.util.Utils; -import com.wgw.photo.preview.util.notch.CutOutMode; -import com.wgw.photo.preview.util.notch.NotchAdapterUtils; - -import java.util.Objects; - import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.annotation.RestrictTo; @@ -50,6 +38,16 @@ import androidx.fragment.app.FragmentManager; import androidx.lifecycle.Lifecycle.State; import androidx.viewpager.widget.ViewPager.SimpleOnPageChangeListener; +import com.wgw.photo.preview.PreloadImageView.DrawableLoadListener; +import com.wgw.photo.preview.interfaces.IFindThumbnailView; +import com.wgw.photo.preview.interfaces.OnDismissListener; +import com.wgw.photo.preview.util.SpannableString; +import com.wgw.photo.preview.util.Utils; +import com.wgw.photo.preview.util.notch.CutOutMode; +import com.wgw.photo.preview.util.notch.NotchAdapterUtils; + +import java.util.Objects; + /** * 预览界面根布局 * diff --git a/app/build.gradle b/app/build.gradle index c875bc3..b60addc 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -9,6 +9,9 @@ def releaseTime() { } android { + namespace "com.xwad.os" + + buildToolsVersion "36.0.0" compileSdkVersion 29 defaultConfig { @@ -22,25 +25,12 @@ android { testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" - multiDexEnabled true - - vectorDrawables.useSupportLibrary = true - - compileOptions { - sourceCompatibility JavaVersion.VERSION_1_8 - targetCompatibility JavaVersion.VERSION_1_8 - } - ndk { //根据需要 自行选择添加的对应cpu类型的.so库。 abiFilters 'armeabi-v7a', 'arm64-v8a' // 还可以添加 'armeabi', 'x86', 'x86_64', 'mips', 'mips64' } - dataBinding { - enabled true - } - lintOptions { checkReleaseBuilds false // Or, if you prefer, you can continue to check for errors in release builds, @@ -48,6 +38,10 @@ android { abortOnError false } + multiDexEnabled true + + vectorDrawables.useSupportLibrary = true + aaptOptions.cruncherEnabled = false aaptOptions.useNewCruncher = false @@ -66,6 +60,17 @@ android { ] } + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } + + buildFeatures { + dataBinding true + buildConfig true + aidl true + } + externalNativeBuild { cmake { path file('CMakeLists.txt') @@ -87,70 +92,132 @@ android { applicationVariants.all { variant -> def variantName = variant.name.capitalize() - // 建议使用 packageApplication 任务,它更明确指向 APK 生成 + // 建议使用 packageApplication 任务,它更明确指向 APK 生成 def packageTask = tasks.findByName("package${variantName}") if (packageTask) { packageTask.doLast { - // 1. 配置路径优化:尽量使用 project 属性,避免写死 E:\ 盘符 - def cerFile = file("E:\\Xuewang365\\HonorCer\\HONOR.CER") - if (!cerFile.exists()) { - println "⚠️ 未找到证书文件: ${cerFile.path}" - return - } - - def sdkDir = android.sdkDirectory.path -// def buildToolsVersion = android.buildToolsVersion // 建议动态获取,除非有特定版本要求 - def buildToolsVersion = "33.0.0" - def buildToolsPath = "${sdkDir}/build-tools/${buildToolsVersion}" - def aaptPath = "${buildToolsPath}/aapt${org.gradle.internal.os.OperatingSystem.current().isWindows() ? '.exe' : ''}" - def apksignerPath = "${buildToolsPath}/apksigner${org.gradle.internal.os.OperatingSystem.current().isWindows() ? '.bat' : ''}" - - // 2. 关键优化:精准定位当前 Variant 的输出文件 - // 使用 variant.outputs 获取当前构建生成的特定文件 - variant.outputs.all { output -> - def apkFile = output.outputFile - println "APK地址:${apkFile.absolutePath}" - - if (apkFile != null && apkFile.name.endsWith(".apk")) { - println "🛠️ 开始对当前 APK 注入: ${apkFile.name}" - - // 3. 准备 META-INF 临时结构 - def tempBaseDir = new File(project.buildDir, "intermediates/honor_cer_temp/${variant.name}") - def metaInfDir = new File(tempBaseDir, "META-INF") - metaInfDir.deleteDir() // 清理旧数据 - metaInfDir.mkdirs() - - def targetFile = new File(metaInfDir, cerFile.name) - ant.copy(file: cerFile, tofile: targetFile) - - // 4. 调用 aapt 注入 - exec { - workingDir tempBaseDir - commandLine aaptPath, "add", apkFile.absolutePath, "META-INF/${cerFile.name}" - } - - // 5. 重新签名 (Apksigner) - def signingConfig = variant.signingConfig - if (signingConfig != null && signingConfig.storeFile.exists()) { - exec { - commandLine apksignerPath, "sign", - "--ks", signingConfig.storeFile.absolutePath, - "--ks-pass", "pass:${signingConfig.storePassword}", - "--ks-key-alias", signingConfig.keyAlias, - "--key-pass", "pass:${signingConfig.keyPassword}", - "--v2-signing-enabled", "true", - "--v3-signing-enabled", "true", - apkFile.path - } - println "✅ [${variant.name}] 注入并修复签名成功!" - } else { - println "❌ [${variant.name}] 签名失败:SigningConfig 配置无效" - } - - // 清理临时目录 - tempBaseDir.deleteDir() + try { + // 1. 配置路径优化:尽量使用 project 属性,避免写死 E:\ 盘符 + def cerFile = file("E:\\Huawei\\MagicOSSdk\\HONOR.CER") + if (!cerFile.exists()) { + println "⚠️ 未找到证书文件: ${cerFile.path},跳过注入步骤" + return } + + def sdkDir = android.sdkDirectory.path +// def buildToolsVersion = android.buildToolsVersion // 建议动态获取,除非有特定版本要求 + def buildToolsVersion = "36.0.0" + def buildToolsPath = "${sdkDir}/build-tools/${buildToolsVersion}" + def aaptPath = "${buildToolsPath}/aapt${org.gradle.internal.os.OperatingSystem.current().isWindows() ? '.exe' : ''}" + def apksignerPath = "${buildToolsPath}/apksigner${org.gradle.internal.os.OperatingSystem.current().isWindows() ? '.bat' : ''}" + + // 验证工具是否存在 + if (!file(aaptPath).exists()) { + println "❌ 未找到 aapt 工具: ${aaptPath}" + return + } + if (!file(apksignerPath).exists()) { + println "❌ 未找到 apksigner 工具: ${apksignerPath}" + return + } + + // 2. 关键优化:精准定位当前 Variant 的输出文件 + // 使用 variant.outputs 获取当前构建生成的特定文件 + variant.outputs.each { output -> + def apkFile = output.outputFile + + if (apkFile == null) { + println "⚠️ APK 文件为 null,跳过处理" + return + } + + if (!apkFile.exists()) { + println "⚠️ APK 文件不存在: ${apkFile.absolutePath},跳过处理" + return + } + + println "APK地址:${apkFile.absolutePath}" + + if (apkFile.name.endsWith(".apk")) { + println "🛠️ 开始对当前 APK 注入: ${apkFile.name}" + + try { + // 3. 准备 META-INF 临时结构 + def tempBaseDir = new File(project.buildDir, "intermediates/honor_cer_temp/${variant.name}") + def metaInfDir = new File(tempBaseDir, "META-INF") + + // 确保清理旧数据 + if (metaInfDir.exists()) { + metaInfDir.deleteDir() + } + metaInfDir.mkdirs() + + def targetFile = new File(metaInfDir, cerFile.name) + ant.copy(file: cerFile, tofile: targetFile) + + // 4. 调用 aapt 注入 - 添加错误输出捕获 + println "执行命令: ${aaptPath} add ${apkFile.absolutePath} META-INF/${cerFile.name}" + def aaptResult = exec { + workingDir tempBaseDir + commandLine aaptPath, "add", apkFile.absolutePath, "META-INF/${cerFile.name}" + ignoreExitValue = true // 不立即失败,让我们自己处理 + standardOutput = new ByteArrayOutputStream() + errorOutput = new ByteArrayOutputStream() + } + + if (aaptResult.exitValue != 0) { + def errorMsg = aaptResult.errorOutput.toString() + println "❌ aapt 执行失败 (退出码: ${aaptResult.exitValue})" + println "错误信息: ${errorMsg}" + println "尝试继续重新签名..." + } else { + println "✅ aapt 注入成功" + } + + // 5. 重新签名 (Apksigner) + def signingConfig = variant.signingConfig + if (signingConfig != null && signingConfig.storeFile != null && signingConfig.storeFile.exists()) { + println "执行签名..." + def signResult = exec { + commandLine apksignerPath, "sign", + "--ks", signingConfig.storeFile.absolutePath, + "--ks-pass", "pass:${signingConfig.storePassword}", + "--ks-key-alias", signingConfig.keyAlias, + "--key-pass", "pass:${signingConfig.keyPassword}", + "--v2-signing-enabled", "true", + "--v3-signing-enabled", "true", + apkFile.path + ignoreExitValue = true + standardOutput = new ByteArrayOutputStream() + errorOutput = new ByteArrayOutputStream() + } + + if (signResult.exitValue == 0) { + println "✅ [${variant.name}] 注入并修复签名成功!" + } else { + def errorMsg = signResult.errorOutput.toString() + println "❌ [${variant.name}] 签名失败 (退出码: ${signResult.exitValue})" + println "错误信息: ${errorMsg}" + } + } else { + println "❌ [${variant.name}] 签名失败:SigningConfig 配置无效" + } + + // 清理临时目录 + if (tempBaseDir.exists()) { + tempBaseDir.deleteDir() + } + } catch (Exception e) { + println "❌ 处理 APK 时发生异常: ${e.message}" + e.printStackTrace() + } + } + } + } catch (Exception e) { + println "❌ 证书注入过程发生严重错误: ${e.message}" + e.printStackTrace() + // 不中断构建流程 } } } @@ -161,44 +228,34 @@ android { debug { versionNameSuffix "-debug" minifyEnabled false - //Zipalign优化 - zipAlignEnabled true buildConfigField "String", "platform", '"HONOR"' signingConfig signingConfigs.tuixin - applicationVariants.all { variant -> - variant.outputs.each { output -> - if (outputFile != null) { -// def app_name = getResValues().get("app_name").value - def fileName = "${appName()}_${variant.versionCode}_V${variant.versionName}_${releaseTime()}_${buildType.name}.apk" - output.outputFileName = fileName - } - } - } } release { minifyEnabled false - //Zipalign优化 - zipAlignEnabled true //前一部分代表系统默认的android程序的混淆文件,该文件已经包含了基本的混淆声明,后一个文件是自己的定义混淆文件 - proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' - //签名 + proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' signingConfig signingConfigs.tuixin buildConfigField "String", "platform", '"HONOR"' -// 将release版本的包名重命名,加上版本及日期 - applicationVariants.all { variant -> - variant.outputs.each { output -> - def outputFile = "" - if (outputFile != null) { -// def app_name = getResValues().get("app_name").value - def fileName = "${appName()}_${variant.versionCode}_V${variant.versionName}_${releaseTime()}_${buildType.name}.apk" - output.outputFileName = new File(outputFile, fileName) - } - } - } } } + // Add application variant configuration here instead + applicationVariants.all { variant -> + variant.outputs.each { output -> + def buildType = variant.buildType.name + def fileName = "" + + if (buildType.contains("debug")) { + fileName = "${appName()}_V${defaultConfig.versionName}_${releaseTime()}.apk" + } else { + fileName = "${appName()}_${variant.versionCode}_V${variant.versionName}_${releaseTime()}_${buildType}.apk" + } + + output.outputFileName = fileName + } + } } @@ -316,22 +373,32 @@ dependencies { implementation 'org.greenrobot:eventbus:3.3.1' } -preBuild { - doLast { - def imlFile = file(project.name + ".iml") -// def imlFile = file("..\\.idea\\modules\\" + project.name + "\\" + rootProject.name + "." + project.name + ".iml") - println 'Change ' + project.name + '.iml order' - try { - def parsedXml = (new XmlParser()).parse(imlFile) - def jdkNode = parsedXml.component[1].orderEntry.find { it.'@type' == 'jdk' } - parsedXml.component[1].remove(jdkNode) - def sdkString = "Android API " + android.compileSdkVersion.substring("android-".length()) + " Platform" - println 'what' + sdkString - new Node(parsedXml.component[1], 'orderEntry', ['type': 'jdk', 'jdkName': sdkString, 'jdkType': 'Android SDK']) - groovy.xml.XmlUtil.serialize(parsedXml, new FileOutputStream(imlFile)) - } catch (FileNotFoundException e) { - // nop, iml not found - println "no iml found" - } +// 在 dependencies 之后添加 +project.afterEvaluate { + android.applicationVariants.all { variant -> + variant.javaCompileProvider.get().options.bootstrapClasspath = files( + file('libs/framework.jar'), + android.getBootClasspath() + ) } } + +//preBuild { +// doLast { +// def imlFile = file(project.name + ".iml") +//// def imlFile = file("..\\.idea\\modules\\" + project.name + "\\" + rootProject.name + "." + project.name + ".iml") +// println 'Change ' + project.name + '.iml order' +// try { +// def parsedXml = (new XmlParser()).parse(imlFile) +// def jdkNode = parsedXml.component[1].orderEntry.find { it.'@type' == 'jdk' } +// parsedXml.component[1].remove(jdkNode) +// def sdkString = "Android API " + android.compileSdkVersion.substring("android-".length()) + " Platform" +// println 'what' + sdkString +// new Node(parsedXml.component[1], 'orderEntry', ['type': 'jdk', 'jdkName': sdkString, 'jdkType': 'Android SDK']) +// groovy.xml.XmlUtil.serialize(parsedXml, new FileOutputStream(imlFile)) +// } catch (FileNotFoundException e) { +// // nop, iml not found +// println "no iml found" +// } +// } +//} diff --git a/app/src/main/res/drawable/ps_image_placeholder.xml b/app/src/main/res/drawable/ps_image_placeholder.xml new file mode 100644 index 0000000..ee5c625 --- /dev/null +++ b/app/src/main/res/drawable/ps_image_placeholder.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/build.gradle b/build.gradle index 6d2fcb8..73b49b9 100644 --- a/build.gradle +++ b/build.gradle @@ -3,10 +3,11 @@ buildscript { repositories { google() -// mavenCentral() + mavenCentral() maven { url 'https://jitpack.io' } - maven { url 'https://developer.hihonor.com/repo' } + maven { url 'https://maven.google.com' } maven { url 'https://developer.huawei.com/repo/' } + maven { url 'https://developer.hihonor.com/repo' } maven { url 'https://maven.aliyun.com/repository/central' } maven { url 'https://maven.aliyun.com/repository/jcenter' } maven { url 'https://maven.aliyun.com/repository/public' } @@ -14,7 +15,7 @@ buildscript { } dependencies { - classpath 'com.android.tools.build:gradle:3.6.4' + classpath 'com.android.tools.build:gradle:8.13.2' // NOTE: Do not place your application dependencies here; they belong // in the individual module build.gradle files @@ -25,12 +26,35 @@ allprojects { configurations.all { resolutionStrategy { force 'androidx.constraintlayout:constraintlayout:2.0.4' + force 'androidx.core:core:1.5.0' + + //for targetSdkVersion 29 + force 'androidx.activity:activity:1.2.2' + force 'androidx.lifecycle:lifecycle-livedata:2.3.1' + force 'androidx.lifecycle:lifecycle-livedata-core:2.3.1' + force 'androidx.lifecycle:lifecycle-runtime:2.3.1' + force 'androidx.lifecycle:lifecycle-viewmodel:2.3.1' + force 'androidx.lifecycle:lifecycle-viewmodel-savedstate:2.3.1' + force 'androidx.lifecycle:lifecycle-service:2.3.1' + force 'androidx.lifecycle:lifecycle-process:2.3.1' + force 'androidx.lifecycle:lifecycle-runtime-ktx:2.3.1' + force 'androidx.savedstate:savedstate:1.1.0' + force 'androidx.profileinstaller:profileinstaller:1.1.0' + force 'androidx.startup:startup-runtime:1.0.0' + force 'androidx.arch.core:core-runtime:2.1.0' + force 'androidx.sqlite:sqlite:2.1.0' + force 'androidx.sqlite:sqlite-framework:2.1.0' + force 'androidx.fragment:fragment:1.3.6' + force 'androidx.room:room-runtime:2.3.0' + } } + repositories { google() -// mavenCentral() + mavenCentral() maven { url 'https://jitpack.io' } + maven { url 'https://maven.google.com' } maven { url 'https://developer.huawei.com/repo/' } maven { url 'https://developer.hihonor.com/repo' } maven { url 'https://maven.aliyun.com/repository/central' } diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index a501ef7..1056b7c 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-5.6.4-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.13-bin.zip diff --git a/niceimageview/build.gradle b/niceimageview/build.gradle index 2d83a3e..a88e9fa 100644 --- a/niceimageview/build.gradle +++ b/niceimageview/build.gradle @@ -1,6 +1,8 @@ apply plugin: 'com.android.library' android { + namespace "com.shehuan.niv" + compileSdkVersion 28 defaultConfig { diff --git a/niceimageview/src/main/AndroidManifest.xml b/niceimageview/src/main/AndroidManifest.xml index 6dab987..a215831 100644 --- a/niceimageview/src/main/AndroidManifest.xml +++ b/niceimageview/src/main/AndroidManifest.xml @@ -1,2 +1 @@ - + diff --git a/verification-view/build.gradle b/verification-view/build.gradle index f662b9b..735b71c 100644 --- a/verification-view/build.gradle +++ b/verification-view/build.gradle @@ -1,9 +1,9 @@ apply plugin: 'com.android.library' android { - compileSdkVersion 25 - buildToolsVersion '25.0.2' + namespace "com.tuo.customview" + compileSdkVersion 25 defaultConfig { minSdkVersion 15 diff --git a/verification-view/src/main/AndroidManifest.xml b/verification-view/src/main/AndroidManifest.xml index 9a187a7..053df78 100644 --- a/verification-view/src/main/AndroidManifest.xml +++ b/verification-view/src/main/AndroidManifest.xml @@ -1,2 +1 @@ - +