commit d42f50cab15358c15a18b44a3a476280cfc0d71b Author: xuhuixiang Date: Mon Mar 16 13:31:12 2026 +0800 第一次提交 diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..aa724b7 --- /dev/null +++ b/.gitignore @@ -0,0 +1,15 @@ +*.iml +.gradle +/local.properties +/.idea/caches +/.idea/libraries +/.idea/modules.xml +/.idea/workspace.xml +/.idea/navEditor.xml +/.idea/assetWizardSettings.xml +.DS_Store +/build +/captures +.externalNativeBuild +.cxx +local.properties diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000..26d3352 --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,3 @@ +# Default ignored files +/shelf/ +/workspace.xml diff --git a/.idea/.name b/.idea/.name new file mode 100644 index 0000000..8c777b8 --- /dev/null +++ b/.idea/.name @@ -0,0 +1 @@ +WebShell \ No newline at end of file diff --git a/.idea/AndroidProjectSystem.xml b/.idea/AndroidProjectSystem.xml new file mode 100644 index 0000000..4a53bee --- /dev/null +++ b/.idea/AndroidProjectSystem.xml @@ -0,0 +1,6 @@ + + + + + \ No newline at end of file diff --git a/.idea/compiler.xml b/.idea/compiler.xml new file mode 100644 index 0000000..b86273d --- /dev/null +++ b/.idea/compiler.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/.idea/deploymentTargetSelector.xml b/.idea/deploymentTargetSelector.xml new file mode 100644 index 0000000..8ca4464 --- /dev/null +++ b/.idea/deploymentTargetSelector.xml @@ -0,0 +1,40 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/gradle.xml b/.idea/gradle.xml new file mode 100644 index 0000000..191781b --- /dev/null +++ b/.idea/gradle.xml @@ -0,0 +1,30 @@ + + + + + + + \ No newline at end of file diff --git a/.idea/migrations.xml b/.idea/migrations.xml new file mode 100644 index 0000000..f8051a6 --- /dev/null +++ b/.idea/migrations.xml @@ -0,0 +1,10 @@ + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..b2c751a --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,9 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/runConfigurations.xml b/.idea/runConfigurations.xml new file mode 100644 index 0000000..16660f1 --- /dev/null +++ b/.idea/runConfigurations.xml @@ -0,0 +1,17 @@ + + + + + + \ No newline at end of file diff --git a/1xhuat/.gitignore b/1xhuat/.gitignore new file mode 100644 index 0000000..956c004 --- /dev/null +++ b/1xhuat/.gitignore @@ -0,0 +1,2 @@ +/build +/release \ No newline at end of file diff --git a/1xhuat/build.gradle b/1xhuat/build.gradle new file mode 100644 index 0000000..c1d016e --- /dev/null +++ b/1xhuat/build.gradle @@ -0,0 +1,93 @@ +plugins { + id 'com.android.application' + id 'com.google.gms.google-services' +} + +def appOutPutName = "1xhuatdsigiudsogdfghdfghdf" + +android { + namespace "com.webclip.base" + compileSdk 36 + defaultConfig { + minSdkVersion 24 + targetSdk 36 + versionCode rootProject.ext.versionCode + versionName rootProject.ext.versionName + testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" + + //包名 + applicationId "com.xyz.xhuat" + //app大背景色 + resValue('color', 'windows_color', '#3c0a0b') + //底部导航栏颜色 大背景颜色为 windows_color——style_color的上下渐变色 + resValue('color', 'style_color', '#2f0000') + //app 名字 + resValue('string', 'app_name', '1XHUAT') +// 预埋订阅网址 + buildConfigField "String", "BASE_URL", "\"https://1xhuat.com/\"" + buildConfigField "int", "USERID", "248" + buildConfigField "boolean", "IS_WHITE", "true" + buildConfigField "boolean", "IS_ROUND", "false" + buildConfigField "int", "ROUND_RADIUS", "0" + buildConfigField "boolean", "HAS_CONTACT", "false" + buildConfigField "boolean", "HAS_HOOK", "false" + + + } + buildFeatures { + buildConfig = true + } + + signingConfigs { + debug { + storeFile file('justlet.jks') + storePassword "123456" + keyAlias 'key0' + keyPassword "123456" + } + release { + storeFile file('justlet.jks') + storePassword "123456" + keyAlias 'key0' + keyPassword "123456" + } + } + + buildTypes { + release { + signingConfig signingConfigs.release + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' + } + } + compileOptions { + sourceCompatibility JavaVersion.VERSION_17 + targetCompatibility JavaVersion.VERSION_17 + } + + applicationVariants.all { variant -> + variant.outputs.all { + def outputDir = new File(rootProject.ext.outputPath) + outputDir.mkdirs() + def outputFileName = "${appOutPutName}.apk" + setOutputFileName(outputFileName) + def newOutputFile = new File(outputDir, outputFileName) + newOutputFile.parentFile.mkdirs() + variant.assemble.doLast { + try { + java.nio.file.Files.copy( + outputFile.toPath(), + newOutputFile.toPath(), + java.nio.file.StandardCopyOption.REPLACE_EXISTING + ) + } catch (java.io.IOException e) { + } + } + } + } + +} + +dependencies { + implementation project(path: ':base_noupdata') +} \ No newline at end of file diff --git a/1xhuat/google-services.json b/1xhuat/google-services.json new file mode 100644 index 0000000..a91e88d --- /dev/null +++ b/1xhuat/google-services.json @@ -0,0 +1,29 @@ +{ + "project_info": { + "project_number": "722866808349", + "project_id": "xhuat-7da8d", + "storage_bucket": "xhuat-7da8d.firebasestorage.app" + }, + "client": [ + { + "client_info": { + "mobilesdk_app_id": "1:722866808349:android:d96ba99e4c161682d848f4", + "android_client_info": { + "package_name": "com.xyz.xhuat" + } + }, + "oauth_client": [], + "api_key": [ + { + "current_key": "AIzaSyBR0nae-jXRJuX1e8a-53fWuZYQZKC1jlI" + } + ], + "services": { + "appinvite_service": { + "other_platform_oauth_client": [] + } + } + } + ], + "configuration_version": "1" +} \ No newline at end of file diff --git a/1xhuat/justlet.jks b/1xhuat/justlet.jks new file mode 100644 index 0000000..a33b839 Binary files /dev/null and b/1xhuat/justlet.jks differ diff --git a/1xhuat/proguard-rules.pro b/1xhuat/proguard-rules.pro new file mode 100644 index 0000000..107b7ee --- /dev/null +++ b/1xhuat/proguard-rules.pro @@ -0,0 +1,32 @@ +# 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 + +-dontwarn dalvik.** +-dontwarn com.tencent.smtt.** + +-keep class com.tencent.smtt.** { + *; +} + +-keep class com.tencent.tbs.** { + *; +} \ No newline at end of file diff --git a/1xhuat/src/main/AndroidManifest.xml b/1xhuat/src/main/AndroidManifest.xml new file mode 100644 index 0000000..3b959c6 --- /dev/null +++ b/1xhuat/src/main/AndroidManifest.xml @@ -0,0 +1,64 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/1xhuat/src/main/java/com/webclip/base/IndexActivity.java b/1xhuat/src/main/java/com/webclip/base/IndexActivity.java new file mode 100644 index 0000000..b1298c9 --- /dev/null +++ b/1xhuat/src/main/java/com/webclip/base/IndexActivity.java @@ -0,0 +1,76 @@ +package com.webclip.base; + +import android.os.Bundle; + +import com.google.firebase.messaging.FirebaseMessaging; + +public class IndexActivity extends MainActivity { + + @Override + protected void onCreate(Bundle savedInstanceState) { + initConfig(); + super.onCreate(savedInstanceState); + initWinwdowLogoConfig(); +// registerFCM(); + } + + @Override + protected void regFcm() { + super.regFcm(); + registerFCM(); + } + + /** + * 注册FCM + */ + private void registerFCM() { + //订阅主题 + LogUtils.i("支持FCM 去注册"); + try { + FirebaseMessaging.getInstance().subscribeToTopic("demo") + .addOnCompleteListener(task -> { + String msg = "Subscribed"; + if (!task.isSuccessful()) { + msg = "Subscribe failed"; + }else{ + //注册成功了再去请求通知权限 不然通知权限请求了也没啥意义 + checkNotify(); + } + LogUtils.i("支持FCM 结果:"+msg); + }); + }catch (Exception e){ + e.printStackTrace(); + LogUtils.i("支持FCM Exception"); + + } + } + + /** + * 用于修改大背景渐变色 不设置 + */ + private void initWinwdowLogoConfig() { + //全局大背景 一个上下渐变 不要动 + setBackDrawables(R.drawable.big_bg); + setImageView(BuildConfig.IS_ROUND,BuildConfig.ROUND_RADIUS); + getWindow().getDecorView().setBackgroundResource(R.drawable.big_bg); + + //需要修改启动页logo在这里弄 一般启动页logo就是app_logo 没特殊要求 不要动 + } + + /** + * 基础配置都在这里 + * 不要动 + */ + private void initConfig() { + userId = BuildConfig.USERID; + saveInt(IndexActivity.this,"user_code",userId); + saveString(this, "base_url",BuildConfig.BASE_URL); + styleColor = getColor(R.color.style_color); + windowsColor = getColor(R.color.windows_color); + isWhite = BuildConfig.IS_WHITE; + hasContact = BuildConfig.HAS_CONTACT; + hasHook = BuildConfig.HAS_HOOK; + + } + +} diff --git a/1xhuat/src/main/java/com/webclip/base/MyFirebaseMessageingService.java b/1xhuat/src/main/java/com/webclip/base/MyFirebaseMessageingService.java new file mode 100644 index 0000000..36f2d65 --- /dev/null +++ b/1xhuat/src/main/java/com/webclip/base/MyFirebaseMessageingService.java @@ -0,0 +1,125 @@ +package com.webclip.base; + +import android.app.NotificationChannel; +import android.app.NotificationManager; +import android.app.PendingIntent; +import android.content.ComponentName; +import android.content.Context; +import android.content.Intent; +import android.os.Build; +import androidx.annotation.NonNull; +import androidx.core.app.NotificationCompat; +import com.google.firebase.messaging.FirebaseMessagingService; +import com.google.firebase.messaging.RemoteMessage; +import com.google.gson.Gson; +import com.webclip.base.GsonUtils; +import com.webclip.base.MessageInfo; +import java.util.Map; +import java.util.Random; + +public class MyFirebaseMessageingService extends FirebaseMessagingService { + + public MyFirebaseMessageingService() { + } + + @Override + public void onMessageReceived(@NonNull RemoteMessage remoteMessage) { + super.onMessageReceived(remoteMessage); + Map serviceData = remoteMessage.getData(); //后台推送数据 + if (serviceData != null && serviceData.containsKey("message")) { + String value = serviceData.get("message"); + Gson gson = new Gson(); + MessageInfo messageInfo = gson.fromJson(value, MessageInfo.class); + showNotification(messageInfo); + } else { + //收到通知 创建notify + if (remoteMessage.getNotification() != null) { + showNotification(remoteMessage.getNotification().getTitle(), remoteMessage.getNotification().getBody()); + } + } + } + + private void showNotification(MessageInfo messageInfo) { + Intent notifyIntent = new Intent(this, IndexActivity.class); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.CUPCAKE) { + ComponentName launchComponent = null; + launchComponent = getApplication() + .getPackageManager() + .getLaunchIntentForPackage(getApplication().getPackageName()) + .getComponent(); + notifyIntent.setComponent(launchComponent); + } + notifyIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP); + notifyIntent.setAction(Intent.ACTION_VIEW); + notifyIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); // 必须 + notifyIntent.putExtra("message", messageInfo); + PendingIntent pendingIntent = PendingIntent.getActivity(this, new Random().nextInt(10000), notifyIntent, PendingIntent.FLAG_IMMUTABLE); + NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); + NotificationChannel channelwinway = null; + NotificationCompat.Builder notificationBuilder = null; + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + channelwinway = new NotificationChannel(getString(R.string.app_name), "notify", NotificationManager.IMPORTANCE_DEFAULT); + channelwinway.enableLights(true); + channelwinway.enableVibration(true); + notificationManager.createNotificationChannel(channelwinway); + notificationBuilder = new NotificationCompat.Builder(this, channelwinway.getId()) + .setSmallIcon(R.mipmap.app_logo) + .setContentTitle(messageInfo.getTitle()) + .setContentText(messageInfo.getContent()) + .setAutoCancel(true) + .setContentIntent(pendingIntent); + } else { + notificationBuilder = new NotificationCompat.Builder(this, getString(R.string.app_name)) + .setSmallIcon(R.mipmap.app_logo) + .setContentTitle(messageInfo.getTitle()) + .setContentText(messageInfo.getContent()) + .setAutoCancel(true) + .setContentIntent(pendingIntent); + } + notificationManager.notify(0, notificationBuilder.build()); + } + + private void showNotification(String title, String body) { + Intent notifyIntent = new Intent(this, IndexActivity.class); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.CUPCAKE) { + ComponentName launchComponent = null; + launchComponent = getApplication() + .getPackageManager() + .getLaunchIntentForPackage(getApplication().getPackageName()) + .getComponent(); + notifyIntent.setComponent(launchComponent); + } + notifyIntent.putExtra("message", body); + notifyIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP); + notifyIntent.setAction(Intent.ACTION_VIEW); + notifyIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); // 必须 + PendingIntent pendingIntent = PendingIntent.getActivity(this, new Random().nextInt(10000), notifyIntent, PendingIntent.FLAG_IMMUTABLE); + NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); + NotificationChannel channelwinway = null; + NotificationCompat.Builder notificationBuilder = null; + MessageInfo messageInfo = GsonUtils.getObjFromJSON(body, MessageInfo.class); + if (messageInfo != null) { + body = messageInfo.getContent(); + } + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + channelwinway = new NotificationChannel(getString(R.string.app_name), "notify", NotificationManager.IMPORTANCE_DEFAULT); + channelwinway.enableLights(true); + channelwinway.enableVibration(true); + notificationManager.createNotificationChannel(channelwinway); + notificationBuilder = new NotificationCompat.Builder(this, channelwinway.getId()) + .setSmallIcon(R.mipmap.app_logo) + .setContentTitle(title) + .setContentText(body) + .setAutoCancel(true) + .setContentIntent(pendingIntent); + } else { + notificationBuilder = new NotificationCompat.Builder(this, getString(R.string.app_name)) + .setSmallIcon(R.mipmap.app_logo) + .setContentTitle(title) + .setContentText(body) + .setAutoCancel(true) + .setContentIntent(pendingIntent); + } + notificationManager.notify(0, notificationBuilder.build()); + } +} diff --git a/1xhuat/src/main/java/com/webclip/base/WebApplication.java b/1xhuat/src/main/java/com/webclip/base/WebApplication.java new file mode 100644 index 0000000..36e2512 --- /dev/null +++ b/1xhuat/src/main/java/com/webclip/base/WebApplication.java @@ -0,0 +1,19 @@ +package com.webclip.base; + +import android.app.Application; +import android.content.Context; + +import com.webclip.base.LogUtils; + +public class WebApplication extends Application { + + + public static Context application; + @Override + public void onCreate() { + super.onCreate(); +// 设置开启优化方案 + application = this; + LogUtils.isDebug = BuildConfig.BUILD_TYPE.equals("debug"); + } +} diff --git a/1xhuat/src/main/res/drawable/big_bg.xml b/1xhuat/src/main/res/drawable/big_bg.xml new file mode 100644 index 0000000..b058f1e --- /dev/null +++ b/1xhuat/src/main/res/drawable/big_bg.xml @@ -0,0 +1,10 @@ + + + + \ No newline at end of file diff --git a/1xhuat/src/main/res/mipmap-xxhdpi/app_logo.png b/1xhuat/src/main/res/mipmap-xxhdpi/app_logo.png new file mode 100644 index 0000000..9db195f Binary files /dev/null and b/1xhuat/src/main/res/mipmap-xxhdpi/app_logo.png differ diff --git a/1xhuat/src/main/res/values/themes.xml b/1xhuat/src/main/res/values/themes.xml new file mode 100644 index 0000000..f1ef249 --- /dev/null +++ b/1xhuat/src/main/res/values/themes.xml @@ -0,0 +1,91 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/1xhuat/src/main/res/xml/app_updater_paths.xml b/1xhuat/src/main/res/xml/app_updater_paths.xml new file mode 100644 index 0000000..1254450 --- /dev/null +++ b/1xhuat/src/main/res/xml/app_updater_paths.xml @@ -0,0 +1,10 @@ + + + + + + + + + + \ No newline at end of file diff --git a/1xhuat/src/main/res/xml/network_security_config.xml b/1xhuat/src/main/res/xml/network_security_config.xml new file mode 100644 index 0000000..dca93c0 --- /dev/null +++ b/1xhuat/src/main/res/xml/network_security_config.xml @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/1xhuat/src/main/res/xml/provider_paths.xml b/1xhuat/src/main/res/xml/provider_paths.xml new file mode 100644 index 0000000..c9a897a --- /dev/null +++ b/1xhuat/src/main/res/xml/provider_paths.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/1xsgd/.gitignore b/1xsgd/.gitignore new file mode 100644 index 0000000..956c004 --- /dev/null +++ b/1xsgd/.gitignore @@ -0,0 +1,2 @@ +/build +/release \ No newline at end of file diff --git a/1xsgd/build.gradle b/1xsgd/build.gradle new file mode 100644 index 0000000..69965e9 --- /dev/null +++ b/1xsgd/build.gradle @@ -0,0 +1,98 @@ +plugins { + id 'com.android.application' + id 'com.google.gms.google-services' +} + +def appOutPutName = "1xsgdsdgsdlgfsdgdflgdfh" + +android { + namespace "com.webclip.base" + compileSdk 36 + defaultConfig { + minSdkVersion 24 + targetSdk 36 + versionCode rootProject.ext.versionCode + versionName rootProject.ext.versionName + testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" + + //包名 + applicationId "com.xyz.xsgd1" + //app大背景色 + resValue('color', 'windows_color', '#400e15') + //底部导航栏颜色 大背景颜色为 windows_color——style_color的上下渐变色 + resValue('color', 'style_color', '#121212') + //app 名字 + resValue('string', 'app_name', '1XSGD') + //预埋订阅网址 + buildConfigField "String", "BASE_URL", "\"https://1xsgd.org/\"" + //后台唯一ID + buildConfigField "int", "USERID", "255" + //状态栏文字颜色是否为白色 + buildConfigField "boolean", "IS_WHITE", "true" + //是否强转启动图为圆形 + buildConfigField "boolean", "IS_ROUND", "false" + //IS_ROUND 为 true时 圆角启动logo的 圆角大小 为0 表示为圆形 否则为ROUND_RADIUS的 dp2px的 数字大小 + buildConfigField "int", "ROUND_RADIUS", "0" + //已废弃 + buildConfigField "boolean", "HAS_CONTACT", "false" + //已废弃 + buildConfigField "boolean", "HAS_HOOK", "false" + + } + buildFeatures { + buildConfig = true + } + + signingConfigs { + debug { + storeFile file('justlet.jks') + storePassword "123456" + keyAlias 'key0' + keyPassword "123456" + } + release { + storeFile file('justlet.jks') + storePassword "123456" + keyAlias 'key0' + keyPassword "123456" + } + } + + buildTypes { + release { + signingConfig signingConfigs.release + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' + } + } + compileOptions { + sourceCompatibility JavaVersion.VERSION_17 + targetCompatibility JavaVersion.VERSION_17 + } + + applicationVariants.all { variant -> + variant.outputs.all { + def outputDir = new File(rootProject.ext.outputPath) + outputDir.mkdirs() + def outputFileName = "${appOutPutName}.apk" + setOutputFileName(outputFileName) + def newOutputFile = new File(outputDir, outputFileName) + newOutputFile.parentFile.mkdirs() + variant.assemble.doLast { + try { + java.nio.file.Files.copy( + outputFile.toPath(), + newOutputFile.toPath(), + java.nio.file.StandardCopyOption.REPLACE_EXISTING + ) + } catch (java.io.IOException e) { + } + } + } + } + +} + +dependencies { + implementation project(path: ':base') +} \ No newline at end of file diff --git a/1xsgd/google-services.json b/1xsgd/google-services.json new file mode 100644 index 0000000..cf7594f --- /dev/null +++ b/1xsgd/google-services.json @@ -0,0 +1,29 @@ +{ + "project_info": { + "project_number": "905177738214", + "project_id": "xsgd-b0ad7", + "storage_bucket": "xsgd-b0ad7.firebasestorage.app" + }, + "client": [ + { + "client_info": { + "mobilesdk_app_id": "1:905177738214:android:c3252140ede0027bf70427", + "android_client_info": { + "package_name": "com.xyz.xsgd1" + } + }, + "oauth_client": [], + "api_key": [ + { + "current_key": "AIzaSyDdzd2lTSj86yRmSfW2l0c7Ud5cJpk9BXg" + } + ], + "services": { + "appinvite_service": { + "other_platform_oauth_client": [] + } + } + } + ], + "configuration_version": "1" +} \ No newline at end of file diff --git a/1xsgd/justlet.jks b/1xsgd/justlet.jks new file mode 100644 index 0000000..a33b839 Binary files /dev/null and b/1xsgd/justlet.jks differ diff --git a/1xsgd/proguard-rules.pro b/1xsgd/proguard-rules.pro new file mode 100644 index 0000000..107b7ee --- /dev/null +++ b/1xsgd/proguard-rules.pro @@ -0,0 +1,32 @@ +# 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 + +-dontwarn dalvik.** +-dontwarn com.tencent.smtt.** + +-keep class com.tencent.smtt.** { + *; +} + +-keep class com.tencent.tbs.** { + *; +} \ No newline at end of file diff --git a/1xsgd/src/main/AndroidManifest.xml b/1xsgd/src/main/AndroidManifest.xml new file mode 100644 index 0000000..f129a21 --- /dev/null +++ b/1xsgd/src/main/AndroidManifest.xml @@ -0,0 +1,63 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/1xsgd/src/main/java/com/webclip/base/IndexActivity.java b/1xsgd/src/main/java/com/webclip/base/IndexActivity.java new file mode 100644 index 0000000..50f5597 --- /dev/null +++ b/1xsgd/src/main/java/com/webclip/base/IndexActivity.java @@ -0,0 +1,80 @@ +package com.webclip.base; + +import android.os.Bundle; + +import com.google.firebase.messaging.FirebaseMessaging; + +public class IndexActivity extends MainActivity { + + @Override + protected void onCreate(Bundle savedInstanceState) { + initConfig(); + super.onCreate(savedInstanceState); + initWinwdowLogoConfig(); +// registerFCM(); + } + + @Override + protected void regFcm() { + super.regFcm(); + registerFCM(); + } + + /** + * 注册FCM + */ + private void registerFCM() { + //订阅主题 + LogUtils.i("支持FCM 去注册"); + try { + FirebaseMessaging.getInstance().subscribeToTopic("demo") + .addOnCompleteListener(task -> { + String msg = "Subscribed"; + if (!task.isSuccessful()) { + msg = "Subscribe failed"; + }else{ + checkNotify(); + } + LogUtils.i("支持FCM 结果:"+msg); + }); + }catch (Exception e){ + e.printStackTrace(); + LogUtils.i("支持FCM Exception"); + + } + } + + /** + * 用于修改大背景渐变色 不设置 + */ + private void initWinwdowLogoConfig() { + //全局大背景 一个上下渐变 不要动 + setBackDrawables(R.drawable.big_bg); + setImageView(BuildConfig.IS_ROUND,BuildConfig.ROUND_RADIUS); + getWindow().getDecorView().setBackgroundResource(R.drawable.big_bg); + activityMain2Binding.showTopV1.setImageResource(R.mipmap.start_logo); + //需要修改启动页logo在这里弄 一般启动页logo就是app_logo 没特殊要求 不要动 + } + + /** + * 基础配置都在这里 + * 不要动 + */ + private void initConfig() { + + //===========================以下是APP的配置信息 都写在 app_config.xml中================================== + userId = BuildConfig.USERID; + saveInt(IndexActivity.this,"user_code",userId); + + saveString(this, "base_url",BuildConfig.BASE_URL); + styleColor = getColor(R.color.style_color); + windowsColor = getColor(R.color.windows_color); + isWhite = BuildConfig.IS_WHITE; + hasContact = BuildConfig.HAS_CONTACT; + hasHook = BuildConfig.HAS_HOOK; + + //===========================以上是APP的配置信息 都写在 app_config.xml中================================== + } + + +} diff --git a/1xsgd/src/main/java/com/webclip/base/MyFirebaseMessageingService.java b/1xsgd/src/main/java/com/webclip/base/MyFirebaseMessageingService.java new file mode 100644 index 0000000..36f2d65 --- /dev/null +++ b/1xsgd/src/main/java/com/webclip/base/MyFirebaseMessageingService.java @@ -0,0 +1,125 @@ +package com.webclip.base; + +import android.app.NotificationChannel; +import android.app.NotificationManager; +import android.app.PendingIntent; +import android.content.ComponentName; +import android.content.Context; +import android.content.Intent; +import android.os.Build; +import androidx.annotation.NonNull; +import androidx.core.app.NotificationCompat; +import com.google.firebase.messaging.FirebaseMessagingService; +import com.google.firebase.messaging.RemoteMessage; +import com.google.gson.Gson; +import com.webclip.base.GsonUtils; +import com.webclip.base.MessageInfo; +import java.util.Map; +import java.util.Random; + +public class MyFirebaseMessageingService extends FirebaseMessagingService { + + public MyFirebaseMessageingService() { + } + + @Override + public void onMessageReceived(@NonNull RemoteMessage remoteMessage) { + super.onMessageReceived(remoteMessage); + Map serviceData = remoteMessage.getData(); //后台推送数据 + if (serviceData != null && serviceData.containsKey("message")) { + String value = serviceData.get("message"); + Gson gson = new Gson(); + MessageInfo messageInfo = gson.fromJson(value, MessageInfo.class); + showNotification(messageInfo); + } else { + //收到通知 创建notify + if (remoteMessage.getNotification() != null) { + showNotification(remoteMessage.getNotification().getTitle(), remoteMessage.getNotification().getBody()); + } + } + } + + private void showNotification(MessageInfo messageInfo) { + Intent notifyIntent = new Intent(this, IndexActivity.class); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.CUPCAKE) { + ComponentName launchComponent = null; + launchComponent = getApplication() + .getPackageManager() + .getLaunchIntentForPackage(getApplication().getPackageName()) + .getComponent(); + notifyIntent.setComponent(launchComponent); + } + notifyIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP); + notifyIntent.setAction(Intent.ACTION_VIEW); + notifyIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); // 必须 + notifyIntent.putExtra("message", messageInfo); + PendingIntent pendingIntent = PendingIntent.getActivity(this, new Random().nextInt(10000), notifyIntent, PendingIntent.FLAG_IMMUTABLE); + NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); + NotificationChannel channelwinway = null; + NotificationCompat.Builder notificationBuilder = null; + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + channelwinway = new NotificationChannel(getString(R.string.app_name), "notify", NotificationManager.IMPORTANCE_DEFAULT); + channelwinway.enableLights(true); + channelwinway.enableVibration(true); + notificationManager.createNotificationChannel(channelwinway); + notificationBuilder = new NotificationCompat.Builder(this, channelwinway.getId()) + .setSmallIcon(R.mipmap.app_logo) + .setContentTitle(messageInfo.getTitle()) + .setContentText(messageInfo.getContent()) + .setAutoCancel(true) + .setContentIntent(pendingIntent); + } else { + notificationBuilder = new NotificationCompat.Builder(this, getString(R.string.app_name)) + .setSmallIcon(R.mipmap.app_logo) + .setContentTitle(messageInfo.getTitle()) + .setContentText(messageInfo.getContent()) + .setAutoCancel(true) + .setContentIntent(pendingIntent); + } + notificationManager.notify(0, notificationBuilder.build()); + } + + private void showNotification(String title, String body) { + Intent notifyIntent = new Intent(this, IndexActivity.class); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.CUPCAKE) { + ComponentName launchComponent = null; + launchComponent = getApplication() + .getPackageManager() + .getLaunchIntentForPackage(getApplication().getPackageName()) + .getComponent(); + notifyIntent.setComponent(launchComponent); + } + notifyIntent.putExtra("message", body); + notifyIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP); + notifyIntent.setAction(Intent.ACTION_VIEW); + notifyIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); // 必须 + PendingIntent pendingIntent = PendingIntent.getActivity(this, new Random().nextInt(10000), notifyIntent, PendingIntent.FLAG_IMMUTABLE); + NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); + NotificationChannel channelwinway = null; + NotificationCompat.Builder notificationBuilder = null; + MessageInfo messageInfo = GsonUtils.getObjFromJSON(body, MessageInfo.class); + if (messageInfo != null) { + body = messageInfo.getContent(); + } + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + channelwinway = new NotificationChannel(getString(R.string.app_name), "notify", NotificationManager.IMPORTANCE_DEFAULT); + channelwinway.enableLights(true); + channelwinway.enableVibration(true); + notificationManager.createNotificationChannel(channelwinway); + notificationBuilder = new NotificationCompat.Builder(this, channelwinway.getId()) + .setSmallIcon(R.mipmap.app_logo) + .setContentTitle(title) + .setContentText(body) + .setAutoCancel(true) + .setContentIntent(pendingIntent); + } else { + notificationBuilder = new NotificationCompat.Builder(this, getString(R.string.app_name)) + .setSmallIcon(R.mipmap.app_logo) + .setContentTitle(title) + .setContentText(body) + .setAutoCancel(true) + .setContentIntent(pendingIntent); + } + notificationManager.notify(0, notificationBuilder.build()); + } +} diff --git a/1xsgd/src/main/java/com/webclip/base/WebApplication.java b/1xsgd/src/main/java/com/webclip/base/WebApplication.java new file mode 100644 index 0000000..36e2512 --- /dev/null +++ b/1xsgd/src/main/java/com/webclip/base/WebApplication.java @@ -0,0 +1,19 @@ +package com.webclip.base; + +import android.app.Application; +import android.content.Context; + +import com.webclip.base.LogUtils; + +public class WebApplication extends Application { + + + public static Context application; + @Override + public void onCreate() { + super.onCreate(); +// 设置开启优化方案 + application = this; + LogUtils.isDebug = BuildConfig.BUILD_TYPE.equals("debug"); + } +} diff --git a/1xsgd/src/main/res/drawable/big_bg.xml b/1xsgd/src/main/res/drawable/big_bg.xml new file mode 100644 index 0000000..b058f1e --- /dev/null +++ b/1xsgd/src/main/res/drawable/big_bg.xml @@ -0,0 +1,10 @@ + + + + \ No newline at end of file diff --git a/1xsgd/src/main/res/mipmap-xxhdpi/app_logo.png b/1xsgd/src/main/res/mipmap-xxhdpi/app_logo.png new file mode 100644 index 0000000..0569e4c Binary files /dev/null and b/1xsgd/src/main/res/mipmap-xxhdpi/app_logo.png differ diff --git a/1xsgd/src/main/res/mipmap-xxhdpi/start_logo.png b/1xsgd/src/main/res/mipmap-xxhdpi/start_logo.png new file mode 100644 index 0000000..3c94089 Binary files /dev/null and b/1xsgd/src/main/res/mipmap-xxhdpi/start_logo.png differ diff --git a/1xsgd/src/main/res/values/themes.xml b/1xsgd/src/main/res/values/themes.xml new file mode 100644 index 0000000..f1ef249 --- /dev/null +++ b/1xsgd/src/main/res/values/themes.xml @@ -0,0 +1,91 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/1xsgd/src/main/res/xml/app_updater_paths.xml b/1xsgd/src/main/res/xml/app_updater_paths.xml new file mode 100644 index 0000000..1254450 --- /dev/null +++ b/1xsgd/src/main/res/xml/app_updater_paths.xml @@ -0,0 +1,10 @@ + + + + + + + + + + \ No newline at end of file diff --git a/1xsgd/src/main/res/xml/network_security_config.xml b/1xsgd/src/main/res/xml/network_security_config.xml new file mode 100644 index 0000000..dca93c0 --- /dev/null +++ b/1xsgd/src/main/res/xml/network_security_config.xml @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/1xsgd/src/main/res/xml/provider_paths.xml b/1xsgd/src/main/res/xml/provider_paths.xml new file mode 100644 index 0000000..c9a897a --- /dev/null +++ b/1xsgd/src/main/res/xml/provider_paths.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/base/.gitignore b/base/.gitignore new file mode 100644 index 0000000..42afabf --- /dev/null +++ b/base/.gitignore @@ -0,0 +1 @@ +/build \ No newline at end of file diff --git a/base/build.gradle b/base/build.gradle new file mode 100644 index 0000000..9b24046 --- /dev/null +++ b/base/build.gradle @@ -0,0 +1,50 @@ +plugins { + id 'com.android.library' +} + +android { + namespace "com.webclip.base" + compileSdk 36 + defaultConfig { + minSdkVersion 24 + targetSdk 36 + testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" + } + + compileOptions { + sourceCompatibility JavaVersion.VERSION_17 + targetCompatibility JavaVersion.VERSION_17 + } + + buildFeatures { + viewBinding true + } +} + +dependencies { + + api 'androidx.appcompat:appcompat:1.1.0' + api 'com.google.android.material:material:1.1.0' + api 'androidx.constraintlayout:constraintlayout:1.1.3' + + // okhttp相关库 + api 'com.squareup.okhttp3:okhttp:4.9.3' + + // JSON解析库 + api 'com.google.code.gson:gson:2.9.0' + api 'com.squareup.retrofit2:retrofit:2.5.0' + api 'com.squareup.retrofit2:converter-scalars:2.3.0' + api 'com.squareup.retrofit2:converter-gson:2.4.0' + api 'com.squareup.retrofit2:adapter-rxjava2:2.4.0' + api 'io.reactivex.rxjava2:rxjava:2.1.16' + api 'io.reactivex.rxjava2:rxandroid:2.0.2' + api 'com.squareup.okhttp3:logging-interceptor:3.10.0' + + api("com.github.bumptech.glide:glide:4.13.1") + api 'com.github.jenly1314.AppUpdater:app-updater:2.1.0' + // sdk 33 + api platform('com.google.firebase:firebase-bom:32.7.0') + // Firebase Cloud Messaging + api("com.google.firebase:firebase-messaging") + api libs.play.services.base +} \ No newline at end of file diff --git a/base/proguard-rules.pro b/base/proguard-rules.pro new file mode 100644 index 0000000..107b7ee --- /dev/null +++ b/base/proguard-rules.pro @@ -0,0 +1,32 @@ +# 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 + +-dontwarn dalvik.** +-dontwarn com.tencent.smtt.** + +-keep class com.tencent.smtt.** { + *; +} + +-keep class com.tencent.tbs.** { + *; +} \ No newline at end of file diff --git a/base/src/main/AndroidManifest.xml b/base/src/main/AndroidManifest.xml new file mode 100644 index 0000000..7cd7cbb --- /dev/null +++ b/base/src/main/AndroidManifest.xml @@ -0,0 +1,20 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/base/src/main/java/com/webclip/base/ActionConfirmDialog.java b/base/src/main/java/com/webclip/base/ActionConfirmDialog.java new file mode 100644 index 0000000..86599dd --- /dev/null +++ b/base/src/main/java/com/webclip/base/ActionConfirmDialog.java @@ -0,0 +1,112 @@ +package com.webclip.base; + +import android.app.Dialog; +import android.content.Context; +import android.os.Bundle; +import android.text.TextUtils; +import android.view.Gravity; +import android.view.View; +import android.view.ViewTreeObserver; +import android.view.Window; +import android.view.WindowManager; +import android.widget.TextView; + +import com.webclip.base.databinding.DialogActionConfirmBinding; + + +/** + * 通用弹窗 + */ +public class ActionConfirmDialog extends Dialog { + DialogActionConfirmBinding dialogActionConfirmBinding; + + String content; + String cancel = null; + String sure = null; + boolean showCancel = true; + OnToActionListener onToActionListener; + + public interface OnToActionListener { + void toSumbit(); + void toCancel(); + + } + + public void setOnToActionListener(OnToActionListener onNextCallListener) { + this.onToActionListener = onNextCallListener; + } + + + public ActionConfirmDialog(Context context, String content,boolean showCancel) { + super(context, R.style.MaterialDesignDialog); + this.content = content; + this.showCancel = showCancel; + } + public ActionConfirmDialog(Context context, String content, String cancel, String sure) { + super(context, R.style.MaterialDesignDialog); + this.content = content; + this.cancel = cancel; + this.sure = sure; + } + + public ActionConfirmDialog(Context context, String content, String cancel, String sure,boolean showCancel) { + super(context, R.style.MaterialDesignDialog); + this.content = content; + this.cancel = cancel; + this.sure = sure; + this.showCancel = showCancel; + } + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + dialogActionConfirmBinding = DialogActionConfirmBinding.inflate(getLayoutInflater()); + setContentView(dialogActionConfirmBinding.getRoot()); + dialogActionConfirmBinding.contentTv.setText(content); + dialogActionConfirmBinding.contentTv.getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() { + @Override + public boolean onPreDraw() { + //这个监听的回调是异步的,在监听完以后一定要把绘制监听移除,不然这个会一直回调,导致界面错乱 + dialogActionConfirmBinding.contentTv.getViewTreeObserver().removeOnPreDrawListener(this); + int line = dialogActionConfirmBinding.contentTv.getLineCount(); + if(line>1){ + dialogActionConfirmBinding.contentTv.setGravity(Gravity.LEFT|Gravity.CENTER_VERTICAL); + } + + return true; + } + }); + if(!TextUtils.isEmpty(cancel)){ + dialogActionConfirmBinding.cancelTv.setText(cancel); + } + if(!TextUtils.isEmpty(sure)){ + dialogActionConfirmBinding.sumbitTv.setText(sure); + } + if(!showCancel){ + dialogActionConfirmBinding.cancelTv.setVisibility(View.GONE); + dialogActionConfirmBinding.lineV.setVisibility(View.GONE); + } + + dialogActionConfirmBinding.sumbitTv.setOnClickListener(v -> { + dismiss(); + if(onToActionListener!=null){ + onToActionListener.toSumbit(); + } + }); + dialogActionConfirmBinding.cancelTv.setOnClickListener(v -> { + dismiss(); + if(onToActionListener!=null){ + onToActionListener.toCancel(); + } + }); + + Window window = getWindow(); + WindowManager.LayoutParams wlp = window.getAttributes(); + wlp.gravity = Gravity.CENTER; + wlp.width = WindowManager.LayoutParams.WRAP_CONTENT; + wlp.height = WindowManager.LayoutParams.WRAP_CONTENT; + + window.setAttributes(wlp); + } + +} diff --git a/base/src/main/java/com/webclip/base/Api.java b/base/src/main/java/com/webclip/base/Api.java new file mode 100644 index 0000000..c4e9672 --- /dev/null +++ b/base/src/main/java/com/webclip/base/Api.java @@ -0,0 +1,69 @@ +package com.webclip.base; + +import java.net.Proxy; +import java.util.concurrent.TimeUnit; + +import okhttp3.OkHttpClient; +import okhttp3.logging.HttpLoggingInterceptor; + +/** + * 项目名: TODO-MVVM + * 包名 com.azhon.mvvm.api + * 文件名: Api + * 创建时间: 2019-03-27 on 14:56 + * 描述: TODO 使用Retrofit基础服务 + * + * @author + */ + +public class Api extends BaseApi { + + private static final long CONNECT_TIMEOUT = 10; + private static final long READ_TIMEOUT = 10; + private static final long WRITE_TIMEOUT = 10; + + /** + * 静态内部类单例 + */ + private static class ApiHolder { + private static Api api = new Api(); + private final static ApiService apiService = api.initRetrofit(ApiService.URL) + .create(ApiService.class); + + } + + public static ApiService getInstance() { + return ApiHolder.apiService; + } + + /** + * 做自己需要的操作 + */ + @Override + protected OkHttpClient setClient() { + OkHttpClient.Builder builder; + builder = new OkHttpClient() + .newBuilder(); + //禁止使用代理抓取数据 + builder.proxy(Proxy.NO_PROXY); + //设置超时 + builder.connectTimeout(CONNECT_TIMEOUT, TimeUnit.SECONDS); + builder.readTimeout(READ_TIMEOUT, TimeUnit.SECONDS); + builder.writeTimeout(WRITE_TIMEOUT, TimeUnit.SECONDS); + //错误重连 + builder.retryOnConnectionFailure(true); + + if (LogUtils.isDebug) { + HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor(message -> { + String text = message; + LogUtils.i("OKHttp111111-----", text); + + }); + interceptor.setLevel(HttpLoggingInterceptor.Level.BODY); + builder.addInterceptor(interceptor); + } + return builder.build(); + + } + +} diff --git a/base/src/main/java/com/webclip/base/ApiService.java b/base/src/main/java/com/webclip/base/ApiService.java new file mode 100644 index 0000000..993c21c --- /dev/null +++ b/base/src/main/java/com/webclip/base/ApiService.java @@ -0,0 +1,59 @@ +package com.webclip.base; + + +import java.util.List; +import java.util.Map; + +import io.reactivex.Observable; +import okhttp3.RequestBody; +import okhttp3.ResponseBody; +import retrofit2.Call; +import retrofit2.Callback; +import retrofit2.http.Body; +import retrofit2.http.GET; +import retrofit2.http.Headers; +import retrofit2.http.POST; +import retrofit2.http.PUT; +import retrofit2.http.Path; +import retrofit2.http.Query; +import retrofit2.http.Url; + +public interface ApiService { + String URL = "https://api.liulao.top/"; + + + @GET("api/system/applicationConf") + Observable> geUrlNew(@Query("userId") int userId); + + + /** + * 統計下載量 + */ + @PUT("api/statistics/downloads") + Observable downloadNumbers(@Body Map map); + + /** + * 每日活跃统计 + */ + @PUT("api/statistics/use") + Observable totalTongJi(@Body Map map); + + /** + * 统计通知 + */ + @POST("api/push/statistics") + Observable totalNotify(@Body Map map); + + + /** + * 获取通知列表 + * @param userid + * @param page + * @param size + * @return + */ + @GET("api/push/pushRecords") + Observable>> getNotifyList(@Query("userId") int userid, @Query("page") int page, @Query("size") int size); + + +} diff --git a/base/src/main/java/com/webclip/base/BaseApi.java b/base/src/main/java/com/webclip/base/BaseApi.java new file mode 100644 index 0000000..6e89376 --- /dev/null +++ b/base/src/main/java/com/webclip/base/BaseApi.java @@ -0,0 +1,46 @@ +package com.webclip.base; + +import okhttp3.OkHttpClient; +import retrofit2.Retrofit; +import retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory; +import retrofit2.converter.gson.GsonConverterFactory; +import retrofit2.converter.scalars.ScalarsConverterFactory; + +/** + * 项目名: TODO-MVVM + * 包名 com.azhon.basic.retrofit + * 文件名: BaseApi + * 创建时间: 2019-03-27 on 14:52 + * 描述: TODO 封装基础的Retrofit + * + * @author + */ + +public abstract class BaseApi { + + /** + * 初始化Retrofit + */ + public Retrofit initRetrofit(String baseUrl) { + Retrofit.Builder builder = new Retrofit.Builder(); + //支持返回Call + builder.addConverterFactory(ScalarsConverterFactory.create()); + //支持直接格式化json返回Bean对象 + builder.addConverterFactory(GsonConverterFactory.create()); + //支持RxJava + builder.addCallAdapterFactory(RxJava2CallAdapterFactory.create()); + builder.baseUrl(baseUrl); + OkHttpClient client = setClient(); + if (client != null) { + builder.client(client); + } + return builder.build(); + } + + /** + * 设置OkHttpClient,添加拦截器等 + * + * @return 可以返回为null + */ + protected abstract OkHttpClient setClient(); +} diff --git a/base/src/main/java/com/webclip/base/BaseObserver.java b/base/src/main/java/com/webclip/base/BaseObserver.java new file mode 100644 index 0000000..7030489 --- /dev/null +++ b/base/src/main/java/com/webclip/base/BaseObserver.java @@ -0,0 +1,113 @@ +package com.webclip.base; + +import com.google.gson.JsonParseException; + +import org.json.JSONException; + +import java.io.InterruptedIOException; +import java.net.ConnectException; +import java.net.UnknownHostException; +import java.text.ParseException; + +import io.reactivex.observers.DisposableObserver; +import retrofit2.HttpException; + +public abstract class BaseObserver extends DisposableObserver { + /** + * 解析数据失败 + */ + public static final int PARSE_ERROR = 1001; + /** + * 网络问题 + */ + public static final int BAD_NETWORK = 1002; + /** + * 连接错误 + */ + public static final int CONNECT_ERROR = 1003; + /** + * 连接超时 + */ + public static final int CONNECT_TIMEOUT = 1004; + + @Override + public void onNext(T o) { + if (o instanceof String) { + onError(0, "接口解析失败"); +// LogUtils.i("返回个string就没意思了"); + } else { + Result model = (Result) o; + if (model.isSuccessful()) { + onSuccess(o); + } else { + onError2(o); + } + } + + + } + + @Override + public void onError(Throwable e) { + if (e instanceof HttpException) { + // HTTP错误 + onException(BAD_NETWORK); + } else if (e instanceof ConnectException + || e instanceof UnknownHostException) { + // 连接错误 + onException(CONNECT_ERROR); + } else if (e instanceof InterruptedIOException) { + // 连接超时 + onException(CONNECT_TIMEOUT); + } else if (e instanceof JsonParseException + || e instanceof JSONException + || e instanceof ParseException) { + // 解析错误 + + onException(PARSE_ERROR); + } else { + if (e != null) { + onError(409, e.toString()); + } else { + onError(407, "未知错误"); + } + } + + } + + private void onException(int unknownError) { + switch (unknownError) { + case CONNECT_ERROR: + onError(CONNECT_ERROR, "连接错误"); + break; + + case CONNECT_TIMEOUT: + onError(CONNECT_TIMEOUT, "连接超时"); + break; + + case BAD_NETWORK: + onError(BAD_NETWORK, "网络问题"); + break; + + case PARSE_ERROR: + onError(PARSE_ERROR, "宇宙也是有尽头的"); + + break; + + default: + break; + } + } + + @Override + public void onComplete() { + + } + + public abstract void onSuccess(T o); + + public abstract void onError(int code, String msg); + + public abstract void onError2(T o); + +} diff --git a/base/src/main/java/com/webclip/base/CircleImageView.java b/base/src/main/java/com/webclip/base/CircleImageView.java new file mode 100644 index 0000000..b0d11f1 --- /dev/null +++ b/base/src/main/java/com/webclip/base/CircleImageView.java @@ -0,0 +1,320 @@ +package com.webclip.base; + +import android.annotation.SuppressLint; +import android.content.Context; +import android.content.res.TypedArray; +import android.graphics.Bitmap; +import android.graphics.Canvas; +import android.graphics.Matrix; +import android.graphics.Paint; +import android.graphics.PorterDuff; +import android.graphics.PorterDuffXfermode; +import android.graphics.RectF; +import android.graphics.drawable.BitmapDrawable; +import android.graphics.drawable.Drawable; +import android.util.AttributeSet; +import android.view.MotionEvent; + +import androidx.appcompat.widget.AppCompatImageView; + + +public class CircleImageView extends AppCompatImageView { + // paint when user press + private Paint pressPaint; + private int width; + private int height; + + // default bitmap config + private static final Bitmap.Config BITMAP_CONFIG = Bitmap.Config.ARGB_8888; + + // border color + private int borderColor; + // width of border + private int borderWidth; + // alpha when pressed + private int pressAlpha; + // color when pressed + private int pressColor; + // radius + private int radius; + // rectangle or round, 1 is circle, 2 is rectangle + private int shapeType; + + public CircleImageView(Context context) { + super(context); + init(context, null); + } + + public CircleImageView(Context context, AttributeSet attrs) { + super(context, attrs); + init(context, attrs); + } + + public CircleImageView(Context context, AttributeSet attrs, int defStyleAttr) { + super(context, attrs, defStyleAttr); + init(context, attrs); + } + + + private void init(Context context, AttributeSet attrs) { + //init the value + borderWidth = 0; + borderColor = 0xddffffff; + pressAlpha = 0x42; + pressColor = 0x42000000; + radius = 16; + shapeType = 0; + + // get attribute of EaseImageView + if (attrs != null) { + TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.CircleImageView); + borderColor = array.getColor(R.styleable.CircleImageView_ease_border_color, borderColor); + borderWidth = array.getDimensionPixelOffset(R.styleable.CircleImageView_ease_border_width, borderWidth); + pressAlpha = array.getInteger(R.styleable.CircleImageView_ease_press_alpha, pressAlpha); + pressColor = array.getColor(R.styleable.CircleImageView_ease_press_color, pressColor); + radius = array.getDimensionPixelOffset(R.styleable.CircleImageView_ease_radius, radius); + shapeType = array.getInteger(R.styleable.CircleImageView_es_shape_type, shapeType); + array.recycle(); + } + + // set paint when pressed + pressPaint = new Paint(); + pressPaint.setAntiAlias(true); + pressPaint.setStyle(Paint.Style.FILL); + pressPaint.setColor(pressColor); + pressPaint.setAlpha(0); + pressPaint.setFlags(Paint.ANTI_ALIAS_FLAG); + + setDrawingCacheEnabled(true); + setWillNotDraw(false); + } + + @Override + protected void onDraw(Canvas canvas) { + + if (shapeType == 0) { + super.onDraw(canvas); + return; + } + Drawable drawable = getDrawable(); + if (drawable == null) { + return; + } + // the width and height is in xml file + if (getWidth() == 0 || getHeight() == 0) { + return; + } + Bitmap bitmap = getBitmapFromDrawable(drawable); + drawDrawable(canvas, bitmap); + + if (isClickable()) { + drawPress(canvas); + } + drawBorder(canvas); + } + + /** + * draw Rounded Rectangle + * + * @param canvas + * @param bitmap + */ + @SuppressLint("WrongConstant") + private void drawDrawable(Canvas canvas, Bitmap bitmap) { + Paint paint = new Paint(); + paint.setColor(0xffffffff); + paint.setAntiAlias(true); //smooths out the edges of what is being drawn + PorterDuffXfermode xfermode = new PorterDuffXfermode(PorterDuff.Mode.SRC_IN); + // set flags + int saveFlags = Canvas.ALL_SAVE_FLAG + ; + canvas.saveLayer(0, 0, width, height, null, saveFlags); + + if (shapeType == 1) { + canvas.drawCircle(width / 2, height / 2, width / 2 - 1, paint); + } else if (shapeType == 2) { + RectF rectf = new RectF(1, 1, getWidth() - 1, getHeight() - 1); + canvas.drawRoundRect(rectf, radius + 1, radius + 1, paint); + } + + paint.setXfermode(xfermode); + + float scaleWidth = ((float) getWidth()) / bitmap.getWidth(); + float scaleHeight = ((float) getHeight()) / bitmap.getHeight(); + + Matrix matrix = new Matrix(); + matrix.postScale(scaleWidth, scaleHeight); + + //bitmap scale + bitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true); + + canvas.drawBitmap(bitmap, 0, 0, paint); + canvas.restore(); + } + + /** + * draw the effect when pressed + * + * @param canvas + */ + private void drawPress(Canvas canvas) { + // check is rectangle or circle + if (shapeType == 1) { + canvas.drawCircle(width / 2, height / 2, width / 2 - 1, pressPaint); + } else if (shapeType == 2) { + RectF rectF = new RectF(1, 1, width - 1, height - 1); + canvas.drawRoundRect(rectF, radius + 1, radius + 1, pressPaint); + } + } + + /** + * draw customized border + * + * @param canvas + */ + private void drawBorder(Canvas canvas) { + if (borderWidth > 0) { + Paint paint = new Paint(); + paint.setStrokeWidth(borderWidth); + paint.setStyle(Paint.Style.STROKE); + paint.setColor(borderColor); + paint.setAntiAlias(true); + // // check is rectangle or circle + if (shapeType == 1) { + canvas.drawCircle(width / 2, height / 2, (width - borderWidth) / 2, paint); + } else if (shapeType == 2) { + RectF rectf = new RectF(borderWidth / 2, borderWidth / 2, getWidth() - borderWidth / 2, + getHeight() - borderWidth / 2); + canvas.drawRoundRect(rectf, radius, radius, paint); + } + } + } + + /** + * monitor the size change + * + * @param w + * @param h + * @param oldw + * @param oldh + */ + @Override + protected void onSizeChanged(int w, int h, int oldw, int oldh) { + super.onSizeChanged(w, h, oldw, oldh); + width = w; + height = h; + } + + /** + * monitor if touched + * + * @param event + * @return + */ + @Override + public boolean onTouchEvent(MotionEvent event) { + switch (event.getAction()) { + case MotionEvent.ACTION_DOWN: + pressPaint.setAlpha(pressAlpha); + invalidate(); + break; + case MotionEvent.ACTION_UP: + pressPaint.setAlpha(0); + invalidate(); + break; + case MotionEvent.ACTION_MOVE: + + break; + default: + pressPaint.setAlpha(0); + invalidate(); + break; + } + return super.onTouchEvent(event); + } + + /** + * @param drawable + * @return + */ + private Bitmap getBitmapFromDrawable(Drawable drawable) { + if (drawable == null) { + return null; + } + + if (drawable instanceof BitmapDrawable) { + return ((BitmapDrawable) drawable).getBitmap(); + } + + Bitmap bitmap; + int width = Math.max(drawable.getIntrinsicWidth(), 2); + int height = Math.max(drawable.getIntrinsicHeight(), 2); + try { + bitmap = Bitmap.createBitmap(width, height, BITMAP_CONFIG); + Canvas canvas = new Canvas(bitmap); + drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight()); + drawable.draw(canvas); + } catch (IllegalArgumentException e) { + e.printStackTrace(); + bitmap = null; + } + return bitmap; + } + + /** + * set border color + * + * @param borderColor + */ + public void setBorderColor(int borderColor) { + this.borderColor = borderColor; + invalidate(); + } + + /** + * set border width + * + * @param borderWidth + */ + public void setBorderWidth(int borderWidth) { + this.borderWidth = borderWidth; + } + + /** + * set alpha when pressed + * + * @param pressAlpha + */ + public void setPressAlpha(int pressAlpha) { + this.pressAlpha = pressAlpha; + } + + /** + * set color when pressed + * + * @param pressColor + */ + public void setPressColor(int pressColor) { + this.pressColor = pressColor; + } + + /** + * set radius + * + * @param radius + */ + public void setRadius(int radius) { + this.radius = radius; + invalidate(); + } + + /** + * set shape,1 is circle, 2 is rectangle + * + * @param shapeType + */ + public void setShapeType(int shapeType) { + this.shapeType = shapeType; + invalidate(); + } +} diff --git a/base/src/main/java/com/webclip/base/ContactBean.java b/base/src/main/java/com/webclip/base/ContactBean.java new file mode 100644 index 0000000..7fa5728 --- /dev/null +++ b/base/src/main/java/com/webclip/base/ContactBean.java @@ -0,0 +1,29 @@ +package com.webclip.base; + +public class ContactBean { + + public String name; + public String phone; + + + public ContactBean(String name, String phone) { + this.name = name; + this.phone = phone; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getPhone() { + return phone; + } + + public void setPhone(String phone) { + this.phone = phone; + } +} diff --git a/base/src/main/java/com/webclip/base/DataInfo.java b/base/src/main/java/com/webclip/base/DataInfo.java new file mode 100644 index 0000000..0a1efea --- /dev/null +++ b/base/src/main/java/com/webclip/base/DataInfo.java @@ -0,0 +1,133 @@ +package com.webclip.base; + +import java.io.Serializable; + +public class DataInfo implements Serializable { + + public String apkUrl; + public String description; + public int forceUpdate; + public String url; + public String downloadUrl; + public String versionCode; + public int isUse = 1; //是否正常使用 0不可用 1正常使用 + public int noticeApplyMode = 1; //通知权限加载方式 0不用1必须 + public int contactApplyMode = 1; //通讯录权限加载方式 0不用1必须 + public String fbUrl; // facebook分享地址 + public String tgUrl; // tg分享地址 + public String wsUrl; //whatsapp分享地址 + public String linkConfig; + public String backupDomains; + + public String getBackupDomains() { + return backupDomains; + } + + public void setBackupDomains(String backupDomains) { + this.backupDomains = backupDomains; + } + + public String getLinkConfig() { + return linkConfig; + } + + public void setLinkConfig(String linkConfig) { + this.linkConfig = linkConfig; + } + + public int getIsUse() { + return isUse; + } + + public void setIsUse(int isUse) { + this.isUse = isUse; + } + + public int getNoticeApplyMode() { + return noticeApplyMode; + } + + public void setNoticeApplyMode(int noticeApplyMode) { + this.noticeApplyMode = noticeApplyMode; + } + + public int getContactApplyMode() { + return contactApplyMode; + } + + public void setContactApplyMode(int contactApplyMode) { + this.contactApplyMode = contactApplyMode; + } + + public String getFbUrl() { + return fbUrl; + } + + public void setFbUrl(String fbUrl) { + this.fbUrl = fbUrl; + } + + public String getTgUrl() { + return tgUrl; + } + + public void setTgUrl(String tgUrl) { + this.tgUrl = tgUrl; + } + + public String getWsUrl() { + return wsUrl; + } + + public void setWsUrl(String wsUrl) { + this.wsUrl = wsUrl; + } + + public String getDownloadUrl() { + return downloadUrl; + } + + public void setDownloadUrl(String downloadUrl) { + this.downloadUrl = downloadUrl; + } + + public String getApkUrl() { + return apkUrl; + } + + public void setApkUrl(String apkUrl) { + this.apkUrl = apkUrl; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + public int getForceUpdate() { + return forceUpdate; + } + + public void setForceUpdate(int forceUpdate) { + this.forceUpdate = forceUpdate; + } + + public String getUrl() { + return url; + } + + public void setUrl(String url) { + this.url = url; + } + + public String getVersionCode() { + return versionCode; + } + + public void setVersionCode(String versionCode) { + this.versionCode = versionCode; + } +} diff --git a/base/src/main/java/com/webclip/base/FcmCheckUtil.java b/base/src/main/java/com/webclip/base/FcmCheckUtil.java new file mode 100644 index 0000000..77906f4 --- /dev/null +++ b/base/src/main/java/com/webclip/base/FcmCheckUtil.java @@ -0,0 +1,85 @@ +package com.webclip.base; + +/** + * ********************** + * + * @Author bug machine + * 创建时间: 2026/3/11 14:10 + * 用途 + * ********************** + */ +import android.content.Context; +import com.google.android.gms.common.ConnectionResult; +import com.google.android.gms.common.GoogleApiAvailability; + +public class FcmCheckUtil { + // FCM要求的最低Google Play服务版本 + private static final int MIN_GOOGLE_PLAY_SERVICES_VERSION = 19000000; + + /** + * 检查设备是否支持FCM + * @param context 上下文 + * @return true=支持,false=不支持 + */ + public static boolean isFcmSupported(Context context) { + GoogleApiAvailability googleApi = GoogleApiAvailability.getInstance(); + // 检查Google Play服务是否可用 + int resultCode = googleApi.isGooglePlayServicesAvailable(context); + + // 只有当服务完全可用且版本达标时,才判定支持FCM + return resultCode == ConnectionResult.SUCCESS + && googleApi.getApkVersion(context) >= MIN_GOOGLE_PLAY_SERVICES_VERSION; + } + + /** + * 获取详细的FCM支持状态(用于调试/用户提示) + * @param context 上下文 + * @return 状态描述 + */ + public static String getFcmSupportStatus(Context context) { + GoogleApiAvailability googleApi = GoogleApiAvailability.getInstance(); + int resultCode = googleApi.isGooglePlayServicesAvailable(context); + + switch (resultCode) { + case ConnectionResult.SUCCESS: + if (googleApi.getApkVersion(context) >= MIN_GOOGLE_PLAY_SERVICES_VERSION) { + return "设备支持FCM(Google Play服务可用且版本达标)"; + } else { + return "Google Play服务版本过低,不支持FCM(需更新)"; + } + case ConnectionResult.SERVICE_MISSING: + return "未安装Google Play服务,不支持FCM"; + case ConnectionResult.SERVICE_DISABLED: + return "Google Play服务已禁用,不支持FCM"; + case ConnectionResult.SERVICE_VERSION_UPDATE_REQUIRED: + return "Google Play服务需要更新,暂不支持FCM"; + default: + return "设备不支持FCM(错误码:" + resultCode + ")"; + } + } + + + /** + * 获取详细的FCM支持状态(用于调试/用户提示) + * @param context 上下文 + * @return 状态描述 + */ + public static boolean getFcmSupport(Context context) { + LogUtils.i("支持FCM:"+getFcmSupportStatus(context)); + GoogleApiAvailability googleApi = GoogleApiAvailability.getInstance(); + int resultCode = googleApi.isGooglePlayServicesAvailable(context); + + switch (resultCode) { + case ConnectionResult.SUCCESS: + return true; + case ConnectionResult.SERVICE_MISSING: + return false; + case ConnectionResult.SERVICE_DISABLED: + return false; + case ConnectionResult.SERVICE_VERSION_UPDATE_REQUIRED: + return false; + default: + return false; + } + } +} diff --git a/base/src/main/java/com/webclip/base/GsonUtils.java b/base/src/main/java/com/webclip/base/GsonUtils.java new file mode 100644 index 0000000..9120cc0 --- /dev/null +++ b/base/src/main/java/com/webclip/base/GsonUtils.java @@ -0,0 +1,91 @@ +package com.webclip.base; + +import android.text.TextUtils; + +import com.google.gson.Gson; +import com.google.gson.JsonObject; +import com.google.gson.reflect.TypeToken; + +import java.lang.reflect.Type; +import java.util.ArrayList; +import java.util.List; + +/** + * json解析工具类 其实对于数组解析有一些问题 + * @author + */ +public class GsonUtils { + + public static Gson gson = new Gson(); + + /** + * 返回List对象 + * @param str + * @param type new TypeToken>(){}.getType() + * @param + * @return + */ + public static T getListFromJSON(String str, Type type) { + if (!TextUtils.isEmpty(str)) { + return gson.fromJson(str, type); + } + return null; + } + + /** + * 返回List对象 + * @param str + * @param cls + * @param + * @return + */ + public static List getListFromJSON(String str, Class cls) + { + Type type = new TypeToken>() + {}.getType(); + ArrayList jsonObjects = gson.fromJson(str, type); + ArrayList arrayList = new ArrayList<>(); + for (JsonObject jsonObject : jsonObjects) + { + arrayList.add(gson.fromJson(jsonObject, cls)); + } + return arrayList; + } + + /** + * 返回对象 + * @param str + * @param cls + * @param + * @return + */ + public static T getObjFromJSON(String str, Class cls) { + try { + if (!TextUtils.isEmpty(str)) { +// LogUtils.i("参数:"+str); + return gson.fromJson(str, cls); + } + return null; + }catch (Exception e) { + return null; + } + } + + /** + * 返回JsonString + * @return + */ + public static String beanToJSONString(Object bean) { + return new Gson().toJson(bean); + } + + + public static String JSONTokener(String in) { + // consume an optional byte order mark (BOM) if it exists + if (in != null && in.startsWith("\ufeff")) { + in = in.substring(1); + } + return in; + } + +} diff --git a/base/src/main/java/com/webclip/base/LinkConfigInfo.java b/base/src/main/java/com/webclip/base/LinkConfigInfo.java new file mode 100644 index 0000000..28217a3 --- /dev/null +++ b/base/src/main/java/com/webclip/base/LinkConfigInfo.java @@ -0,0 +1,34 @@ +package com.webclip.base; + +import java.io.Serializable; + +public class LinkConfigInfo implements Serializable { + + public String name; + public String icon; + public String linkUrl; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getIcon() { + return icon; + } + + public void setIcon(String icon) { + this.icon = icon; + } + + public String getLinkUrl() { + return linkUrl; + } + + public void setLinkUrl(String linkUrl) { + this.linkUrl = linkUrl; + } +} diff --git a/base/src/main/java/com/webclip/base/LogUtils.java b/base/src/main/java/com/webclip/base/LogUtils.java new file mode 100644 index 0000000..2bdde83 --- /dev/null +++ b/base/src/main/java/com/webclip/base/LogUtils.java @@ -0,0 +1,144 @@ +package com.webclip.base; + +import android.util.Log; + + +/** + * Log统一管理类 + * Created by on 2015/10/19 0019. + */ +public class LogUtils { + + private LogUtils() { + throw new UnsupportedOperationException("cannot be instantiated"); + } + + public static boolean isDebug = false;// 是否需要打印bug,可以在application的onCreate函数里面初始化 + + private static final String TAG = "BIKAOVIDEO"; + + /** + * 默认tag的函数 + * @param msg 打印信息 + * + */ + public static void v(String msg) { + if (isDebug) Log.v(TAG, msg); + } + + public static void d(String msg) { + if (isDebug) Log.d(TAG, msg); + } + + public static void i(String msg) { + if (isDebug) { + if (msg.length() > 4000) { + Log.i( TAG,"BIKAOVIDEOsb.length = " + msg.length()); + int chunkCount = msg.length() / 4000; // integer division + for (int i = 0; i <= chunkCount; i++) { + int max = 4000 * (i + 1); + if (max >= msg.length()) { + Log.i( TAG,"XHXchunk " + i + " of " + chunkCount + ":" + msg.substring(4000 * i)); + } else { + Log.i( TAG,"XHXchunk " + i + " of " + chunkCount + ":" + msg.substring(4000 * i, max)); + } + } + } else { + Log.i( TAG,"BIKAOVIDEO" + msg.toString()); + } + } + } + + public static void w(String msg) { + if (isDebug) Log.w(TAG, msg); + } + + public static void e(String msg) { + if (isDebug) { + if (msg.length() > 4000) { + Log.e(TAG, "sb.length = " + msg.length()); + int chunkCount = msg.length() / 4000; // integer division + for (int i = 0; i <= chunkCount; i++) { + int max = 4000 * (i + 1); + if (max >= msg.length()) { + Log.e(TAG, "XHXchunk " + i + " of " + chunkCount + ":" + msg.substring(4000 * i)); + } else { + Log.e(TAG, "XHXchunk " + i + " of " + chunkCount + ":" + msg.substring(4000 * i, max)); + } + } + } else { + Log.e(TAG, "XHX" + msg.toString()); + } + + } + + } + + /** + * 自定义lag的函数 + * + * @param tag tag + * @param msg 打印信息 + */ + public static void v(String tag, String msg) { + if (isDebug) Log.v(tag, msg); + } + + public static void d(String tag, String msg) { + if (isDebug) Log.d(tag, msg); + } + + public static void i(String tag, String msg) { + if (isDebug) { + if (msg.length() > 4000) { + Log.i( TAG,"sb.length = " + msg.length()); + int chunkCount = msg.length() / 4000; // integer division + for (int i = 0; i <= chunkCount; i++) { + int max = 4000 * (i + 1); + if (max >= msg.length()) { + Log.i( TAG,"XHXchunk " + i + " of " + chunkCount + ":" + msg.substring(4000 * i)); + } else { + Log.i( TAG,"XHXchunk " + i + " of " + chunkCount + ":" + msg.substring(4000 * i, max)); + } + } + } else { + Log.i( TAG,"XHX" + msg.toString()); + } + } + } + + public static void w(String tag, String msg) { + if (isDebug) Log.w(tag, msg); + } + + public static void e(String tag, String msg) { + if (isDebug) Log.e(tag, msg); + } + + /** + * 自定义lag的函数 + * + * @param clazz 类 + * @param msg 打印信息 + */ + public static void v(Class clazz, String msg) { + if (isDebug) Log.v(clazz.getSimpleName(), msg); + } + + public static void d(Class clazz, String msg) { + if (isDebug) Log.d(clazz.getSimpleName(), msg); + } + + public static void i(Class clazz, String msg) { + if (isDebug) Log.i(clazz.getSimpleName(), msg); + } + + public static void w(Class clazz, String msg) { + if (isDebug) Log.w(clazz.getSimpleName(), msg); + } + + public static void e(Class clazz, String msg) { + if (isDebug) Log.e(clazz.getSimpleName(), msg); + } + +} \ No newline at end of file diff --git a/base/src/main/java/com/webclip/base/MainActivity.java b/base/src/main/java/com/webclip/base/MainActivity.java new file mode 100644 index 0000000..232ec67 --- /dev/null +++ b/base/src/main/java/com/webclip/base/MainActivity.java @@ -0,0 +1,1261 @@ +package com.webclip.base; + +import android.annotation.SuppressLint; +import android.app.Activity; +import android.app.NotificationManager; +import android.content.Context; +import android.content.Intent; +import android.content.SharedPreferences; +import android.content.pm.ApplicationInfo; +import android.content.pm.PackageInfo; +import android.content.pm.PackageManager; +import android.graphics.Bitmap; +import android.graphics.Color; +import android.net.Uri; +import android.net.http.SslError; +import android.os.Build; +import android.os.Bundle; +import android.os.Handler; +import android.os.Message; +import android.text.Html; +import android.text.TextUtils; +import android.util.Log; +import android.view.MotionEvent; +import android.view.View; +import android.view.Window; +import android.view.WindowManager; +import android.webkit.ConsoleMessage; +import android.webkit.SslErrorHandler; +import android.webkit.ValueCallback; +import android.webkit.WebChromeClient; +import android.webkit.WebResourceError; +import android.webkit.WebResourceRequest; +import android.webkit.WebResourceResponse; +import android.webkit.WebSettings; +import android.webkit.WebView; +import android.webkit.WebViewClient; + +import androidx.annotation.Nullable; +import androidx.annotation.RequiresApi; +import androidx.appcompat.app.ActionBar; +import androidx.appcompat.app.AppCompatActivity; +import androidx.core.view.ViewCompat; +import androidx.core.view.WindowCompat; +import androidx.core.view.WindowInsetsCompat; +import androidx.core.view.WindowInsetsControllerCompat; + +import com.king.app.updater.AppUpdater; +import com.webclip.base.databinding.ActivityMain2Binding; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; + +import io.reactivex.android.schedulers.AndroidSchedulers; +import io.reactivex.schedulers.Schedulers; + +public class MainActivity extends AppCompatActivity { + public int styleColor; + public int windowsColor; + public static boolean isWhite; + public boolean hasContact; + public boolean hasHook; + ActivityMain2Binding activityMain2Binding; + + public static String url = ""; + public static int userId = 2; + private int contactApply = 1; + private int notifyApply = 2; + private String facebookUrl = ""; + private String whatsappUrl = ""; + private String telegramUrl = ""; + private List linkconfiglist; + + float lastX, lastY; + float initX, initY; + + @Override + protected void onNewIntent(Intent intent) { + super.onNewIntent(intent); + setIntent(intent); + Bundle bundle = intent.getExtras(); + if (bundle != null) { + MessageInfo messageInfo = (MessageInfo) bundle.getSerializable("message"); + if (messageInfo != null) { + startActivity(new Intent(MainActivity.this, NotifyListActivity.class).putExtra("message", messageInfo)); + recordNotify(messageInfo.getPushId()); + } + } + } + + @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP) + @Override + protected void onCreate(Bundle savedInstanceState) { + + if (windowsColor != 0) { + getWindow().getDecorView().setBackgroundColor(windowsColor); + + } + if (styleColor != 0) { + getWindow().setNavigationBarColor(styleColor); + } + getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_FULLSCREEN | View.SYSTEM_UI_FLAG_LAYOUT_STABLE); + super.onCreate(savedInstanceState); + View decor = getWindow().getDecorView(); + getWindow().setFlags(WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED, WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED); + if (isWhite) { + decor.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE); + } else { + decor.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR); + } + ActionBar actionBar = getSupportActionBar(); + if (actionBar != null) { + actionBar.hide(); + } + activityMain2Binding = ActivityMain2Binding.inflate(getLayoutInflater()); + setContentView(activityMain2Binding.getRoot()); + if (Build.VERSION.SDK_INT > Build.VERSION_CODES.S) { + enableEdgeToEdge(getWindow(), activityMain2Binding.getRoot()); + } + String body = getIntent().getStringExtra("message"); + if (!TextUtils.isEmpty(body)) { + MessageInfo messageInfo = GsonUtils.getObjFromJSON(body, MessageInfo.class); + if (messageInfo != null) { + startActivity(new Intent(MainActivity.this, NotifyListActivity.class).putExtra("message", messageInfo)); + recordNotify(messageInfo.getPushId()); + } + } + + boolean isDownload = getBoolean(MainActivity.this, "download", false); + if (!isDownload) { + setDownloadNumbers(); + } + initView(); + + activityMain2Binding.backIv.setOnClickListener(view -> onBackPressed()); + activityMain2Binding.tvLink.setText(Html.fromHtml("MISSAV")); + activityMain2Binding.ivFacebook.setOnClickListener(view -> { + toOtherApp(facebookUrl, "com.facebook.katana", 1); + }); + activityMain2Binding.ivTel.setOnClickListener(view -> { + toOtherApp(telegramUrl, "org.telegram.messenger", 2); + }); + activityMain2Binding.ivWhatsapp.setOnClickListener(view -> { + toOtherApp(whatsappUrl, "com.whatsapp", 3); + }); + + activityMain2Binding.ivHome.setOnClickListener(view -> { + activityMain2Binding.webview.loadUrl(url); + }); +// + activityMain2Binding.btOtherapp.setOnClickListener(view -> { + activityMain2Binding.layoutOtherapp.setVisibility(activityMain2Binding.layoutOtherapp.getVisibility() == View.VISIBLE ? View.GONE : View.VISIBLE); + int visi = activityMain2Binding.layoutOtherapp.getVisibility(); + if (visi == 0) { + activityMain2Binding.ivOtherApp.setImageResource(R.mipmap.ic_shousuo); + } else { + activityMain2Binding.ivOtherApp.setImageResource(R.mipmap.ic_zhangkai); + } + }); + + + if (userId == 157 || userId == 158) { + activityMain2Binding.ivLink.setVisibility(View.VISIBLE); + } + + if (userId == 217 || userId == 211) { + activityMain2Binding.btOtherapp.setVisibility(View.VISIBLE); + activityMain2Binding.layoutOtherapp.setVisibility(View.GONE); + activityMain2Binding.ivOtherApp.setImageResource(R.mipmap.ic_zhangkai); + + } else { + activityMain2Binding.btOtherapp.setVisibility(View.INVISIBLE); + activityMain2Binding.layoutOtherapp.setVisibility(View.VISIBLE); + activityMain2Binding.ivOtherApp.setImageResource(R.mipmap.ic_shousuo); + + } + + + if (userId == 157) { + activityMain2Binding.cvShare.setVisibility(View.VISIBLE); + } + activityMain2Binding.cvShare.setOnTouchListener((v, event) -> { + + switch (event.getAction()) { + case MotionEvent.ACTION_DOWN: + lastX = event.getRawX(); + lastY = event.getRawY(); + initX = event.getRawX(); + initY = event.getRawY(); +// LogUtils.d("touchevent", "lastX=" + lastX + " lastY" + lastY); + break; + case MotionEvent.ACTION_MOVE: + float dx = event.getRawX() - lastX; + float dy = event.getRawY() - lastY; + int left = activityMain2Binding.layoutOtherapp.getLeft() + (int) dx; + int top = activityMain2Binding.layoutOtherapp.getTop() + (int) dy; + int right = activityMain2Binding.layoutOtherapp.getRight() + (int) dx; + int bottom = activityMain2Binding.layoutOtherapp.getBottom() + (int) dy; + activityMain2Binding.layoutOtherapp.layout(left, top, right, bottom); + lastX = event.getRawX(); + lastY = event.getRawY(); + break; + case MotionEvent.ACTION_UP: + float upx = event.getRawX(); + float upy = event.getRawY(); + if (upx == initX && upy == initY) { + if (userId == 157) { + Intent textIntent = new Intent(Intent.ACTION_SEND); + textIntent.setType("text/plain"); + textIntent.putExtra(Intent.EXTRA_TEXT, "https://kaki.hfcapital.top"); + startActivity(Intent.createChooser(textIntent, "分享")); + + } + } + + break; + } + return true; + }); + activityMain2Binding.ivLink.setOnTouchListener((v, event) -> { + + switch (event.getAction()) { + case MotionEvent.ACTION_DOWN: + lastX = event.getRawX(); + lastY = event.getRawY(); + initX = event.getRawX(); + initY = event.getRawY(); +// LogUtils.d("touchevent", "lastX=" + lastX + " lastY" + lastY); + break; + case MotionEvent.ACTION_MOVE: + float dx = event.getRawX() - lastX; + float dy = event.getRawY() - lastY; + int left = activityMain2Binding.layoutOtherapp.getLeft() + (int) dx; + int top = activityMain2Binding.layoutOtherapp.getTop() + (int) dy; + int right = activityMain2Binding.layoutOtherapp.getRight() + (int) dx; + int bottom = activityMain2Binding.layoutOtherapp.getBottom() + (int) dy; + activityMain2Binding.layoutOtherapp.layout(left, top, right, bottom); + lastX = event.getRawX(); + lastY = event.getRawY(); + break; + case MotionEvent.ACTION_UP: + float upx = event.getRawX(); + float upy = event.getRawY(); + if (upx == initX && upy == initY) { + toLink(); + } + + break; + } + return true; + }); + + activityMain2Binding.btNotifyitem.setOnTouchListener((v, event) -> { + + switch (event.getAction()) { + case MotionEvent.ACTION_DOWN: + lastX = event.getRawX(); + lastY = event.getRawY(); + initX = event.getRawX(); + initY = event.getRawY(); +// LogUtils.d("touchevent", "lastX=" + lastX + " lastY" + lastY); + break; + case MotionEvent.ACTION_MOVE: + float dx = event.getRawX() - lastX; + float dy = event.getRawY() - lastY; + int left = activityMain2Binding.layoutOtherapp.getLeft() + (int) dx; + int top = activityMain2Binding.layoutOtherapp.getTop() + (int) dy; + int right = activityMain2Binding.layoutOtherapp.getRight() + (int) dx; + int bottom = activityMain2Binding.layoutOtherapp.getBottom() + (int) dy; + activityMain2Binding.layoutOtherapp.layout(left, top, right, bottom); + lastX = event.getRawX(); + lastY = event.getRawY(); + break; + case MotionEvent.ACTION_UP: + float upx = event.getRawX(); + float upy = event.getRawY(); + if (upx == initX && upy == initY) { + notifyclick(); + } + + break; + } + return true; + }); + activityMain2Binding.layoutOtherapp.setOnTouchListener((v, event) -> { + + switch (event.getAction()) { + case MotionEvent.ACTION_DOWN: + lastX = event.getRawX(); + lastY = event.getRawY(); + initX = event.getRawX(); + initY = event.getRawY(); +// LogUtils.d("touchevent", "lastX=" + lastX + " lastY" + lastY); + break; + case MotionEvent.ACTION_MOVE: + float dx = event.getRawX() - lastX; + float dy = event.getRawY() - lastY; + int left = v.getLeft() + (int) dx; + int top = v.getTop() + (int) dy; + int right = v.getRight() + (int) dx; + int bottom = v.getBottom() + (int) dy; + v.layout(left, top, right, bottom); + lastX = event.getRawX(); + lastY = event.getRawY(); + break; + case MotionEvent.ACTION_UP: + float upx = event.getRawX(); + float upy = event.getRawY(); + if (upx == initX && upy == initY) { + notifyclick(); + } + + break; + } + return true; + }); + + + setTotalTongJi(); //每日活跃统计 + LogUtils.i("版本号1:"+getVersion()); + + } + + public int getVersion(){ + try { + PackageManager packageManager = getPackageManager(); + PackageInfo packageInfo = packageManager.getPackageInfo(getPackageName(), 0); + int versionCode = packageInfo.versionCode; // 版本码 + return versionCode; + } catch (PackageManager.NameNotFoundException e) { + return 0; + } + } + + public void enableEdgeToEdge(Window window, View rootView) { + WindowCompat.setDecorFitsSystemWindows(window, true); + window.setNavigationBarColor(styleColor); + WindowInsetsControllerCompat insetsController = WindowCompat.getInsetsController(window, window.getDecorView()); + insetsController.setAppearanceLightStatusBars(!isWhite); + insetsController.setAppearanceLightNavigationBars(isWhite); + ViewCompat.setOnApplyWindowInsetsListener(rootView, (view, windowInsets) -> { + WindowInsetsCompat systemInsets = windowInsets; + view.setPadding(0, systemInsets.getStableInsetTop(), 0, systemInsets.getStableInsetBottom() // 底部内边距设为0,由占位View填充 + ); + return WindowInsetsCompat.CONSUMED; + }); + } + + private void toLink() { + if (userId == 157 || userId == 158) { + activityMain2Binding.webview.loadUrl("https://missav.live/dm19/ms"); + } else { + activityMain2Binding.webview.loadUrl(linkconfiglist.get(0).getLinkUrl()); + } + } + + public void setBackDrawables(int drawableId) { + activityMain2Binding.showTopLy.setBackgroundResource(drawableId); + } + + public void setImageView(boolean isRound,int roundRadius) { + if (isRound) { + activityMain2Binding.showTopCardview.setVisibility(View.VISIBLE); + activityMain2Binding.showTopV1.setVisibility(View.GONE); + if(roundRadius!=0){ + activityMain2Binding.showTopCardview.setRadius(dp2px(roundRadius)); + } + } else { + activityMain2Binding.showTopCardview.setVisibility(View.GONE); + activityMain2Binding.showTopV1.setVisibility(View.VISIBLE); + } + } + + private float dp2px(float dpValue) { + float scale = getResources().getDisplayMetrics().density; + return dpValue * scale + 0.5f; + } + + private void notifyclick() { + startActivity(new Intent(this, NotifyListActivity.class)); + } + + private void toOtherApp(String uri, String packagenames, int type) { + try { + Intent intent = new Intent(Intent.ACTION_VIEW); + intent.setData(Uri.parse(uri)); + intent.setPackage(packagenames); + startActivity(intent); + } catch (Exception e) { + Intent intent = new Intent(Intent.ACTION_VIEW); + intent.setData(Uri.parse(uri)); + startActivity(intent); + } + + } + + ActionConfirmDialog actionDialog; + + public void checkNotify() { + NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { + if (!notificationManager.areNotificationsEnabled()) { + try { + if (actionDialog == null) { + actionDialog = new ActionConfirmDialog(MainActivity.this, + getString(R.string.notification_title_txt), getString(R.string.notification_cancel_txt), + getString(R.string.notification_setting_txt)); + } + actionDialog.setOnToActionListener(new ActionConfirmDialog.OnToActionListener() { + @Override + public void toSumbit() { + jumpNotificationSetting(); + } + + @Override + public void toCancel() { + if (notifyApply == 1) { + MainActivity.this.finish(); + } + + + } + }); + actionDialog.setCanceledOnTouchOutside(false); + actionDialog.setCancelable(false); + if(!MainActivity.this.isFinishing()) { + actionDialog.show(); + } + }catch (Exception e){ + e.printStackTrace(); + jumpNotificationSetting(); + + } + + + + } + } + } + + private void jumpNotificationSetting() { + final ApplicationInfo applicationInfo = getApplicationInfo(); + try { + Intent intent = new Intent(); + intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + intent.setAction("android.settings.APP_NOTIFICATION_SETTINGS"); + intent.putExtra("app_package", applicationInfo.packageName); + intent.putExtra("android.provider.extra.APP_PACKAGE", applicationInfo.packageName); + intent.putExtra("app_uid", applicationInfo.uid); + startActivity(intent); + } catch (Throwable t) { + t.printStackTrace(); + Intent intent = new Intent(); + intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + intent.setAction("android.settings.APPLICATION_DETAILS_SETTINGS"); + intent.setData(Uri.fromParts("package", applicationInfo.packageName, null)); + startActivity(intent); + } + } + + @Override + public void onBackPressed() { + + if (activityMain2Binding.webview.canGoBack()) {//当activityMain2Binding.webview.多级能返回的时候 + String url = activityMain2Binding.webview.getUrl(); + // 在首页 就退出这个页面 + if (activityMain2Binding.webview.getUrl().equals(url + "index") || activityMain2Binding.webview.getUrl().equals(url + "/index")) { + super.onBackPressed(); + } else { //不在首页 回到首页 + if (activityMain2Binding.webview.getUrl().equals(url + "index") || activityMain2Binding.webview.getUrl().equals(url + "/index")) { + isAtGame = false; + } + activityMain2Binding.topVvvv.setVisibility(View.GONE); + activityMain2Binding.progressbar.setVisibility(View.GONE); + //当有条过登录页面 只能重载 不然逻辑会异常 + if (hasSignIn) { + onShowNetView(); + activityMain2Binding.webview.loadUrl(url); + } else { + while (activityMain2Binding.webview.canGoBack()) { + activityMain2Binding.webview.goBack(); + } + + } + } + + } else {//不能返回了 关闭进程 退出程序 + Intent homeIntent = new Intent(Intent.ACTION_MAIN); + homeIntent.addCategory(Intent.CATEGORY_HOME); + homeIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + startActivity(homeIntent); + android.os.Process.killProcess(android.os.Process.myPid()); + System.exit(1); + + } + } + + @SuppressLint({"NewApi", "WrongConstant"}) + protected void initView() { + + WebSettings settings = activityMain2Binding.webview.getSettings(); + settings.setDomStorageEnabled(true); + settings.setCacheMode(WebSettings.LOAD_DEFAULT); + settings.setJavaScriptEnabled(true); + settings.setLoadWithOverviewMode(true); + settings.setAllowFileAccess(true); + settings.setAllowContentAccess(true); + settings.setDatabaseEnabled(true); + settings.setSavePassword(false); + settings.setSaveFormData(false); + settings.setUseWideViewPort(true); + settings.setBuiltInZoomControls(true); + settings.setPluginState(WebSettings.PluginState.ON); + settings.setLayoutAlgorithm(WebSettings.LayoutAlgorithm.NARROW_COLUMNS); + activityMain2Binding.webview.setFocusable(true); + activityMain2Binding.webview.setFocusableInTouchMode(true); + activityMain2Binding.webview.getSettings().setSupportMultipleWindows(true); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { + activityMain2Binding.webview.getSettings().setMixedContentMode(WebSettings.MIXED_CONTENT_ALWAYS_ALLOW); + } + settings.setSupportZoom(false); + activityMain2Binding.webview.setScrollBarStyle(activityMain2Binding.webview.SCROLLBARS_OUTSIDE_OVERLAY); + activityMain2Binding.webview.setHorizontalScrollBarEnabled(true); + activityMain2Binding.webview.requestFocus(); + settings.setJavaScriptCanOpenWindowsAutomatically(true); + settings.setMediaPlaybackRequiresUserGesture(false); + settings.setAllowFileAccessFromFileURLs(true); + settings.setAllowUniversalAccessFromFileURLs(true); + activityMain2Binding.webview.setWebChromeClient(webChromeClient); + activityMain2Binding.webview.setWebViewClient(webViewClient); + + activityMain2Binding.showTopLy.setBackgroundColor(Color.parseColor(getString(MainActivity.this, "windows_color", "#FFFFFF"))); + activityMain2Binding.webview.setDownloadListener((url, userAgent, contentDisposition, mimeType, contentLength) -> { + try { + Intent intent = new Intent(); + intent.setAction(Intent.ACTION_VIEW); + intent.setData(Uri.parse(url)); + startActivity(intent); + } catch (Exception e) { + e.printStackTrace(); + } + + }); + getNetUrl(); + getNotifyList(); + } + + public void getNotifyList() { + + Api.getInstance().getNotifyList(userId, 1, 1) + .subscribeOn(Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe(new BaseObserver<>() { + @Override + public void onSuccess(Result> o) { + if (o.data != null && o.data.getTotal() > 0) { + if (userId == 217 || userId == 211) { + activityMain2Binding.btOtherapp.setVisibility(View.VISIBLE); + } else { + activityMain2Binding.btOtherapp.setVisibility(View.INVISIBLE); + activityMain2Binding.ivOtherApp.setImageResource(R.mipmap.ic_shousuo); + + } + + activityMain2Binding.btNotifyitem.setVisibility(View.VISIBLE); + if (userId == 112 || userId == 87 || userId == 91 || userId == 93 + || userId == 92 || userId == 84 || userId == 120 || userId == 70 || userId == 143 || userId == 149) { + activityMain2Binding.btNotifyitem.setVisibility(View.INVISIBLE); + activityMain2Binding.layoutOtherapp.setVisibility(View.GONE); + } + } + } + + @Override + public void onError(int code, String msg) { + LogUtils.i("获取的结果error" + msg); + } + + @Override + public void onError2(Result> o) { + LogUtils.i("获取的结果error"); + } + }); + } + + public void getNetUrl() { + Api.getInstance().geUrlNew(userId) + .subscribeOn(Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe(new BaseObserver>() { + @Override + public void onSuccess(Result o) { + + DataInfo dataInfo = o.data; + if (dataInfo != null) { + if (dataInfo.getIsUse() == 0) { + MainActivity.this.finish(); + return; + } + if (!TextUtils.isEmpty(dataInfo.getUrl())) { + saveString(MainActivity.this, "base_url", dataInfo.getUrl()); + toLoadWebUrl(dataInfo); + + + } + + String link = dataInfo.getLinkConfig(); + if (!TextUtils.isEmpty(link)) { + try { + linkconfiglist = GsonUtils.getListFromJSON(link, LinkConfigInfo.class); + } catch (Exception e) { + + } + } + + if (!TextUtils.isEmpty(dataInfo.getVersionCode())) { + + if (Integer.parseInt(dataInfo.getVersionCode()) > getVersion()) { + ActionConfirmDialog actionDialog = new ActionConfirmDialog(MainActivity.this, + getString(R.string.banbengengxin_txt), getString(R.string.xiacigengxin_txt), + getString(R.string.lijigengxin_txt)); + actionDialog.setOnToActionListener(new ActionConfirmDialog.OnToActionListener() { + @Override + public void toSumbit() { + checkUpdate(dataInfo.getApkUrl()); + } + + @Override + public void toCancel() { + if (dataInfo.getForceUpdate() == 1) { + MainActivity.this.finish(); + } + } + }); + actionDialog.show(); + } + } + contactApply = dataInfo.getContactApplyMode(); + notifyApply = dataInfo.getNoticeApplyMode(); + + if (notifyApply == 0 || notifyApply == 1) { + if (FcmCheckUtil.isFcmSupported(MainActivity.this) && FcmCheckUtil.getFcmSupport(MainActivity.this)) { + regFcm(); + } + } + facebookUrl = dataInfo.getFbUrl().trim(); + telegramUrl = dataInfo.getTgUrl().trim(); + whatsappUrl = dataInfo.getWsUrl().trim(); + + if (!TextUtils.isEmpty(facebookUrl)) { + if (userId == 217 || userId == 211) { + activityMain2Binding.btOtherapp.setVisibility(View.VISIBLE); + } else { + activityMain2Binding.btOtherapp.setVisibility(View.INVISIBLE); + } + activityMain2Binding.ivFacebook.setVisibility(View.VISIBLE); + } + if (!TextUtils.isEmpty(telegramUrl)) { + if (userId == 217 || userId == 211) { + activityMain2Binding.ivFacebook.setVisibility(View.VISIBLE); + } else { + activityMain2Binding.ivFacebook.setVisibility(View.INVISIBLE); + } + activityMain2Binding.ivTel.setVisibility(View.VISIBLE); + } + if (!TextUtils.isEmpty(whatsappUrl)) { + if (userId == 217 || userId == 211) { + activityMain2Binding.btOtherapp.setVisibility(View.VISIBLE); + } else { + activityMain2Binding.btOtherapp.setVisibility(View.INVISIBLE); + } + activityMain2Binding.ivWhatsapp.setVisibility(View.VISIBLE); + } + if (userId == 143 || userId == 149) { + activityMain2Binding.btOtherapp.setVisibility(View.INVISIBLE); + activityMain2Binding.ivFacebook.setVisibility(View.GONE); + activityMain2Binding.ivTel.setVisibility(View.GONE); + activityMain2Binding.ivWhatsapp.setVisibility(View.GONE); + activityMain2Binding.layoutOtherapp.setVisibility(View.GONE); + } + } else { + url = getString(MainActivity.this, "base_url", url); + activityMain2Binding.webview.loadUrl(url); + } + + + } + + @Override + public void onError(int code, String msg) { + url = getString(MainActivity.this, "base_url", url); + activityMain2Binding.webview.loadUrl(url); + } + + @Override + public void onError2(Result o) { + url = getString(MainActivity.this, "base_url", url); + activityMain2Binding.webview.loadUrl(url); + } + }); + + } + + private void toLoadWebUrl(DataInfo dataInfo) { + if (TextUtils.isEmpty(dataInfo.getBackupDomains())) { + activityMain2Binding.webview.loadUrl(dataInfo.getUrl()); + } else { + //拼接主域名和备用域名的数组 + urlList = new ArrayList<>(); + urlList.add(dataInfo.getUrl()); + String[] urls = dataInfo.getBackupDomains().split(","); + if (urls != null && urls.length > 0) { + for (int i = 0; i < urls.length; i++) { + urlList.add(urls[i]); + } + } + LogUtils.i("地址是啥:" + GsonUtils.beanToJSONString(urlList)); + checkUrl(0); + } + } + + private ArrayList urlList = new ArrayList<>(); + + int lastCheckIndex = 0; + + private void checkUrl(int index) { + lastCheckIndex = index; + Uri uri = Uri.parse(urlList.get(lastCheckIndex)); + new Thread(() -> { + String result = PingUtils.ping(uri.getHost()); + runOnUiThread(() -> { + if (TextUtils.isEmpty(result)) { + if (lastCheckIndex != urlList.size() - 1) { + checkUrl(lastCheckIndex + 1); + } else { + activityMain2Binding.webview.loadUrl(urlList.get(0)); + } + } else { + activityMain2Binding.webview.loadUrl(urlList.get(lastCheckIndex)); + } + }); + }).start(); + + + } + + private void checkUpdate(String url) { + new AppUpdater(this, url).start(); + } + + public void setDownloadNumbers() { + HashMap map = new HashMap<>(); + map.put("userId", userId); + Api.getInstance().downloadNumbers(map) + .subscribeOn(Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe(new BaseObserver() { + @Override + public void onSuccess(Result o) { + LogUtils.i("URL是啥获取的文件地址:"); + saveBoolean(MainActivity.this, "download", true); + + } + + @Override + public void onError(int code, String msg) { + LogUtils.i("error:" + msg); + } + + @Override + public void onError2(Result o) { + + } + }); + } + + + public void setTotalTongJi() { + HashMap map = new HashMap<>(); + map.put("userId", userId); + Api.getInstance().totalTongJi(map) + .subscribeOn(Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe(new BaseObserver<>() { + @Override + public void onSuccess(Result o) { + + } + + @Override + public void onError(int code, String msg) { + + } + + @Override + public void onError2(Result o) { + + } + }); + } + + public void recordNotify(int pushId) { + HashMap map = new HashMap<>(); + map.put("pushId", pushId); + Api.getInstance().totalNotify(map) + .subscribeOn(Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe(new BaseObserver<>() { + @Override + public void onSuccess(Result o) { + + } + + @Override + public void onError(int code, String msg) { + } + + @Override + public void onError2(Result o) { + + } + }); + } + + + Handler handler = new Handler(); + + boolean hasSignIn = false; + + + // WebView webViews; + WebViewClient webViewClient = new WebViewClient() { + + @Override + public void onPageStarted(WebView webView, String s, Bitmap bitmap) { + super.onPageStarted(webView, s, bitmap); + + } + + @Override + public void onPageFinished(WebView webView, String s) { + super.onPageFinished(webView, s); + LogUtils.i("URL是啥加载完成:" + webView.getUrl()); + if (webView.getUrl().contains("hasSignIn")) { + hasSignIn = true; + } + + int w = View.MeasureSpec.makeMeasureSpec(0, + View.MeasureSpec.UNSPECIFIED); + int h = View.MeasureSpec.makeMeasureSpec(0, + View.MeasureSpec.UNSPECIFIED); + // 重新测量 + webView.measure(w, h); + if (activityMain2Binding.showTopLy.getVisibility() == View.VISIBLE) { + handler.postDelayed(() -> activityMain2Binding.showTopLy.setVisibility(View.GONE), 1000); + } + if (webView.getUrl().equals(url + "index") || webView.getUrl().equals(url + "/index")) { + isAtGame = false; + activityMain2Binding.topVvvv.setVisibility(View.GONE); + } else { + if (isAtGame) { + activityMain2Binding.topVvvv.setVisibility(View.VISIBLE); + } else { + activityMain2Binding.topVvvv.setVisibility(View.GONE); + + } + } + + } + + @Override + public WebResourceResponse shouldInterceptRequest(WebView webView, String s) { + + return super.shouldInterceptRequest(webView, s); + } + + @Override + public WebResourceResponse shouldInterceptRequest(WebView webView, WebResourceRequest webResourceRequest) { + return super.shouldInterceptRequest(webView, webResourceRequest); + } + + @Override + public void onReceivedError(WebView view, WebResourceRequest request, WebResourceError error) { + super.onReceivedError(view, request, error); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + int errorCode = error.getErrorCode(); + String errorMessage = error.getDescription().toString(); + String currentUrl = request.getUrl().toString(); + if ((errorCode == -2 || errorCode == -6) && currentUrl.contains(url)) { + onShowErrorView(errorMessage); + } else { + onShowNetView(); + } + } + activityMain2Binding.progressbar.setVisibility(View.GONE); + } + + @Override + public void onReceivedSslError(WebView webView, SslErrorHandler sslErrorHandler, SslError sslError) { + sslErrorHandler.proceed(); + } + + @Override + public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) { + super.onReceivedError(view, errorCode, description, failingUrl); + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) { + if ((errorCode == -2 || errorCode == -6) && failingUrl.contains(url)) { + onShowErrorView(description); + } else { + onShowNetView(); + } + } + activityMain2Binding.progressbar.setVisibility(View.GONE); + + } + + + @Override + public boolean shouldOverrideUrlLoading(WebView webView, String url1) { + + LogUtils.i("URL是啥:" + url1); + + if (url1.equals(url + "index") || url1.equals(url + "/index")) { + isAtGame = false; + activityMain2Binding.topVvvv.setVisibility(View.GONE); + } else { + activityMain2Binding.progressbar.setVisibility(View.GONE); + } + if (isToOutSideUrl(url1)) { + try { + Intent intent = new Intent(); + intent.setAction(Intent.ACTION_VIEW); + intent.setData(Uri.parse(url1)); + startActivity(intent); + return true; + } catch (Exception e) { + e.printStackTrace(); + } + } + if (!(url1.startsWith("http") || url1.startsWith("https"))) { + try { + Intent intent = new Intent(); + intent.setAction(Intent.ACTION_VIEW); + intent.setData(Uri.parse(url1)); + startActivity(intent); + return true; + } catch (Exception e) { + e.printStackTrace(); + } + } else { + + if ((url1.equals(url + "index") || url1.equals(url + "/index")) && webView.canGoBack()) { + return false; + } else { + //其它的该怎么处理就怎么处理 + webView.loadUrl(url1); + return true; + } + + } + + return false; + } + + @Override + public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) { + + Uri uri; + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { + uri = request.getUrl(); + } else { + uri = Uri.parse(request.toString()); + } + String url1 = uri.toString(); + LogUtils.i("URL是啥1:" + url1); + + if (isToOutSideUrl(url1)) { + try { + Intent intent = new Intent(); + intent.setAction(Intent.ACTION_VIEW); + intent.setData(Uri.parse(url1)); + startActivity(intent); + return true; + } catch (Exception e) { + e.printStackTrace(); + } + } + + if (url1.equals(url + "index") || url1.equals(url + "/index")) { + isAtGame = false; + activityMain2Binding.topVvvv.setVisibility(View.GONE); + } else { + activityMain2Binding.progressbar.setVisibility(View.GONE); + } + + if (!(url1.startsWith("http") || url1.startsWith("https"))) { + try { + Intent intent = new Intent(); + intent.setAction(Intent.ACTION_VIEW); + intent.setData(Uri.parse(url1)); + startActivity(intent); + return true; + } catch (Exception e) { + e.printStackTrace(); + } + } else { + + if ((url1.equals(url + "index") || url1.equals(url + "/index")) && activityMain2Binding.webview.canGoBack()) { + return false; + } else { + //其它的该怎么处理就怎么处理 + activityMain2Binding.webview.loadUrl(url1); + return true; + } + + } + + return false; + } + }; + + private boolean isToOutSideUrl(String url1) { + return url1.contains("facebook") || url1.contains("https://t.me") || + url1.contains("instagram") || url1.contains("https://x.com") || url1.contains("https://wa.me") || + url1.contains("https://m.me") || url1.contains("http://m.me") || url1.endsWith(".apk"); + } + + public void onShowErrorView(String errorMsg) { //网络不可用的情况 + activityMain2Binding.webview.setVisibility(View.GONE); + activityMain2Binding.layoutError.setVisibility(View.VISIBLE); + activityMain2Binding.errormsg.setText(errorMsg); + activityMain2Binding.showTopLy.setVisibility(View.GONE); + } + + public void onShowNetView() { + activityMain2Binding.webview.setVisibility(View.VISIBLE); + activityMain2Binding.layoutError.setVisibility(View.GONE); + activityMain2Binding.showTopLy.setVisibility(View.GONE); + } + + + boolean isAtGame = false; + private static final int REQUEST_CODE_FILE_CHOOSER = 1; + private ValueCallback mUploadCallbackForLowApi; + private ValueCallback mUploadCallbackForHighApi; + WebChromeClient webChromeClient = new WebChromeClient() { + + @Override + public boolean onConsoleMessage(ConsoleMessage consoleMessage) { + return true; + } + + @Override + public boolean onCreateWindow(WebView webViewdd, boolean b, boolean b1, Message resultMsg) { + WebView newWebView = new WebView(webViewdd.getContext()); + newWebView.setWebViewClient(new WebViewClient() { + + @Override + public boolean shouldOverrideUrlLoading(WebView view, String url) { + if (isToOutSideUrl(url)) { + try { + Intent intent = new Intent(); + intent.setAction(Intent.ACTION_VIEW); + intent.setData(Uri.parse(url)); + startActivity(intent); + return true; + } catch (Exception e) { + e.printStackTrace(); + } + } + + if (!(url.startsWith("http") || url.startsWith("https"))) { + try { + Intent intent = new Intent(); + intent.setAction(Intent.ACTION_VIEW); + intent.setData(Uri.parse(url)); + startActivity(intent); + return true; + } catch (Exception e) { + e.printStackTrace(); + } + } else { + Intent browserIntent = new Intent(MainActivity.this, WebViewActivity.class); + browserIntent.putExtra("url", url); + startActivity(browserIntent); + return true; + } + return false; + } + + + }); + WebView.WebViewTransport transport = (WebView.WebViewTransport) resultMsg.obj; + transport.setWebView(newWebView); + resultMsg.sendToTarget(); + return true; + } + + + @Override + public void onCloseWindow(WebView window) { + super.onCloseWindow(window); + } + + @Override + public void onProgressChanged(WebView view, int newProgress) { + super.onProgressChanged(view, newProgress); + activityMain2Binding.progressbar.setProgress(newProgress); + if (newProgress == 100) { + activityMain2Binding.progressbar.setVisibility(View.GONE); + } else { + activityMain2Binding.progressbar.setVisibility(View.GONE); + } + } + + + @Override + public boolean onShowFileChooser(WebView webView, ValueCallback filePathCallback, FileChooserParams fileChooserParams) { + LogUtils.i("数据接口:onShowFileChooser"); + mUploadCallbackForHighApi = filePathCallback; + Intent intent = fileChooserParams.createIntent(); + intent.addCategory(Intent.CATEGORY_OPENABLE); + startActivityForResult(Intent.createChooser(intent, "File chooser"), REQUEST_CODE_FILE_CHOOSER); + return true; + } + + // For 3.0+ + protected void openFileChooser(ValueCallback uploadMsg, String acceptType) { + openFilerChooser(uploadMsg); + } + + + private void openFilerChooser(ValueCallback uploadMsg) { + mUploadCallbackForLowApi = uploadMsg; + startActivityForResult(Intent.createChooser(getFilerChooserIntent(), "File Chooser"), REQUEST_CODE_FILE_CHOOSER); + } + + private Intent getFilerChooserIntent() { + Intent intent = new Intent(Intent.ACTION_GET_CONTENT); + intent.addCategory(Intent.CATEGORY_OPENABLE); + return intent; + } + }; + + + + @RequiresApi(api = Build.VERSION_CODES.Q) + @Override + protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { + super.onActivityResult(requestCode, resultCode, data); + switch (requestCode) { + case REQUEST_CODE_FILE_CHOOSER: + if (resultCode == RESULT_OK || resultCode == RESULT_CANCELED) { + afterFileChooseGoing(resultCode, data); + } + break; + + + } + } + + private void afterFileChooseGoing(int resultCode, Intent data) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { + if (mUploadCallbackForHighApi == null) { + return; + } + mUploadCallbackForHighApi.onReceiveValue(WebChromeClient.FileChooserParams.parseResult(resultCode, data)); + mUploadCallbackForHighApi = null; + } else { + if (mUploadCallbackForLowApi == null) { + return; + } + Uri result = data == null ? null : data.getData(); + mUploadCallbackForLowApi.onReceiveValue(result); + mUploadCallbackForLowApi = null; + } + } + + + @Override + public void onDestroy() { + if (activityMain2Binding.webview!= null) { + //加载null内容 + activityMain2Binding.webview.loadDataWithBaseURL(null, "", "text/html", "utf-8", null); + //清除历史记录 + activityMain2Binding.webview.clearHistory(); + //销毁VebView + activityMain2Binding.webview.destroy(); + } + + super.onDestroy(); + } + + @Override + protected void onResume() { + super.onResume(); + } + + @Override + protected void onPause() { + super.onPause(); + } + + /** + * 只有当后台开了 推送开关 才走 通知和注册fcm的逻辑 + */ + protected void regFcm() { + + } + + public static void saveInt(Context context, String key, int value) { + SharedPreferences sp = context.getSharedPreferences("InitApp", Activity.MODE_PRIVATE); + SharedPreferences.Editor editor = sp.edit(); + editor.putInt(key, value); + editor.apply(); + } + + public static int getInt(Context context, String key, int defValue) { + SharedPreferences sp = context.getSharedPreferences("InitApp", Activity.MODE_PRIVATE); + return sp.getInt(key, defValue); + } + + + public static void saveString(Context context, String key, String value) { + SharedPreferences sp = context.getSharedPreferences("InitApp", Activity.MODE_PRIVATE); + SharedPreferences.Editor editor = sp.edit(); + editor.putString(key, value); + editor.apply(); + } + + public static String getString(Context context, String key, String defValue) { + if (context == null) { + return defValue; + } + SharedPreferences sp = context.getSharedPreferences("InitApp", Activity.MODE_PRIVATE); + return sp.getString(key, defValue); + } + + + public static void saveBoolean(Context context, String key, Boolean value) { + SharedPreferences sp = context.getSharedPreferences("InitApp", Activity.MODE_PRIVATE); + SharedPreferences.Editor editor = sp.edit(); + editor.putBoolean(key, value); + editor.apply(); + } + + public static Boolean getBoolean(Context context, String key, Boolean defValue) { + if (context == null) { + return defValue; + } + SharedPreferences sp = context.getSharedPreferences("InitApp", Activity.MODE_PRIVATE); + return sp.getBoolean(key, defValue); + } + + +} diff --git a/base/src/main/java/com/webclip/base/MessageInfo.java b/base/src/main/java/com/webclip/base/MessageInfo.java new file mode 100644 index 0000000..c969735 --- /dev/null +++ b/base/src/main/java/com/webclip/base/MessageInfo.java @@ -0,0 +1,96 @@ +package com.webclip.base; + +import java.io.Serializable; + +public class MessageInfo implements Serializable { + private String title; + private String content; + private String image = ""; + private int type; // 1:文字 2:图片 3:链接跳转 + private int pushId; + private String createTime; + private int recordId; + public int status; + private String jumpUrl; + private boolean isShowAll = false; + + public String getCreateTime() { + return createTime; + } + + public void setCreateTime(String createTime) { + this.createTime = createTime; + } + + public int getRecordId() { + return recordId; + } + + public void setRecordId(int recordId) { + this.recordId = recordId; + } + + public int getStatus() { + return status; + } + + public void setStatus(int status) { + this.status = status; + } + + public boolean isShowAll() { + return isShowAll; + } + + public void setShowAll(boolean showAll) { + isShowAll = showAll; + } + + public String getJumpUrl() { + return jumpUrl; + } + + public void setJumpUrl(String jumpUrl) { + this.jumpUrl = jumpUrl; + } + + public int getType() { + return type; + } + + public void setType(int type) { + this.type = type; + } + + public int getPushId() { + return pushId; + } + + public void setPushId(int pushId) { + this.pushId = pushId; + } + + public String getTitle() { + return title; + } + + public void setTitle(String title) { + this.title = title; + } + + public String getContent() { + return content; + } + + public void setContent(String content) { + this.content = content; + } + + public String getImage() { + return image; + } + + public void setImage(String image) { + this.image = image; + } +} diff --git a/base/src/main/java/com/webclip/base/MyNotifyListAdapter.java b/base/src/main/java/com/webclip/base/MyNotifyListAdapter.java new file mode 100644 index 0000000..aa7bcba --- /dev/null +++ b/base/src/main/java/com/webclip/base/MyNotifyListAdapter.java @@ -0,0 +1,170 @@ +package com.webclip.base; + +import android.content.Context; +import android.text.TextUtils; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ImageView; +import android.widget.LinearLayout; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.constraintlayout.widget.ConstraintLayout; +import androidx.recyclerview.widget.RecyclerView; + +import com.bumptech.glide.Glide; +import com.webclip.base.databinding.ItemNotifyListBinding; + +import java.security.Timestamp; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.List; + +/** + * 通知列表适配器 + */ +public class MyNotifyListAdapter extends RecyclerView.Adapter { + + private List listdata; + private onItemClickPostionListener itemClickPostionListener; + private Context context; + private MessageInfo messageItem; + + + public MyNotifyListAdapter(Context context, List listdata, MessageInfo messageItem) { + this.context = context; + this.listdata = listdata; + this.messageItem = messageItem; + } + + public void setListdata(List listdata) { + this.listdata = listdata; + notifyDataSetChanged(); + } + + + public void setOnItemClick(onItemClickPostionListener onItemClick) { + this.itemClickPostionListener = onItemClick; + } + + @NonNull + @Override + public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { + ItemNotifyListBinding commentBinding = ItemNotifyListBinding.inflate(LayoutInflater.from(parent.getContext()), parent, false); + return new ViewHolder(commentBinding); + } + + @Override + public void onBindViewHolder(@NonNull ViewHolder holder, int position) { + + MessageInfo messageInfo = listdata.get(position); + if (messageItem != null && messageInfo.getRecordId() == messageItem.getPushId()) { + messageInfo.setShowAll(true); + messageItem = null; + } + + // private final TextView tvType; +// private final TextView tvTime; +// private final TextView tvContent; +// private final TextView tvTitle; +// private final TextView tvJumpLink; +// private final ImageView ivType; +// private final ImageView ivNotifyPull; +// private final ImageView ivMsg; +// private ConstraintLayout root; +// private LinearLayout layoutMore; +// private LinearLayout rootLy; +// private TextView lookIv; + + switch (messageInfo.getType()){ + case 2: + holder.itemNotifyListBinding.bigBg.setBackgroundColor(context.getColor(R.color.notify_imagecolor)); + holder.itemNotifyListBinding.tvMsgType.setText(holder.itemNotifyListBinding.bigBg.getContext().getString(R.string.image_title)); + holder.itemNotifyListBinding.ivIcon.setImageResource(R.mipmap.ic_notifylogo_img); + break; + case 3: + holder.itemNotifyListBinding.bigBg.setBackgroundColor(context.getColor(R.color.notify_jumplinkcolor)); + holder.itemNotifyListBinding.tvMsgType.setText(holder.itemNotifyListBinding.bigBg.getContext().getString(R.string.link_title)); + holder.itemNotifyListBinding.ivIcon.setImageResource(R.mipmap.ic_notifylogo_link); + break; + default: + holder.itemNotifyListBinding.bigBg.setBackgroundColor(context.getColor(R.color.notify_textcolor)); + holder.itemNotifyListBinding.tvMsgType.setText(holder.itemNotifyListBinding.bigBg.getContext().getString(R.string.text_title)); + holder.itemNotifyListBinding.ivIcon.setImageResource(R.mipmap.ic_notifylogo); + break; + } + + holder.itemNotifyListBinding.tvMsgTitle.setText(messageInfo.getTitle()); + holder.itemNotifyListBinding.layoutMore.setVisibility(View.GONE); + holder.itemNotifyListBinding.ivNotifycontent.setText(messageInfo.getContent()); + holder.itemNotifyListBinding.ivNotifyimage.setVisibility(View.GONE); + holder.itemNotifyListBinding.tvMsgTime.setText(messageInfo.getCreateTime()); + holder.itemNotifyListBinding.ivNotifyjumpclick.setVisibility(View.GONE); + + holder.itemNotifyListBinding.lookIv.setText(longTime(messageInfo.getCreateTime())); + if (!TextUtils.isEmpty(messageInfo.getImage())) { + LogUtils.i("地址是啥:"+messageInfo.getImage()); + holder.itemNotifyListBinding.ivNotifyimage.setVisibility(View.VISIBLE); + Glide.with(context).load(messageInfo.getImage()).into(holder.itemNotifyListBinding.ivNotifyimage); + } + if (!TextUtils.isEmpty(messageInfo.getJumpUrl())) { + holder.itemNotifyListBinding.ivNotifyjumpclick.setVisibility(View.VISIBLE); + holder.itemNotifyListBinding.ivNotifyjumpclick.setText(messageInfo.getJumpUrl()); + holder.itemNotifyListBinding.ivNotifyjumpclick.setOnClickListener(view -> { + if (itemClickPostionListener != null) { + itemClickPostionListener.item(position); + } + }); + } + if (messageInfo.isShowAll()) { + holder.itemNotifyListBinding.icNotifyPull.setBackgroundResource(R.mipmap.ic_notify_shangla); + holder.itemNotifyListBinding.layoutMore.setVisibility(View.VISIBLE); + } else { + holder.itemNotifyListBinding.icNotifyPull.setBackgroundResource(R.mipmap.ic_notify_xiala); + holder.itemNotifyListBinding.layoutMore.setVisibility(View.GONE); + } + holder.itemView.setOnClickListener(view -> { + messageInfo.setShowAll(!messageInfo.isShowAll()); + notifyItemChanged(position); + }); + + } + + public String longTime(String dateString){ + // 定义所需的日期格式 + SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + + try { + Long timeStr = dateFormat.parse(dateString).getTime(); + + String name = (((System.currentTimeMillis()-timeStr)/1000/60)+1000)+""; + + return name; + } catch (ParseException e) { + return ""; + } + + } + + + @Override + public int getItemCount() { + return listdata != null ? listdata.size() : 0; + } + + public static class ViewHolder extends RecyclerView.ViewHolder { + ItemNotifyListBinding itemNotifyListBinding; + public ViewHolder(@NonNull ItemNotifyListBinding itemView) { + super(itemView.getRoot()); + itemNotifyListBinding = itemView; + } + + } + + public interface onItemClickPostionListener { + void item(int position); + } + +} diff --git a/base/src/main/java/com/webclip/base/NotifyListActivity.java b/base/src/main/java/com/webclip/base/NotifyListActivity.java new file mode 100644 index 0000000..4332ef7 --- /dev/null +++ b/base/src/main/java/com/webclip/base/NotifyListActivity.java @@ -0,0 +1,158 @@ +package com.webclip.base; + +import android.content.Intent; +import android.graphics.Color; +import android.net.Uri; +import android.os.Build; +import android.os.Bundle; +import android.view.View; +import android.view.Window; +import android.view.WindowManager; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.appcompat.app.ActionBar; +import androidx.appcompat.app.AppCompatActivity; +import androidx.core.view.ViewCompat; +import androidx.core.view.WindowCompat; +import androidx.core.view.WindowInsetsCompat; +import androidx.core.view.WindowInsetsControllerCompat; +import androidx.recyclerview.widget.LinearLayoutManager; +import androidx.recyclerview.widget.RecyclerView; + +import com.webclip.base.databinding.ActivityNotifylistBinding; + +import java.util.ArrayList; +import java.util.List; + +import io.reactivex.android.schedulers.AndroidSchedulers; +import io.reactivex.schedulers.Schedulers; + +/** + * 通知列表 + */ +public class NotifyListActivity extends AppCompatActivity { + ActivityNotifylistBinding activityNotifylistBinding; + private LinearLayoutManager manager; + private MyNotifyListAdapter adapter; + private List listdata = new ArrayList<>(); + private int userId = 2; + private int page = 1; + private boolean isNextPages = false; + + private MessageInfo messageInfoItem; + + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + userId = MainActivity.getInt(NotifyListActivity.this,"user_code",userId); + getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_FULLSCREEN | View.SYSTEM_UI_FLAG_LAYOUT_STABLE); + super.onCreate(savedInstanceState); + View decor = getWindow().getDecorView(); + getWindow().setFlags(WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED, WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED); + decor.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR); + ActionBar actionBar = getSupportActionBar(); + if (actionBar != null) { + actionBar.hide(); + } + activityNotifylistBinding = ActivityNotifylistBinding.inflate(getLayoutInflater()); + setContentView(activityNotifylistBinding.getRoot()); + enableEdgeToEdge(getWindow(), activityNotifylistBinding.getRoot(), true, false); + messageInfoItem = (MessageInfo) getIntent().getSerializableExtra("message"); + activityNotifylistBinding.backIv.setOnClickListener(view -> finish()); + manager = new LinearLayoutManager(this); + activityNotifylistBinding.recyclerNofity.setLayoutManager(manager); + activityNotifylistBinding.recyclerNofity.addOnScrollListener(new RecyclerView.OnScrollListener() { + + @Override + public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) { + int visibleCount = manager.getChildCount(); + int totalCount = manager.getItemCount(); + int firstvisibleCount = manager.findFirstVisibleItemPosition(); + if (visibleCount > 0 && visibleCount + firstvisibleCount == totalCount) { //滑动到底部 + if (!isNextPages) { +// Toast.makeText(NotifyListActivity.this, getString(R.string.app_toastloading), Toast.LENGTH_SHORT).show(); + return; + } + page++; + getNotifyList(); + } +// super.onScrolled(recyclerView, dx, dy); + } + }); + adapter = new MyNotifyListAdapter(NotifyListActivity.this, listdata,messageInfoItem); + activityNotifylistBinding.recyclerNofity.setAdapter(adapter); + adapter.setOnItemClick(position -> { + try{ + MessageInfo messageInfo = listdata.get(position); + Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(messageInfo.getJumpUrl())); + startActivity(intent); + }catch (Exception e){ + + } + + }); + getNotifyList(); + } + /** + * 启用Edge-to-Edge模式(核心方法) + * + * @param window Activity的Window对象 + * @param rootView Activity的根布局(用于调整内边距)@param isLightStatusBar 状态栏文字是否为浅色(true=白色,false=黑色) + * * + * @param isLightNavigationBar 导航栏文字是否为浅色(仅Android O+生效) + */ + public void enableEdgeToEdge(Window window, View rootView, + boolean isLightStatusBar, boolean isLightNavigationBar) { + WindowCompat.setDecorFitsSystemWindows(window, true); + + // 3. 直接设置导航栏颜色(兼容所有版本) + window.setNavigationBarColor(Color.TRANSPARENT); + // 4. 可选:设置导航栏文字颜色(保证可读性) + WindowInsetsControllerCompat insetsController = WindowCompat.getInsetsController(window, window.getDecorView()); + insetsController.setAppearanceLightStatusBars(isLightStatusBar); + // true=浅色文字(白色),false=深色文字(黑色),根据导航栏颜色调整 + insetsController.setAppearanceLightNavigationBars(isLightNavigationBar); + window.getDecorView().setBackgroundColor(Color.WHITE); + + + } + + public void getNotifyList() { + //通知列表 + Api.getInstance().getNotifyList(userId, page, 10) + .subscribeOn(Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe(new BaseObserver<>() { + @Override + public void onSuccess(Result> o) { + if (o.data != null) { + isNextPages = o.data.isHasNextPage(); + if (page == 1) { + listdata.clear(); + } + listdata.addAll(o.data.getList()); + adapter.setListdata(listdata); + + } + + } + + @Override + public void onError(int code, String msg) { + LogUtils.i("获取的结果error" + msg); + if (page > 1) { + page--; + } + } + + @Override + public void onError2(Result> o) { + LogUtils.i("获取的结果error"); + if (page > 1) { + page--; + } + } + }); + } +} diff --git a/base/src/main/java/com/webclip/base/PingUtils.java b/base/src/main/java/com/webclip/base/PingUtils.java new file mode 100644 index 0000000..fb9becd --- /dev/null +++ b/base/src/main/java/com/webclip/base/PingUtils.java @@ -0,0 +1,39 @@ +package com.webclip.base; + +import java.io.BufferedReader; +import java.io.InputStreamReader; + +/** + * ********************** + * + * @Author bug machine + * 创建时间: 2026/1/16 15:30 + * 用途 + * ********************** + */ +public class PingUtils { + + /** + * 执行 ping 命令 + * @param address 域名或IP + * @return 返回执行结果 + */ + public static String ping(String address) { + StringBuilder result = new StringBuilder(); + try { + // -c 4 表示执行4次 + Process process = Runtime.getRuntime().exec("ping -c 3 " + address); + BufferedReader reader = new BufferedReader( + new InputStreamReader(process.getInputStream())); + String line; + while ((line = reader.readLine()) != null) { + result.append(line).append("\n"); + } + reader.close(); + process.destroy(); + } catch (Exception e) { + result.append("Ping失败: ").append(e.getMessage()); + } + return result.toString(); + } +} diff --git a/base/src/main/java/com/webclip/base/Result.java b/base/src/main/java/com/webclip/base/Result.java new file mode 100644 index 0000000..bd31919 --- /dev/null +++ b/base/src/main/java/com/webclip/base/Result.java @@ -0,0 +1,29 @@ +package com.webclip.base; + + +import java.io.Serializable; + +/** + * created by wmm on 2020/9/8 + */ +public class Result implements Serializable { + + public String error; + public int code; + public T data; + public String message; + + + public boolean isSuccessful() { + return code == 1; + } + + @Override + public String toString() { + return "Result{" + + "message='" + error + '\'' + + ", code=" + code + + ", data=" + GsonUtils.beanToJSONString(data) + + '}'; + } +} diff --git a/base/src/main/java/com/webclip/base/ResultDataInfo.java b/base/src/main/java/com/webclip/base/ResultDataInfo.java new file mode 100644 index 0000000..6c74730 --- /dev/null +++ b/base/src/main/java/com/webclip/base/ResultDataInfo.java @@ -0,0 +1,45 @@ +package com.webclip.base; + +import java.io.Serializable; +import java.util.List; + +public class ResultDataInfo implements Serializable { + + public List list; + public int pages; + public int total; + public boolean hasNextPage; + + + public boolean isHasNextPage() { + return hasNextPage; + } + + public void setHasNextPage(boolean hasNextPage) { + this.hasNextPage = hasNextPage; + } + + public List getList() { + return list; + } + + public void setList(List list) { + this.list = list; + } + + public int getPages() { + return pages; + } + + public void setPages(int pages) { + this.pages = pages; + } + + public int getTotal() { + return total; + } + + public void setTotal(int total) { + this.total = total; + } +} diff --git a/base/src/main/java/com/webclip/base/StatusLayout.java b/base/src/main/java/com/webclip/base/StatusLayout.java new file mode 100644 index 0000000..603e3c4 --- /dev/null +++ b/base/src/main/java/com/webclip/base/StatusLayout.java @@ -0,0 +1,44 @@ +package com.webclip.base; + +import android.content.Context; +import android.util.AttributeSet; +import android.view.ViewGroup; +import android.widget.LinearLayout; + +import androidx.annotation.Nullable; + +/** + * Created by kiun_2007 on 2018/3/29. + */ + +public class StatusLayout extends LinearLayout { + public StatusLayout(Context context) { + this(context, null); + } + + public StatusLayout(Context context, @Nullable AttributeSet attrs) { + this(context, attrs, 0); + } + + public StatusLayout(Context context, @Nullable AttributeSet attrs, int defStyleAttr) { + super(context, attrs, defStyleAttr); + } + + private int getStatusBarHeight(Context context) { + int result = 0; + int resourceId = context.getResources().getIdentifier("status_bar_height", "dimen", "android"); + if (resourceId > 0) { + result = context.getResources().getDimensionPixelSize(resourceId); + } + return result; + } + + @Override + protected void onAttachedToWindow() { + ViewGroup.LayoutParams lp = this.getLayoutParams(); + lp.width = -1; + lp.height = getStatusBarHeight(getContext()); + this.setLayoutParams(lp); + super.onAttachedToWindow(); + } +} diff --git a/base/src/main/java/com/webclip/base/WebViewActivity.java b/base/src/main/java/com/webclip/base/WebViewActivity.java new file mode 100644 index 0000000..99f3766 --- /dev/null +++ b/base/src/main/java/com/webclip/base/WebViewActivity.java @@ -0,0 +1,379 @@ +package com.webclip.base; + +import android.content.Intent; +import android.graphics.Bitmap; +import android.net.Uri; +import android.os.Build; +import android.os.Bundle; +import android.os.Message; +import android.view.MotionEvent; +import android.view.View; +import android.view.WindowManager; +import android.webkit.ValueCallback; +import android.webkit.WebChromeClient; +import android.webkit.WebResourceError; +import android.webkit.WebResourceRequest; +import android.webkit.WebSettings; +import android.webkit.WebView; +import android.webkit.WebViewClient; +import android.widget.FrameLayout; +import android.widget.ImageView; +import android.widget.LinearLayout; +import android.widget.ProgressBar; +import android.widget.TextView; +import android.widget.Toast; +import androidx.annotation.Nullable; +import androidx.annotation.RequiresApi; +import androidx.appcompat.app.ActionBar; +import androidx.appcompat.app.AppCompatActivity; +import com.king.app.updater.AppUpdater; +import com.webclip.base.databinding.ActivityMain2Binding; + +public class WebViewActivity extends AppCompatActivity { + ActivityMain2Binding activityMain2Binding; + private String url; + + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + getWindow().setNavigationBarColor(getColor(R.color.white)); + getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_FULLSCREEN | View.SYSTEM_UI_FLAG_LAYOUT_STABLE); + + super.onCreate(savedInstanceState); + View decor = getWindow().getDecorView(); + getWindow().setFlags(WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED, WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED); + decor.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR); + ActionBar actionBar = getSupportActionBar(); + if (actionBar != null) { + actionBar.hide(); + } + activityMain2Binding = ActivityMain2Binding.inflate(getLayoutInflater()); + setContentView(activityMain2Binding.getRoot()); + activityMain2Binding.backIv.setOnClickListener(view -> finish()); + url = getIntent().getStringExtra("url"); + initView(); + } + + private ValueCallback mUploadCallbackForHighApi; + + public void initView() { + WebSettings settings = activityMain2Binding.webview.getSettings(); + settings.setDomStorageEnabled(true); +// settings.setAppCacheEnabled(true); + settings.setCacheMode(WebSettings.LOAD_DEFAULT); + settings.setJavaScriptEnabled(true); + settings.setLoadWithOverviewMode(true); + // 设置允许访问文件数据 + settings.setAllowFileAccess(true); + settings.setAllowContentAccess(true); + settings.setDatabaseEnabled(true); + settings.setSavePassword(false); + settings.setSaveFormData(false); + settings.setUseWideViewPort(true); + settings.setBuiltInZoomControls(true); + settings.setPluginState(WebSettings.PluginState.ON); + settings.setLayoutAlgorithm(WebSettings.LayoutAlgorithm.NARROW_COLUMNS); + activityMain2Binding.webview.setFocusable(true); + activityMain2Binding.webview.setFocusableInTouchMode(true); + activityMain2Binding.webview.getSettings().setSupportMultipleWindows(true); + if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { + activityMain2Binding.webview.getSettings().setMixedContentMode(WebSettings.MIXED_CONTENT_ALWAYS_ALLOW); + } + settings.setSupportZoom(false); + activityMain2Binding.webview.setScrollBarStyle(WebView.SCROLLBARS_OUTSIDE_OVERLAY); + activityMain2Binding.webview.setHorizontalScrollBarEnabled(true); + activityMain2Binding.webview.requestFocus(); + settings.setJavaScriptCanOpenWindowsAutomatically(false); + // Android 4.1前默认允许,4.1后默认禁止 + settings.setAllowFileAccessFromFileURLs(true); + // Android 4.1前默认允许,4.1后默认禁止 + settings.setAllowUniversalAccessFromFileURLs(true); + + + + activityMain2Binding.webview.setWebChromeClient(new WebChromeClient() { + @Override + public boolean onCreateWindow(WebView view, boolean isDialog, boolean isUserGesture, Message resultMsg) { + + WebView newWebView = new WebView(WebViewActivity.this); + activityMain2Binding.topVvvv.setVisibility(View.VISIBLE); + activityMain2Binding.webview.addView(newWebView); + WebView.WebViewTransport transport = (WebView.WebViewTransport) resultMsg.obj; + transport.setWebView(newWebView); + resultMsg.sendToTarget(); + + newWebView.setWebViewClient(new WebViewClient() { + @Override + public boolean shouldOverrideUrlLoading(WebView view, String url) { + activityMain2Binding.progressbar.setVisibility(View.GONE); + activityMain2Binding.webview.loadUrl(url); + return true; + } + }); + + return true; + } + + + @Override + public boolean onShowFileChooser(WebView webView, ValueCallback filePathCallback, FileChooserParams fileChooserParams) { + LogUtils.i("数据接口:onShowFileChooser"); + mUploadCallbackForHighApi = filePathCallback; + Intent intent = fileChooserParams.createIntent(); + intent.addCategory(Intent.CATEGORY_OPENABLE); + startActivityForResult(Intent.createChooser(intent, "File chooser"), REQUEST_CODE_FILE_CHOOSER); + return true; + } + + // For 3.0+ + protected void openFileChooser(ValueCallback uploadMsg, String acceptType) { + LogUtils.i("数据接口:openFileChooseracceptType"); + openFilerChooser(uploadMsg); + } + + + private void openFilerChooser(ValueCallback uploadMsg) { + LogUtils.i("数据接口:openFileChooser"); + mUploadCallbackForLowApi = uploadMsg; + startActivityForResult(Intent.createChooser(getFilerChooserIntent(), "File Chooser"), REQUEST_CODE_FILE_CHOOSER); + } + + + + }); + activityMain2Binding.webview.setWebViewClient(new WebViewClient() { + + + @Override + public void onPageFinished(WebView view, String url) { + super.onPageFinished(view, url); + activityMain2Binding.showTopLy.setVisibility(View.GONE); + activityMain2Binding.progressbar.setVisibility(View.GONE); + activityMain2Binding.topVvvv.setVisibility(View.VISIBLE); + + } + + @Override + public void onPageStarted(WebView view, String url, Bitmap favicon) { + super.onPageStarted(view, url, favicon); + activityMain2Binding.progressbar.setVisibility(View.VISIBLE); + activityMain2Binding.topVvvv.setVisibility(View.VISIBLE); + } + + @Override + public void onReceivedError(WebView view, WebResourceRequest request, WebResourceError error) { + super.onReceivedError(view, request, error); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + int errorCode = error.getErrorCode(); + String errorMessage = error.getDescription().toString(); + String currentUrl = request.getUrl().toString(); + LogUtils.d("onReceivedError2 url==" + url + " errorCode ==" + errorCode); + if ((errorCode == -2 || errorCode == -6) && currentUrl.contains(url)) { + onShowErrorView(errorMessage); + } else { + onShowNetView(); + } + } + activityMain2Binding.topVvvv.setVisibility(View.GONE); + } + + @Override + public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) { + super.onReceivedError(view, errorCode, description, failingUrl); + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) { + LogUtils.d("onReceivedError2 url==" + failingUrl + " errorCode ==" + errorCode); + if ((errorCode == -2 || errorCode == -6) && failingUrl.contains(url)) { + onShowErrorView(description); + } else { + onShowNetView(); + } + } + activityMain2Binding.topVvvv.setVisibility(View.GONE); + + } + + + @Override + public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) { + + Uri uri; + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { + uri = request.getUrl(); + } else { + uri = Uri.parse(request.toString()); + } + String url1 = uri.toString(); + if (url1.equals(url + "index") || url1.equals(url + "/index")) { + activityMain2Binding.topVvvv.setVisibility(View.GONE); + } else { + activityMain2Binding.topVvvv.setVisibility(View.VISIBLE); + } + + if (!(url1.startsWith("http") || url1.startsWith("https"))) { + try { + Intent intent = new Intent(); + intent.setAction(Intent.ACTION_VIEW); + intent.setData(Uri.parse(url1)); + startActivity(intent); + return true; + } catch (Exception e) { + e.printStackTrace(); + } + } else { + + if ((url1.equals(url + "index") || url1.equals(url + "/index")) && activityMain2Binding.webview.canGoBack()) { + return false; + } else { + if (url1.contains(".apk")) { //下载 + Toast.makeText(WebViewActivity.this, "下载开始,请稍后...", Toast.LENGTH_SHORT).show(); + new AppUpdater(WebViewActivity.this, url1).start(); + return false; + } + //其它的该怎么处理就怎么处理 + activityMain2Binding.webview.loadUrl(url1); + return true; + } + + } + return false; + } + + + @Override + public boolean shouldOverrideUrlLoading(WebView view, String url1) { + if (url1.equals(url + "index") || url1.equals(url + "/index")) { + activityMain2Binding.topVvvv.setVisibility(View.GONE); + } else { + activityMain2Binding.progressbar.setVisibility(View.VISIBLE); + } + + if (!(url1.startsWith("http") || url1.startsWith("https"))) { + try { + Intent intent = new Intent(); + intent.setAction(Intent.ACTION_VIEW); + intent.setData(Uri.parse(url1)); + startActivity(intent); + return true; + } catch (Exception e) { + e.printStackTrace(); + } + } else { + + if ((url1.equals(url + "index") || url1.equals(url + "/index")) && activityMain2Binding.webview.canGoBack()) { + return false; + } else { + if (url1.contains(".apk")) { //下载 + new AppUpdater(WebViewActivity.this, url1).start(); + return false; + } + //其它的该怎么处理就怎么处理 + activityMain2Binding.webview.loadUrl(url1); + return false; + } + + } + + return false; + } + + + }); + activityMain2Binding.webview.setOnGenericMotionListener(new View.OnGenericMotionListener() { + @Override + public boolean onGenericMotion(View view, MotionEvent motionEvent) { + return false; + } + }); + + if (url != null) { + activityMain2Binding.webview.loadUrl(url); + } + } + + + @RequiresApi(api = Build.VERSION_CODES.Q) + @Override + protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { + super.onActivityResult(requestCode, resultCode, data); + switch (requestCode) { + case REQUEST_CODE_FILE_CHOOSER: + if (resultCode == RESULT_OK || resultCode == RESULT_CANCELED) { + afterFileChooseGoing(resultCode, data); + } + break; + + + } + } + + + /** + * onActivityResult方法 + */ + + private void afterFileChooseGoing(int resultCode, Intent data) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { + if (mUploadCallbackForHighApi == null) { + return; + } + mUploadCallbackForHighApi.onReceiveValue(WebChromeClient.FileChooserParams.parseResult(resultCode, data)); + mUploadCallbackForHighApi = null; + } else { + if (mUploadCallbackForLowApi == null) { + return; + } + Uri result = data == null ? null : data.getData(); + mUploadCallbackForLowApi.onReceiveValue(result); + mUploadCallbackForLowApi = null; + } + } + + private Intent getFilerChooserIntent() { + Intent intent = new Intent(Intent.ACTION_GET_CONTENT); + intent.addCategory(Intent.CATEGORY_OPENABLE); + return intent; + } + + + private static final int REQUEST_CODE_FILE_CHOOSER = 1; + private ValueCallback mUploadCallbackForLowApi; + private boolean isNetError = false; + + public void onShowErrorView(String errorMsg) { //网络不可用的情况 + activityMain2Binding.topVvvv.setVisibility(View.VISIBLE); + activityMain2Binding.webview.setVisibility(View.GONE); + activityMain2Binding.layoutError.setVisibility(View.VISIBLE); + activityMain2Binding.errormsg.setText(errorMsg); + activityMain2Binding.showTopLy.setVisibility(View.GONE); + isNetError = true; + + } + + public void onShowNetView() { + activityMain2Binding.topVvvv.setVisibility(View.VISIBLE); + activityMain2Binding.webview.setVisibility(View.VISIBLE); + activityMain2Binding.layoutError.setVisibility(View.GONE); + activityMain2Binding.showTopLy.setVisibility(View.GONE); + isNetError = false; + } + + + @Override + public void onBackPressed() { + if (activityMain2Binding.webview.canGoBack()) {//当webview有多级能返回的时候 + onShowNetView(); + activityMain2Binding.webview.goBack(); + } else {//不能返回了 + WebViewActivity.this.finish(); + } + } + + @Override + protected void onDestroy() { + if (activityMain2Binding.webview != null) { + //销毁VebView + activityMain2Binding.webview.destroy(); + } + super.onDestroy(); + } +} diff --git a/base/src/main/res/drawable-anydpi/ic_action_back.xml b/base/src/main/res/drawable-anydpi/ic_action_back.xml new file mode 100644 index 0000000..013ab07 --- /dev/null +++ b/base/src/main/res/drawable-anydpi/ic_action_back.xml @@ -0,0 +1,11 @@ + + + diff --git a/base/src/main/res/drawable-hdpi/ic_action_back.png b/base/src/main/res/drawable-hdpi/ic_action_back.png new file mode 100644 index 0000000..1560c04 Binary files /dev/null and b/base/src/main/res/drawable-hdpi/ic_action_back.png differ diff --git a/base/src/main/res/drawable-mdpi/ic_action_back.png b/base/src/main/res/drawable-mdpi/ic_action_back.png new file mode 100644 index 0000000..d5841d2 Binary files /dev/null and b/base/src/main/res/drawable-mdpi/ic_action_back.png differ diff --git a/base/src/main/res/drawable-v24/ic_launcher_foreground.xml b/base/src/main/res/drawable-v24/ic_launcher_foreground.xml new file mode 100644 index 0000000..2b068d1 --- /dev/null +++ b/base/src/main/res/drawable-v24/ic_launcher_foreground.xml @@ -0,0 +1,30 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/base/src/main/res/drawable-xhdpi/ic_action_back.png b/base/src/main/res/drawable-xhdpi/ic_action_back.png new file mode 100644 index 0000000..5c14e41 Binary files /dev/null and b/base/src/main/res/drawable-xhdpi/ic_action_back.png differ diff --git a/base/src/main/res/drawable-xxhdpi/ic_action_back.png b/base/src/main/res/drawable-xxhdpi/ic_action_back.png new file mode 100644 index 0000000..0516d08 Binary files /dev/null and b/base/src/main/res/drawable-xxhdpi/ic_action_back.png differ diff --git a/base/src/main/res/drawable/big_bg.xml b/base/src/main/res/drawable/big_bg.xml new file mode 100644 index 0000000..2e41ced --- /dev/null +++ b/base/src/main/res/drawable/big_bg.xml @@ -0,0 +1,8 @@ + + + + \ No newline at end of file diff --git a/base/src/main/res/drawable/input_bg.xml b/base/src/main/res/drawable/input_bg.xml new file mode 100644 index 0000000..4e895aa --- /dev/null +++ b/base/src/main/res/drawable/input_bg.xml @@ -0,0 +1,20 @@ + + + + + + + + + + + + + + + + + + diff --git a/base/src/main/res/drawable/pass_word_bg1.xml b/base/src/main/res/drawable/pass_word_bg1.xml new file mode 100644 index 0000000..83b8c14 --- /dev/null +++ b/base/src/main/res/drawable/pass_word_bg1.xml @@ -0,0 +1,23 @@ + + + + + + \ No newline at end of file diff --git a/base/src/main/res/drawable/pass_word_bg2.xml b/base/src/main/res/drawable/pass_word_bg2.xml new file mode 100644 index 0000000..916d99c --- /dev/null +++ b/base/src/main/res/drawable/pass_word_bg2.xml @@ -0,0 +1,23 @@ + + + + + + \ No newline at end of file diff --git a/base/src/main/res/drawable/shape_btn_bg.xml b/base/src/main/res/drawable/shape_btn_bg.xml new file mode 100644 index 0000000..af87a0d --- /dev/null +++ b/base/src/main/res/drawable/shape_btn_bg.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/base/src/main/res/drawable/shape_dialog_bg3.xml b/base/src/main/res/drawable/shape_dialog_bg3.xml new file mode 100644 index 0000000..ca0a18d --- /dev/null +++ b/base/src/main/res/drawable/shape_dialog_bg3.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/base/src/main/res/drawable/shape_notify_typebg.xml b/base/src/main/res/drawable/shape_notify_typebg.xml new file mode 100644 index 0000000..a5baad8 --- /dev/null +++ b/base/src/main/res/drawable/shape_notify_typebg.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/base/src/main/res/layout/activity_main2.xml b/base/src/main/res/layout/activity_main2.xml new file mode 100644 index 0000000..a6aa6ad --- /dev/null +++ b/base/src/main/res/layout/activity_main2.xml @@ -0,0 +1,415 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/base/src/main/res/layout/activity_notifylist.xml b/base/src/main/res/layout/activity_notifylist.xml new file mode 100644 index 0000000..73b74e4 --- /dev/null +++ b/base/src/main/res/layout/activity_notifylist.xml @@ -0,0 +1,44 @@ + + + + + + + + + + + + + + + + diff --git a/base/src/main/res/layout/dialog_action_confirm.xml b/base/src/main/res/layout/dialog_action_confirm.xml new file mode 100644 index 0000000..cfe3f0f --- /dev/null +++ b/base/src/main/res/layout/dialog_action_confirm.xml @@ -0,0 +1,71 @@ + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/base/src/main/res/layout/item_notify_list.xml b/base/src/main/res/layout/item_notify_list.xml new file mode 100644 index 0000000..99af181 --- /dev/null +++ b/base/src/main/res/layout/item_notify_list.xml @@ -0,0 +1,175 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/base/src/main/res/mipmap-hdpi/ic_empty.png b/base/src/main/res/mipmap-hdpi/ic_empty.png new file mode 100644 index 0000000..72473d6 Binary files /dev/null and b/base/src/main/res/mipmap-hdpi/ic_empty.png differ diff --git a/base/src/main/res/mipmap-hdpi/ic_pull_down.png b/base/src/main/res/mipmap-hdpi/ic_pull_down.png new file mode 100644 index 0000000..7dc0ec3 Binary files /dev/null and b/base/src/main/res/mipmap-hdpi/ic_pull_down.png differ diff --git a/base/src/main/res/mipmap-xhdpi/ic_close.png b/base/src/main/res/mipmap-xhdpi/ic_close.png new file mode 100644 index 0000000..c0b0127 Binary files /dev/null and b/base/src/main/res/mipmap-xhdpi/ic_close.png differ diff --git a/base/src/main/res/mipmap-xhdpi/ic_email.png b/base/src/main/res/mipmap-xhdpi/ic_email.png new file mode 100644 index 0000000..9fc3a42 Binary files /dev/null and b/base/src/main/res/mipmap-xhdpi/ic_email.png differ diff --git a/base/src/main/res/mipmap-xhdpi/ic_email1.png b/base/src/main/res/mipmap-xhdpi/ic_email1.png new file mode 100644 index 0000000..9fc3a42 Binary files /dev/null and b/base/src/main/res/mipmap-xhdpi/ic_email1.png differ diff --git a/base/src/main/res/mipmap-xhdpi/ic_facebook.png b/base/src/main/res/mipmap-xhdpi/ic_facebook.png new file mode 100644 index 0000000..de378dc Binary files /dev/null and b/base/src/main/res/mipmap-xhdpi/ic_facebook.png differ diff --git a/base/src/main/res/mipmap-xhdpi/ic_hometo.png b/base/src/main/res/mipmap-xhdpi/ic_hometo.png new file mode 100644 index 0000000..4e93043 Binary files /dev/null and b/base/src/main/res/mipmap-xhdpi/ic_hometo.png differ diff --git a/base/src/main/res/mipmap-xhdpi/ic_link.png b/base/src/main/res/mipmap-xhdpi/ic_link.png new file mode 100644 index 0000000..2f98612 Binary files /dev/null and b/base/src/main/res/mipmap-xhdpi/ic_link.png differ diff --git a/base/src/main/res/mipmap-xhdpi/ic_menu.png b/base/src/main/res/mipmap-xhdpi/ic_menu.png new file mode 100644 index 0000000..2b55ec5 Binary files /dev/null and b/base/src/main/res/mipmap-xhdpi/ic_menu.png differ diff --git a/base/src/main/res/mipmap-xhdpi/ic_notify_email.png b/base/src/main/res/mipmap-xhdpi/ic_notify_email.png new file mode 100644 index 0000000..5a2df8e Binary files /dev/null and b/base/src/main/res/mipmap-xhdpi/ic_notify_email.png differ diff --git a/base/src/main/res/mipmap-xhdpi/ic_notify_normal.png b/base/src/main/res/mipmap-xhdpi/ic_notify_normal.png new file mode 100644 index 0000000..f056d32 Binary files /dev/null and b/base/src/main/res/mipmap-xhdpi/ic_notify_normal.png differ diff --git a/base/src/main/res/mipmap-xhdpi/ic_notify_shangla.png b/base/src/main/res/mipmap-xhdpi/ic_notify_shangla.png new file mode 100644 index 0000000..eb1d3e9 Binary files /dev/null and b/base/src/main/res/mipmap-xhdpi/ic_notify_shangla.png differ diff --git a/base/src/main/res/mipmap-xhdpi/ic_notify_xiala.png b/base/src/main/res/mipmap-xhdpi/ic_notify_xiala.png new file mode 100644 index 0000000..7999f63 Binary files /dev/null and b/base/src/main/res/mipmap-xhdpi/ic_notify_xiala.png differ diff --git a/base/src/main/res/mipmap-xhdpi/ic_notifylogo.png b/base/src/main/res/mipmap-xhdpi/ic_notifylogo.png new file mode 100644 index 0000000..b975e45 Binary files /dev/null and b/base/src/main/res/mipmap-xhdpi/ic_notifylogo.png differ diff --git a/base/src/main/res/mipmap-xhdpi/ic_notifylogo_img.png b/base/src/main/res/mipmap-xhdpi/ic_notifylogo_img.png new file mode 100644 index 0000000..e78b250 Binary files /dev/null and b/base/src/main/res/mipmap-xhdpi/ic_notifylogo_img.png differ diff --git a/base/src/main/res/mipmap-xhdpi/ic_notifylogo_link.png b/base/src/main/res/mipmap-xhdpi/ic_notifylogo_link.png new file mode 100644 index 0000000..3d09922 Binary files /dev/null and b/base/src/main/res/mipmap-xhdpi/ic_notifylogo_link.png differ diff --git a/base/src/main/res/mipmap-xhdpi/ic_shousuo.png b/base/src/main/res/mipmap-xhdpi/ic_shousuo.png new file mode 100644 index 0000000..16b38be Binary files /dev/null and b/base/src/main/res/mipmap-xhdpi/ic_shousuo.png differ diff --git a/base/src/main/res/mipmap-xhdpi/ic_tel.png b/base/src/main/res/mipmap-xhdpi/ic_tel.png new file mode 100644 index 0000000..df82270 Binary files /dev/null and b/base/src/main/res/mipmap-xhdpi/ic_tel.png differ diff --git a/base/src/main/res/mipmap-xhdpi/ic_whatsapp.png b/base/src/main/res/mipmap-xhdpi/ic_whatsapp.png new file mode 100644 index 0000000..7ca41ed Binary files /dev/null and b/base/src/main/res/mipmap-xhdpi/ic_whatsapp.png differ diff --git a/base/src/main/res/mipmap-xhdpi/ic_zhangkai.png b/base/src/main/res/mipmap-xhdpi/ic_zhangkai.png new file mode 100644 index 0000000..bdc84b3 Binary files /dev/null and b/base/src/main/res/mipmap-xhdpi/ic_zhangkai.png differ diff --git a/base/src/main/res/mipmap-xxhdpi/app_logo.png b/base/src/main/res/mipmap-xxhdpi/app_logo.png new file mode 100644 index 0000000..9cca57b Binary files /dev/null and b/base/src/main/res/mipmap-xxhdpi/app_logo.png differ diff --git a/base/src/main/res/mipmap-xxhdpi/look_img.png b/base/src/main/res/mipmap-xxhdpi/look_img.png new file mode 100644 index 0000000..bb76ba1 Binary files /dev/null and b/base/src/main/res/mipmap-xxhdpi/look_img.png differ diff --git a/base/src/main/res/mipmap-xxhdpi/share_img.png b/base/src/main/res/mipmap-xxhdpi/share_img.png new file mode 100644 index 0000000..203b4b7 Binary files /dev/null and b/base/src/main/res/mipmap-xxhdpi/share_img.png differ diff --git a/base/src/main/res/values-en/strings.xml b/base/src/main/res/values-en/strings.xml new file mode 100644 index 0000000..829e9ce --- /dev/null +++ b/base/src/main/res/values-en/strings.xml @@ -0,0 +1,59 @@ + + Please Set Your Password + Cancel + Sure + New Version Update + Next Update + Update Immediately + Click to close notification + Click to re-download + Download failed + Click to install + Download completed + Downloading... + Version update + Downloading game + Getting download data... + Version update + Downloading game + Need to turn on mobile phone notification permission + Exit + Setting + Tip + Please enter the invitation code + My invitation code: + Superior invitation code: + Total number of invites: + App download link: + Share + Check Invitation Records + Invitation Records + Total number of invitees: %d + No Data + Withdrawal Record + Withdrawal Application + Edit Bank Card Information + 60 + Name: + Please enter the bank card name + Bank card account: + Please enter the bank card account + Country: + Please select a country + Bank Name: + Please select a bank name + Note: Please enter the country code before selecting the bank name! + Balance: %s + Total Earnings: %s + Amount: %s + Please enter the withdrawal amount + Withdrawal application has been submitted + No additional data available for now + NOTIFICATIONS + Loading… + Text + Image + Jump link + + + \ No newline at end of file diff --git a/base/src/main/res/values/colors.xml b/base/src/main/res/values/colors.xml new file mode 100644 index 0000000..ada1b30 --- /dev/null +++ b/base/src/main/res/values/colors.xml @@ -0,0 +1,26 @@ + + + #FFFFFF + #FFFFFF + #FFFFFF + #FF03DAC5 + #FF018786 + #FF000000 + #FFFFFFFF + #EF4723 + #FFFFFFFF + + #2C2C2E + #FFA722 + #434343 + #BCBCBC + + #ACDFEE + #BDDDB7 + #C3B5D0 + #000000 + #000000 + + + + \ No newline at end of file diff --git a/base/src/main/res/values/strings.xml b/base/src/main/res/values/strings.xml new file mode 100644 index 0000000..17a082d --- /dev/null +++ b/base/src/main/res/values/strings.xml @@ -0,0 +1,60 @@ + + 请输入6位密码 + 取消 + 确定 + 版本更新 + 下次更新 + 立即更新 + 点击关闭通知 + 点击重新下载 + 下载失败 + 点击安装 + 下载完成 + 正在下载… + 版本更新 + 下载游戏中 + 版本更新 + 下载游戏中 + 正在获取下载数据… + 需要打开手机通知权限 + 退出 + 设置 + 提示 + 请输入邀请码 + 我的邀请码: + 上级邀请码: + 总邀请人数: + 邀请您下载: + 分享 + 查看邀请记录 + 邀请记录 + 总邀请人数: %d + 暂无数据 + 提现记录 + 提现申请 + 编辑银行卡信息 + 86 + 持卡人姓名: + 请输入持卡人姓名 + 国家地区: + 请选择国家地区 + 开户行名称: + 请选择开户行名称 + 银行户口: + 请输入银行卡户口 + (注:请先输入国家区号再选择开户行名称!) + 余额: %s + 总收益: %s + 金额: %s + 请输入提现金额 + 提现申请已提交 + 暂无更多数据 + 通知 + Loading… + 文本 + 图片 + 链接 + + + + \ No newline at end of file diff --git a/base/src/main/res/values/themes.xml b/base/src/main/res/values/themes.xml new file mode 100644 index 0000000..e47899f --- /dev/null +++ b/base/src/main/res/values/themes.xml @@ -0,0 +1,88 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/base/src/main/res/xml/app_updater_paths.xml b/base/src/main/res/xml/app_updater_paths.xml new file mode 100644 index 0000000..1254450 --- /dev/null +++ b/base/src/main/res/xml/app_updater_paths.xml @@ -0,0 +1,10 @@ + + + + + + + + + + \ No newline at end of file diff --git a/base/src/main/res/xml/network_security_config.xml b/base/src/main/res/xml/network_security_config.xml new file mode 100644 index 0000000..dca93c0 --- /dev/null +++ b/base/src/main/res/xml/network_security_config.xml @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/base/src/main/res/xml/provider_paths.xml b/base/src/main/res/xml/provider_paths.xml new file mode 100644 index 0000000..c9a897a --- /dev/null +++ b/base/src/main/res/xml/provider_paths.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/base_noupdata/.gitignore b/base_noupdata/.gitignore new file mode 100644 index 0000000..42afabf --- /dev/null +++ b/base_noupdata/.gitignore @@ -0,0 +1 @@ +/build \ No newline at end of file diff --git a/base_noupdata/build.gradle b/base_noupdata/build.gradle new file mode 100644 index 0000000..4ea27dc --- /dev/null +++ b/base_noupdata/build.gradle @@ -0,0 +1,49 @@ +plugins { + id 'com.android.library' +} + +android { + namespace "com.webclip.base" + compileSdk 36 + defaultConfig { + minSdkVersion 24 + targetSdk 36 + testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" + } + + compileOptions { + sourceCompatibility JavaVersion.VERSION_17 + targetCompatibility JavaVersion.VERSION_17 + } + + buildFeatures { + viewBinding true + } +} + +dependencies { + + api 'androidx.appcompat:appcompat:1.1.0' + api 'com.google.android.material:material:1.1.0' + api 'androidx.constraintlayout:constraintlayout:1.1.3' + + // okhttp相关库 + api 'com.squareup.okhttp3:okhttp:4.9.3' + + // JSON解析库 + api 'com.google.code.gson:gson:2.9.0' + api 'com.squareup.retrofit2:retrofit:2.5.0' + api 'com.squareup.retrofit2:converter-scalars:2.3.0' + api 'com.squareup.retrofit2:converter-gson:2.4.0' + api 'com.squareup.retrofit2:adapter-rxjava2:2.4.0' + api 'io.reactivex.rxjava2:rxjava:2.1.16' + api 'io.reactivex.rxjava2:rxandroid:2.0.2' + api 'com.squareup.okhttp3:logging-interceptor:3.10.0' + + api("com.github.bumptech.glide:glide:4.13.1") + // sdk 33 + api platform('com.google.firebase:firebase-bom:32.7.0') + // Firebase Cloud Messaging + api("com.google.firebase:firebase-messaging") + api libs.play.services.base +} \ No newline at end of file diff --git a/base_noupdata/proguard-rules.pro b/base_noupdata/proguard-rules.pro new file mode 100644 index 0000000..107b7ee --- /dev/null +++ b/base_noupdata/proguard-rules.pro @@ -0,0 +1,32 @@ +# 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 + +-dontwarn dalvik.** +-dontwarn com.tencent.smtt.** + +-keep class com.tencent.smtt.** { + *; +} + +-keep class com.tencent.tbs.** { + *; +} \ No newline at end of file diff --git a/base_noupdata/src/main/AndroidManifest.xml b/base_noupdata/src/main/AndroidManifest.xml new file mode 100644 index 0000000..7cd7cbb --- /dev/null +++ b/base_noupdata/src/main/AndroidManifest.xml @@ -0,0 +1,20 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/base_noupdata/src/main/java/com/webclip/base/ActionConfirmDialog.java b/base_noupdata/src/main/java/com/webclip/base/ActionConfirmDialog.java new file mode 100644 index 0000000..86599dd --- /dev/null +++ b/base_noupdata/src/main/java/com/webclip/base/ActionConfirmDialog.java @@ -0,0 +1,112 @@ +package com.webclip.base; + +import android.app.Dialog; +import android.content.Context; +import android.os.Bundle; +import android.text.TextUtils; +import android.view.Gravity; +import android.view.View; +import android.view.ViewTreeObserver; +import android.view.Window; +import android.view.WindowManager; +import android.widget.TextView; + +import com.webclip.base.databinding.DialogActionConfirmBinding; + + +/** + * 通用弹窗 + */ +public class ActionConfirmDialog extends Dialog { + DialogActionConfirmBinding dialogActionConfirmBinding; + + String content; + String cancel = null; + String sure = null; + boolean showCancel = true; + OnToActionListener onToActionListener; + + public interface OnToActionListener { + void toSumbit(); + void toCancel(); + + } + + public void setOnToActionListener(OnToActionListener onNextCallListener) { + this.onToActionListener = onNextCallListener; + } + + + public ActionConfirmDialog(Context context, String content,boolean showCancel) { + super(context, R.style.MaterialDesignDialog); + this.content = content; + this.showCancel = showCancel; + } + public ActionConfirmDialog(Context context, String content, String cancel, String sure) { + super(context, R.style.MaterialDesignDialog); + this.content = content; + this.cancel = cancel; + this.sure = sure; + } + + public ActionConfirmDialog(Context context, String content, String cancel, String sure,boolean showCancel) { + super(context, R.style.MaterialDesignDialog); + this.content = content; + this.cancel = cancel; + this.sure = sure; + this.showCancel = showCancel; + } + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + dialogActionConfirmBinding = DialogActionConfirmBinding.inflate(getLayoutInflater()); + setContentView(dialogActionConfirmBinding.getRoot()); + dialogActionConfirmBinding.contentTv.setText(content); + dialogActionConfirmBinding.contentTv.getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() { + @Override + public boolean onPreDraw() { + //这个监听的回调是异步的,在监听完以后一定要把绘制监听移除,不然这个会一直回调,导致界面错乱 + dialogActionConfirmBinding.contentTv.getViewTreeObserver().removeOnPreDrawListener(this); + int line = dialogActionConfirmBinding.contentTv.getLineCount(); + if(line>1){ + dialogActionConfirmBinding.contentTv.setGravity(Gravity.LEFT|Gravity.CENTER_VERTICAL); + } + + return true; + } + }); + if(!TextUtils.isEmpty(cancel)){ + dialogActionConfirmBinding.cancelTv.setText(cancel); + } + if(!TextUtils.isEmpty(sure)){ + dialogActionConfirmBinding.sumbitTv.setText(sure); + } + if(!showCancel){ + dialogActionConfirmBinding.cancelTv.setVisibility(View.GONE); + dialogActionConfirmBinding.lineV.setVisibility(View.GONE); + } + + dialogActionConfirmBinding.sumbitTv.setOnClickListener(v -> { + dismiss(); + if(onToActionListener!=null){ + onToActionListener.toSumbit(); + } + }); + dialogActionConfirmBinding.cancelTv.setOnClickListener(v -> { + dismiss(); + if(onToActionListener!=null){ + onToActionListener.toCancel(); + } + }); + + Window window = getWindow(); + WindowManager.LayoutParams wlp = window.getAttributes(); + wlp.gravity = Gravity.CENTER; + wlp.width = WindowManager.LayoutParams.WRAP_CONTENT; + wlp.height = WindowManager.LayoutParams.WRAP_CONTENT; + + window.setAttributes(wlp); + } + +} diff --git a/base_noupdata/src/main/java/com/webclip/base/Api.java b/base_noupdata/src/main/java/com/webclip/base/Api.java new file mode 100644 index 0000000..c4e9672 --- /dev/null +++ b/base_noupdata/src/main/java/com/webclip/base/Api.java @@ -0,0 +1,69 @@ +package com.webclip.base; + +import java.net.Proxy; +import java.util.concurrent.TimeUnit; + +import okhttp3.OkHttpClient; +import okhttp3.logging.HttpLoggingInterceptor; + +/** + * 项目名: TODO-MVVM + * 包名 com.azhon.mvvm.api + * 文件名: Api + * 创建时间: 2019-03-27 on 14:56 + * 描述: TODO 使用Retrofit基础服务 + * + * @author + */ + +public class Api extends BaseApi { + + private static final long CONNECT_TIMEOUT = 10; + private static final long READ_TIMEOUT = 10; + private static final long WRITE_TIMEOUT = 10; + + /** + * 静态内部类单例 + */ + private static class ApiHolder { + private static Api api = new Api(); + private final static ApiService apiService = api.initRetrofit(ApiService.URL) + .create(ApiService.class); + + } + + public static ApiService getInstance() { + return ApiHolder.apiService; + } + + /** + * 做自己需要的操作 + */ + @Override + protected OkHttpClient setClient() { + OkHttpClient.Builder builder; + builder = new OkHttpClient() + .newBuilder(); + //禁止使用代理抓取数据 + builder.proxy(Proxy.NO_PROXY); + //设置超时 + builder.connectTimeout(CONNECT_TIMEOUT, TimeUnit.SECONDS); + builder.readTimeout(READ_TIMEOUT, TimeUnit.SECONDS); + builder.writeTimeout(WRITE_TIMEOUT, TimeUnit.SECONDS); + //错误重连 + builder.retryOnConnectionFailure(true); + + if (LogUtils.isDebug) { + HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor(message -> { + String text = message; + LogUtils.i("OKHttp111111-----", text); + + }); + interceptor.setLevel(HttpLoggingInterceptor.Level.BODY); + builder.addInterceptor(interceptor); + } + return builder.build(); + + } + +} diff --git a/base_noupdata/src/main/java/com/webclip/base/ApiService.java b/base_noupdata/src/main/java/com/webclip/base/ApiService.java new file mode 100644 index 0000000..993c21c --- /dev/null +++ b/base_noupdata/src/main/java/com/webclip/base/ApiService.java @@ -0,0 +1,59 @@ +package com.webclip.base; + + +import java.util.List; +import java.util.Map; + +import io.reactivex.Observable; +import okhttp3.RequestBody; +import okhttp3.ResponseBody; +import retrofit2.Call; +import retrofit2.Callback; +import retrofit2.http.Body; +import retrofit2.http.GET; +import retrofit2.http.Headers; +import retrofit2.http.POST; +import retrofit2.http.PUT; +import retrofit2.http.Path; +import retrofit2.http.Query; +import retrofit2.http.Url; + +public interface ApiService { + String URL = "https://api.liulao.top/"; + + + @GET("api/system/applicationConf") + Observable> geUrlNew(@Query("userId") int userId); + + + /** + * 統計下載量 + */ + @PUT("api/statistics/downloads") + Observable downloadNumbers(@Body Map map); + + /** + * 每日活跃统计 + */ + @PUT("api/statistics/use") + Observable totalTongJi(@Body Map map); + + /** + * 统计通知 + */ + @POST("api/push/statistics") + Observable totalNotify(@Body Map map); + + + /** + * 获取通知列表 + * @param userid + * @param page + * @param size + * @return + */ + @GET("api/push/pushRecords") + Observable>> getNotifyList(@Query("userId") int userid, @Query("page") int page, @Query("size") int size); + + +} diff --git a/base_noupdata/src/main/java/com/webclip/base/BaseApi.java b/base_noupdata/src/main/java/com/webclip/base/BaseApi.java new file mode 100644 index 0000000..6e89376 --- /dev/null +++ b/base_noupdata/src/main/java/com/webclip/base/BaseApi.java @@ -0,0 +1,46 @@ +package com.webclip.base; + +import okhttp3.OkHttpClient; +import retrofit2.Retrofit; +import retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory; +import retrofit2.converter.gson.GsonConverterFactory; +import retrofit2.converter.scalars.ScalarsConverterFactory; + +/** + * 项目名: TODO-MVVM + * 包名 com.azhon.basic.retrofit + * 文件名: BaseApi + * 创建时间: 2019-03-27 on 14:52 + * 描述: TODO 封装基础的Retrofit + * + * @author + */ + +public abstract class BaseApi { + + /** + * 初始化Retrofit + */ + public Retrofit initRetrofit(String baseUrl) { + Retrofit.Builder builder = new Retrofit.Builder(); + //支持返回Call + builder.addConverterFactory(ScalarsConverterFactory.create()); + //支持直接格式化json返回Bean对象 + builder.addConverterFactory(GsonConverterFactory.create()); + //支持RxJava + builder.addCallAdapterFactory(RxJava2CallAdapterFactory.create()); + builder.baseUrl(baseUrl); + OkHttpClient client = setClient(); + if (client != null) { + builder.client(client); + } + return builder.build(); + } + + /** + * 设置OkHttpClient,添加拦截器等 + * + * @return 可以返回为null + */ + protected abstract OkHttpClient setClient(); +} diff --git a/base_noupdata/src/main/java/com/webclip/base/BaseObserver.java b/base_noupdata/src/main/java/com/webclip/base/BaseObserver.java new file mode 100644 index 0000000..7030489 --- /dev/null +++ b/base_noupdata/src/main/java/com/webclip/base/BaseObserver.java @@ -0,0 +1,113 @@ +package com.webclip.base; + +import com.google.gson.JsonParseException; + +import org.json.JSONException; + +import java.io.InterruptedIOException; +import java.net.ConnectException; +import java.net.UnknownHostException; +import java.text.ParseException; + +import io.reactivex.observers.DisposableObserver; +import retrofit2.HttpException; + +public abstract class BaseObserver extends DisposableObserver { + /** + * 解析数据失败 + */ + public static final int PARSE_ERROR = 1001; + /** + * 网络问题 + */ + public static final int BAD_NETWORK = 1002; + /** + * 连接错误 + */ + public static final int CONNECT_ERROR = 1003; + /** + * 连接超时 + */ + public static final int CONNECT_TIMEOUT = 1004; + + @Override + public void onNext(T o) { + if (o instanceof String) { + onError(0, "接口解析失败"); +// LogUtils.i("返回个string就没意思了"); + } else { + Result model = (Result) o; + if (model.isSuccessful()) { + onSuccess(o); + } else { + onError2(o); + } + } + + + } + + @Override + public void onError(Throwable e) { + if (e instanceof HttpException) { + // HTTP错误 + onException(BAD_NETWORK); + } else if (e instanceof ConnectException + || e instanceof UnknownHostException) { + // 连接错误 + onException(CONNECT_ERROR); + } else if (e instanceof InterruptedIOException) { + // 连接超时 + onException(CONNECT_TIMEOUT); + } else if (e instanceof JsonParseException + || e instanceof JSONException + || e instanceof ParseException) { + // 解析错误 + + onException(PARSE_ERROR); + } else { + if (e != null) { + onError(409, e.toString()); + } else { + onError(407, "未知错误"); + } + } + + } + + private void onException(int unknownError) { + switch (unknownError) { + case CONNECT_ERROR: + onError(CONNECT_ERROR, "连接错误"); + break; + + case CONNECT_TIMEOUT: + onError(CONNECT_TIMEOUT, "连接超时"); + break; + + case BAD_NETWORK: + onError(BAD_NETWORK, "网络问题"); + break; + + case PARSE_ERROR: + onError(PARSE_ERROR, "宇宙也是有尽头的"); + + break; + + default: + break; + } + } + + @Override + public void onComplete() { + + } + + public abstract void onSuccess(T o); + + public abstract void onError(int code, String msg); + + public abstract void onError2(T o); + +} diff --git a/base_noupdata/src/main/java/com/webclip/base/CircleImageView.java b/base_noupdata/src/main/java/com/webclip/base/CircleImageView.java new file mode 100644 index 0000000..b0d11f1 --- /dev/null +++ b/base_noupdata/src/main/java/com/webclip/base/CircleImageView.java @@ -0,0 +1,320 @@ +package com.webclip.base; + +import android.annotation.SuppressLint; +import android.content.Context; +import android.content.res.TypedArray; +import android.graphics.Bitmap; +import android.graphics.Canvas; +import android.graphics.Matrix; +import android.graphics.Paint; +import android.graphics.PorterDuff; +import android.graphics.PorterDuffXfermode; +import android.graphics.RectF; +import android.graphics.drawable.BitmapDrawable; +import android.graphics.drawable.Drawable; +import android.util.AttributeSet; +import android.view.MotionEvent; + +import androidx.appcompat.widget.AppCompatImageView; + + +public class CircleImageView extends AppCompatImageView { + // paint when user press + private Paint pressPaint; + private int width; + private int height; + + // default bitmap config + private static final Bitmap.Config BITMAP_CONFIG = Bitmap.Config.ARGB_8888; + + // border color + private int borderColor; + // width of border + private int borderWidth; + // alpha when pressed + private int pressAlpha; + // color when pressed + private int pressColor; + // radius + private int radius; + // rectangle or round, 1 is circle, 2 is rectangle + private int shapeType; + + public CircleImageView(Context context) { + super(context); + init(context, null); + } + + public CircleImageView(Context context, AttributeSet attrs) { + super(context, attrs); + init(context, attrs); + } + + public CircleImageView(Context context, AttributeSet attrs, int defStyleAttr) { + super(context, attrs, defStyleAttr); + init(context, attrs); + } + + + private void init(Context context, AttributeSet attrs) { + //init the value + borderWidth = 0; + borderColor = 0xddffffff; + pressAlpha = 0x42; + pressColor = 0x42000000; + radius = 16; + shapeType = 0; + + // get attribute of EaseImageView + if (attrs != null) { + TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.CircleImageView); + borderColor = array.getColor(R.styleable.CircleImageView_ease_border_color, borderColor); + borderWidth = array.getDimensionPixelOffset(R.styleable.CircleImageView_ease_border_width, borderWidth); + pressAlpha = array.getInteger(R.styleable.CircleImageView_ease_press_alpha, pressAlpha); + pressColor = array.getColor(R.styleable.CircleImageView_ease_press_color, pressColor); + radius = array.getDimensionPixelOffset(R.styleable.CircleImageView_ease_radius, radius); + shapeType = array.getInteger(R.styleable.CircleImageView_es_shape_type, shapeType); + array.recycle(); + } + + // set paint when pressed + pressPaint = new Paint(); + pressPaint.setAntiAlias(true); + pressPaint.setStyle(Paint.Style.FILL); + pressPaint.setColor(pressColor); + pressPaint.setAlpha(0); + pressPaint.setFlags(Paint.ANTI_ALIAS_FLAG); + + setDrawingCacheEnabled(true); + setWillNotDraw(false); + } + + @Override + protected void onDraw(Canvas canvas) { + + if (shapeType == 0) { + super.onDraw(canvas); + return; + } + Drawable drawable = getDrawable(); + if (drawable == null) { + return; + } + // the width and height is in xml file + if (getWidth() == 0 || getHeight() == 0) { + return; + } + Bitmap bitmap = getBitmapFromDrawable(drawable); + drawDrawable(canvas, bitmap); + + if (isClickable()) { + drawPress(canvas); + } + drawBorder(canvas); + } + + /** + * draw Rounded Rectangle + * + * @param canvas + * @param bitmap + */ + @SuppressLint("WrongConstant") + private void drawDrawable(Canvas canvas, Bitmap bitmap) { + Paint paint = new Paint(); + paint.setColor(0xffffffff); + paint.setAntiAlias(true); //smooths out the edges of what is being drawn + PorterDuffXfermode xfermode = new PorterDuffXfermode(PorterDuff.Mode.SRC_IN); + // set flags + int saveFlags = Canvas.ALL_SAVE_FLAG + ; + canvas.saveLayer(0, 0, width, height, null, saveFlags); + + if (shapeType == 1) { + canvas.drawCircle(width / 2, height / 2, width / 2 - 1, paint); + } else if (shapeType == 2) { + RectF rectf = new RectF(1, 1, getWidth() - 1, getHeight() - 1); + canvas.drawRoundRect(rectf, radius + 1, radius + 1, paint); + } + + paint.setXfermode(xfermode); + + float scaleWidth = ((float) getWidth()) / bitmap.getWidth(); + float scaleHeight = ((float) getHeight()) / bitmap.getHeight(); + + Matrix matrix = new Matrix(); + matrix.postScale(scaleWidth, scaleHeight); + + //bitmap scale + bitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true); + + canvas.drawBitmap(bitmap, 0, 0, paint); + canvas.restore(); + } + + /** + * draw the effect when pressed + * + * @param canvas + */ + private void drawPress(Canvas canvas) { + // check is rectangle or circle + if (shapeType == 1) { + canvas.drawCircle(width / 2, height / 2, width / 2 - 1, pressPaint); + } else if (shapeType == 2) { + RectF rectF = new RectF(1, 1, width - 1, height - 1); + canvas.drawRoundRect(rectF, radius + 1, radius + 1, pressPaint); + } + } + + /** + * draw customized border + * + * @param canvas + */ + private void drawBorder(Canvas canvas) { + if (borderWidth > 0) { + Paint paint = new Paint(); + paint.setStrokeWidth(borderWidth); + paint.setStyle(Paint.Style.STROKE); + paint.setColor(borderColor); + paint.setAntiAlias(true); + // // check is rectangle or circle + if (shapeType == 1) { + canvas.drawCircle(width / 2, height / 2, (width - borderWidth) / 2, paint); + } else if (shapeType == 2) { + RectF rectf = new RectF(borderWidth / 2, borderWidth / 2, getWidth() - borderWidth / 2, + getHeight() - borderWidth / 2); + canvas.drawRoundRect(rectf, radius, radius, paint); + } + } + } + + /** + * monitor the size change + * + * @param w + * @param h + * @param oldw + * @param oldh + */ + @Override + protected void onSizeChanged(int w, int h, int oldw, int oldh) { + super.onSizeChanged(w, h, oldw, oldh); + width = w; + height = h; + } + + /** + * monitor if touched + * + * @param event + * @return + */ + @Override + public boolean onTouchEvent(MotionEvent event) { + switch (event.getAction()) { + case MotionEvent.ACTION_DOWN: + pressPaint.setAlpha(pressAlpha); + invalidate(); + break; + case MotionEvent.ACTION_UP: + pressPaint.setAlpha(0); + invalidate(); + break; + case MotionEvent.ACTION_MOVE: + + break; + default: + pressPaint.setAlpha(0); + invalidate(); + break; + } + return super.onTouchEvent(event); + } + + /** + * @param drawable + * @return + */ + private Bitmap getBitmapFromDrawable(Drawable drawable) { + if (drawable == null) { + return null; + } + + if (drawable instanceof BitmapDrawable) { + return ((BitmapDrawable) drawable).getBitmap(); + } + + Bitmap bitmap; + int width = Math.max(drawable.getIntrinsicWidth(), 2); + int height = Math.max(drawable.getIntrinsicHeight(), 2); + try { + bitmap = Bitmap.createBitmap(width, height, BITMAP_CONFIG); + Canvas canvas = new Canvas(bitmap); + drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight()); + drawable.draw(canvas); + } catch (IllegalArgumentException e) { + e.printStackTrace(); + bitmap = null; + } + return bitmap; + } + + /** + * set border color + * + * @param borderColor + */ + public void setBorderColor(int borderColor) { + this.borderColor = borderColor; + invalidate(); + } + + /** + * set border width + * + * @param borderWidth + */ + public void setBorderWidth(int borderWidth) { + this.borderWidth = borderWidth; + } + + /** + * set alpha when pressed + * + * @param pressAlpha + */ + public void setPressAlpha(int pressAlpha) { + this.pressAlpha = pressAlpha; + } + + /** + * set color when pressed + * + * @param pressColor + */ + public void setPressColor(int pressColor) { + this.pressColor = pressColor; + } + + /** + * set radius + * + * @param radius + */ + public void setRadius(int radius) { + this.radius = radius; + invalidate(); + } + + /** + * set shape,1 is circle, 2 is rectangle + * + * @param shapeType + */ + public void setShapeType(int shapeType) { + this.shapeType = shapeType; + invalidate(); + } +} diff --git a/base_noupdata/src/main/java/com/webclip/base/ContactBean.java b/base_noupdata/src/main/java/com/webclip/base/ContactBean.java new file mode 100644 index 0000000..7fa5728 --- /dev/null +++ b/base_noupdata/src/main/java/com/webclip/base/ContactBean.java @@ -0,0 +1,29 @@ +package com.webclip.base; + +public class ContactBean { + + public String name; + public String phone; + + + public ContactBean(String name, String phone) { + this.name = name; + this.phone = phone; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getPhone() { + return phone; + } + + public void setPhone(String phone) { + this.phone = phone; + } +} diff --git a/base_noupdata/src/main/java/com/webclip/base/DataInfo.java b/base_noupdata/src/main/java/com/webclip/base/DataInfo.java new file mode 100644 index 0000000..0a1efea --- /dev/null +++ b/base_noupdata/src/main/java/com/webclip/base/DataInfo.java @@ -0,0 +1,133 @@ +package com.webclip.base; + +import java.io.Serializable; + +public class DataInfo implements Serializable { + + public String apkUrl; + public String description; + public int forceUpdate; + public String url; + public String downloadUrl; + public String versionCode; + public int isUse = 1; //是否正常使用 0不可用 1正常使用 + public int noticeApplyMode = 1; //通知权限加载方式 0不用1必须 + public int contactApplyMode = 1; //通讯录权限加载方式 0不用1必须 + public String fbUrl; // facebook分享地址 + public String tgUrl; // tg分享地址 + public String wsUrl; //whatsapp分享地址 + public String linkConfig; + public String backupDomains; + + public String getBackupDomains() { + return backupDomains; + } + + public void setBackupDomains(String backupDomains) { + this.backupDomains = backupDomains; + } + + public String getLinkConfig() { + return linkConfig; + } + + public void setLinkConfig(String linkConfig) { + this.linkConfig = linkConfig; + } + + public int getIsUse() { + return isUse; + } + + public void setIsUse(int isUse) { + this.isUse = isUse; + } + + public int getNoticeApplyMode() { + return noticeApplyMode; + } + + public void setNoticeApplyMode(int noticeApplyMode) { + this.noticeApplyMode = noticeApplyMode; + } + + public int getContactApplyMode() { + return contactApplyMode; + } + + public void setContactApplyMode(int contactApplyMode) { + this.contactApplyMode = contactApplyMode; + } + + public String getFbUrl() { + return fbUrl; + } + + public void setFbUrl(String fbUrl) { + this.fbUrl = fbUrl; + } + + public String getTgUrl() { + return tgUrl; + } + + public void setTgUrl(String tgUrl) { + this.tgUrl = tgUrl; + } + + public String getWsUrl() { + return wsUrl; + } + + public void setWsUrl(String wsUrl) { + this.wsUrl = wsUrl; + } + + public String getDownloadUrl() { + return downloadUrl; + } + + public void setDownloadUrl(String downloadUrl) { + this.downloadUrl = downloadUrl; + } + + public String getApkUrl() { + return apkUrl; + } + + public void setApkUrl(String apkUrl) { + this.apkUrl = apkUrl; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + public int getForceUpdate() { + return forceUpdate; + } + + public void setForceUpdate(int forceUpdate) { + this.forceUpdate = forceUpdate; + } + + public String getUrl() { + return url; + } + + public void setUrl(String url) { + this.url = url; + } + + public String getVersionCode() { + return versionCode; + } + + public void setVersionCode(String versionCode) { + this.versionCode = versionCode; + } +} diff --git a/base_noupdata/src/main/java/com/webclip/base/FcmCheckUtil.java b/base_noupdata/src/main/java/com/webclip/base/FcmCheckUtil.java new file mode 100644 index 0000000..77906f4 --- /dev/null +++ b/base_noupdata/src/main/java/com/webclip/base/FcmCheckUtil.java @@ -0,0 +1,85 @@ +package com.webclip.base; + +/** + * ********************** + * + * @Author bug machine + * 创建时间: 2026/3/11 14:10 + * 用途 + * ********************** + */ +import android.content.Context; +import com.google.android.gms.common.ConnectionResult; +import com.google.android.gms.common.GoogleApiAvailability; + +public class FcmCheckUtil { + // FCM要求的最低Google Play服务版本 + private static final int MIN_GOOGLE_PLAY_SERVICES_VERSION = 19000000; + + /** + * 检查设备是否支持FCM + * @param context 上下文 + * @return true=支持,false=不支持 + */ + public static boolean isFcmSupported(Context context) { + GoogleApiAvailability googleApi = GoogleApiAvailability.getInstance(); + // 检查Google Play服务是否可用 + int resultCode = googleApi.isGooglePlayServicesAvailable(context); + + // 只有当服务完全可用且版本达标时,才判定支持FCM + return resultCode == ConnectionResult.SUCCESS + && googleApi.getApkVersion(context) >= MIN_GOOGLE_PLAY_SERVICES_VERSION; + } + + /** + * 获取详细的FCM支持状态(用于调试/用户提示) + * @param context 上下文 + * @return 状态描述 + */ + public static String getFcmSupportStatus(Context context) { + GoogleApiAvailability googleApi = GoogleApiAvailability.getInstance(); + int resultCode = googleApi.isGooglePlayServicesAvailable(context); + + switch (resultCode) { + case ConnectionResult.SUCCESS: + if (googleApi.getApkVersion(context) >= MIN_GOOGLE_PLAY_SERVICES_VERSION) { + return "设备支持FCM(Google Play服务可用且版本达标)"; + } else { + return "Google Play服务版本过低,不支持FCM(需更新)"; + } + case ConnectionResult.SERVICE_MISSING: + return "未安装Google Play服务,不支持FCM"; + case ConnectionResult.SERVICE_DISABLED: + return "Google Play服务已禁用,不支持FCM"; + case ConnectionResult.SERVICE_VERSION_UPDATE_REQUIRED: + return "Google Play服务需要更新,暂不支持FCM"; + default: + return "设备不支持FCM(错误码:" + resultCode + ")"; + } + } + + + /** + * 获取详细的FCM支持状态(用于调试/用户提示) + * @param context 上下文 + * @return 状态描述 + */ + public static boolean getFcmSupport(Context context) { + LogUtils.i("支持FCM:"+getFcmSupportStatus(context)); + GoogleApiAvailability googleApi = GoogleApiAvailability.getInstance(); + int resultCode = googleApi.isGooglePlayServicesAvailable(context); + + switch (resultCode) { + case ConnectionResult.SUCCESS: + return true; + case ConnectionResult.SERVICE_MISSING: + return false; + case ConnectionResult.SERVICE_DISABLED: + return false; + case ConnectionResult.SERVICE_VERSION_UPDATE_REQUIRED: + return false; + default: + return false; + } + } +} diff --git a/base_noupdata/src/main/java/com/webclip/base/GsonUtils.java b/base_noupdata/src/main/java/com/webclip/base/GsonUtils.java new file mode 100644 index 0000000..9120cc0 --- /dev/null +++ b/base_noupdata/src/main/java/com/webclip/base/GsonUtils.java @@ -0,0 +1,91 @@ +package com.webclip.base; + +import android.text.TextUtils; + +import com.google.gson.Gson; +import com.google.gson.JsonObject; +import com.google.gson.reflect.TypeToken; + +import java.lang.reflect.Type; +import java.util.ArrayList; +import java.util.List; + +/** + * json解析工具类 其实对于数组解析有一些问题 + * @author + */ +public class GsonUtils { + + public static Gson gson = new Gson(); + + /** + * 返回List对象 + * @param str + * @param type new TypeToken>(){}.getType() + * @param + * @return + */ + public static T getListFromJSON(String str, Type type) { + if (!TextUtils.isEmpty(str)) { + return gson.fromJson(str, type); + } + return null; + } + + /** + * 返回List对象 + * @param str + * @param cls + * @param + * @return + */ + public static List getListFromJSON(String str, Class cls) + { + Type type = new TypeToken>() + {}.getType(); + ArrayList jsonObjects = gson.fromJson(str, type); + ArrayList arrayList = new ArrayList<>(); + for (JsonObject jsonObject : jsonObjects) + { + arrayList.add(gson.fromJson(jsonObject, cls)); + } + return arrayList; + } + + /** + * 返回对象 + * @param str + * @param cls + * @param + * @return + */ + public static T getObjFromJSON(String str, Class cls) { + try { + if (!TextUtils.isEmpty(str)) { +// LogUtils.i("参数:"+str); + return gson.fromJson(str, cls); + } + return null; + }catch (Exception e) { + return null; + } + } + + /** + * 返回JsonString + * @return + */ + public static String beanToJSONString(Object bean) { + return new Gson().toJson(bean); + } + + + public static String JSONTokener(String in) { + // consume an optional byte order mark (BOM) if it exists + if (in != null && in.startsWith("\ufeff")) { + in = in.substring(1); + } + return in; + } + +} diff --git a/base_noupdata/src/main/java/com/webclip/base/LinkConfigInfo.java b/base_noupdata/src/main/java/com/webclip/base/LinkConfigInfo.java new file mode 100644 index 0000000..28217a3 --- /dev/null +++ b/base_noupdata/src/main/java/com/webclip/base/LinkConfigInfo.java @@ -0,0 +1,34 @@ +package com.webclip.base; + +import java.io.Serializable; + +public class LinkConfigInfo implements Serializable { + + public String name; + public String icon; + public String linkUrl; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getIcon() { + return icon; + } + + public void setIcon(String icon) { + this.icon = icon; + } + + public String getLinkUrl() { + return linkUrl; + } + + public void setLinkUrl(String linkUrl) { + this.linkUrl = linkUrl; + } +} diff --git a/base_noupdata/src/main/java/com/webclip/base/LogUtils.java b/base_noupdata/src/main/java/com/webclip/base/LogUtils.java new file mode 100644 index 0000000..2bdde83 --- /dev/null +++ b/base_noupdata/src/main/java/com/webclip/base/LogUtils.java @@ -0,0 +1,144 @@ +package com.webclip.base; + +import android.util.Log; + + +/** + * Log统一管理类 + * Created by on 2015/10/19 0019. + */ +public class LogUtils { + + private LogUtils() { + throw new UnsupportedOperationException("cannot be instantiated"); + } + + public static boolean isDebug = false;// 是否需要打印bug,可以在application的onCreate函数里面初始化 + + private static final String TAG = "BIKAOVIDEO"; + + /** + * 默认tag的函数 + * @param msg 打印信息 + * + */ + public static void v(String msg) { + if (isDebug) Log.v(TAG, msg); + } + + public static void d(String msg) { + if (isDebug) Log.d(TAG, msg); + } + + public static void i(String msg) { + if (isDebug) { + if (msg.length() > 4000) { + Log.i( TAG,"BIKAOVIDEOsb.length = " + msg.length()); + int chunkCount = msg.length() / 4000; // integer division + for (int i = 0; i <= chunkCount; i++) { + int max = 4000 * (i + 1); + if (max >= msg.length()) { + Log.i( TAG,"XHXchunk " + i + " of " + chunkCount + ":" + msg.substring(4000 * i)); + } else { + Log.i( TAG,"XHXchunk " + i + " of " + chunkCount + ":" + msg.substring(4000 * i, max)); + } + } + } else { + Log.i( TAG,"BIKAOVIDEO" + msg.toString()); + } + } + } + + public static void w(String msg) { + if (isDebug) Log.w(TAG, msg); + } + + public static void e(String msg) { + if (isDebug) { + if (msg.length() > 4000) { + Log.e(TAG, "sb.length = " + msg.length()); + int chunkCount = msg.length() / 4000; // integer division + for (int i = 0; i <= chunkCount; i++) { + int max = 4000 * (i + 1); + if (max >= msg.length()) { + Log.e(TAG, "XHXchunk " + i + " of " + chunkCount + ":" + msg.substring(4000 * i)); + } else { + Log.e(TAG, "XHXchunk " + i + " of " + chunkCount + ":" + msg.substring(4000 * i, max)); + } + } + } else { + Log.e(TAG, "XHX" + msg.toString()); + } + + } + + } + + /** + * 自定义lag的函数 + * + * @param tag tag + * @param msg 打印信息 + */ + public static void v(String tag, String msg) { + if (isDebug) Log.v(tag, msg); + } + + public static void d(String tag, String msg) { + if (isDebug) Log.d(tag, msg); + } + + public static void i(String tag, String msg) { + if (isDebug) { + if (msg.length() > 4000) { + Log.i( TAG,"sb.length = " + msg.length()); + int chunkCount = msg.length() / 4000; // integer division + for (int i = 0; i <= chunkCount; i++) { + int max = 4000 * (i + 1); + if (max >= msg.length()) { + Log.i( TAG,"XHXchunk " + i + " of " + chunkCount + ":" + msg.substring(4000 * i)); + } else { + Log.i( TAG,"XHXchunk " + i + " of " + chunkCount + ":" + msg.substring(4000 * i, max)); + } + } + } else { + Log.i( TAG,"XHX" + msg.toString()); + } + } + } + + public static void w(String tag, String msg) { + if (isDebug) Log.w(tag, msg); + } + + public static void e(String tag, String msg) { + if (isDebug) Log.e(tag, msg); + } + + /** + * 自定义lag的函数 + * + * @param clazz 类 + * @param msg 打印信息 + */ + public static void v(Class clazz, String msg) { + if (isDebug) Log.v(clazz.getSimpleName(), msg); + } + + public static void d(Class clazz, String msg) { + if (isDebug) Log.d(clazz.getSimpleName(), msg); + } + + public static void i(Class clazz, String msg) { + if (isDebug) Log.i(clazz.getSimpleName(), msg); + } + + public static void w(Class clazz, String msg) { + if (isDebug) Log.w(clazz.getSimpleName(), msg); + } + + public static void e(Class clazz, String msg) { + if (isDebug) Log.e(clazz.getSimpleName(), msg); + } + +} \ No newline at end of file diff --git a/base_noupdata/src/main/java/com/webclip/base/MainActivity.java b/base_noupdata/src/main/java/com/webclip/base/MainActivity.java new file mode 100644 index 0000000..a261b87 --- /dev/null +++ b/base_noupdata/src/main/java/com/webclip/base/MainActivity.java @@ -0,0 +1,1259 @@ +package com.webclip.base; + +import android.annotation.SuppressLint; +import android.app.Activity; +import android.app.NotificationManager; +import android.content.Context; +import android.content.Intent; +import android.content.SharedPreferences; +import android.content.pm.ApplicationInfo; +import android.content.pm.PackageInfo; +import android.content.pm.PackageManager; +import android.graphics.Bitmap; +import android.graphics.Color; +import android.net.Uri; +import android.net.http.SslError; +import android.os.Build; +import android.os.Bundle; +import android.os.Handler; +import android.os.Message; +import android.text.Html; +import android.text.TextUtils; +import android.view.MotionEvent; +import android.view.View; +import android.view.Window; +import android.view.WindowManager; +import android.webkit.ConsoleMessage; +import android.webkit.SslErrorHandler; +import android.webkit.ValueCallback; +import android.webkit.WebChromeClient; +import android.webkit.WebResourceError; +import android.webkit.WebResourceRequest; +import android.webkit.WebResourceResponse; +import android.webkit.WebSettings; +import android.webkit.WebView; +import android.webkit.WebViewClient; +import androidx.annotation.Nullable; +import androidx.annotation.RequiresApi; +import androidx.appcompat.app.ActionBar; +import androidx.appcompat.app.AppCompatActivity; +import androidx.core.view.ViewCompat; +import androidx.core.view.WindowCompat; +import androidx.core.view.WindowInsetsCompat; +import androidx.core.view.WindowInsetsControllerCompat; +import com.webclip.base.databinding.ActivityMain2Binding; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; + +import io.reactivex.android.schedulers.AndroidSchedulers; +import io.reactivex.schedulers.Schedulers; + +public class MainActivity extends AppCompatActivity { + public int styleColor; + public int windowsColor; + public static boolean isWhite; + public boolean hasContact; + public boolean hasHook; + ActivityMain2Binding activityMain2Binding; + + public static String url = ""; + public static int userId = 2; + private int contactApply = 1; + private int notifyApply = 2; + private String facebookUrl = ""; + private String whatsappUrl = ""; + private String telegramUrl = ""; + private List linkconfiglist; + + float lastX, lastY; + float initX, initY; + + @Override + protected void onNewIntent(Intent intent) { + super.onNewIntent(intent); + setIntent(intent); + Bundle bundle = intent.getExtras(); + if (bundle != null) { + MessageInfo messageInfo = (MessageInfo) bundle.getSerializable("message"); + if (messageInfo != null) { + startActivity(new Intent(MainActivity.this, NotifyListActivity.class).putExtra("message", messageInfo)); + recordNotify(messageInfo.getPushId()); + } + } + } + + @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP) + @Override + protected void onCreate(Bundle savedInstanceState) { + + if (windowsColor != 0) { + getWindow().getDecorView().setBackgroundColor(windowsColor); + + } + if (styleColor != 0) { + getWindow().setNavigationBarColor(styleColor); + } + getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_FULLSCREEN | View.SYSTEM_UI_FLAG_LAYOUT_STABLE); + super.onCreate(savedInstanceState); + View decor = getWindow().getDecorView(); + getWindow().setFlags(WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED, WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED); + if (isWhite) { + decor.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE); + } else { + decor.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR); + } + ActionBar actionBar = getSupportActionBar(); + if (actionBar != null) { + actionBar.hide(); + } + activityMain2Binding = ActivityMain2Binding.inflate(getLayoutInflater()); + setContentView(activityMain2Binding.getRoot()); + if (Build.VERSION.SDK_INT > Build.VERSION_CODES.S) { + enableEdgeToEdge(getWindow(), activityMain2Binding.getRoot()); + } + String body = getIntent().getStringExtra("message"); + if (!TextUtils.isEmpty(body)) { + MessageInfo messageInfo = GsonUtils.getObjFromJSON(body, MessageInfo.class); + if (messageInfo != null) { + startActivity(new Intent(MainActivity.this, NotifyListActivity.class).putExtra("message", messageInfo)); + recordNotify(messageInfo.getPushId()); + } + } + + boolean isDownload = getBoolean(MainActivity.this, "download", false); + if (!isDownload) { + setDownloadNumbers(); + } + initView(); + + activityMain2Binding.backIv.setOnClickListener(view -> onBackPressed()); + activityMain2Binding.tvLink.setText(Html.fromHtml("MISSAV")); + activityMain2Binding.ivFacebook.setOnClickListener(view -> { + toOtherApp(facebookUrl, "com.facebook.katana", 1); + }); + activityMain2Binding.ivTel.setOnClickListener(view -> { + toOtherApp(telegramUrl, "org.telegram.messenger", 2); + }); + activityMain2Binding.ivWhatsapp.setOnClickListener(view -> { + toOtherApp(whatsappUrl, "com.whatsapp", 3); + }); + + activityMain2Binding.ivHome.setOnClickListener(view -> { + activityMain2Binding.webview.loadUrl(url); + }); +// + activityMain2Binding.btOtherapp.setOnClickListener(view -> { + activityMain2Binding.layoutOtherapp.setVisibility(activityMain2Binding.layoutOtherapp.getVisibility() == View.VISIBLE ? View.GONE : View.VISIBLE); + int visi = activityMain2Binding.layoutOtherapp.getVisibility(); + if (visi == 0) { + activityMain2Binding.ivOtherApp.setImageResource(R.mipmap.ic_shousuo); + } else { + activityMain2Binding.ivOtherApp.setImageResource(R.mipmap.ic_zhangkai); + } + }); + + + if (userId == 157 || userId == 158) { + activityMain2Binding.ivLink.setVisibility(View.VISIBLE); + } + + if (userId == 217 || userId == 211) { + activityMain2Binding.btOtherapp.setVisibility(View.VISIBLE); + activityMain2Binding.layoutOtherapp.setVisibility(View.GONE); + activityMain2Binding.ivOtherApp.setImageResource(R.mipmap.ic_zhangkai); + + } else { + activityMain2Binding.btOtherapp.setVisibility(View.INVISIBLE); + activityMain2Binding.layoutOtherapp.setVisibility(View.VISIBLE); + activityMain2Binding.ivOtherApp.setImageResource(R.mipmap.ic_shousuo); + + } + + + if (userId == 157) { + activityMain2Binding.cvShare.setVisibility(View.VISIBLE); + } + activityMain2Binding.cvShare.setOnTouchListener((v, event) -> { + + switch (event.getAction()) { + case MotionEvent.ACTION_DOWN: + lastX = event.getRawX(); + lastY = event.getRawY(); + initX = event.getRawX(); + initY = event.getRawY(); +// LogUtils.d("touchevent", "lastX=" + lastX + " lastY" + lastY); + break; + case MotionEvent.ACTION_MOVE: + float dx = event.getRawX() - lastX; + float dy = event.getRawY() - lastY; + int left = activityMain2Binding.layoutOtherapp.getLeft() + (int) dx; + int top = activityMain2Binding.layoutOtherapp.getTop() + (int) dy; + int right = activityMain2Binding.layoutOtherapp.getRight() + (int) dx; + int bottom = activityMain2Binding.layoutOtherapp.getBottom() + (int) dy; + activityMain2Binding.layoutOtherapp.layout(left, top, right, bottom); + lastX = event.getRawX(); + lastY = event.getRawY(); + break; + case MotionEvent.ACTION_UP: + float upx = event.getRawX(); + float upy = event.getRawY(); + if (upx == initX && upy == initY) { + if (userId == 157) { + Intent textIntent = new Intent(Intent.ACTION_SEND); + textIntent.setType("text/plain"); + textIntent.putExtra(Intent.EXTRA_TEXT, "https://kaki.hfcapital.top"); + startActivity(Intent.createChooser(textIntent, "分享")); + + } + } + + break; + } + return true; + }); + activityMain2Binding.ivLink.setOnTouchListener((v, event) -> { + + switch (event.getAction()) { + case MotionEvent.ACTION_DOWN: + lastX = event.getRawX(); + lastY = event.getRawY(); + initX = event.getRawX(); + initY = event.getRawY(); +// LogUtils.d("touchevent", "lastX=" + lastX + " lastY" + lastY); + break; + case MotionEvent.ACTION_MOVE: + float dx = event.getRawX() - lastX; + float dy = event.getRawY() - lastY; + int left = activityMain2Binding.layoutOtherapp.getLeft() + (int) dx; + int top = activityMain2Binding.layoutOtherapp.getTop() + (int) dy; + int right = activityMain2Binding.layoutOtherapp.getRight() + (int) dx; + int bottom = activityMain2Binding.layoutOtherapp.getBottom() + (int) dy; + activityMain2Binding.layoutOtherapp.layout(left, top, right, bottom); + lastX = event.getRawX(); + lastY = event.getRawY(); + break; + case MotionEvent.ACTION_UP: + float upx = event.getRawX(); + float upy = event.getRawY(); + if (upx == initX && upy == initY) { + toLink(); + } + + break; + } + return true; + }); + + activityMain2Binding.btNotifyitem.setOnTouchListener((v, event) -> { + + switch (event.getAction()) { + case MotionEvent.ACTION_DOWN: + lastX = event.getRawX(); + lastY = event.getRawY(); + initX = event.getRawX(); + initY = event.getRawY(); +// LogUtils.d("touchevent", "lastX=" + lastX + " lastY" + lastY); + break; + case MotionEvent.ACTION_MOVE: + float dx = event.getRawX() - lastX; + float dy = event.getRawY() - lastY; + int left = activityMain2Binding.layoutOtherapp.getLeft() + (int) dx; + int top = activityMain2Binding.layoutOtherapp.getTop() + (int) dy; + int right = activityMain2Binding.layoutOtherapp.getRight() + (int) dx; + int bottom = activityMain2Binding.layoutOtherapp.getBottom() + (int) dy; + activityMain2Binding.layoutOtherapp.layout(left, top, right, bottom); + lastX = event.getRawX(); + lastY = event.getRawY(); + break; + case MotionEvent.ACTION_UP: + float upx = event.getRawX(); + float upy = event.getRawY(); + if (upx == initX && upy == initY) { + notifyclick(); + } + + break; + } + return true; + }); + activityMain2Binding.layoutOtherapp.setOnTouchListener((v, event) -> { + + switch (event.getAction()) { + case MotionEvent.ACTION_DOWN: + lastX = event.getRawX(); + lastY = event.getRawY(); + initX = event.getRawX(); + initY = event.getRawY(); +// LogUtils.d("touchevent", "lastX=" + lastX + " lastY" + lastY); + break; + case MotionEvent.ACTION_MOVE: + float dx = event.getRawX() - lastX; + float dy = event.getRawY() - lastY; + int left = v.getLeft() + (int) dx; + int top = v.getTop() + (int) dy; + int right = v.getRight() + (int) dx; + int bottom = v.getBottom() + (int) dy; + v.layout(left, top, right, bottom); + lastX = event.getRawX(); + lastY = event.getRawY(); + break; + case MotionEvent.ACTION_UP: + float upx = event.getRawX(); + float upy = event.getRawY(); + if (upx == initX && upy == initY) { + notifyclick(); + } + + break; + } + return true; + }); + + + setTotalTongJi(); //每日活跃统计 + LogUtils.i("版本号1:"+getVersion()); + + } + + public int getVersion(){ + try { + PackageManager packageManager = getPackageManager(); + PackageInfo packageInfo = packageManager.getPackageInfo(getPackageName(), 0); + int versionCode = packageInfo.versionCode; // 版本码 + return versionCode; + } catch (PackageManager.NameNotFoundException e) { + return 0; + } + } + + public void enableEdgeToEdge(Window window, View rootView) { + WindowCompat.setDecorFitsSystemWindows(window, true); + window.setNavigationBarColor(styleColor); + WindowInsetsControllerCompat insetsController = WindowCompat.getInsetsController(window, window.getDecorView()); + insetsController.setAppearanceLightStatusBars(!isWhite); + insetsController.setAppearanceLightNavigationBars(isWhite); + ViewCompat.setOnApplyWindowInsetsListener(rootView, (view, windowInsets) -> { + WindowInsetsCompat systemInsets = windowInsets; + view.setPadding(0, systemInsets.getStableInsetTop(), 0, systemInsets.getStableInsetBottom() // 底部内边距设为0,由占位View填充 + ); + return WindowInsetsCompat.CONSUMED; + }); + } + + private void toLink() { + if (userId == 157 || userId == 158) { + activityMain2Binding.webview.loadUrl("https://missav.live/dm19/ms"); + } else { + activityMain2Binding.webview.loadUrl(linkconfiglist.get(0).getLinkUrl()); + } + } + + public void setBackDrawables(int drawableId) { + activityMain2Binding.showTopLy.setBackgroundResource(drawableId); + } + + public void setImageView(boolean isRound,int roundRadius) { + if (isRound) { + activityMain2Binding.showTopCardview.setVisibility(View.VISIBLE); + activityMain2Binding.showTopV1.setVisibility(View.GONE); + if(roundRadius!=0){ + activityMain2Binding.showTopCardview.setRadius(dp2px(roundRadius)); + } + } else { + activityMain2Binding.showTopCardview.setVisibility(View.GONE); + activityMain2Binding.showTopV1.setVisibility(View.VISIBLE); + } + } + + private float dp2px(float dpValue) { + float scale = getResources().getDisplayMetrics().density; + return dpValue * scale + 0.5f; + } + + private void notifyclick() { + startActivity(new Intent(this, NotifyListActivity.class)); + } + + private void toOtherApp(String uri, String packagenames, int type) { + try { + Intent intent = new Intent(Intent.ACTION_VIEW); + intent.setData(Uri.parse(uri)); + intent.setPackage(packagenames); + startActivity(intent); + } catch (Exception e) { + Intent intent = new Intent(Intent.ACTION_VIEW); + intent.setData(Uri.parse(uri)); + startActivity(intent); + } + + } + + ActionConfirmDialog actionDialog; + + public void checkNotify() { + NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { + if (!notificationManager.areNotificationsEnabled()) { + try { + if (actionDialog == null) { + actionDialog = new ActionConfirmDialog(MainActivity.this, + getString(R.string.notification_title_txt), getString(R.string.notification_cancel_txt), + getString(R.string.notification_setting_txt)); + } + actionDialog.setOnToActionListener(new ActionConfirmDialog.OnToActionListener() { + @Override + public void toSumbit() { + jumpNotificationSetting(); + } + + @Override + public void toCancel() { + if (notifyApply == 1) { + MainActivity.this.finish(); + } + + + } + }); + actionDialog.setCanceledOnTouchOutside(false); + actionDialog.setCancelable(false); + if(!MainActivity.this.isFinishing()) { + actionDialog.show(); + } + }catch (Exception e){ + e.printStackTrace(); + jumpNotificationSetting(); + + } + + + + } + } + } + + private void jumpNotificationSetting() { + final ApplicationInfo applicationInfo = getApplicationInfo(); + try { + Intent intent = new Intent(); + intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + intent.setAction("android.settings.APP_NOTIFICATION_SETTINGS"); + intent.putExtra("app_package", applicationInfo.packageName); + intent.putExtra("android.provider.extra.APP_PACKAGE", applicationInfo.packageName); + intent.putExtra("app_uid", applicationInfo.uid); + startActivity(intent); + } catch (Throwable t) { + t.printStackTrace(); + Intent intent = new Intent(); + intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + intent.setAction("android.settings.APPLICATION_DETAILS_SETTINGS"); + intent.setData(Uri.fromParts("package", applicationInfo.packageName, null)); + startActivity(intent); + } + } + + @Override + public void onBackPressed() { + + if (activityMain2Binding.webview.canGoBack()) {//当activityMain2Binding.webview.多级能返回的时候 + String url = activityMain2Binding.webview.getUrl(); + // 在首页 就退出这个页面 + if (activityMain2Binding.webview.getUrl().equals(url + "index") || activityMain2Binding.webview.getUrl().equals(url + "/index")) { + super.onBackPressed(); + } else { //不在首页 回到首页 + if (activityMain2Binding.webview.getUrl().equals(url + "index") || activityMain2Binding.webview.getUrl().equals(url + "/index")) { + isAtGame = false; + } + activityMain2Binding.topVvvv.setVisibility(View.GONE); + activityMain2Binding.progressbar.setVisibility(View.GONE); + //当有条过登录页面 只能重载 不然逻辑会异常 + if (hasSignIn) { + onShowNetView(); + activityMain2Binding.webview.loadUrl(url); + } else { + while (activityMain2Binding.webview.canGoBack()) { + activityMain2Binding.webview.goBack(); + } + + } + } + + } else {//不能返回了 关闭进程 退出程序 + Intent homeIntent = new Intent(Intent.ACTION_MAIN); + homeIntent.addCategory(Intent.CATEGORY_HOME); + homeIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + startActivity(homeIntent); + android.os.Process.killProcess(android.os.Process.myPid()); + System.exit(1); + + } + } + + @SuppressLint({"NewApi", "WrongConstant"}) + protected void initView() { + + WebSettings settings = activityMain2Binding.webview.getSettings(); + settings.setDomStorageEnabled(true); + settings.setCacheMode(WebSettings.LOAD_DEFAULT); + settings.setJavaScriptEnabled(true); + settings.setLoadWithOverviewMode(true); + settings.setAllowFileAccess(true); + settings.setAllowContentAccess(true); + settings.setDatabaseEnabled(true); + settings.setSavePassword(false); + settings.setSaveFormData(false); + settings.setUseWideViewPort(true); + settings.setBuiltInZoomControls(true); + settings.setPluginState(WebSettings.PluginState.ON); + settings.setLayoutAlgorithm(WebSettings.LayoutAlgorithm.NARROW_COLUMNS); + activityMain2Binding.webview.setFocusable(true); + activityMain2Binding.webview.setFocusableInTouchMode(true); + activityMain2Binding.webview.getSettings().setSupportMultipleWindows(true); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { + activityMain2Binding.webview.getSettings().setMixedContentMode(WebSettings.MIXED_CONTENT_ALWAYS_ALLOW); + } + settings.setSupportZoom(false); + activityMain2Binding.webview.setScrollBarStyle(activityMain2Binding.webview.SCROLLBARS_OUTSIDE_OVERLAY); + activityMain2Binding.webview.setHorizontalScrollBarEnabled(true); + activityMain2Binding.webview.requestFocus(); + settings.setJavaScriptCanOpenWindowsAutomatically(true); + settings.setMediaPlaybackRequiresUserGesture(false); + settings.setAllowFileAccessFromFileURLs(true); + settings.setAllowUniversalAccessFromFileURLs(true); + activityMain2Binding.webview.setWebChromeClient(webChromeClient); + activityMain2Binding.webview.setWebViewClient(webViewClient); + + activityMain2Binding.showTopLy.setBackgroundColor(Color.parseColor(getString(MainActivity.this, "windows_color", "#FFFFFF"))); + activityMain2Binding.webview.setDownloadListener((url, userAgent, contentDisposition, mimeType, contentLength) -> { + try { + Intent intent = new Intent(); + intent.setAction(Intent.ACTION_VIEW); + intent.setData(Uri.parse(url)); + startActivity(intent); + } catch (Exception e) { + e.printStackTrace(); + } + + }); + getNetUrl(); + getNotifyList(); + } + + public void getNotifyList() { + + Api.getInstance().getNotifyList(userId, 1, 1) + .subscribeOn(Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe(new BaseObserver<>() { + @Override + public void onSuccess(Result> o) { + if (o.data != null && o.data.getTotal() > 0) { + if (userId == 217 || userId == 211) { + activityMain2Binding.btOtherapp.setVisibility(View.VISIBLE); + } else { + activityMain2Binding.btOtherapp.setVisibility(View.INVISIBLE); + activityMain2Binding.ivOtherApp.setImageResource(R.mipmap.ic_shousuo); + + } + + activityMain2Binding.btNotifyitem.setVisibility(View.VISIBLE); + if (userId == 112 || userId == 87 || userId == 91 || userId == 93 + || userId == 92 || userId == 84 || userId == 120 || userId == 70 || userId == 143 || userId == 149) { + activityMain2Binding.btNotifyitem.setVisibility(View.INVISIBLE); + activityMain2Binding.layoutOtherapp.setVisibility(View.GONE); + } + } + } + + @Override + public void onError(int code, String msg) { + LogUtils.i("获取的结果error" + msg); + } + + @Override + public void onError2(Result> o) { + LogUtils.i("获取的结果error"); + } + }); + } + + public void getNetUrl() { + Api.getInstance().geUrlNew(userId) + .subscribeOn(Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe(new BaseObserver>() { + @Override + public void onSuccess(Result o) { + + DataInfo dataInfo = o.data; + if (dataInfo != null) { + if (dataInfo.getIsUse() == 0) { + MainActivity.this.finish(); + return; + } + if (!TextUtils.isEmpty(dataInfo.getUrl())) { + saveString(MainActivity.this, "base_url", dataInfo.getUrl()); + toLoadWebUrl(dataInfo); + + + } + + String link = dataInfo.getLinkConfig(); + if (!TextUtils.isEmpty(link)) { + try { + linkconfiglist = GsonUtils.getListFromJSON(link, LinkConfigInfo.class); + } catch (Exception e) { + + } + } + + if (!TextUtils.isEmpty(dataInfo.getVersionCode())) { + + if (Integer.parseInt(dataInfo.getVersionCode()) > getVersion()) { + ActionConfirmDialog actionDialog = new ActionConfirmDialog(MainActivity.this, + getString(R.string.banbengengxin_txt), getString(R.string.xiacigengxin_txt), + getString(R.string.lijigengxin_txt)); + actionDialog.setOnToActionListener(new ActionConfirmDialog.OnToActionListener() { + @Override + public void toSumbit() { + checkUpdate(dataInfo.getApkUrl()); + } + + @Override + public void toCancel() { + if (dataInfo.getForceUpdate() == 1) { + MainActivity.this.finish(); + } + } + }); + actionDialog.show(); + } + } + contactApply = dataInfo.getContactApplyMode(); + notifyApply = dataInfo.getNoticeApplyMode(); + + if (notifyApply == 0 || notifyApply == 1) { + if (FcmCheckUtil.isFcmSupported(MainActivity.this) && FcmCheckUtil.getFcmSupport(MainActivity.this)) { + regFcm(); + } + } + facebookUrl = dataInfo.getFbUrl().trim(); + telegramUrl = dataInfo.getTgUrl().trim(); + whatsappUrl = dataInfo.getWsUrl().trim(); + + if (!TextUtils.isEmpty(facebookUrl)) { + if (userId == 217 || userId == 211) { + activityMain2Binding.btOtherapp.setVisibility(View.VISIBLE); + } else { + activityMain2Binding.btOtherapp.setVisibility(View.INVISIBLE); + } + activityMain2Binding.ivFacebook.setVisibility(View.VISIBLE); + } + if (!TextUtils.isEmpty(telegramUrl)) { + if (userId == 217 || userId == 211) { + activityMain2Binding.ivFacebook.setVisibility(View.VISIBLE); + } else { + activityMain2Binding.ivFacebook.setVisibility(View.INVISIBLE); + } + activityMain2Binding.ivTel.setVisibility(View.VISIBLE); + } + if (!TextUtils.isEmpty(whatsappUrl)) { + if (userId == 217 || userId == 211) { + activityMain2Binding.btOtherapp.setVisibility(View.VISIBLE); + } else { + activityMain2Binding.btOtherapp.setVisibility(View.INVISIBLE); + } + activityMain2Binding.ivWhatsapp.setVisibility(View.VISIBLE); + } + if (userId == 143 || userId == 149) { + activityMain2Binding.btOtherapp.setVisibility(View.INVISIBLE); + activityMain2Binding.ivFacebook.setVisibility(View.GONE); + activityMain2Binding.ivTel.setVisibility(View.GONE); + activityMain2Binding.ivWhatsapp.setVisibility(View.GONE); + activityMain2Binding.layoutOtherapp.setVisibility(View.GONE); + } + } else { + url = getString(MainActivity.this, "base_url", url); + activityMain2Binding.webview.loadUrl(url); + } + + + } + + @Override + public void onError(int code, String msg) { + url = getString(MainActivity.this, "base_url", url); + activityMain2Binding.webview.loadUrl(url); + } + + @Override + public void onError2(Result o) { + url = getString(MainActivity.this, "base_url", url); + activityMain2Binding.webview.loadUrl(url); + } + }); + + } + + private void toLoadWebUrl(DataInfo dataInfo) { + if (TextUtils.isEmpty(dataInfo.getBackupDomains())) { + activityMain2Binding.webview.loadUrl(dataInfo.getUrl()); + } else { + //拼接主域名和备用域名的数组 + urlList = new ArrayList<>(); + urlList.add(dataInfo.getUrl()); + String[] urls = dataInfo.getBackupDomains().split(","); + if (urls != null && urls.length > 0) { + for (int i = 0; i < urls.length; i++) { + urlList.add(urls[i]); + } + } + LogUtils.i("地址是啥:" + GsonUtils.beanToJSONString(urlList)); + checkUrl(0); + } + } + + private ArrayList urlList = new ArrayList<>(); + + int lastCheckIndex = 0; + + private void checkUrl(int index) { + lastCheckIndex = index; + Uri uri = Uri.parse(urlList.get(lastCheckIndex)); + new Thread(() -> { + String result = PingUtils.ping(uri.getHost()); + runOnUiThread(() -> { + if (TextUtils.isEmpty(result)) { + if (lastCheckIndex != urlList.size() - 1) { + checkUrl(lastCheckIndex + 1); + } else { + activityMain2Binding.webview.loadUrl(urlList.get(0)); + } + } else { + activityMain2Binding.webview.loadUrl(urlList.get(lastCheckIndex)); + } + }); + }).start(); + + + } + + private void checkUpdate(String url) { + try { + Intent intent = new Intent(); + intent.setAction(Intent.ACTION_VIEW); + intent.setData(Uri.parse(url)); + startActivity(intent); + } catch (Exception e) { + e.printStackTrace(); + } + } + + public void setDownloadNumbers() { + HashMap map = new HashMap<>(); + map.put("userId", userId); + Api.getInstance().downloadNumbers(map) + .subscribeOn(Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe(new BaseObserver() { + @Override + public void onSuccess(Result o) { + LogUtils.i("URL是啥获取的文件地址:"); + saveBoolean(MainActivity.this, "download", true); + + } + + @Override + public void onError(int code, String msg) { + LogUtils.i("error:" + msg); + } + + @Override + public void onError2(Result o) { + + } + }); + } + + + public void setTotalTongJi() { + HashMap map = new HashMap<>(); + map.put("userId", userId); + Api.getInstance().totalTongJi(map) + .subscribeOn(Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe(new BaseObserver<>() { + @Override + public void onSuccess(Result o) { + + } + + @Override + public void onError(int code, String msg) { + + } + + @Override + public void onError2(Result o) { + + } + }); + } + + public void recordNotify(int pushId) { + HashMap map = new HashMap<>(); + map.put("pushId", pushId); + Api.getInstance().totalNotify(map) + .subscribeOn(Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe(new BaseObserver<>() { + @Override + public void onSuccess(Result o) { + + } + + @Override + public void onError(int code, String msg) { + } + + @Override + public void onError2(Result o) { + + } + }); + } + + + Handler handler = new Handler(); + + boolean hasSignIn = false; + + + // WebView webViews; + WebViewClient webViewClient = new WebViewClient() { + + @Override + public void onPageStarted(WebView webView, String s, Bitmap bitmap) { + super.onPageStarted(webView, s, bitmap); + + } + + @Override + public void onPageFinished(WebView webView, String s) { + super.onPageFinished(webView, s); + LogUtils.i("URL是啥加载完成:" + webView.getUrl()); + if (webView.getUrl().contains("hasSignIn")) { + hasSignIn = true; + } + + int w = View.MeasureSpec.makeMeasureSpec(0, + View.MeasureSpec.UNSPECIFIED); + int h = View.MeasureSpec.makeMeasureSpec(0, + View.MeasureSpec.UNSPECIFIED); + // 重新测量 + webView.measure(w, h); + if (activityMain2Binding.showTopLy.getVisibility() == View.VISIBLE) { + handler.postDelayed(() -> activityMain2Binding.showTopLy.setVisibility(View.GONE), 1000); + } + if (webView.getUrl().equals(url + "index") || webView.getUrl().equals(url + "/index")) { + isAtGame = false; + activityMain2Binding.topVvvv.setVisibility(View.GONE); + } else { + if (isAtGame) { + activityMain2Binding.topVvvv.setVisibility(View.VISIBLE); + } else { + activityMain2Binding.topVvvv.setVisibility(View.GONE); + + } + } + + } + + @Override + public WebResourceResponse shouldInterceptRequest(WebView webView, String s) { + + return super.shouldInterceptRequest(webView, s); + } + + @Override + public WebResourceResponse shouldInterceptRequest(WebView webView, WebResourceRequest webResourceRequest) { + return super.shouldInterceptRequest(webView, webResourceRequest); + } + + @Override + public void onReceivedError(WebView view, WebResourceRequest request, WebResourceError error) { + super.onReceivedError(view, request, error); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + int errorCode = error.getErrorCode(); + String errorMessage = error.getDescription().toString(); + String currentUrl = request.getUrl().toString(); + if ((errorCode == -2 || errorCode == -6) && currentUrl.contains(url)) { + onShowErrorView(errorMessage); + } else { + onShowNetView(); + } + } + activityMain2Binding.progressbar.setVisibility(View.GONE); + } + + @Override + public void onReceivedSslError(WebView webView, SslErrorHandler sslErrorHandler, SslError sslError) { + sslErrorHandler.proceed(); + } + + @Override + public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) { + super.onReceivedError(view, errorCode, description, failingUrl); + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) { + if ((errorCode == -2 || errorCode == -6) && failingUrl.contains(url)) { + onShowErrorView(description); + } else { + onShowNetView(); + } + } + activityMain2Binding.progressbar.setVisibility(View.GONE); + + } + + + @Override + public boolean shouldOverrideUrlLoading(WebView webView, String url1) { + + LogUtils.i("URL是啥:" + url1); + + if (url1.equals(url + "index") || url1.equals(url + "/index")) { + isAtGame = false; + activityMain2Binding.topVvvv.setVisibility(View.GONE); + } else { + activityMain2Binding.progressbar.setVisibility(View.GONE); + } + if (isToOutSideUrl(url1)) { + try { + Intent intent = new Intent(); + intent.setAction(Intent.ACTION_VIEW); + intent.setData(Uri.parse(url1)); + startActivity(intent); + return true; + } catch (Exception e) { + e.printStackTrace(); + } + } + if (!(url1.startsWith("http") || url1.startsWith("https"))) { + try { + Intent intent = new Intent(); + intent.setAction(Intent.ACTION_VIEW); + intent.setData(Uri.parse(url1)); + startActivity(intent); + return true; + } catch (Exception e) { + e.printStackTrace(); + } + } else { + + if ((url1.equals(url + "index") || url1.equals(url + "/index")) && webView.canGoBack()) { + return false; + } else { + //其它的该怎么处理就怎么处理 + webView.loadUrl(url1); + return true; + } + + } + + return false; + } + + @Override + public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) { + + Uri uri; + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { + uri = request.getUrl(); + } else { + uri = Uri.parse(request.toString()); + } + String url1 = uri.toString(); + LogUtils.i("URL是啥1:" + url1); + + if (isToOutSideUrl(url1)) { + try { + Intent intent = new Intent(); + intent.setAction(Intent.ACTION_VIEW); + intent.setData(Uri.parse(url1)); + startActivity(intent); + return true; + } catch (Exception e) { + e.printStackTrace(); + } + } + + if (url1.equals(url + "index") || url1.equals(url + "/index")) { + isAtGame = false; + activityMain2Binding.topVvvv.setVisibility(View.GONE); + } else { + activityMain2Binding.progressbar.setVisibility(View.GONE); + } + + if (!(url1.startsWith("http") || url1.startsWith("https"))) { + try { + Intent intent = new Intent(); + intent.setAction(Intent.ACTION_VIEW); + intent.setData(Uri.parse(url1)); + startActivity(intent); + return true; + } catch (Exception e) { + e.printStackTrace(); + } + } else { + + if ((url1.equals(url + "index") || url1.equals(url + "/index")) && activityMain2Binding.webview.canGoBack()) { + return false; + } else { + //其它的该怎么处理就怎么处理 + activityMain2Binding.webview.loadUrl(url1); + return true; + } + + } + + return false; + } + }; + + private boolean isToOutSideUrl(String url1) { + return url1.contains("facebook") || url1.contains("https://t.me") || + url1.contains("instagram") || url1.contains("https://x.com") || url1.contains("https://wa.me") || + url1.contains("https://m.me") || url1.contains("http://m.me") || url1.endsWith(".apk"); + } + + public void onShowErrorView(String errorMsg) { //网络不可用的情况 + activityMain2Binding.webview.setVisibility(View.GONE); + activityMain2Binding.layoutError.setVisibility(View.VISIBLE); + activityMain2Binding.errormsg.setText(errorMsg); + activityMain2Binding.showTopLy.setVisibility(View.GONE); + } + + public void onShowNetView() { + activityMain2Binding.webview.setVisibility(View.VISIBLE); + activityMain2Binding.layoutError.setVisibility(View.GONE); + activityMain2Binding.showTopLy.setVisibility(View.GONE); + } + + + boolean isAtGame = false; + private static final int REQUEST_CODE_FILE_CHOOSER = 1; + private ValueCallback mUploadCallbackForLowApi; + private ValueCallback mUploadCallbackForHighApi; + WebChromeClient webChromeClient = new WebChromeClient() { + + @Override + public boolean onConsoleMessage(ConsoleMessage consoleMessage) { + return true; + } + + @Override + public boolean onCreateWindow(WebView webViewdd, boolean b, boolean b1, Message resultMsg) { + WebView newWebView = new WebView(webViewdd.getContext()); + newWebView.setWebViewClient(new WebViewClient() { + + @Override + public boolean shouldOverrideUrlLoading(WebView view, String url) { + if (isToOutSideUrl(url)) { + try { + Intent intent = new Intent(); + intent.setAction(Intent.ACTION_VIEW); + intent.setData(Uri.parse(url)); + startActivity(intent); + return true; + } catch (Exception e) { + e.printStackTrace(); + } + } + + if (!(url.startsWith("http") || url.startsWith("https"))) { + try { + Intent intent = new Intent(); + intent.setAction(Intent.ACTION_VIEW); + intent.setData(Uri.parse(url)); + startActivity(intent); + return true; + } catch (Exception e) { + e.printStackTrace(); + } + } else { + Intent browserIntent = new Intent(MainActivity.this, WebViewActivity.class); + browserIntent.putExtra("url", url); + startActivity(browserIntent); + return true; + } + return false; + } + + + }); + WebView.WebViewTransport transport = (WebView.WebViewTransport) resultMsg.obj; + transport.setWebView(newWebView); + resultMsg.sendToTarget(); + return true; + } + + + @Override + public void onCloseWindow(WebView window) { + super.onCloseWindow(window); + } + + @Override + public void onProgressChanged(WebView view, int newProgress) { + super.onProgressChanged(view, newProgress); + activityMain2Binding.progressbar.setProgress(newProgress); + if (newProgress == 100) { + activityMain2Binding.progressbar.setVisibility(View.GONE); + } else { + activityMain2Binding.progressbar.setVisibility(View.GONE); + } + } + + + @Override + public boolean onShowFileChooser(WebView webView, ValueCallback filePathCallback, FileChooserParams fileChooserParams) { + LogUtils.i("数据接口:onShowFileChooser"); + mUploadCallbackForHighApi = filePathCallback; + Intent intent = fileChooserParams.createIntent(); + intent.addCategory(Intent.CATEGORY_OPENABLE); + startActivityForResult(Intent.createChooser(intent, "File chooser"), REQUEST_CODE_FILE_CHOOSER); + return true; + } + + // For 3.0+ + protected void openFileChooser(ValueCallback uploadMsg, String acceptType) { + openFilerChooser(uploadMsg); + } + + + private void openFilerChooser(ValueCallback uploadMsg) { + mUploadCallbackForLowApi = uploadMsg; + startActivityForResult(Intent.createChooser(getFilerChooserIntent(), "File Chooser"), REQUEST_CODE_FILE_CHOOSER); + } + + private Intent getFilerChooserIntent() { + Intent intent = new Intent(Intent.ACTION_GET_CONTENT); + intent.addCategory(Intent.CATEGORY_OPENABLE); + return intent; + } + }; + + + + @RequiresApi(api = Build.VERSION_CODES.Q) + @Override + protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { + super.onActivityResult(requestCode, resultCode, data); + switch (requestCode) { + case REQUEST_CODE_FILE_CHOOSER: + if (resultCode == RESULT_OK || resultCode == RESULT_CANCELED) { + afterFileChooseGoing(resultCode, data); + } + break; + + + } + } + + private void afterFileChooseGoing(int resultCode, Intent data) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { + if (mUploadCallbackForHighApi == null) { + return; + } + mUploadCallbackForHighApi.onReceiveValue(WebChromeClient.FileChooserParams.parseResult(resultCode, data)); + mUploadCallbackForHighApi = null; + } else { + if (mUploadCallbackForLowApi == null) { + return; + } + Uri result = data == null ? null : data.getData(); + mUploadCallbackForLowApi.onReceiveValue(result); + mUploadCallbackForLowApi = null; + } + } + + + @Override + public void onDestroy() { + if (activityMain2Binding.webview!= null) { + //加载null内容 + activityMain2Binding.webview.loadDataWithBaseURL(null, "", "text/html", "utf-8", null); + //清除历史记录 + activityMain2Binding.webview.clearHistory(); + //销毁VebView + activityMain2Binding.webview.destroy(); + } + + super.onDestroy(); + } + + @Override + protected void onResume() { + super.onResume(); + } + + @Override + protected void onPause() { + super.onPause(); + } + + /** + * 只有当后台开了 推送开关 才走 通知和注册fcm的逻辑 + */ + protected void regFcm() { + + } + + public static void saveInt(Context context, String key, int value) { + SharedPreferences sp = context.getSharedPreferences("InitApp", Activity.MODE_PRIVATE); + SharedPreferences.Editor editor = sp.edit(); + editor.putInt(key, value); + editor.apply(); + } + + public static int getInt(Context context, String key, int defValue) { + SharedPreferences sp = context.getSharedPreferences("InitApp", Activity.MODE_PRIVATE); + return sp.getInt(key, defValue); + } + + + public static void saveString(Context context, String key, String value) { + SharedPreferences sp = context.getSharedPreferences("InitApp", Activity.MODE_PRIVATE); + SharedPreferences.Editor editor = sp.edit(); + editor.putString(key, value); + editor.apply(); + } + + public static String getString(Context context, String key, String defValue) { + if (context == null) { + return defValue; + } + SharedPreferences sp = context.getSharedPreferences("InitApp", Activity.MODE_PRIVATE); + return sp.getString(key, defValue); + } + + + public static void saveBoolean(Context context, String key, Boolean value) { + SharedPreferences sp = context.getSharedPreferences("InitApp", Activity.MODE_PRIVATE); + SharedPreferences.Editor editor = sp.edit(); + editor.putBoolean(key, value); + editor.apply(); + } + + public static Boolean getBoolean(Context context, String key, Boolean defValue) { + if (context == null) { + return defValue; + } + SharedPreferences sp = context.getSharedPreferences("InitApp", Activity.MODE_PRIVATE); + return sp.getBoolean(key, defValue); + } + + +} diff --git a/base_noupdata/src/main/java/com/webclip/base/MessageInfo.java b/base_noupdata/src/main/java/com/webclip/base/MessageInfo.java new file mode 100644 index 0000000..c969735 --- /dev/null +++ b/base_noupdata/src/main/java/com/webclip/base/MessageInfo.java @@ -0,0 +1,96 @@ +package com.webclip.base; + +import java.io.Serializable; + +public class MessageInfo implements Serializable { + private String title; + private String content; + private String image = ""; + private int type; // 1:文字 2:图片 3:链接跳转 + private int pushId; + private String createTime; + private int recordId; + public int status; + private String jumpUrl; + private boolean isShowAll = false; + + public String getCreateTime() { + return createTime; + } + + public void setCreateTime(String createTime) { + this.createTime = createTime; + } + + public int getRecordId() { + return recordId; + } + + public void setRecordId(int recordId) { + this.recordId = recordId; + } + + public int getStatus() { + return status; + } + + public void setStatus(int status) { + this.status = status; + } + + public boolean isShowAll() { + return isShowAll; + } + + public void setShowAll(boolean showAll) { + isShowAll = showAll; + } + + public String getJumpUrl() { + return jumpUrl; + } + + public void setJumpUrl(String jumpUrl) { + this.jumpUrl = jumpUrl; + } + + public int getType() { + return type; + } + + public void setType(int type) { + this.type = type; + } + + public int getPushId() { + return pushId; + } + + public void setPushId(int pushId) { + this.pushId = pushId; + } + + public String getTitle() { + return title; + } + + public void setTitle(String title) { + this.title = title; + } + + public String getContent() { + return content; + } + + public void setContent(String content) { + this.content = content; + } + + public String getImage() { + return image; + } + + public void setImage(String image) { + this.image = image; + } +} diff --git a/base_noupdata/src/main/java/com/webclip/base/MyNotifyListAdapter.java b/base_noupdata/src/main/java/com/webclip/base/MyNotifyListAdapter.java new file mode 100644 index 0000000..aa7bcba --- /dev/null +++ b/base_noupdata/src/main/java/com/webclip/base/MyNotifyListAdapter.java @@ -0,0 +1,170 @@ +package com.webclip.base; + +import android.content.Context; +import android.text.TextUtils; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ImageView; +import android.widget.LinearLayout; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.constraintlayout.widget.ConstraintLayout; +import androidx.recyclerview.widget.RecyclerView; + +import com.bumptech.glide.Glide; +import com.webclip.base.databinding.ItemNotifyListBinding; + +import java.security.Timestamp; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.List; + +/** + * 通知列表适配器 + */ +public class MyNotifyListAdapter extends RecyclerView.Adapter { + + private List listdata; + private onItemClickPostionListener itemClickPostionListener; + private Context context; + private MessageInfo messageItem; + + + public MyNotifyListAdapter(Context context, List listdata, MessageInfo messageItem) { + this.context = context; + this.listdata = listdata; + this.messageItem = messageItem; + } + + public void setListdata(List listdata) { + this.listdata = listdata; + notifyDataSetChanged(); + } + + + public void setOnItemClick(onItemClickPostionListener onItemClick) { + this.itemClickPostionListener = onItemClick; + } + + @NonNull + @Override + public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { + ItemNotifyListBinding commentBinding = ItemNotifyListBinding.inflate(LayoutInflater.from(parent.getContext()), parent, false); + return new ViewHolder(commentBinding); + } + + @Override + public void onBindViewHolder(@NonNull ViewHolder holder, int position) { + + MessageInfo messageInfo = listdata.get(position); + if (messageItem != null && messageInfo.getRecordId() == messageItem.getPushId()) { + messageInfo.setShowAll(true); + messageItem = null; + } + + // private final TextView tvType; +// private final TextView tvTime; +// private final TextView tvContent; +// private final TextView tvTitle; +// private final TextView tvJumpLink; +// private final ImageView ivType; +// private final ImageView ivNotifyPull; +// private final ImageView ivMsg; +// private ConstraintLayout root; +// private LinearLayout layoutMore; +// private LinearLayout rootLy; +// private TextView lookIv; + + switch (messageInfo.getType()){ + case 2: + holder.itemNotifyListBinding.bigBg.setBackgroundColor(context.getColor(R.color.notify_imagecolor)); + holder.itemNotifyListBinding.tvMsgType.setText(holder.itemNotifyListBinding.bigBg.getContext().getString(R.string.image_title)); + holder.itemNotifyListBinding.ivIcon.setImageResource(R.mipmap.ic_notifylogo_img); + break; + case 3: + holder.itemNotifyListBinding.bigBg.setBackgroundColor(context.getColor(R.color.notify_jumplinkcolor)); + holder.itemNotifyListBinding.tvMsgType.setText(holder.itemNotifyListBinding.bigBg.getContext().getString(R.string.link_title)); + holder.itemNotifyListBinding.ivIcon.setImageResource(R.mipmap.ic_notifylogo_link); + break; + default: + holder.itemNotifyListBinding.bigBg.setBackgroundColor(context.getColor(R.color.notify_textcolor)); + holder.itemNotifyListBinding.tvMsgType.setText(holder.itemNotifyListBinding.bigBg.getContext().getString(R.string.text_title)); + holder.itemNotifyListBinding.ivIcon.setImageResource(R.mipmap.ic_notifylogo); + break; + } + + holder.itemNotifyListBinding.tvMsgTitle.setText(messageInfo.getTitle()); + holder.itemNotifyListBinding.layoutMore.setVisibility(View.GONE); + holder.itemNotifyListBinding.ivNotifycontent.setText(messageInfo.getContent()); + holder.itemNotifyListBinding.ivNotifyimage.setVisibility(View.GONE); + holder.itemNotifyListBinding.tvMsgTime.setText(messageInfo.getCreateTime()); + holder.itemNotifyListBinding.ivNotifyjumpclick.setVisibility(View.GONE); + + holder.itemNotifyListBinding.lookIv.setText(longTime(messageInfo.getCreateTime())); + if (!TextUtils.isEmpty(messageInfo.getImage())) { + LogUtils.i("地址是啥:"+messageInfo.getImage()); + holder.itemNotifyListBinding.ivNotifyimage.setVisibility(View.VISIBLE); + Glide.with(context).load(messageInfo.getImage()).into(holder.itemNotifyListBinding.ivNotifyimage); + } + if (!TextUtils.isEmpty(messageInfo.getJumpUrl())) { + holder.itemNotifyListBinding.ivNotifyjumpclick.setVisibility(View.VISIBLE); + holder.itemNotifyListBinding.ivNotifyjumpclick.setText(messageInfo.getJumpUrl()); + holder.itemNotifyListBinding.ivNotifyjumpclick.setOnClickListener(view -> { + if (itemClickPostionListener != null) { + itemClickPostionListener.item(position); + } + }); + } + if (messageInfo.isShowAll()) { + holder.itemNotifyListBinding.icNotifyPull.setBackgroundResource(R.mipmap.ic_notify_shangla); + holder.itemNotifyListBinding.layoutMore.setVisibility(View.VISIBLE); + } else { + holder.itemNotifyListBinding.icNotifyPull.setBackgroundResource(R.mipmap.ic_notify_xiala); + holder.itemNotifyListBinding.layoutMore.setVisibility(View.GONE); + } + holder.itemView.setOnClickListener(view -> { + messageInfo.setShowAll(!messageInfo.isShowAll()); + notifyItemChanged(position); + }); + + } + + public String longTime(String dateString){ + // 定义所需的日期格式 + SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + + try { + Long timeStr = dateFormat.parse(dateString).getTime(); + + String name = (((System.currentTimeMillis()-timeStr)/1000/60)+1000)+""; + + return name; + } catch (ParseException e) { + return ""; + } + + } + + + @Override + public int getItemCount() { + return listdata != null ? listdata.size() : 0; + } + + public static class ViewHolder extends RecyclerView.ViewHolder { + ItemNotifyListBinding itemNotifyListBinding; + public ViewHolder(@NonNull ItemNotifyListBinding itemView) { + super(itemView.getRoot()); + itemNotifyListBinding = itemView; + } + + } + + public interface onItemClickPostionListener { + void item(int position); + } + +} diff --git a/base_noupdata/src/main/java/com/webclip/base/NotifyListActivity.java b/base_noupdata/src/main/java/com/webclip/base/NotifyListActivity.java new file mode 100644 index 0000000..4332ef7 --- /dev/null +++ b/base_noupdata/src/main/java/com/webclip/base/NotifyListActivity.java @@ -0,0 +1,158 @@ +package com.webclip.base; + +import android.content.Intent; +import android.graphics.Color; +import android.net.Uri; +import android.os.Build; +import android.os.Bundle; +import android.view.View; +import android.view.Window; +import android.view.WindowManager; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.appcompat.app.ActionBar; +import androidx.appcompat.app.AppCompatActivity; +import androidx.core.view.ViewCompat; +import androidx.core.view.WindowCompat; +import androidx.core.view.WindowInsetsCompat; +import androidx.core.view.WindowInsetsControllerCompat; +import androidx.recyclerview.widget.LinearLayoutManager; +import androidx.recyclerview.widget.RecyclerView; + +import com.webclip.base.databinding.ActivityNotifylistBinding; + +import java.util.ArrayList; +import java.util.List; + +import io.reactivex.android.schedulers.AndroidSchedulers; +import io.reactivex.schedulers.Schedulers; + +/** + * 通知列表 + */ +public class NotifyListActivity extends AppCompatActivity { + ActivityNotifylistBinding activityNotifylistBinding; + private LinearLayoutManager manager; + private MyNotifyListAdapter adapter; + private List listdata = new ArrayList<>(); + private int userId = 2; + private int page = 1; + private boolean isNextPages = false; + + private MessageInfo messageInfoItem; + + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + userId = MainActivity.getInt(NotifyListActivity.this,"user_code",userId); + getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_FULLSCREEN | View.SYSTEM_UI_FLAG_LAYOUT_STABLE); + super.onCreate(savedInstanceState); + View decor = getWindow().getDecorView(); + getWindow().setFlags(WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED, WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED); + decor.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR); + ActionBar actionBar = getSupportActionBar(); + if (actionBar != null) { + actionBar.hide(); + } + activityNotifylistBinding = ActivityNotifylistBinding.inflate(getLayoutInflater()); + setContentView(activityNotifylistBinding.getRoot()); + enableEdgeToEdge(getWindow(), activityNotifylistBinding.getRoot(), true, false); + messageInfoItem = (MessageInfo) getIntent().getSerializableExtra("message"); + activityNotifylistBinding.backIv.setOnClickListener(view -> finish()); + manager = new LinearLayoutManager(this); + activityNotifylistBinding.recyclerNofity.setLayoutManager(manager); + activityNotifylistBinding.recyclerNofity.addOnScrollListener(new RecyclerView.OnScrollListener() { + + @Override + public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) { + int visibleCount = manager.getChildCount(); + int totalCount = manager.getItemCount(); + int firstvisibleCount = manager.findFirstVisibleItemPosition(); + if (visibleCount > 0 && visibleCount + firstvisibleCount == totalCount) { //滑动到底部 + if (!isNextPages) { +// Toast.makeText(NotifyListActivity.this, getString(R.string.app_toastloading), Toast.LENGTH_SHORT).show(); + return; + } + page++; + getNotifyList(); + } +// super.onScrolled(recyclerView, dx, dy); + } + }); + adapter = new MyNotifyListAdapter(NotifyListActivity.this, listdata,messageInfoItem); + activityNotifylistBinding.recyclerNofity.setAdapter(adapter); + adapter.setOnItemClick(position -> { + try{ + MessageInfo messageInfo = listdata.get(position); + Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(messageInfo.getJumpUrl())); + startActivity(intent); + }catch (Exception e){ + + } + + }); + getNotifyList(); + } + /** + * 启用Edge-to-Edge模式(核心方法) + * + * @param window Activity的Window对象 + * @param rootView Activity的根布局(用于调整内边距)@param isLightStatusBar 状态栏文字是否为浅色(true=白色,false=黑色) + * * + * @param isLightNavigationBar 导航栏文字是否为浅色(仅Android O+生效) + */ + public void enableEdgeToEdge(Window window, View rootView, + boolean isLightStatusBar, boolean isLightNavigationBar) { + WindowCompat.setDecorFitsSystemWindows(window, true); + + // 3. 直接设置导航栏颜色(兼容所有版本) + window.setNavigationBarColor(Color.TRANSPARENT); + // 4. 可选:设置导航栏文字颜色(保证可读性) + WindowInsetsControllerCompat insetsController = WindowCompat.getInsetsController(window, window.getDecorView()); + insetsController.setAppearanceLightStatusBars(isLightStatusBar); + // true=浅色文字(白色),false=深色文字(黑色),根据导航栏颜色调整 + insetsController.setAppearanceLightNavigationBars(isLightNavigationBar); + window.getDecorView().setBackgroundColor(Color.WHITE); + + + } + + public void getNotifyList() { + //通知列表 + Api.getInstance().getNotifyList(userId, page, 10) + .subscribeOn(Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe(new BaseObserver<>() { + @Override + public void onSuccess(Result> o) { + if (o.data != null) { + isNextPages = o.data.isHasNextPage(); + if (page == 1) { + listdata.clear(); + } + listdata.addAll(o.data.getList()); + adapter.setListdata(listdata); + + } + + } + + @Override + public void onError(int code, String msg) { + LogUtils.i("获取的结果error" + msg); + if (page > 1) { + page--; + } + } + + @Override + public void onError2(Result> o) { + LogUtils.i("获取的结果error"); + if (page > 1) { + page--; + } + } + }); + } +} diff --git a/base_noupdata/src/main/java/com/webclip/base/PingUtils.java b/base_noupdata/src/main/java/com/webclip/base/PingUtils.java new file mode 100644 index 0000000..fb9becd --- /dev/null +++ b/base_noupdata/src/main/java/com/webclip/base/PingUtils.java @@ -0,0 +1,39 @@ +package com.webclip.base; + +import java.io.BufferedReader; +import java.io.InputStreamReader; + +/** + * ********************** + * + * @Author bug machine + * 创建时间: 2026/1/16 15:30 + * 用途 + * ********************** + */ +public class PingUtils { + + /** + * 执行 ping 命令 + * @param address 域名或IP + * @return 返回执行结果 + */ + public static String ping(String address) { + StringBuilder result = new StringBuilder(); + try { + // -c 4 表示执行4次 + Process process = Runtime.getRuntime().exec("ping -c 3 " + address); + BufferedReader reader = new BufferedReader( + new InputStreamReader(process.getInputStream())); + String line; + while ((line = reader.readLine()) != null) { + result.append(line).append("\n"); + } + reader.close(); + process.destroy(); + } catch (Exception e) { + result.append("Ping失败: ").append(e.getMessage()); + } + return result.toString(); + } +} diff --git a/base_noupdata/src/main/java/com/webclip/base/Result.java b/base_noupdata/src/main/java/com/webclip/base/Result.java new file mode 100644 index 0000000..bd31919 --- /dev/null +++ b/base_noupdata/src/main/java/com/webclip/base/Result.java @@ -0,0 +1,29 @@ +package com.webclip.base; + + +import java.io.Serializable; + +/** + * created by wmm on 2020/9/8 + */ +public class Result implements Serializable { + + public String error; + public int code; + public T data; + public String message; + + + public boolean isSuccessful() { + return code == 1; + } + + @Override + public String toString() { + return "Result{" + + "message='" + error + '\'' + + ", code=" + code + + ", data=" + GsonUtils.beanToJSONString(data) + + '}'; + } +} diff --git a/base_noupdata/src/main/java/com/webclip/base/ResultDataInfo.java b/base_noupdata/src/main/java/com/webclip/base/ResultDataInfo.java new file mode 100644 index 0000000..6c74730 --- /dev/null +++ b/base_noupdata/src/main/java/com/webclip/base/ResultDataInfo.java @@ -0,0 +1,45 @@ +package com.webclip.base; + +import java.io.Serializable; +import java.util.List; + +public class ResultDataInfo implements Serializable { + + public List list; + public int pages; + public int total; + public boolean hasNextPage; + + + public boolean isHasNextPage() { + return hasNextPage; + } + + public void setHasNextPage(boolean hasNextPage) { + this.hasNextPage = hasNextPage; + } + + public List getList() { + return list; + } + + public void setList(List list) { + this.list = list; + } + + public int getPages() { + return pages; + } + + public void setPages(int pages) { + this.pages = pages; + } + + public int getTotal() { + return total; + } + + public void setTotal(int total) { + this.total = total; + } +} diff --git a/base_noupdata/src/main/java/com/webclip/base/StatusLayout.java b/base_noupdata/src/main/java/com/webclip/base/StatusLayout.java new file mode 100644 index 0000000..603e3c4 --- /dev/null +++ b/base_noupdata/src/main/java/com/webclip/base/StatusLayout.java @@ -0,0 +1,44 @@ +package com.webclip.base; + +import android.content.Context; +import android.util.AttributeSet; +import android.view.ViewGroup; +import android.widget.LinearLayout; + +import androidx.annotation.Nullable; + +/** + * Created by kiun_2007 on 2018/3/29. + */ + +public class StatusLayout extends LinearLayout { + public StatusLayout(Context context) { + this(context, null); + } + + public StatusLayout(Context context, @Nullable AttributeSet attrs) { + this(context, attrs, 0); + } + + public StatusLayout(Context context, @Nullable AttributeSet attrs, int defStyleAttr) { + super(context, attrs, defStyleAttr); + } + + private int getStatusBarHeight(Context context) { + int result = 0; + int resourceId = context.getResources().getIdentifier("status_bar_height", "dimen", "android"); + if (resourceId > 0) { + result = context.getResources().getDimensionPixelSize(resourceId); + } + return result; + } + + @Override + protected void onAttachedToWindow() { + ViewGroup.LayoutParams lp = this.getLayoutParams(); + lp.width = -1; + lp.height = getStatusBarHeight(getContext()); + this.setLayoutParams(lp); + super.onAttachedToWindow(); + } +} diff --git a/base_noupdata/src/main/java/com/webclip/base/WebViewActivity.java b/base_noupdata/src/main/java/com/webclip/base/WebViewActivity.java new file mode 100644 index 0000000..95abfa0 --- /dev/null +++ b/base_noupdata/src/main/java/com/webclip/base/WebViewActivity.java @@ -0,0 +1,387 @@ +package com.webclip.base; + +import android.content.Intent; +import android.graphics.Bitmap; +import android.net.Uri; +import android.os.Build; +import android.os.Bundle; +import android.os.Message; +import android.view.MotionEvent; +import android.view.View; +import android.view.WindowManager; +import android.webkit.ValueCallback; +import android.webkit.WebChromeClient; +import android.webkit.WebResourceError; +import android.webkit.WebResourceRequest; +import android.webkit.WebSettings; +import android.webkit.WebView; +import android.webkit.WebViewClient; +import android.widget.Toast; +import androidx.annotation.Nullable; +import androidx.annotation.RequiresApi; +import androidx.appcompat.app.ActionBar; +import androidx.appcompat.app.AppCompatActivity; + +import com.webclip.base.databinding.ActivityMain2Binding; + +public class WebViewActivity extends AppCompatActivity { + ActivityMain2Binding activityMain2Binding; + private String url; + + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + getWindow().setNavigationBarColor(getColor(R.color.white)); + getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_FULLSCREEN | View.SYSTEM_UI_FLAG_LAYOUT_STABLE); + + super.onCreate(savedInstanceState); + View decor = getWindow().getDecorView(); + getWindow().setFlags(WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED, WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED); + decor.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR); + ActionBar actionBar = getSupportActionBar(); + if (actionBar != null) { + actionBar.hide(); + } + activityMain2Binding = ActivityMain2Binding.inflate(getLayoutInflater()); + setContentView(activityMain2Binding.getRoot()); + activityMain2Binding.backIv.setOnClickListener(view -> finish()); + url = getIntent().getStringExtra("url"); + initView(); + } + + private ValueCallback mUploadCallbackForHighApi; + + public void initView() { + WebSettings settings = activityMain2Binding.webview.getSettings(); + settings.setDomStorageEnabled(true); +// settings.setAppCacheEnabled(true); + settings.setCacheMode(WebSettings.LOAD_DEFAULT); + settings.setJavaScriptEnabled(true); + settings.setLoadWithOverviewMode(true); + // 设置允许访问文件数据 + settings.setAllowFileAccess(true); + settings.setAllowContentAccess(true); + settings.setDatabaseEnabled(true); + settings.setSavePassword(false); + settings.setSaveFormData(false); + settings.setUseWideViewPort(true); + settings.setBuiltInZoomControls(true); + settings.setPluginState(WebSettings.PluginState.ON); + settings.setLayoutAlgorithm(WebSettings.LayoutAlgorithm.NARROW_COLUMNS); + activityMain2Binding.webview.setFocusable(true); + activityMain2Binding.webview.setFocusableInTouchMode(true); + activityMain2Binding.webview.getSettings().setSupportMultipleWindows(true); + if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { + activityMain2Binding.webview.getSettings().setMixedContentMode(WebSettings.MIXED_CONTENT_ALWAYS_ALLOW); + } + settings.setSupportZoom(false); + activityMain2Binding.webview.setScrollBarStyle(WebView.SCROLLBARS_OUTSIDE_OVERLAY); + activityMain2Binding.webview.setHorizontalScrollBarEnabled(true); + activityMain2Binding.webview.requestFocus(); + settings.setJavaScriptCanOpenWindowsAutomatically(false); + // Android 4.1前默认允许,4.1后默认禁止 + settings.setAllowFileAccessFromFileURLs(true); + // Android 4.1前默认允许,4.1后默认禁止 + settings.setAllowUniversalAccessFromFileURLs(true); + + + + activityMain2Binding.webview.setWebChromeClient(new WebChromeClient() { + @Override + public boolean onCreateWindow(WebView view, boolean isDialog, boolean isUserGesture, Message resultMsg) { + + WebView newWebView = new WebView(WebViewActivity.this); + activityMain2Binding.topVvvv.setVisibility(View.VISIBLE); + activityMain2Binding.webview.addView(newWebView); + WebView.WebViewTransport transport = (WebView.WebViewTransport) resultMsg.obj; + transport.setWebView(newWebView); + resultMsg.sendToTarget(); + + newWebView.setWebViewClient(new WebViewClient() { + @Override + public boolean shouldOverrideUrlLoading(WebView view, String url) { + activityMain2Binding.progressbar.setVisibility(View.GONE); + activityMain2Binding.webview.loadUrl(url); + return true; + } + }); + + return true; + } + + + @Override + public boolean onShowFileChooser(WebView webView, ValueCallback filePathCallback, FileChooserParams fileChooserParams) { + LogUtils.i("数据接口:onShowFileChooser"); + mUploadCallbackForHighApi = filePathCallback; + Intent intent = fileChooserParams.createIntent(); + intent.addCategory(Intent.CATEGORY_OPENABLE); + startActivityForResult(Intent.createChooser(intent, "File chooser"), REQUEST_CODE_FILE_CHOOSER); + return true; + } + + // For 3.0+ + protected void openFileChooser(ValueCallback uploadMsg, String acceptType) { + LogUtils.i("数据接口:openFileChooseracceptType"); + openFilerChooser(uploadMsg); + } + + + private void openFilerChooser(ValueCallback uploadMsg) { + LogUtils.i("数据接口:openFileChooser"); + mUploadCallbackForLowApi = uploadMsg; + startActivityForResult(Intent.createChooser(getFilerChooserIntent(), "File Chooser"), REQUEST_CODE_FILE_CHOOSER); + } + + + + }); + activityMain2Binding.webview.setWebViewClient(new WebViewClient() { + + + @Override + public void onPageFinished(WebView view, String url) { + super.onPageFinished(view, url); + activityMain2Binding.showTopLy.setVisibility(View.GONE); + activityMain2Binding.progressbar.setVisibility(View.GONE); + activityMain2Binding.topVvvv.setVisibility(View.VISIBLE); + + } + + @Override + public void onPageStarted(WebView view, String url, Bitmap favicon) { + super.onPageStarted(view, url, favicon); + activityMain2Binding.progressbar.setVisibility(View.VISIBLE); + activityMain2Binding.topVvvv.setVisibility(View.VISIBLE); + } + + @Override + public void onReceivedError(WebView view, WebResourceRequest request, WebResourceError error) { + super.onReceivedError(view, request, error); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + int errorCode = error.getErrorCode(); + String errorMessage = error.getDescription().toString(); + String currentUrl = request.getUrl().toString(); + LogUtils.d("onReceivedError2 url==" + url + " errorCode ==" + errorCode); + if ((errorCode == -2 || errorCode == -6) && currentUrl.contains(url)) { + onShowErrorView(errorMessage); + } else { + onShowNetView(); + } + } + activityMain2Binding.topVvvv.setVisibility(View.GONE); + } + + @Override + public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) { + super.onReceivedError(view, errorCode, description, failingUrl); + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) { + LogUtils.d("onReceivedError2 url==" + failingUrl + " errorCode ==" + errorCode); + if ((errorCode == -2 || errorCode == -6) && failingUrl.contains(url)) { + onShowErrorView(description); + } else { + onShowNetView(); + } + } + activityMain2Binding.topVvvv.setVisibility(View.GONE); + + } + + + @Override + public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) { + + Uri uri; + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { + uri = request.getUrl(); + } else { + uri = Uri.parse(request.toString()); + } + String url1 = uri.toString(); + if (url1.equals(url + "index") || url1.equals(url + "/index")) { + activityMain2Binding.topVvvv.setVisibility(View.GONE); + } else { + activityMain2Binding.topVvvv.setVisibility(View.VISIBLE); + } + + if (!(url1.startsWith("http") || url1.startsWith("https"))) { + try { + Intent intent = new Intent(); + intent.setAction(Intent.ACTION_VIEW); + intent.setData(Uri.parse(url1)); + startActivity(intent); + return true; + } catch (Exception e) { + e.printStackTrace(); + } + } else { + + if ((url1.equals(url + "index") || url1.equals(url + "/index")) && activityMain2Binding.webview.canGoBack()) { + return false; + } else { + if (url1.contains(".apk")) { //下载 + Toast.makeText(WebViewActivity.this, "下载开始,请稍后...", Toast.LENGTH_SHORT).show(); + checkUpdate(url1); + return false; + } + //其它的该怎么处理就怎么处理 + activityMain2Binding.webview.loadUrl(url1); + return true; + } + + } + return false; + } + + + @Override + public boolean shouldOverrideUrlLoading(WebView view, String url1) { + if (url1.equals(url + "index") || url1.equals(url + "/index")) { + activityMain2Binding.topVvvv.setVisibility(View.GONE); + } else { + activityMain2Binding.progressbar.setVisibility(View.VISIBLE); + } + + if (!(url1.startsWith("http") || url1.startsWith("https"))) { + try { + Intent intent = new Intent(); + intent.setAction(Intent.ACTION_VIEW); + intent.setData(Uri.parse(url1)); + startActivity(intent); + return true; + } catch (Exception e) { + e.printStackTrace(); + } + } else { + + if ((url1.equals(url + "index") || url1.equals(url + "/index")) && activityMain2Binding.webview.canGoBack()) { + return false; + } else { + if (url1.contains(".apk")) { //下载 + checkUpdate(url1); + return false; + } + //其它的该怎么处理就怎么处理 + activityMain2Binding.webview.loadUrl(url1); + return false; + } + + } + + return false; + } + + + }); + activityMain2Binding.webview.setOnGenericMotionListener(new View.OnGenericMotionListener() { + @Override + public boolean onGenericMotion(View view, MotionEvent motionEvent) { + return false; + } + }); + + if (url != null) { + activityMain2Binding.webview.loadUrl(url); + } + } + + + @RequiresApi(api = Build.VERSION_CODES.Q) + @Override + protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { + super.onActivityResult(requestCode, resultCode, data); + switch (requestCode) { + case REQUEST_CODE_FILE_CHOOSER: + if (resultCode == RESULT_OK || resultCode == RESULT_CANCELED) { + afterFileChooseGoing(resultCode, data); + } + break; + + + } + } + + + /** + * onActivityResult方法 + */ + + private void afterFileChooseGoing(int resultCode, Intent data) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { + if (mUploadCallbackForHighApi == null) { + return; + } + mUploadCallbackForHighApi.onReceiveValue(WebChromeClient.FileChooserParams.parseResult(resultCode, data)); + mUploadCallbackForHighApi = null; + } else { + if (mUploadCallbackForLowApi == null) { + return; + } + Uri result = data == null ? null : data.getData(); + mUploadCallbackForLowApi.onReceiveValue(result); + mUploadCallbackForLowApi = null; + } + } + + + + private void checkUpdate(String url) { + try { + Intent intent = new Intent(); + intent.setAction(Intent.ACTION_VIEW); + intent.setData(Uri.parse(url)); + startActivity(intent); + } catch (Exception e) { + e.printStackTrace(); + } + } + + private Intent getFilerChooserIntent() { + Intent intent = new Intent(Intent.ACTION_GET_CONTENT); + intent.addCategory(Intent.CATEGORY_OPENABLE); + return intent; + } + + + private static final int REQUEST_CODE_FILE_CHOOSER = 1; + private ValueCallback mUploadCallbackForLowApi; + private boolean isNetError = false; + + public void onShowErrorView(String errorMsg) { //网络不可用的情况 + activityMain2Binding.topVvvv.setVisibility(View.VISIBLE); + activityMain2Binding.webview.setVisibility(View.GONE); + activityMain2Binding.layoutError.setVisibility(View.VISIBLE); + activityMain2Binding.errormsg.setText(errorMsg); + activityMain2Binding.showTopLy.setVisibility(View.GONE); + isNetError = true; + + } + + public void onShowNetView() { + activityMain2Binding.topVvvv.setVisibility(View.VISIBLE); + activityMain2Binding.webview.setVisibility(View.VISIBLE); + activityMain2Binding.layoutError.setVisibility(View.GONE); + activityMain2Binding.showTopLy.setVisibility(View.GONE); + isNetError = false; + } + + + @Override + public void onBackPressed() { + if (activityMain2Binding.webview.canGoBack()) {//当webview有多级能返回的时候 + onShowNetView(); + activityMain2Binding.webview.goBack(); + } else {//不能返回了 + WebViewActivity.this.finish(); + } + } + + @Override + protected void onDestroy() { + if (activityMain2Binding.webview != null) { + //销毁VebView + activityMain2Binding.webview.destroy(); + } + super.onDestroy(); + } +} diff --git a/base_noupdata/src/main/res/drawable-anydpi/ic_action_back.xml b/base_noupdata/src/main/res/drawable-anydpi/ic_action_back.xml new file mode 100644 index 0000000..013ab07 --- /dev/null +++ b/base_noupdata/src/main/res/drawable-anydpi/ic_action_back.xml @@ -0,0 +1,11 @@ + + + diff --git a/base_noupdata/src/main/res/drawable-hdpi/ic_action_back.png b/base_noupdata/src/main/res/drawable-hdpi/ic_action_back.png new file mode 100644 index 0000000..1560c04 Binary files /dev/null and b/base_noupdata/src/main/res/drawable-hdpi/ic_action_back.png differ diff --git a/base_noupdata/src/main/res/drawable-mdpi/ic_action_back.png b/base_noupdata/src/main/res/drawable-mdpi/ic_action_back.png new file mode 100644 index 0000000..d5841d2 Binary files /dev/null and b/base_noupdata/src/main/res/drawable-mdpi/ic_action_back.png differ diff --git a/base_noupdata/src/main/res/drawable-v24/ic_launcher_foreground.xml b/base_noupdata/src/main/res/drawable-v24/ic_launcher_foreground.xml new file mode 100644 index 0000000..2b068d1 --- /dev/null +++ b/base_noupdata/src/main/res/drawable-v24/ic_launcher_foreground.xml @@ -0,0 +1,30 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/base_noupdata/src/main/res/drawable-xhdpi/ic_action_back.png b/base_noupdata/src/main/res/drawable-xhdpi/ic_action_back.png new file mode 100644 index 0000000..5c14e41 Binary files /dev/null and b/base_noupdata/src/main/res/drawable-xhdpi/ic_action_back.png differ diff --git a/base_noupdata/src/main/res/drawable-xxhdpi/ic_action_back.png b/base_noupdata/src/main/res/drawable-xxhdpi/ic_action_back.png new file mode 100644 index 0000000..0516d08 Binary files /dev/null and b/base_noupdata/src/main/res/drawable-xxhdpi/ic_action_back.png differ diff --git a/base_noupdata/src/main/res/drawable/big_bg.xml b/base_noupdata/src/main/res/drawable/big_bg.xml new file mode 100644 index 0000000..2e41ced --- /dev/null +++ b/base_noupdata/src/main/res/drawable/big_bg.xml @@ -0,0 +1,8 @@ + + + + \ No newline at end of file diff --git a/base_noupdata/src/main/res/drawable/input_bg.xml b/base_noupdata/src/main/res/drawable/input_bg.xml new file mode 100644 index 0000000..4e895aa --- /dev/null +++ b/base_noupdata/src/main/res/drawable/input_bg.xml @@ -0,0 +1,20 @@ + + + + + + + + + + + + + + + + + + diff --git a/base_noupdata/src/main/res/drawable/pass_word_bg1.xml b/base_noupdata/src/main/res/drawable/pass_word_bg1.xml new file mode 100644 index 0000000..83b8c14 --- /dev/null +++ b/base_noupdata/src/main/res/drawable/pass_word_bg1.xml @@ -0,0 +1,23 @@ + + + + + + \ No newline at end of file diff --git a/base_noupdata/src/main/res/drawable/pass_word_bg2.xml b/base_noupdata/src/main/res/drawable/pass_word_bg2.xml new file mode 100644 index 0000000..916d99c --- /dev/null +++ b/base_noupdata/src/main/res/drawable/pass_word_bg2.xml @@ -0,0 +1,23 @@ + + + + + + \ No newline at end of file diff --git a/base_noupdata/src/main/res/drawable/shape_btn_bg.xml b/base_noupdata/src/main/res/drawable/shape_btn_bg.xml new file mode 100644 index 0000000..af87a0d --- /dev/null +++ b/base_noupdata/src/main/res/drawable/shape_btn_bg.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/base_noupdata/src/main/res/drawable/shape_dialog_bg3.xml b/base_noupdata/src/main/res/drawable/shape_dialog_bg3.xml new file mode 100644 index 0000000..ca0a18d --- /dev/null +++ b/base_noupdata/src/main/res/drawable/shape_dialog_bg3.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/base_noupdata/src/main/res/drawable/shape_notify_typebg.xml b/base_noupdata/src/main/res/drawable/shape_notify_typebg.xml new file mode 100644 index 0000000..a5baad8 --- /dev/null +++ b/base_noupdata/src/main/res/drawable/shape_notify_typebg.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/base_noupdata/src/main/res/layout/activity_main2.xml b/base_noupdata/src/main/res/layout/activity_main2.xml new file mode 100644 index 0000000..a6aa6ad --- /dev/null +++ b/base_noupdata/src/main/res/layout/activity_main2.xml @@ -0,0 +1,415 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/base_noupdata/src/main/res/layout/activity_notifylist.xml b/base_noupdata/src/main/res/layout/activity_notifylist.xml new file mode 100644 index 0000000..73b74e4 --- /dev/null +++ b/base_noupdata/src/main/res/layout/activity_notifylist.xml @@ -0,0 +1,44 @@ + + + + + + + + + + + + + + + + diff --git a/base_noupdata/src/main/res/layout/dialog_action_confirm.xml b/base_noupdata/src/main/res/layout/dialog_action_confirm.xml new file mode 100644 index 0000000..cfe3f0f --- /dev/null +++ b/base_noupdata/src/main/res/layout/dialog_action_confirm.xml @@ -0,0 +1,71 @@ + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/base_noupdata/src/main/res/layout/item_notify_list.xml b/base_noupdata/src/main/res/layout/item_notify_list.xml new file mode 100644 index 0000000..99af181 --- /dev/null +++ b/base_noupdata/src/main/res/layout/item_notify_list.xml @@ -0,0 +1,175 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/base_noupdata/src/main/res/mipmap-hdpi/ic_empty.png b/base_noupdata/src/main/res/mipmap-hdpi/ic_empty.png new file mode 100644 index 0000000..72473d6 Binary files /dev/null and b/base_noupdata/src/main/res/mipmap-hdpi/ic_empty.png differ diff --git a/base_noupdata/src/main/res/mipmap-hdpi/ic_pull_down.png b/base_noupdata/src/main/res/mipmap-hdpi/ic_pull_down.png new file mode 100644 index 0000000..7dc0ec3 Binary files /dev/null and b/base_noupdata/src/main/res/mipmap-hdpi/ic_pull_down.png differ diff --git a/base_noupdata/src/main/res/mipmap-xhdpi/ic_close.png b/base_noupdata/src/main/res/mipmap-xhdpi/ic_close.png new file mode 100644 index 0000000..c0b0127 Binary files /dev/null and b/base_noupdata/src/main/res/mipmap-xhdpi/ic_close.png differ diff --git a/base_noupdata/src/main/res/mipmap-xhdpi/ic_email.png b/base_noupdata/src/main/res/mipmap-xhdpi/ic_email.png new file mode 100644 index 0000000..9fc3a42 Binary files /dev/null and b/base_noupdata/src/main/res/mipmap-xhdpi/ic_email.png differ diff --git a/base_noupdata/src/main/res/mipmap-xhdpi/ic_email1.png b/base_noupdata/src/main/res/mipmap-xhdpi/ic_email1.png new file mode 100644 index 0000000..9fc3a42 Binary files /dev/null and b/base_noupdata/src/main/res/mipmap-xhdpi/ic_email1.png differ diff --git a/base_noupdata/src/main/res/mipmap-xhdpi/ic_facebook.png b/base_noupdata/src/main/res/mipmap-xhdpi/ic_facebook.png new file mode 100644 index 0000000..de378dc Binary files /dev/null and b/base_noupdata/src/main/res/mipmap-xhdpi/ic_facebook.png differ diff --git a/base_noupdata/src/main/res/mipmap-xhdpi/ic_hometo.png b/base_noupdata/src/main/res/mipmap-xhdpi/ic_hometo.png new file mode 100644 index 0000000..4e93043 Binary files /dev/null and b/base_noupdata/src/main/res/mipmap-xhdpi/ic_hometo.png differ diff --git a/base_noupdata/src/main/res/mipmap-xhdpi/ic_link.png b/base_noupdata/src/main/res/mipmap-xhdpi/ic_link.png new file mode 100644 index 0000000..2f98612 Binary files /dev/null and b/base_noupdata/src/main/res/mipmap-xhdpi/ic_link.png differ diff --git a/base_noupdata/src/main/res/mipmap-xhdpi/ic_menu.png b/base_noupdata/src/main/res/mipmap-xhdpi/ic_menu.png new file mode 100644 index 0000000..2b55ec5 Binary files /dev/null and b/base_noupdata/src/main/res/mipmap-xhdpi/ic_menu.png differ diff --git a/base_noupdata/src/main/res/mipmap-xhdpi/ic_notify_email.png b/base_noupdata/src/main/res/mipmap-xhdpi/ic_notify_email.png new file mode 100644 index 0000000..5a2df8e Binary files /dev/null and b/base_noupdata/src/main/res/mipmap-xhdpi/ic_notify_email.png differ diff --git a/base_noupdata/src/main/res/mipmap-xhdpi/ic_notify_normal.png b/base_noupdata/src/main/res/mipmap-xhdpi/ic_notify_normal.png new file mode 100644 index 0000000..f056d32 Binary files /dev/null and b/base_noupdata/src/main/res/mipmap-xhdpi/ic_notify_normal.png differ diff --git a/base_noupdata/src/main/res/mipmap-xhdpi/ic_notify_shangla.png b/base_noupdata/src/main/res/mipmap-xhdpi/ic_notify_shangla.png new file mode 100644 index 0000000..eb1d3e9 Binary files /dev/null and b/base_noupdata/src/main/res/mipmap-xhdpi/ic_notify_shangla.png differ diff --git a/base_noupdata/src/main/res/mipmap-xhdpi/ic_notify_xiala.png b/base_noupdata/src/main/res/mipmap-xhdpi/ic_notify_xiala.png new file mode 100644 index 0000000..7999f63 Binary files /dev/null and b/base_noupdata/src/main/res/mipmap-xhdpi/ic_notify_xiala.png differ diff --git a/base_noupdata/src/main/res/mipmap-xhdpi/ic_notifylogo.png b/base_noupdata/src/main/res/mipmap-xhdpi/ic_notifylogo.png new file mode 100644 index 0000000..b975e45 Binary files /dev/null and b/base_noupdata/src/main/res/mipmap-xhdpi/ic_notifylogo.png differ diff --git a/base_noupdata/src/main/res/mipmap-xhdpi/ic_notifylogo_img.png b/base_noupdata/src/main/res/mipmap-xhdpi/ic_notifylogo_img.png new file mode 100644 index 0000000..e78b250 Binary files /dev/null and b/base_noupdata/src/main/res/mipmap-xhdpi/ic_notifylogo_img.png differ diff --git a/base_noupdata/src/main/res/mipmap-xhdpi/ic_notifylogo_link.png b/base_noupdata/src/main/res/mipmap-xhdpi/ic_notifylogo_link.png new file mode 100644 index 0000000..3d09922 Binary files /dev/null and b/base_noupdata/src/main/res/mipmap-xhdpi/ic_notifylogo_link.png differ diff --git a/base_noupdata/src/main/res/mipmap-xhdpi/ic_shousuo.png b/base_noupdata/src/main/res/mipmap-xhdpi/ic_shousuo.png new file mode 100644 index 0000000..16b38be Binary files /dev/null and b/base_noupdata/src/main/res/mipmap-xhdpi/ic_shousuo.png differ diff --git a/base_noupdata/src/main/res/mipmap-xhdpi/ic_tel.png b/base_noupdata/src/main/res/mipmap-xhdpi/ic_tel.png new file mode 100644 index 0000000..df82270 Binary files /dev/null and b/base_noupdata/src/main/res/mipmap-xhdpi/ic_tel.png differ diff --git a/base_noupdata/src/main/res/mipmap-xhdpi/ic_whatsapp.png b/base_noupdata/src/main/res/mipmap-xhdpi/ic_whatsapp.png new file mode 100644 index 0000000..7ca41ed Binary files /dev/null and b/base_noupdata/src/main/res/mipmap-xhdpi/ic_whatsapp.png differ diff --git a/base_noupdata/src/main/res/mipmap-xhdpi/ic_zhangkai.png b/base_noupdata/src/main/res/mipmap-xhdpi/ic_zhangkai.png new file mode 100644 index 0000000..bdc84b3 Binary files /dev/null and b/base_noupdata/src/main/res/mipmap-xhdpi/ic_zhangkai.png differ diff --git a/base_noupdata/src/main/res/mipmap-xxhdpi/app_logo.png b/base_noupdata/src/main/res/mipmap-xxhdpi/app_logo.png new file mode 100644 index 0000000..9cca57b Binary files /dev/null and b/base_noupdata/src/main/res/mipmap-xxhdpi/app_logo.png differ diff --git a/base_noupdata/src/main/res/mipmap-xxhdpi/look_img.png b/base_noupdata/src/main/res/mipmap-xxhdpi/look_img.png new file mode 100644 index 0000000..bb76ba1 Binary files /dev/null and b/base_noupdata/src/main/res/mipmap-xxhdpi/look_img.png differ diff --git a/base_noupdata/src/main/res/mipmap-xxhdpi/share_img.png b/base_noupdata/src/main/res/mipmap-xxhdpi/share_img.png new file mode 100644 index 0000000..203b4b7 Binary files /dev/null and b/base_noupdata/src/main/res/mipmap-xxhdpi/share_img.png differ diff --git a/base_noupdata/src/main/res/values-en/strings.xml b/base_noupdata/src/main/res/values-en/strings.xml new file mode 100644 index 0000000..829e9ce --- /dev/null +++ b/base_noupdata/src/main/res/values-en/strings.xml @@ -0,0 +1,59 @@ + + Please Set Your Password + Cancel + Sure + New Version Update + Next Update + Update Immediately + Click to close notification + Click to re-download + Download failed + Click to install + Download completed + Downloading... + Version update + Downloading game + Getting download data... + Version update + Downloading game + Need to turn on mobile phone notification permission + Exit + Setting + Tip + Please enter the invitation code + My invitation code: + Superior invitation code: + Total number of invites: + App download link: + Share + Check Invitation Records + Invitation Records + Total number of invitees: %d + No Data + Withdrawal Record + Withdrawal Application + Edit Bank Card Information + 60 + Name: + Please enter the bank card name + Bank card account: + Please enter the bank card account + Country: + Please select a country + Bank Name: + Please select a bank name + Note: Please enter the country code before selecting the bank name! + Balance: %s + Total Earnings: %s + Amount: %s + Please enter the withdrawal amount + Withdrawal application has been submitted + No additional data available for now + NOTIFICATIONS + Loading… + Text + Image + Jump link + + + \ No newline at end of file diff --git a/base_noupdata/src/main/res/values/colors.xml b/base_noupdata/src/main/res/values/colors.xml new file mode 100644 index 0000000..ada1b30 --- /dev/null +++ b/base_noupdata/src/main/res/values/colors.xml @@ -0,0 +1,26 @@ + + + #FFFFFF + #FFFFFF + #FFFFFF + #FF03DAC5 + #FF018786 + #FF000000 + #FFFFFFFF + #EF4723 + #FFFFFFFF + + #2C2C2E + #FFA722 + #434343 + #BCBCBC + + #ACDFEE + #BDDDB7 + #C3B5D0 + #000000 + #000000 + + + + \ No newline at end of file diff --git a/base_noupdata/src/main/res/values/strings.xml b/base_noupdata/src/main/res/values/strings.xml new file mode 100644 index 0000000..17a082d --- /dev/null +++ b/base_noupdata/src/main/res/values/strings.xml @@ -0,0 +1,60 @@ + + 请输入6位密码 + 取消 + 确定 + 版本更新 + 下次更新 + 立即更新 + 点击关闭通知 + 点击重新下载 + 下载失败 + 点击安装 + 下载完成 + 正在下载… + 版本更新 + 下载游戏中 + 版本更新 + 下载游戏中 + 正在获取下载数据… + 需要打开手机通知权限 + 退出 + 设置 + 提示 + 请输入邀请码 + 我的邀请码: + 上级邀请码: + 总邀请人数: + 邀请您下载: + 分享 + 查看邀请记录 + 邀请记录 + 总邀请人数: %d + 暂无数据 + 提现记录 + 提现申请 + 编辑银行卡信息 + 86 + 持卡人姓名: + 请输入持卡人姓名 + 国家地区: + 请选择国家地区 + 开户行名称: + 请选择开户行名称 + 银行户口: + 请输入银行卡户口 + (注:请先输入国家区号再选择开户行名称!) + 余额: %s + 总收益: %s + 金额: %s + 请输入提现金额 + 提现申请已提交 + 暂无更多数据 + 通知 + Loading… + 文本 + 图片 + 链接 + + + + \ No newline at end of file diff --git a/base_noupdata/src/main/res/values/themes.xml b/base_noupdata/src/main/res/values/themes.xml new file mode 100644 index 0000000..e47899f --- /dev/null +++ b/base_noupdata/src/main/res/values/themes.xml @@ -0,0 +1,88 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/base_noupdata/src/main/res/xml/app_updater_paths.xml b/base_noupdata/src/main/res/xml/app_updater_paths.xml new file mode 100644 index 0000000..1254450 --- /dev/null +++ b/base_noupdata/src/main/res/xml/app_updater_paths.xml @@ -0,0 +1,10 @@ + + + + + + + + + + \ No newline at end of file diff --git a/base_noupdata/src/main/res/xml/network_security_config.xml b/base_noupdata/src/main/res/xml/network_security_config.xml new file mode 100644 index 0000000..dca93c0 --- /dev/null +++ b/base_noupdata/src/main/res/xml/network_security_config.xml @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/base_noupdata/src/main/res/xml/provider_paths.xml b/base_noupdata/src/main/res/xml/provider_paths.xml new file mode 100644 index 0000000..c9a897a --- /dev/null +++ b/base_noupdata/src/main/res/xml/provider_paths.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/build.gradle b/build.gradle new file mode 100644 index 0000000..16d2c7b --- /dev/null +++ b/build.gradle @@ -0,0 +1,11 @@ +// Top-level build file where you can add configuration options common to all sub-projects/modules. +plugins { + alias(libs.plugins.android.application) apply false + id 'com.google.gms.google-services' version '4.3.15' apply false +} + +ext { + outputPath = "F:/webApp2" + versionCode = 133 + versionName = "v1.3.3" +} \ No newline at end of file diff --git a/cucislot365/.gitignore b/cucislot365/.gitignore new file mode 100644 index 0000000..956c004 --- /dev/null +++ b/cucislot365/.gitignore @@ -0,0 +1,2 @@ +/build +/release \ No newline at end of file diff --git a/cucislot365/build.gradle b/cucislot365/build.gradle new file mode 100644 index 0000000..e606973 --- /dev/null +++ b/cucislot365/build.gradle @@ -0,0 +1,96 @@ +plugins { + id 'com.android.application' + id 'com.google.gms.google-services' +} + +def appOutPutName = "cucislotjehtjuewrhrrregrgg" + +android { + namespace "com.webclip.base" + compileSdk 36 + defaultConfig { + minSdkVersion 24 + targetSdk 36 + versionName rootProject.ext.versionName + versionCode rootProject.ext.versionCode + + testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" + + //包名 + applicationId "com.xyz.cucislot365" + //app大背景色 + resValue('color', 'windows_color', '#fdfdfe') + //底部导航栏颜色 大背景颜色为 windows_color——style_color的上下渐变色 + resValue('color', 'style_color', '#1f3681') + + //app 名字 + resValue('string', 'app_name', 'CUCISLOT365') + //app ID + //预埋订阅网址 + + buildConfigField "String", "BASE_URL", "\"https://cucislot365.com/\"" + buildConfigField "int", "USERID", "242" + buildConfigField "boolean", "IS_WHITE", "false" + buildConfigField "boolean", "IS_ROUND", "false" + buildConfigField "int", "ROUND_RADIUS", "0" + buildConfigField "boolean", "HAS_CONTACT", "false" + buildConfigField "boolean", "HAS_HOOK", "false" + + } + buildFeatures { + buildConfig = true + } + + signingConfigs { + debug { + storeFile file('justlet.jks') + storePassword "123456" + keyAlias 'key0' + keyPassword "123456" + } + release { + storeFile file('justlet.jks') + storePassword "123456" + keyAlias 'key0' + keyPassword "123456" + } + } + + buildTypes { + release { + signingConfig signingConfigs.release + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' + } + } + compileOptions { + sourceCompatibility JavaVersion.VERSION_17 + targetCompatibility JavaVersion.VERSION_17 + } + + applicationVariants.all { variant -> + variant.outputs.all { + def outputDir = new File(rootProject.ext.outputPath) + outputDir.mkdirs() + def outputFileName = "${appOutPutName}.apk" + setOutputFileName(outputFileName) + def newOutputFile = new File(outputDir, outputFileName) + newOutputFile.parentFile.mkdirs() + variant.assemble.doLast { + try { + java.nio.file.Files.copy( + outputFile.toPath(), + newOutputFile.toPath(), + java.nio.file.StandardCopyOption.REPLACE_EXISTING + ) + } catch (java.io.IOException e) { + } + } + } + } + +} + +dependencies { + implementation project(path: ':base') +} \ No newline at end of file diff --git a/cucislot365/google-services.json b/cucislot365/google-services.json new file mode 100644 index 0000000..fb7f241 --- /dev/null +++ b/cucislot365/google-services.json @@ -0,0 +1,29 @@ +{ + "project_info": { + "project_number": "719624001236", + "project_id": "cusl365", + "storage_bucket": "cusl365.firebasestorage.app" + }, + "client": [ + { + "client_info": { + "mobilesdk_app_id": "1:719624001236:android:56a13fcef8eacbc1a84d41", + "android_client_info": { + "package_name": "com.xyz.cucislot365" + } + }, + "oauth_client": [], + "api_key": [ + { + "current_key": "AIzaSyD8RyUgAzvT9tN0P00dgOq1414c463bKPw" + } + ], + "services": { + "appinvite_service": { + "other_platform_oauth_client": [] + } + } + } + ], + "configuration_version": "1" +} \ No newline at end of file diff --git a/cucislot365/justlet.jks b/cucislot365/justlet.jks new file mode 100644 index 0000000..a33b839 Binary files /dev/null and b/cucislot365/justlet.jks differ diff --git a/cucislot365/proguard-rules.pro b/cucislot365/proguard-rules.pro new file mode 100644 index 0000000..107b7ee --- /dev/null +++ b/cucislot365/proguard-rules.pro @@ -0,0 +1,32 @@ +# 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 + +-dontwarn dalvik.** +-dontwarn com.tencent.smtt.** + +-keep class com.tencent.smtt.** { + *; +} + +-keep class com.tencent.tbs.** { + *; +} \ No newline at end of file diff --git a/cucislot365/src/main/AndroidManifest.xml b/cucislot365/src/main/AndroidManifest.xml new file mode 100644 index 0000000..7cbc0e0 --- /dev/null +++ b/cucislot365/src/main/AndroidManifest.xml @@ -0,0 +1,67 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/cucislot365/src/main/java/com/webclip/base/IndexActivity.java b/cucislot365/src/main/java/com/webclip/base/IndexActivity.java new file mode 100644 index 0000000..612ecad --- /dev/null +++ b/cucislot365/src/main/java/com/webclip/base/IndexActivity.java @@ -0,0 +1,78 @@ +package com.webclip.base; + +import android.os.Bundle; + +import com.google.firebase.messaging.FirebaseMessaging; + +public class IndexActivity extends MainActivity { + + @Override + protected void onCreate(Bundle savedInstanceState) { + initConfig(); + super.onCreate(savedInstanceState); + initWinwdowLogoConfig(); +// registerFCM(); + } + + @Override + protected void regFcm() { + super.regFcm(); + registerFCM(); + } + + /** + * 注册FCM + */ + private void registerFCM() { + //订阅主题 + LogUtils.i("支持FCM 去注册"); + try { + FirebaseMessaging.getInstance().subscribeToTopic("demo") + .addOnCompleteListener(task -> { + String msg = "Subscribed"; + if (!task.isSuccessful()) { + msg = "Subscribe failed"; + }else{ + checkNotify(); + } + LogUtils.i("支持FCM 结果:"+msg); + }); + }catch (Exception e){ + e.printStackTrace(); + LogUtils.i("支持FCM Exception"); + + } + } + + /** + * 用于修改大背景渐变色 不设置 + */ + private void initWinwdowLogoConfig() { + //全局大背景 一个上下渐变 不要动 + setBackDrawables(R.drawable.big_bg); + setImageView(BuildConfig.IS_ROUND,BuildConfig.ROUND_RADIUS); + getWindow().getDecorView().setBackgroundResource(R.drawable.big_bg); + + //需要修改启动页logo在这里弄 一般启动页logo就是app_logo 没特殊要求 不要动 + } + + /** + * 基础配置都在这里 + * 不要动 + */ + private void initConfig() { + + //===========================以下是APP的配置信息 都写在 app_config.xml中================================== + userId = BuildConfig.USERID; + saveInt(IndexActivity.this,"user_code",userId); + saveString(this, "base_url",BuildConfig.BASE_URL); + styleColor = getColor(R.color.style_color); + windowsColor = getColor(R.color.windows_color); + isWhite = BuildConfig.IS_WHITE; + hasContact = BuildConfig.HAS_CONTACT; + hasHook = BuildConfig.HAS_HOOK; + + //===========================以上是APP的配置信息 都写在 app_config.xml中================================== + } + +} diff --git a/cucislot365/src/main/java/com/webclip/base/MyFirebaseMessageingService.java b/cucislot365/src/main/java/com/webclip/base/MyFirebaseMessageingService.java new file mode 100644 index 0000000..36f2d65 --- /dev/null +++ b/cucislot365/src/main/java/com/webclip/base/MyFirebaseMessageingService.java @@ -0,0 +1,125 @@ +package com.webclip.base; + +import android.app.NotificationChannel; +import android.app.NotificationManager; +import android.app.PendingIntent; +import android.content.ComponentName; +import android.content.Context; +import android.content.Intent; +import android.os.Build; +import androidx.annotation.NonNull; +import androidx.core.app.NotificationCompat; +import com.google.firebase.messaging.FirebaseMessagingService; +import com.google.firebase.messaging.RemoteMessage; +import com.google.gson.Gson; +import com.webclip.base.GsonUtils; +import com.webclip.base.MessageInfo; +import java.util.Map; +import java.util.Random; + +public class MyFirebaseMessageingService extends FirebaseMessagingService { + + public MyFirebaseMessageingService() { + } + + @Override + public void onMessageReceived(@NonNull RemoteMessage remoteMessage) { + super.onMessageReceived(remoteMessage); + Map serviceData = remoteMessage.getData(); //后台推送数据 + if (serviceData != null && serviceData.containsKey("message")) { + String value = serviceData.get("message"); + Gson gson = new Gson(); + MessageInfo messageInfo = gson.fromJson(value, MessageInfo.class); + showNotification(messageInfo); + } else { + //收到通知 创建notify + if (remoteMessage.getNotification() != null) { + showNotification(remoteMessage.getNotification().getTitle(), remoteMessage.getNotification().getBody()); + } + } + } + + private void showNotification(MessageInfo messageInfo) { + Intent notifyIntent = new Intent(this, IndexActivity.class); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.CUPCAKE) { + ComponentName launchComponent = null; + launchComponent = getApplication() + .getPackageManager() + .getLaunchIntentForPackage(getApplication().getPackageName()) + .getComponent(); + notifyIntent.setComponent(launchComponent); + } + notifyIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP); + notifyIntent.setAction(Intent.ACTION_VIEW); + notifyIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); // 必须 + notifyIntent.putExtra("message", messageInfo); + PendingIntent pendingIntent = PendingIntent.getActivity(this, new Random().nextInt(10000), notifyIntent, PendingIntent.FLAG_IMMUTABLE); + NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); + NotificationChannel channelwinway = null; + NotificationCompat.Builder notificationBuilder = null; + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + channelwinway = new NotificationChannel(getString(R.string.app_name), "notify", NotificationManager.IMPORTANCE_DEFAULT); + channelwinway.enableLights(true); + channelwinway.enableVibration(true); + notificationManager.createNotificationChannel(channelwinway); + notificationBuilder = new NotificationCompat.Builder(this, channelwinway.getId()) + .setSmallIcon(R.mipmap.app_logo) + .setContentTitle(messageInfo.getTitle()) + .setContentText(messageInfo.getContent()) + .setAutoCancel(true) + .setContentIntent(pendingIntent); + } else { + notificationBuilder = new NotificationCompat.Builder(this, getString(R.string.app_name)) + .setSmallIcon(R.mipmap.app_logo) + .setContentTitle(messageInfo.getTitle()) + .setContentText(messageInfo.getContent()) + .setAutoCancel(true) + .setContentIntent(pendingIntent); + } + notificationManager.notify(0, notificationBuilder.build()); + } + + private void showNotification(String title, String body) { + Intent notifyIntent = new Intent(this, IndexActivity.class); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.CUPCAKE) { + ComponentName launchComponent = null; + launchComponent = getApplication() + .getPackageManager() + .getLaunchIntentForPackage(getApplication().getPackageName()) + .getComponent(); + notifyIntent.setComponent(launchComponent); + } + notifyIntent.putExtra("message", body); + notifyIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP); + notifyIntent.setAction(Intent.ACTION_VIEW); + notifyIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); // 必须 + PendingIntent pendingIntent = PendingIntent.getActivity(this, new Random().nextInt(10000), notifyIntent, PendingIntent.FLAG_IMMUTABLE); + NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); + NotificationChannel channelwinway = null; + NotificationCompat.Builder notificationBuilder = null; + MessageInfo messageInfo = GsonUtils.getObjFromJSON(body, MessageInfo.class); + if (messageInfo != null) { + body = messageInfo.getContent(); + } + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + channelwinway = new NotificationChannel(getString(R.string.app_name), "notify", NotificationManager.IMPORTANCE_DEFAULT); + channelwinway.enableLights(true); + channelwinway.enableVibration(true); + notificationManager.createNotificationChannel(channelwinway); + notificationBuilder = new NotificationCompat.Builder(this, channelwinway.getId()) + .setSmallIcon(R.mipmap.app_logo) + .setContentTitle(title) + .setContentText(body) + .setAutoCancel(true) + .setContentIntent(pendingIntent); + } else { + notificationBuilder = new NotificationCompat.Builder(this, getString(R.string.app_name)) + .setSmallIcon(R.mipmap.app_logo) + .setContentTitle(title) + .setContentText(body) + .setAutoCancel(true) + .setContentIntent(pendingIntent); + } + notificationManager.notify(0, notificationBuilder.build()); + } +} diff --git a/cucislot365/src/main/java/com/webclip/base/WebApplication.java b/cucislot365/src/main/java/com/webclip/base/WebApplication.java new file mode 100644 index 0000000..36e2512 --- /dev/null +++ b/cucislot365/src/main/java/com/webclip/base/WebApplication.java @@ -0,0 +1,19 @@ +package com.webclip.base; + +import android.app.Application; +import android.content.Context; + +import com.webclip.base.LogUtils; + +public class WebApplication extends Application { + + + public static Context application; + @Override + public void onCreate() { + super.onCreate(); +// 设置开启优化方案 + application = this; + LogUtils.isDebug = BuildConfig.BUILD_TYPE.equals("debug"); + } +} diff --git a/cucislot365/src/main/res/drawable/big_bg.xml b/cucislot365/src/main/res/drawable/big_bg.xml new file mode 100644 index 0000000..b058f1e --- /dev/null +++ b/cucislot365/src/main/res/drawable/big_bg.xml @@ -0,0 +1,10 @@ + + + + \ No newline at end of file diff --git a/cucislot365/src/main/res/mipmap-xxhdpi/app_logo.png b/cucislot365/src/main/res/mipmap-xxhdpi/app_logo.png new file mode 100644 index 0000000..1b34087 Binary files /dev/null and b/cucislot365/src/main/res/mipmap-xxhdpi/app_logo.png differ diff --git a/cucislot365/src/main/res/values/themes.xml b/cucislot365/src/main/res/values/themes.xml new file mode 100644 index 0000000..f1ef249 --- /dev/null +++ b/cucislot365/src/main/res/values/themes.xml @@ -0,0 +1,91 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/cucislot365/src/main/res/xml/app_updater_paths.xml b/cucislot365/src/main/res/xml/app_updater_paths.xml new file mode 100644 index 0000000..1254450 --- /dev/null +++ b/cucislot365/src/main/res/xml/app_updater_paths.xml @@ -0,0 +1,10 @@ + + + + + + + + + + \ No newline at end of file diff --git a/cucislot365/src/main/res/xml/network_security_config.xml b/cucislot365/src/main/res/xml/network_security_config.xml new file mode 100644 index 0000000..dca93c0 --- /dev/null +++ b/cucislot365/src/main/res/xml/network_security_config.xml @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/cucislot365/src/main/res/xml/provider_paths.xml b/cucislot365/src/main/res/xml/provider_paths.xml new file mode 100644 index 0000000..c9a897a --- /dev/null +++ b/cucislot365/src/main/res/xml/provider_paths.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/gradle.properties b/gradle.properties new file mode 100644 index 0000000..4387edc --- /dev/null +++ b/gradle.properties @@ -0,0 +1,21 @@ +# Project-wide Gradle settings. +# IDE (e.g. Android Studio) users: +# Gradle settings configured through the IDE *will override* +# any settings specified in this file. +# For more details on how to configure your build environment visit +# http://www.gradle.org/docs/current/userguide/build_environment.html +# Specifies the JVM arguments used for the daemon process. +# The setting is particularly useful for tweaking memory settings. +org.gradle.jvmargs=-Xmx2048m -Dfile.encoding=UTF-8 +# When configured, Gradle will run in incubating parallel mode. +# This option should only be used with decoupled projects. For more details, visit +# https://developer.android.com/r/tools/gradle-multi-project-decoupled-projects +# org.gradle.parallel=true +# AndroidX package structure to make it clearer which packages are bundled with the +# Android operating system, and which are packaged with your app's APK +# https://developer.android.com/topic/libraries/support-library/androidx-rn +android.useAndroidX=true +# Enables namespacing of each library's R class so that its R class includes only the +# resources declared in the library itself and none from the library's dependencies, +# thereby reducing the size of the R class for that library +android.nonTransitiveRClass=true \ No newline at end of file diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml new file mode 100644 index 0000000..15443c0 --- /dev/null +++ b/gradle/libs.versions.toml @@ -0,0 +1,26 @@ +[versions] +agp = "8.11.0" +junit = "4.13.2" +junitVersion = "1.1.5" +espressoCore = "3.5.1" +appcompat = "1.6.1" +material = "1.10.0" +activity = "1.8.0" +constraintlayout = "2.1.4" +playServicesBase = "18.10.0" +viewpager2 = "1.1.0" + +[libraries] +junit = { group = "junit", name = "junit", version.ref = "junit" } +ext-junit = { group = "androidx.test.ext", name = "junit", version.ref = "junitVersion" } +espresso-core = { group = "androidx.test.espresso", name = "espresso-core", version.ref = "espressoCore" } +appcompat = { group = "androidx.appcompat", name = "appcompat", version.ref = "appcompat" } +material = { group = "com.google.android.material", name = "material", version.ref = "material" } +activity = { group = "androidx.activity", name = "activity", version.ref = "activity" } +constraintlayout = { group = "androidx.constraintlayout", name = "constraintlayout", version.ref = "constraintlayout" } +play-services-base = { group = "com.google.android.gms", name = "play-services-base", version.ref = "playServicesBase" } +viewpager2 = { group = "androidx.viewpager2", name = "viewpager2", version.ref = "viewpager2" } + +[plugins] +android-application = { id = "com.android.application", version.ref = "agp" } + diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 0000000..e708b1c Binary files /dev/null and b/gradle/wrapper/gradle-wrapper.jar differ diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 0000000..f7bf3d1 --- /dev/null +++ b/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,6 @@ +#Mon Mar 09 14:34:00 CST 2026 +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-8.13-bin.zip +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists diff --git a/gradlew b/gradlew new file mode 100644 index 0000000..4f906e0 --- /dev/null +++ b/gradlew @@ -0,0 +1,185 @@ +#!/usr/bin/env sh + +# +# Copyright 2015 the original author or authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +############################################################################## +## +## Gradle start up script for UN*X +## +############################################################################## + +# Attempt to set APP_HOME +# Resolve links: $0 may be a link +PRG="$0" +# Need this for relative symlinks. +while [ -h "$PRG" ] ; do + ls=`ls -ld "$PRG"` + link=`expr "$ls" : '.*-> \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + PRG="$link" + else + PRG=`dirname "$PRG"`"/$link" + fi +done +SAVED="`pwd`" +cd "`dirname \"$PRG\"`/" >/dev/null +APP_HOME="`pwd -P`" +cd "$SAVED" >/dev/null + +APP_NAME="Gradle" +APP_BASE_NAME=`basename "$0"` + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD="maximum" + +warn () { + echo "$*" +} + +die () { + echo + echo "$*" + echo + exit 1 +} + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +nonstop=false +case "`uname`" in + CYGWIN* ) + cygwin=true + ;; + Darwin* ) + darwin=true + ;; + MINGW* ) + msys=true + ;; + NONSTOP* ) + nonstop=true + ;; +esac + +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD="$JAVA_HOME/jre/sh/java" + else + JAVACMD="$JAVA_HOME/bin/java" + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD="java" + which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." +fi + +# Increase the maximum file descriptors if we can. +if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then + MAX_FD_LIMIT=`ulimit -H -n` + if [ $? -eq 0 ] ; then + if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then + MAX_FD="$MAX_FD_LIMIT" + fi + ulimit -n $MAX_FD + if [ $? -ne 0 ] ; then + warn "Could not set maximum file descriptor limit: $MAX_FD" + fi + else + warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" + fi +fi + +# For Darwin, add options to specify how the application appears in the dock +if $darwin; then + GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" +fi + +# For Cygwin or MSYS, switch paths to Windows format before running java +if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then + APP_HOME=`cygpath --path --mixed "$APP_HOME"` + CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` + + JAVACMD=`cygpath --unix "$JAVACMD"` + + # We build the pattern for arguments to be converted via cygpath + ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` + SEP="" + for dir in $ROOTDIRSRAW ; do + ROOTDIRS="$ROOTDIRS$SEP$dir" + SEP="|" + done + OURCYGPATTERN="(^($ROOTDIRS))" + # Add a user-defined pattern to the cygpath arguments + if [ "$GRADLE_CYGPATTERN" != "" ] ; then + OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" + fi + # Now convert the arguments - kludge to limit ourselves to /bin/sh + i=0 + for arg in "$@" ; do + CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` + CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option + + if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition + eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` + else + eval `echo args$i`="\"$arg\"" + fi + i=`expr $i + 1` + done + case $i in + 0) set -- ;; + 1) set -- "$args0" ;; + 2) set -- "$args0" "$args1" ;; + 3) set -- "$args0" "$args1" "$args2" ;; + 4) set -- "$args0" "$args1" "$args2" "$args3" ;; + 5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; + 6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; + 7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; + 8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; + 9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; + esac +fi + +# Escape application args +save () { + for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done + echo " " +} +APP_ARGS=`save "$@"` + +# Collect all arguments for the java command, following the shell quoting and substitution rules +eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" + +exec "$JAVACMD" "$@" diff --git a/gradlew.bat b/gradlew.bat new file mode 100644 index 0000000..107acd3 --- /dev/null +++ b/gradlew.bat @@ -0,0 +1,89 @@ +@rem +@rem Copyright 2015 the original author or authors. +@rem +@rem Licensed under the Apache License, Version 2.0 (the "License"); +@rem you may not use this file except in compliance with the License. +@rem You may obtain a copy of the License at +@rem +@rem https://www.apache.org/licenses/LICENSE-2.0 +@rem +@rem Unless required by applicable law or agreed to in writing, software +@rem distributed under the License is distributed on an "AS IS" BASIS, +@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +@rem See the License for the specific language governing permissions and +@rem limitations under the License. +@rem + +@if "%DEBUG%" == "" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%" == "" set DIRNAME=. +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Resolve any "." and ".." in APP_HOME to make it shorter. +for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if "%ERRORLEVEL%" == "0" goto execute + +echo. +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto execute + +echo. +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* + +:end +@rem End local scope for the variables with windows NT shell +if "%ERRORLEVEL%"=="0" goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 +exit /b 1 + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/lorongjudi33/.gitignore b/lorongjudi33/.gitignore new file mode 100644 index 0000000..956c004 --- /dev/null +++ b/lorongjudi33/.gitignore @@ -0,0 +1,2 @@ +/build +/release \ No newline at end of file diff --git a/lorongjudi33/build.gradle b/lorongjudi33/build.gradle new file mode 100644 index 0000000..a3a5747 --- /dev/null +++ b/lorongjudi33/build.gradle @@ -0,0 +1,94 @@ +plugins { + id 'com.android.application' + id 'com.google.gms.google-services' +} + +//app打包后的输出包名 防封乱码包名 +def appOutPutName = "lorongjudi33dgkdfklgjdkfljghkdf" + +android { + namespace "com.webclip.base" + compileSdk 36 + defaultConfig { + minSdkVersion 24 + targetSdk 36 + versionCode rootProject.ext.versionCode + versionName rootProject.ext.versionName + testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" + + //包名 + applicationId "com.xyz.lorongjudi33" + //app大背景色 + resValue('color', 'windows_color', '#fff7e3') + //底部导航栏颜色 大背景颜色为 windows_color——style_color的上下渐变色 + resValue('color', 'style_color', '#7a1801') + //app 名字 + resValue('string', 'app_name', 'LORONGJUDI33') + + buildConfigField "String", "BASE_URL", "\"https://lorongjudi33.com/\"" + buildConfigField "int", "USERID", "252" + buildConfigField "boolean", "IS_WHITE", "false" + buildConfigField "boolean", "IS_ROUND", "false" + buildConfigField "int", "ROUND_RADIUS", "0" + buildConfigField "boolean", "HAS_CONTACT", "false" + buildConfigField "boolean", "HAS_HOOK", "false" + + + } + buildFeatures { + buildConfig = true + } + + signingConfigs { + debug { + storeFile file('justlet.jks') + storePassword "123456" + keyAlias 'key0' + keyPassword "123456" + } + release { + storeFile file('justlet.jks') + storePassword "123456" + keyAlias 'key0' + keyPassword "123456" + } + } + + buildTypes { + release { + signingConfig signingConfigs.release + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' + } + } + compileOptions { + sourceCompatibility JavaVersion.VERSION_17 + targetCompatibility JavaVersion.VERSION_17 + } + + applicationVariants.all { variant -> + variant.outputs.all { + def outputDir = new File(rootProject.ext.outputPath) + outputDir.mkdirs() + def outputFileName = "${appOutPutName}.apk" + setOutputFileName(outputFileName) + def newOutputFile = new File(outputDir, outputFileName) + newOutputFile.parentFile.mkdirs() + variant.assemble.doLast { + try { + java.nio.file.Files.copy( + outputFile.toPath(), + newOutputFile.toPath(), + java.nio.file.StandardCopyOption.REPLACE_EXISTING + ) + } catch (java.io.IOException e) { + } + } + } + } + +} + +dependencies { + implementation project(path: ':base') +} \ No newline at end of file diff --git a/lorongjudi33/google-services.json b/lorongjudi33/google-services.json new file mode 100644 index 0000000..bdf9ab5 --- /dev/null +++ b/lorongjudi33/google-services.json @@ -0,0 +1,29 @@ +{ + "project_info": { + "project_number": "912762941809", + "project_id": "lorongjudi33", + "storage_bucket": "lorongjudi33.firebasestorage.app" + }, + "client": [ + { + "client_info": { + "mobilesdk_app_id": "1:912762941809:android:f4162e54799a01cc9846d0", + "android_client_info": { + "package_name": "com.xyz.lorongjudi33" + } + }, + "oauth_client": [], + "api_key": [ + { + "current_key": "AIzaSyAn_t-m1aHLl7gvQ82ULyonka5dfCvKc_g" + } + ], + "services": { + "appinvite_service": { + "other_platform_oauth_client": [] + } + } + } + ], + "configuration_version": "1" +} \ No newline at end of file diff --git a/lorongjudi33/justlet.jks b/lorongjudi33/justlet.jks new file mode 100644 index 0000000..a33b839 Binary files /dev/null and b/lorongjudi33/justlet.jks differ diff --git a/lorongjudi33/proguard-rules.pro b/lorongjudi33/proguard-rules.pro new file mode 100644 index 0000000..107b7ee --- /dev/null +++ b/lorongjudi33/proguard-rules.pro @@ -0,0 +1,32 @@ +# 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 + +-dontwarn dalvik.** +-dontwarn com.tencent.smtt.** + +-keep class com.tencent.smtt.** { + *; +} + +-keep class com.tencent.tbs.** { + *; +} \ No newline at end of file diff --git a/lorongjudi33/src/main/AndroidManifest.xml b/lorongjudi33/src/main/AndroidManifest.xml new file mode 100644 index 0000000..7cbc0e0 --- /dev/null +++ b/lorongjudi33/src/main/AndroidManifest.xml @@ -0,0 +1,67 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/lorongjudi33/src/main/java/com/webclip/base/IndexActivity.java b/lorongjudi33/src/main/java/com/webclip/base/IndexActivity.java new file mode 100644 index 0000000..a594f71 --- /dev/null +++ b/lorongjudi33/src/main/java/com/webclip/base/IndexActivity.java @@ -0,0 +1,80 @@ +package com.webclip.base; + +import android.os.Bundle; + +import com.google.firebase.messaging.FirebaseMessaging; + +public class IndexActivity extends MainActivity { + + @Override + protected void onCreate(Bundle savedInstanceState) { + initConfig(); + super.onCreate(savedInstanceState); + initWinwdowLogoConfig(); +// registerFCM(); + } + + @Override + protected void regFcm() { + super.regFcm(); + registerFCM(); + } + + /** + * 注册FCM + */ + private void registerFCM() { + //订阅主题 + LogUtils.i("支持FCM 去注册"); + try { + FirebaseMessaging.getInstance().subscribeToTopic("demo") + .addOnCompleteListener(task -> { + String msg = "Subscribed"; + if (!task.isSuccessful()) { + msg = "Subscribe failed"; + }else{ + checkNotify(); + } + LogUtils.i("支持FCM 结果:"+msg); + }); + }catch (Exception e){ + e.printStackTrace(); + LogUtils.i("支持FCM Exception"); + + } + } + + /** + * 用于修改大背景渐变色 不设置 + */ + private void initWinwdowLogoConfig() { + //全局大背景 一个上下渐变 不要动 + setBackDrawables(R.drawable.big_bg); + setImageView(BuildConfig.IS_ROUND,BuildConfig.ROUND_RADIUS); + getWindow().getDecorView().setBackgroundResource(R.drawable.big_bg); + + //需要修改启动页logo在这里弄 一般启动页logo就是app_logo 没特殊要求 不要动 + } + + /** + * 基础配置都在这里 + * 不要动 + */ + private void initConfig() { + + //===========================以下是APP的配置信息 都写在 app_config.xml中================================== + userId = BuildConfig.USERID; + saveInt(IndexActivity.this,"user_code",userId); + + saveString(this, "base_url",BuildConfig.BASE_URL); + styleColor = getColor(R.color.style_color); + windowsColor = getColor(R.color.windows_color); + isWhite = BuildConfig.IS_WHITE; + hasContact = BuildConfig.HAS_CONTACT; + hasHook = BuildConfig.HAS_HOOK; + + //===========================以上是APP的配置信息 都写在 app_config.xml中================================== + } + + +} diff --git a/lorongjudi33/src/main/java/com/webclip/base/MyFirebaseMessageingService.java b/lorongjudi33/src/main/java/com/webclip/base/MyFirebaseMessageingService.java new file mode 100644 index 0000000..36f2d65 --- /dev/null +++ b/lorongjudi33/src/main/java/com/webclip/base/MyFirebaseMessageingService.java @@ -0,0 +1,125 @@ +package com.webclip.base; + +import android.app.NotificationChannel; +import android.app.NotificationManager; +import android.app.PendingIntent; +import android.content.ComponentName; +import android.content.Context; +import android.content.Intent; +import android.os.Build; +import androidx.annotation.NonNull; +import androidx.core.app.NotificationCompat; +import com.google.firebase.messaging.FirebaseMessagingService; +import com.google.firebase.messaging.RemoteMessage; +import com.google.gson.Gson; +import com.webclip.base.GsonUtils; +import com.webclip.base.MessageInfo; +import java.util.Map; +import java.util.Random; + +public class MyFirebaseMessageingService extends FirebaseMessagingService { + + public MyFirebaseMessageingService() { + } + + @Override + public void onMessageReceived(@NonNull RemoteMessage remoteMessage) { + super.onMessageReceived(remoteMessage); + Map serviceData = remoteMessage.getData(); //后台推送数据 + if (serviceData != null && serviceData.containsKey("message")) { + String value = serviceData.get("message"); + Gson gson = new Gson(); + MessageInfo messageInfo = gson.fromJson(value, MessageInfo.class); + showNotification(messageInfo); + } else { + //收到通知 创建notify + if (remoteMessage.getNotification() != null) { + showNotification(remoteMessage.getNotification().getTitle(), remoteMessage.getNotification().getBody()); + } + } + } + + private void showNotification(MessageInfo messageInfo) { + Intent notifyIntent = new Intent(this, IndexActivity.class); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.CUPCAKE) { + ComponentName launchComponent = null; + launchComponent = getApplication() + .getPackageManager() + .getLaunchIntentForPackage(getApplication().getPackageName()) + .getComponent(); + notifyIntent.setComponent(launchComponent); + } + notifyIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP); + notifyIntent.setAction(Intent.ACTION_VIEW); + notifyIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); // 必须 + notifyIntent.putExtra("message", messageInfo); + PendingIntent pendingIntent = PendingIntent.getActivity(this, new Random().nextInt(10000), notifyIntent, PendingIntent.FLAG_IMMUTABLE); + NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); + NotificationChannel channelwinway = null; + NotificationCompat.Builder notificationBuilder = null; + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + channelwinway = new NotificationChannel(getString(R.string.app_name), "notify", NotificationManager.IMPORTANCE_DEFAULT); + channelwinway.enableLights(true); + channelwinway.enableVibration(true); + notificationManager.createNotificationChannel(channelwinway); + notificationBuilder = new NotificationCompat.Builder(this, channelwinway.getId()) + .setSmallIcon(R.mipmap.app_logo) + .setContentTitle(messageInfo.getTitle()) + .setContentText(messageInfo.getContent()) + .setAutoCancel(true) + .setContentIntent(pendingIntent); + } else { + notificationBuilder = new NotificationCompat.Builder(this, getString(R.string.app_name)) + .setSmallIcon(R.mipmap.app_logo) + .setContentTitle(messageInfo.getTitle()) + .setContentText(messageInfo.getContent()) + .setAutoCancel(true) + .setContentIntent(pendingIntent); + } + notificationManager.notify(0, notificationBuilder.build()); + } + + private void showNotification(String title, String body) { + Intent notifyIntent = new Intent(this, IndexActivity.class); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.CUPCAKE) { + ComponentName launchComponent = null; + launchComponent = getApplication() + .getPackageManager() + .getLaunchIntentForPackage(getApplication().getPackageName()) + .getComponent(); + notifyIntent.setComponent(launchComponent); + } + notifyIntent.putExtra("message", body); + notifyIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP); + notifyIntent.setAction(Intent.ACTION_VIEW); + notifyIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); // 必须 + PendingIntent pendingIntent = PendingIntent.getActivity(this, new Random().nextInt(10000), notifyIntent, PendingIntent.FLAG_IMMUTABLE); + NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); + NotificationChannel channelwinway = null; + NotificationCompat.Builder notificationBuilder = null; + MessageInfo messageInfo = GsonUtils.getObjFromJSON(body, MessageInfo.class); + if (messageInfo != null) { + body = messageInfo.getContent(); + } + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + channelwinway = new NotificationChannel(getString(R.string.app_name), "notify", NotificationManager.IMPORTANCE_DEFAULT); + channelwinway.enableLights(true); + channelwinway.enableVibration(true); + notificationManager.createNotificationChannel(channelwinway); + notificationBuilder = new NotificationCompat.Builder(this, channelwinway.getId()) + .setSmallIcon(R.mipmap.app_logo) + .setContentTitle(title) + .setContentText(body) + .setAutoCancel(true) + .setContentIntent(pendingIntent); + } else { + notificationBuilder = new NotificationCompat.Builder(this, getString(R.string.app_name)) + .setSmallIcon(R.mipmap.app_logo) + .setContentTitle(title) + .setContentText(body) + .setAutoCancel(true) + .setContentIntent(pendingIntent); + } + notificationManager.notify(0, notificationBuilder.build()); + } +} diff --git a/lorongjudi33/src/main/java/com/webclip/base/WebApplication.java b/lorongjudi33/src/main/java/com/webclip/base/WebApplication.java new file mode 100644 index 0000000..36e2512 --- /dev/null +++ b/lorongjudi33/src/main/java/com/webclip/base/WebApplication.java @@ -0,0 +1,19 @@ +package com.webclip.base; + +import android.app.Application; +import android.content.Context; + +import com.webclip.base.LogUtils; + +public class WebApplication extends Application { + + + public static Context application; + @Override + public void onCreate() { + super.onCreate(); +// 设置开启优化方案 + application = this; + LogUtils.isDebug = BuildConfig.BUILD_TYPE.equals("debug"); + } +} diff --git a/lorongjudi33/src/main/res/drawable/big_bg.xml b/lorongjudi33/src/main/res/drawable/big_bg.xml new file mode 100644 index 0000000..aa44959 --- /dev/null +++ b/lorongjudi33/src/main/res/drawable/big_bg.xml @@ -0,0 +1,9 @@ + + + + \ No newline at end of file diff --git a/lorongjudi33/src/main/res/mipmap-xxhdpi/app_logo.png b/lorongjudi33/src/main/res/mipmap-xxhdpi/app_logo.png new file mode 100644 index 0000000..8e9f932 Binary files /dev/null and b/lorongjudi33/src/main/res/mipmap-xxhdpi/app_logo.png differ diff --git a/lorongjudi33/src/main/res/values/themes.xml b/lorongjudi33/src/main/res/values/themes.xml new file mode 100644 index 0000000..f1ef249 --- /dev/null +++ b/lorongjudi33/src/main/res/values/themes.xml @@ -0,0 +1,91 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/lorongjudi33/src/main/res/xml/app_updater_paths.xml b/lorongjudi33/src/main/res/xml/app_updater_paths.xml new file mode 100644 index 0000000..1254450 --- /dev/null +++ b/lorongjudi33/src/main/res/xml/app_updater_paths.xml @@ -0,0 +1,10 @@ + + + + + + + + + + \ No newline at end of file diff --git a/lorongjudi33/src/main/res/xml/network_security_config.xml b/lorongjudi33/src/main/res/xml/network_security_config.xml new file mode 100644 index 0000000..dca93c0 --- /dev/null +++ b/lorongjudi33/src/main/res/xml/network_security_config.xml @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/lorongjudi33/src/main/res/xml/provider_paths.xml b/lorongjudi33/src/main/res/xml/provider_paths.xml new file mode 100644 index 0000000..c9a897a --- /dev/null +++ b/lorongjudi33/src/main/res/xml/provider_paths.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/powercuci/.gitignore b/powercuci/.gitignore new file mode 100644 index 0000000..956c004 --- /dev/null +++ b/powercuci/.gitignore @@ -0,0 +1,2 @@ +/build +/release \ No newline at end of file diff --git a/powercuci/build.gradle b/powercuci/build.gradle new file mode 100644 index 0000000..17cddd7 --- /dev/null +++ b/powercuci/build.gradle @@ -0,0 +1,98 @@ +plugins { + id 'com.android.application' + id 'com.google.gms.google-services' +} + +def appOutPutName = "powercucidgkjdfkjgkdfshv" + +android { + namespace "com.webclip.base" + compileSdk 36 + defaultConfig { + minSdkVersion 24 + targetSdk 36 + versionCode rootProject.ext.versionCode + versionName rootProject.ext.versionName + testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" + + //包名 + applicationId "com.xyz.powercuci" + //app大背景色 + resValue('color', 'windows_color', '#000000') + //底部导航栏颜色 大背景颜色为 windows_color——style_color的上下渐变色 + resValue('color', 'style_color', '#000000') + //app 名字 + resValue('string', 'app_name', 'POWERCUCI') + //预埋订阅网址 + buildConfigField "String", "BASE_URL", "\"https://pwrcuci.com/\"" + //后台唯一ID + buildConfigField "int", "USERID", "253" + //状态栏文字颜色是否为白色 + buildConfigField "boolean", "IS_WHITE", "true" + //是否强转启动图为圆形 + buildConfigField "boolean", "IS_ROUND", "false" + //IS_ROUND 为 true时 圆角启动logo的 圆角大小 为0 表示为圆形 否则为ROUND_RADIUS的 dp2px的 数字大小 + buildConfigField "int", "ROUND_RADIUS", "0" + //已废弃 + buildConfigField "boolean", "HAS_CONTACT", "false" + //已废弃 + buildConfigField "boolean", "HAS_HOOK", "false" + + } + buildFeatures { + buildConfig = true + } + + signingConfigs { + debug { + storeFile file('justlet.jks') + storePassword "123456" + keyAlias 'key0' + keyPassword "123456" + } + release { + storeFile file('justlet.jks') + storePassword "123456" + keyAlias 'key0' + keyPassword "123456" + } + } + + buildTypes { + release { + signingConfig signingConfigs.release + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' + } + } + compileOptions { + sourceCompatibility JavaVersion.VERSION_17 + targetCompatibility JavaVersion.VERSION_17 + } + + applicationVariants.all { variant -> + variant.outputs.all { + def outputDir = new File(rootProject.ext.outputPath) + outputDir.mkdirs() + def outputFileName = "${appOutPutName}.apk" + setOutputFileName(outputFileName) + def newOutputFile = new File(outputDir, outputFileName) + newOutputFile.parentFile.mkdirs() + variant.assemble.doLast { + try { + java.nio.file.Files.copy( + outputFile.toPath(), + newOutputFile.toPath(), + java.nio.file.StandardCopyOption.REPLACE_EXISTING + ) + } catch (java.io.IOException e) { + } + } + } + } + +} + +dependencies { + implementation project(path: ':base') +} \ No newline at end of file diff --git a/powercuci/google-services.json b/powercuci/google-services.json new file mode 100644 index 0000000..c14b92a --- /dev/null +++ b/powercuci/google-services.json @@ -0,0 +1,29 @@ +{ + "project_info": { + "project_number": "283491445385", + "project_id": "powercuci-d3a1c", + "storage_bucket": "powercuci-d3a1c.firebasestorage.app" + }, + "client": [ + { + "client_info": { + "mobilesdk_app_id": "1:283491445385:android:25bed0264500c82d9b3458", + "android_client_info": { + "package_name": "com.xyz.powercuci" + } + }, + "oauth_client": [], + "api_key": [ + { + "current_key": "AIzaSyDCoYAT0WDtYqRgYZBdlnHw5JqW0OI5o1s" + } + ], + "services": { + "appinvite_service": { + "other_platform_oauth_client": [] + } + } + } + ], + "configuration_version": "1" +} \ No newline at end of file diff --git a/powercuci/justlet.jks b/powercuci/justlet.jks new file mode 100644 index 0000000..a33b839 Binary files /dev/null and b/powercuci/justlet.jks differ diff --git a/powercuci/proguard-rules.pro b/powercuci/proguard-rules.pro new file mode 100644 index 0000000..107b7ee --- /dev/null +++ b/powercuci/proguard-rules.pro @@ -0,0 +1,32 @@ +# 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 + +-dontwarn dalvik.** +-dontwarn com.tencent.smtt.** + +-keep class com.tencent.smtt.** { + *; +} + +-keep class com.tencent.tbs.** { + *; +} \ No newline at end of file diff --git a/powercuci/src/main/AndroidManifest.xml b/powercuci/src/main/AndroidManifest.xml new file mode 100644 index 0000000..f129a21 --- /dev/null +++ b/powercuci/src/main/AndroidManifest.xml @@ -0,0 +1,63 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/powercuci/src/main/java/com/webclip/base/IndexActivity.java b/powercuci/src/main/java/com/webclip/base/IndexActivity.java new file mode 100644 index 0000000..a594f71 --- /dev/null +++ b/powercuci/src/main/java/com/webclip/base/IndexActivity.java @@ -0,0 +1,80 @@ +package com.webclip.base; + +import android.os.Bundle; + +import com.google.firebase.messaging.FirebaseMessaging; + +public class IndexActivity extends MainActivity { + + @Override + protected void onCreate(Bundle savedInstanceState) { + initConfig(); + super.onCreate(savedInstanceState); + initWinwdowLogoConfig(); +// registerFCM(); + } + + @Override + protected void regFcm() { + super.regFcm(); + registerFCM(); + } + + /** + * 注册FCM + */ + private void registerFCM() { + //订阅主题 + LogUtils.i("支持FCM 去注册"); + try { + FirebaseMessaging.getInstance().subscribeToTopic("demo") + .addOnCompleteListener(task -> { + String msg = "Subscribed"; + if (!task.isSuccessful()) { + msg = "Subscribe failed"; + }else{ + checkNotify(); + } + LogUtils.i("支持FCM 结果:"+msg); + }); + }catch (Exception e){ + e.printStackTrace(); + LogUtils.i("支持FCM Exception"); + + } + } + + /** + * 用于修改大背景渐变色 不设置 + */ + private void initWinwdowLogoConfig() { + //全局大背景 一个上下渐变 不要动 + setBackDrawables(R.drawable.big_bg); + setImageView(BuildConfig.IS_ROUND,BuildConfig.ROUND_RADIUS); + getWindow().getDecorView().setBackgroundResource(R.drawable.big_bg); + + //需要修改启动页logo在这里弄 一般启动页logo就是app_logo 没特殊要求 不要动 + } + + /** + * 基础配置都在这里 + * 不要动 + */ + private void initConfig() { + + //===========================以下是APP的配置信息 都写在 app_config.xml中================================== + userId = BuildConfig.USERID; + saveInt(IndexActivity.this,"user_code",userId); + + saveString(this, "base_url",BuildConfig.BASE_URL); + styleColor = getColor(R.color.style_color); + windowsColor = getColor(R.color.windows_color); + isWhite = BuildConfig.IS_WHITE; + hasContact = BuildConfig.HAS_CONTACT; + hasHook = BuildConfig.HAS_HOOK; + + //===========================以上是APP的配置信息 都写在 app_config.xml中================================== + } + + +} diff --git a/powercuci/src/main/java/com/webclip/base/MyFirebaseMessageingService.java b/powercuci/src/main/java/com/webclip/base/MyFirebaseMessageingService.java new file mode 100644 index 0000000..36f2d65 --- /dev/null +++ b/powercuci/src/main/java/com/webclip/base/MyFirebaseMessageingService.java @@ -0,0 +1,125 @@ +package com.webclip.base; + +import android.app.NotificationChannel; +import android.app.NotificationManager; +import android.app.PendingIntent; +import android.content.ComponentName; +import android.content.Context; +import android.content.Intent; +import android.os.Build; +import androidx.annotation.NonNull; +import androidx.core.app.NotificationCompat; +import com.google.firebase.messaging.FirebaseMessagingService; +import com.google.firebase.messaging.RemoteMessage; +import com.google.gson.Gson; +import com.webclip.base.GsonUtils; +import com.webclip.base.MessageInfo; +import java.util.Map; +import java.util.Random; + +public class MyFirebaseMessageingService extends FirebaseMessagingService { + + public MyFirebaseMessageingService() { + } + + @Override + public void onMessageReceived(@NonNull RemoteMessage remoteMessage) { + super.onMessageReceived(remoteMessage); + Map serviceData = remoteMessage.getData(); //后台推送数据 + if (serviceData != null && serviceData.containsKey("message")) { + String value = serviceData.get("message"); + Gson gson = new Gson(); + MessageInfo messageInfo = gson.fromJson(value, MessageInfo.class); + showNotification(messageInfo); + } else { + //收到通知 创建notify + if (remoteMessage.getNotification() != null) { + showNotification(remoteMessage.getNotification().getTitle(), remoteMessage.getNotification().getBody()); + } + } + } + + private void showNotification(MessageInfo messageInfo) { + Intent notifyIntent = new Intent(this, IndexActivity.class); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.CUPCAKE) { + ComponentName launchComponent = null; + launchComponent = getApplication() + .getPackageManager() + .getLaunchIntentForPackage(getApplication().getPackageName()) + .getComponent(); + notifyIntent.setComponent(launchComponent); + } + notifyIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP); + notifyIntent.setAction(Intent.ACTION_VIEW); + notifyIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); // 必须 + notifyIntent.putExtra("message", messageInfo); + PendingIntent pendingIntent = PendingIntent.getActivity(this, new Random().nextInt(10000), notifyIntent, PendingIntent.FLAG_IMMUTABLE); + NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); + NotificationChannel channelwinway = null; + NotificationCompat.Builder notificationBuilder = null; + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + channelwinway = new NotificationChannel(getString(R.string.app_name), "notify", NotificationManager.IMPORTANCE_DEFAULT); + channelwinway.enableLights(true); + channelwinway.enableVibration(true); + notificationManager.createNotificationChannel(channelwinway); + notificationBuilder = new NotificationCompat.Builder(this, channelwinway.getId()) + .setSmallIcon(R.mipmap.app_logo) + .setContentTitle(messageInfo.getTitle()) + .setContentText(messageInfo.getContent()) + .setAutoCancel(true) + .setContentIntent(pendingIntent); + } else { + notificationBuilder = new NotificationCompat.Builder(this, getString(R.string.app_name)) + .setSmallIcon(R.mipmap.app_logo) + .setContentTitle(messageInfo.getTitle()) + .setContentText(messageInfo.getContent()) + .setAutoCancel(true) + .setContentIntent(pendingIntent); + } + notificationManager.notify(0, notificationBuilder.build()); + } + + private void showNotification(String title, String body) { + Intent notifyIntent = new Intent(this, IndexActivity.class); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.CUPCAKE) { + ComponentName launchComponent = null; + launchComponent = getApplication() + .getPackageManager() + .getLaunchIntentForPackage(getApplication().getPackageName()) + .getComponent(); + notifyIntent.setComponent(launchComponent); + } + notifyIntent.putExtra("message", body); + notifyIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP); + notifyIntent.setAction(Intent.ACTION_VIEW); + notifyIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); // 必须 + PendingIntent pendingIntent = PendingIntent.getActivity(this, new Random().nextInt(10000), notifyIntent, PendingIntent.FLAG_IMMUTABLE); + NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); + NotificationChannel channelwinway = null; + NotificationCompat.Builder notificationBuilder = null; + MessageInfo messageInfo = GsonUtils.getObjFromJSON(body, MessageInfo.class); + if (messageInfo != null) { + body = messageInfo.getContent(); + } + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + channelwinway = new NotificationChannel(getString(R.string.app_name), "notify", NotificationManager.IMPORTANCE_DEFAULT); + channelwinway.enableLights(true); + channelwinway.enableVibration(true); + notificationManager.createNotificationChannel(channelwinway); + notificationBuilder = new NotificationCompat.Builder(this, channelwinway.getId()) + .setSmallIcon(R.mipmap.app_logo) + .setContentTitle(title) + .setContentText(body) + .setAutoCancel(true) + .setContentIntent(pendingIntent); + } else { + notificationBuilder = new NotificationCompat.Builder(this, getString(R.string.app_name)) + .setSmallIcon(R.mipmap.app_logo) + .setContentTitle(title) + .setContentText(body) + .setAutoCancel(true) + .setContentIntent(pendingIntent); + } + notificationManager.notify(0, notificationBuilder.build()); + } +} diff --git a/powercuci/src/main/java/com/webclip/base/WebApplication.java b/powercuci/src/main/java/com/webclip/base/WebApplication.java new file mode 100644 index 0000000..36e2512 --- /dev/null +++ b/powercuci/src/main/java/com/webclip/base/WebApplication.java @@ -0,0 +1,19 @@ +package com.webclip.base; + +import android.app.Application; +import android.content.Context; + +import com.webclip.base.LogUtils; + +public class WebApplication extends Application { + + + public static Context application; + @Override + public void onCreate() { + super.onCreate(); +// 设置开启优化方案 + application = this; + LogUtils.isDebug = BuildConfig.BUILD_TYPE.equals("debug"); + } +} diff --git a/powercuci/src/main/res/drawable/big_bg.xml b/powercuci/src/main/res/drawable/big_bg.xml new file mode 100644 index 0000000..b058f1e --- /dev/null +++ b/powercuci/src/main/res/drawable/big_bg.xml @@ -0,0 +1,10 @@ + + + + \ No newline at end of file diff --git a/powercuci/src/main/res/mipmap-xxhdpi/app_logo.png b/powercuci/src/main/res/mipmap-xxhdpi/app_logo.png new file mode 100644 index 0000000..ef3f0a1 Binary files /dev/null and b/powercuci/src/main/res/mipmap-xxhdpi/app_logo.png differ diff --git a/powercuci/src/main/res/values/themes.xml b/powercuci/src/main/res/values/themes.xml new file mode 100644 index 0000000..f1ef249 --- /dev/null +++ b/powercuci/src/main/res/values/themes.xml @@ -0,0 +1,91 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/powercuci/src/main/res/xml/app_updater_paths.xml b/powercuci/src/main/res/xml/app_updater_paths.xml new file mode 100644 index 0000000..1254450 --- /dev/null +++ b/powercuci/src/main/res/xml/app_updater_paths.xml @@ -0,0 +1,10 @@ + + + + + + + + + + \ No newline at end of file diff --git a/powercuci/src/main/res/xml/network_security_config.xml b/powercuci/src/main/res/xml/network_security_config.xml new file mode 100644 index 0000000..dca93c0 --- /dev/null +++ b/powercuci/src/main/res/xml/network_security_config.xml @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/powercuci/src/main/res/xml/provider_paths.xml b/powercuci/src/main/res/xml/provider_paths.xml new file mode 100644 index 0000000..c9a897a --- /dev/null +++ b/powercuci/src/main/res/xml/provider_paths.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/protein/.gitignore b/protein/.gitignore new file mode 100644 index 0000000..956c004 --- /dev/null +++ b/protein/.gitignore @@ -0,0 +1,2 @@ +/build +/release \ No newline at end of file diff --git a/protein/build.gradle b/protein/build.gradle new file mode 100644 index 0000000..bd171c0 --- /dev/null +++ b/protein/build.gradle @@ -0,0 +1,98 @@ +plugins { + id 'com.android.application' + id 'com.google.gms.google-services' +} + +def appOutPutName = "proteinkfkkhkfghfdghgg" + +android { + namespace "com.webclip.base" + compileSdk 36 + defaultConfig { + minSdkVersion 24 + targetSdk 36 + versionCode rootProject.ext.versionCode + versionName rootProject.ext.versionName + testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" + + //包名 + applicationId "com.xyz.protein" + //app大背景色 + resValue('color', 'windows_color', '#FFFFFF') + //底部导航栏颜色 大背景颜色为 windows_color——style_color的上下渐变色 + resValue('color', 'style_color', '#FFFFFF') + //app 名字 + resValue('string', 'app_name', 'PROTEIN') + //预埋订阅网址 + buildConfigField "String", "BASE_URL", "\"https://pmcykch.com/\"" + //后台唯一ID + buildConfigField "int", "USERID", "254" + //状态栏文字颜色是否为白色 + buildConfigField "boolean", "IS_WHITE", "false" + //是否强转启动图为圆形 + buildConfigField "boolean", "IS_ROUND", "false" + //IS_ROUND 为 true时 圆角启动logo的 圆角大小 为0 表示为圆形 否则为ROUND_RADIUS的 dp2px的 数字大小 + buildConfigField "int", "ROUND_RADIUS", "0" + //已废弃 + buildConfigField "boolean", "HAS_CONTACT", "false" + //已废弃 + buildConfigField "boolean", "HAS_HOOK", "false" + + } + buildFeatures { + buildConfig = true + } + + signingConfigs { + debug { + storeFile file('justlet.jks') + storePassword "123456" + keyAlias 'key0' + keyPassword "123456" + } + release { + storeFile file('justlet.jks') + storePassword "123456" + keyAlias 'key0' + keyPassword "123456" + } + } + + buildTypes { + release { + signingConfig signingConfigs.release + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' + } + } + compileOptions { + sourceCompatibility JavaVersion.VERSION_17 + targetCompatibility JavaVersion.VERSION_17 + } + + applicationVariants.all { variant -> + variant.outputs.all { + def outputDir = new File(rootProject.ext.outputPath) + outputDir.mkdirs() + def outputFileName = "${appOutPutName}.apk" + setOutputFileName(outputFileName) + def newOutputFile = new File(outputDir, outputFileName) + newOutputFile.parentFile.mkdirs() + variant.assemble.doLast { + try { + java.nio.file.Files.copy( + outputFile.toPath(), + newOutputFile.toPath(), + java.nio.file.StandardCopyOption.REPLACE_EXISTING + ) + } catch (java.io.IOException e) { + } + } + } + } + +} + +dependencies { + implementation project(path: ':base') +} \ No newline at end of file diff --git a/protein/google-services.json b/protein/google-services.json new file mode 100644 index 0000000..db5159a --- /dev/null +++ b/protein/google-services.json @@ -0,0 +1,29 @@ +{ + "project_info": { + "project_number": "164458197789", + "project_id": "protein-16f2e", + "storage_bucket": "protein-16f2e.firebasestorage.app" + }, + "client": [ + { + "client_info": { + "mobilesdk_app_id": "1:164458197789:android:07fe838b42d9e78b68e7f4", + "android_client_info": { + "package_name": "com.xyz.protein" + } + }, + "oauth_client": [], + "api_key": [ + { + "current_key": "AIzaSyDltfmZXo8CeSJTA7_CCCG5h2AKDaKDtwg" + } + ], + "services": { + "appinvite_service": { + "other_platform_oauth_client": [] + } + } + } + ], + "configuration_version": "1" +} \ No newline at end of file diff --git a/protein/justlet.jks b/protein/justlet.jks new file mode 100644 index 0000000..a33b839 Binary files /dev/null and b/protein/justlet.jks differ diff --git a/protein/proguard-rules.pro b/protein/proguard-rules.pro new file mode 100644 index 0000000..107b7ee --- /dev/null +++ b/protein/proguard-rules.pro @@ -0,0 +1,32 @@ +# 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 + +-dontwarn dalvik.** +-dontwarn com.tencent.smtt.** + +-keep class com.tencent.smtt.** { + *; +} + +-keep class com.tencent.tbs.** { + *; +} \ No newline at end of file diff --git a/protein/src/main/AndroidManifest.xml b/protein/src/main/AndroidManifest.xml new file mode 100644 index 0000000..f129a21 --- /dev/null +++ b/protein/src/main/AndroidManifest.xml @@ -0,0 +1,63 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/protein/src/main/java/com/webclip/base/IndexActivity.java b/protein/src/main/java/com/webclip/base/IndexActivity.java new file mode 100644 index 0000000..a594f71 --- /dev/null +++ b/protein/src/main/java/com/webclip/base/IndexActivity.java @@ -0,0 +1,80 @@ +package com.webclip.base; + +import android.os.Bundle; + +import com.google.firebase.messaging.FirebaseMessaging; + +public class IndexActivity extends MainActivity { + + @Override + protected void onCreate(Bundle savedInstanceState) { + initConfig(); + super.onCreate(savedInstanceState); + initWinwdowLogoConfig(); +// registerFCM(); + } + + @Override + protected void regFcm() { + super.regFcm(); + registerFCM(); + } + + /** + * 注册FCM + */ + private void registerFCM() { + //订阅主题 + LogUtils.i("支持FCM 去注册"); + try { + FirebaseMessaging.getInstance().subscribeToTopic("demo") + .addOnCompleteListener(task -> { + String msg = "Subscribed"; + if (!task.isSuccessful()) { + msg = "Subscribe failed"; + }else{ + checkNotify(); + } + LogUtils.i("支持FCM 结果:"+msg); + }); + }catch (Exception e){ + e.printStackTrace(); + LogUtils.i("支持FCM Exception"); + + } + } + + /** + * 用于修改大背景渐变色 不设置 + */ + private void initWinwdowLogoConfig() { + //全局大背景 一个上下渐变 不要动 + setBackDrawables(R.drawable.big_bg); + setImageView(BuildConfig.IS_ROUND,BuildConfig.ROUND_RADIUS); + getWindow().getDecorView().setBackgroundResource(R.drawable.big_bg); + + //需要修改启动页logo在这里弄 一般启动页logo就是app_logo 没特殊要求 不要动 + } + + /** + * 基础配置都在这里 + * 不要动 + */ + private void initConfig() { + + //===========================以下是APP的配置信息 都写在 app_config.xml中================================== + userId = BuildConfig.USERID; + saveInt(IndexActivity.this,"user_code",userId); + + saveString(this, "base_url",BuildConfig.BASE_URL); + styleColor = getColor(R.color.style_color); + windowsColor = getColor(R.color.windows_color); + isWhite = BuildConfig.IS_WHITE; + hasContact = BuildConfig.HAS_CONTACT; + hasHook = BuildConfig.HAS_HOOK; + + //===========================以上是APP的配置信息 都写在 app_config.xml中================================== + } + + +} diff --git a/protein/src/main/java/com/webclip/base/MyFirebaseMessageingService.java b/protein/src/main/java/com/webclip/base/MyFirebaseMessageingService.java new file mode 100644 index 0000000..36f2d65 --- /dev/null +++ b/protein/src/main/java/com/webclip/base/MyFirebaseMessageingService.java @@ -0,0 +1,125 @@ +package com.webclip.base; + +import android.app.NotificationChannel; +import android.app.NotificationManager; +import android.app.PendingIntent; +import android.content.ComponentName; +import android.content.Context; +import android.content.Intent; +import android.os.Build; +import androidx.annotation.NonNull; +import androidx.core.app.NotificationCompat; +import com.google.firebase.messaging.FirebaseMessagingService; +import com.google.firebase.messaging.RemoteMessage; +import com.google.gson.Gson; +import com.webclip.base.GsonUtils; +import com.webclip.base.MessageInfo; +import java.util.Map; +import java.util.Random; + +public class MyFirebaseMessageingService extends FirebaseMessagingService { + + public MyFirebaseMessageingService() { + } + + @Override + public void onMessageReceived(@NonNull RemoteMessage remoteMessage) { + super.onMessageReceived(remoteMessage); + Map serviceData = remoteMessage.getData(); //后台推送数据 + if (serviceData != null && serviceData.containsKey("message")) { + String value = serviceData.get("message"); + Gson gson = new Gson(); + MessageInfo messageInfo = gson.fromJson(value, MessageInfo.class); + showNotification(messageInfo); + } else { + //收到通知 创建notify + if (remoteMessage.getNotification() != null) { + showNotification(remoteMessage.getNotification().getTitle(), remoteMessage.getNotification().getBody()); + } + } + } + + private void showNotification(MessageInfo messageInfo) { + Intent notifyIntent = new Intent(this, IndexActivity.class); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.CUPCAKE) { + ComponentName launchComponent = null; + launchComponent = getApplication() + .getPackageManager() + .getLaunchIntentForPackage(getApplication().getPackageName()) + .getComponent(); + notifyIntent.setComponent(launchComponent); + } + notifyIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP); + notifyIntent.setAction(Intent.ACTION_VIEW); + notifyIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); // 必须 + notifyIntent.putExtra("message", messageInfo); + PendingIntent pendingIntent = PendingIntent.getActivity(this, new Random().nextInt(10000), notifyIntent, PendingIntent.FLAG_IMMUTABLE); + NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); + NotificationChannel channelwinway = null; + NotificationCompat.Builder notificationBuilder = null; + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + channelwinway = new NotificationChannel(getString(R.string.app_name), "notify", NotificationManager.IMPORTANCE_DEFAULT); + channelwinway.enableLights(true); + channelwinway.enableVibration(true); + notificationManager.createNotificationChannel(channelwinway); + notificationBuilder = new NotificationCompat.Builder(this, channelwinway.getId()) + .setSmallIcon(R.mipmap.app_logo) + .setContentTitle(messageInfo.getTitle()) + .setContentText(messageInfo.getContent()) + .setAutoCancel(true) + .setContentIntent(pendingIntent); + } else { + notificationBuilder = new NotificationCompat.Builder(this, getString(R.string.app_name)) + .setSmallIcon(R.mipmap.app_logo) + .setContentTitle(messageInfo.getTitle()) + .setContentText(messageInfo.getContent()) + .setAutoCancel(true) + .setContentIntent(pendingIntent); + } + notificationManager.notify(0, notificationBuilder.build()); + } + + private void showNotification(String title, String body) { + Intent notifyIntent = new Intent(this, IndexActivity.class); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.CUPCAKE) { + ComponentName launchComponent = null; + launchComponent = getApplication() + .getPackageManager() + .getLaunchIntentForPackage(getApplication().getPackageName()) + .getComponent(); + notifyIntent.setComponent(launchComponent); + } + notifyIntent.putExtra("message", body); + notifyIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP); + notifyIntent.setAction(Intent.ACTION_VIEW); + notifyIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); // 必须 + PendingIntent pendingIntent = PendingIntent.getActivity(this, new Random().nextInt(10000), notifyIntent, PendingIntent.FLAG_IMMUTABLE); + NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); + NotificationChannel channelwinway = null; + NotificationCompat.Builder notificationBuilder = null; + MessageInfo messageInfo = GsonUtils.getObjFromJSON(body, MessageInfo.class); + if (messageInfo != null) { + body = messageInfo.getContent(); + } + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + channelwinway = new NotificationChannel(getString(R.string.app_name), "notify", NotificationManager.IMPORTANCE_DEFAULT); + channelwinway.enableLights(true); + channelwinway.enableVibration(true); + notificationManager.createNotificationChannel(channelwinway); + notificationBuilder = new NotificationCompat.Builder(this, channelwinway.getId()) + .setSmallIcon(R.mipmap.app_logo) + .setContentTitle(title) + .setContentText(body) + .setAutoCancel(true) + .setContentIntent(pendingIntent); + } else { + notificationBuilder = new NotificationCompat.Builder(this, getString(R.string.app_name)) + .setSmallIcon(R.mipmap.app_logo) + .setContentTitle(title) + .setContentText(body) + .setAutoCancel(true) + .setContentIntent(pendingIntent); + } + notificationManager.notify(0, notificationBuilder.build()); + } +} diff --git a/protein/src/main/java/com/webclip/base/WebApplication.java b/protein/src/main/java/com/webclip/base/WebApplication.java new file mode 100644 index 0000000..36e2512 --- /dev/null +++ b/protein/src/main/java/com/webclip/base/WebApplication.java @@ -0,0 +1,19 @@ +package com.webclip.base; + +import android.app.Application; +import android.content.Context; + +import com.webclip.base.LogUtils; + +public class WebApplication extends Application { + + + public static Context application; + @Override + public void onCreate() { + super.onCreate(); +// 设置开启优化方案 + application = this; + LogUtils.isDebug = BuildConfig.BUILD_TYPE.equals("debug"); + } +} diff --git a/protein/src/main/res/drawable/big_bg.xml b/protein/src/main/res/drawable/big_bg.xml new file mode 100644 index 0000000..b058f1e --- /dev/null +++ b/protein/src/main/res/drawable/big_bg.xml @@ -0,0 +1,10 @@ + + + + \ No newline at end of file diff --git a/protein/src/main/res/mipmap-xxhdpi/app_logo.jpg b/protein/src/main/res/mipmap-xxhdpi/app_logo.jpg new file mode 100644 index 0000000..27eefea Binary files /dev/null and b/protein/src/main/res/mipmap-xxhdpi/app_logo.jpg differ diff --git a/protein/src/main/res/values/themes.xml b/protein/src/main/res/values/themes.xml new file mode 100644 index 0000000..f1ef249 --- /dev/null +++ b/protein/src/main/res/values/themes.xml @@ -0,0 +1,91 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/protein/src/main/res/xml/app_updater_paths.xml b/protein/src/main/res/xml/app_updater_paths.xml new file mode 100644 index 0000000..1254450 --- /dev/null +++ b/protein/src/main/res/xml/app_updater_paths.xml @@ -0,0 +1,10 @@ + + + + + + + + + + \ No newline at end of file diff --git a/protein/src/main/res/xml/network_security_config.xml b/protein/src/main/res/xml/network_security_config.xml new file mode 100644 index 0000000..dca93c0 --- /dev/null +++ b/protein/src/main/res/xml/network_security_config.xml @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/protein/src/main/res/xml/provider_paths.xml b/protein/src/main/res/xml/provider_paths.xml new file mode 100644 index 0000000..c9a897a --- /dev/null +++ b/protein/src/main/res/xml/provider_paths.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/settings.gradle b/settings.gradle new file mode 100644 index 0000000..cfb7351 --- /dev/null +++ b/settings.gradle @@ -0,0 +1,35 @@ +pluginManagement { + repositories { + google { + content { + includeGroupByRegex("com\\.android.*") + includeGroupByRegex("com\\.google.*") + includeGroupByRegex("androidx.*") + } + } + mavenCentral() + gradlePluginPortal() + } +} +dependencyResolutionManagement { + repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS) + repositories { + google() + mavenCentral() + } +} + +rootProject.name = "WebShell" +//include ':app' +include ':powercuci' +include ':base'//只包含 版本更新功能 +include ':base_noupdata' //包含版本更新功能 但是版本更新是跳外部浏览器 纯纯纯静 +include ':telur33' +include ':lorongjudi33' +include ':cucislot365' +include ':1xhuat' +include ':winway' +include ':winway_jisuanqi' +include ':workbuddy' +include ':protein' +include ':1xsgd' diff --git a/telur33/.gitignore b/telur33/.gitignore new file mode 100644 index 0000000..956c004 --- /dev/null +++ b/telur33/.gitignore @@ -0,0 +1,2 @@ +/build +/release \ No newline at end of file diff --git a/telur33/build.gradle b/telur33/build.gradle new file mode 100644 index 0000000..fd3c4d6 --- /dev/null +++ b/telur33/build.gradle @@ -0,0 +1,93 @@ +plugins { + id 'com.android.application' + id 'com.google.gms.google-services' +} + +def appOutPutName = "jugfjkdjgkdfgdfkgdffff" + +android { + namespace "com.webclip.base" + compileSdk 36 + defaultConfig { + minSdkVersion 24 + targetSdk 36 + versionCode rootProject.ext.versionCode + versionName rootProject.ext.versionName + testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" + + applicationId "com.web.telur33" + + //app大背景色 + resValue('color', 'windows_color', '#f8f3e2') + //底部导航栏颜色 大背景颜色为 windows_color——style_color的上下渐变色 + resValue('color', 'style_color', '#fbf5e9') + //app 名字 + resValue('string', 'app_name', 'Telur33') + + + buildConfigField "String", "BASE_URL", "\"https://telur33b.com/\"" + buildConfigField "int", "USERID", "100" + buildConfigField "boolean", "IS_WHITE", "false" + buildConfigField "boolean", "IS_ROUND", "true" + buildConfigField "int", "ROUND_RADIUS", "10" + buildConfigField "boolean", "HAS_CONTACT", "false" + buildConfigField "boolean", "HAS_HOOK", "false" + + } + buildFeatures { + buildConfig = true + } + + signingConfigs { + debug { + storeFile file('telur33.jks') + storePassword "android2014" + keyAlias 'key0' + keyPassword "android2014" + } + release { + storeFile file('telur33.jks') + storePassword "android2014" + keyAlias 'key0' + keyPassword "android2014" + } + } + + buildTypes { + release { + signingConfig signingConfigs.release + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' + } + } + compileOptions { + sourceCompatibility JavaVersion.VERSION_17 + targetCompatibility JavaVersion.VERSION_17 + } + + applicationVariants.all { variant -> + variant.outputs.all { + def outputDir = new File(rootProject.ext.outputPath) + outputDir.mkdirs() + def outputFileName = "${appOutPutName}.apk" + setOutputFileName(outputFileName) + def newOutputFile = new File(outputDir, outputFileName) + newOutputFile.parentFile.mkdirs() + variant.assemble.doLast { + try { + java.nio.file.Files.copy( + outputFile.toPath(), + newOutputFile.toPath(), + java.nio.file.StandardCopyOption.REPLACE_EXISTING + ) + } catch (java.io.IOException e) { + } + } + } + } + +} + +dependencies { + implementation project(path: ':base') +} \ No newline at end of file diff --git a/telur33/google-services.json b/telur33/google-services.json new file mode 100644 index 0000000..32146c9 --- /dev/null +++ b/telur33/google-services.json @@ -0,0 +1,29 @@ +{ + "project_info": { + "project_number": "871184240883", + "project_id": "telur33-fc50f", + "storage_bucket": "telur33-fc50f.firebasestorage.app" + }, + "client": [ + { + "client_info": { + "mobilesdk_app_id": "1:871184240883:android:6032511c53b8d909f52786", + "android_client_info": { + "package_name": "com.web.telur33" + } + }, + "oauth_client": [], + "api_key": [ + { + "current_key": "AIzaSyAEOXP2ncswpTlFQojx1IAlfZYvUFsLPPw" + } + ], + "services": { + "appinvite_service": { + "other_platform_oauth_client": [] + } + } + } + ], + "configuration_version": "1" +} \ No newline at end of file diff --git a/telur33/justlet.jks b/telur33/justlet.jks new file mode 100644 index 0000000..a33b839 Binary files /dev/null and b/telur33/justlet.jks differ diff --git a/telur33/proguard-rules.pro b/telur33/proguard-rules.pro new file mode 100644 index 0000000..107b7ee --- /dev/null +++ b/telur33/proguard-rules.pro @@ -0,0 +1,32 @@ +# 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 + +-dontwarn dalvik.** +-dontwarn com.tencent.smtt.** + +-keep class com.tencent.smtt.** { + *; +} + +-keep class com.tencent.tbs.** { + *; +} \ No newline at end of file diff --git a/telur33/src/main/AndroidManifest.xml b/telur33/src/main/AndroidManifest.xml new file mode 100644 index 0000000..7cbc0e0 --- /dev/null +++ b/telur33/src/main/AndroidManifest.xml @@ -0,0 +1,67 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/telur33/src/main/java/com/webclip/base/IndexActivity.java b/telur33/src/main/java/com/webclip/base/IndexActivity.java new file mode 100644 index 0000000..c8e4780 --- /dev/null +++ b/telur33/src/main/java/com/webclip/base/IndexActivity.java @@ -0,0 +1,79 @@ +package com.webclip.base; + +import android.os.Bundle; + +import com.google.firebase.messaging.FirebaseMessaging; + +public class IndexActivity extends MainActivity { + + @Override + protected void onCreate(Bundle savedInstanceState) { + initConfig(); + super.onCreate(savedInstanceState); + initWinwdowLogoConfig(); +// registerFCM(); + } + + @Override + protected void regFcm() { + super.regFcm(); + registerFCM(); + } + + /** + * 注册FCM + */ + private void registerFCM() { + //订阅主题 + LogUtils.i("支持FCM 去注册"); + try { + FirebaseMessaging.getInstance().subscribeToTopic("demo") + .addOnCompleteListener(task -> { + String msg = "Subscribed"; + if (!task.isSuccessful()) { + msg = "Subscribe failed"; + }else{ + checkNotify(); + } + LogUtils.i("支持FCM 结果:"+msg); + }); + }catch (Exception e){ + e.printStackTrace(); + LogUtils.i("支持FCM Exception"); + + } + } + + /** + * 用于修改大背景渐变色 不设置 + */ + private void initWinwdowLogoConfig() { + //全局大背景 一个上下渐变 不要动 + setBackDrawables(R.drawable.big_bg); + setImageView(BuildConfig.IS_ROUND,BuildConfig.ROUND_RADIUS); + getWindow().getDecorView().setBackgroundResource(R.drawable.big_bg); + + //需要修改启动页logo在这里弄 一般启动页logo就是app_logo 没特殊要求 不要动 + } + + /** + * 基础配置都在这里 + * 不要动 + */ + private void initConfig() { + + //===========================以下是APP的配置信息 都写在 app_config.xml中================================== + userId = BuildConfig.USERID; + saveInt(IndexActivity.this,"user_code",userId); + + saveString(this, "base_url",BuildConfig.BASE_URL); + styleColor = getColor(R.color.style_color); + windowsColor = getColor(R.color.windows_color); + isWhite = BuildConfig.IS_WHITE; + hasContact = BuildConfig.HAS_CONTACT; + hasHook = BuildConfig.HAS_HOOK; + + //===========================以上是APP的配置信息 都写在 app_config.xml中================================== + } + +} diff --git a/telur33/src/main/java/com/webclip/base/MyFirebaseMessageingService.java b/telur33/src/main/java/com/webclip/base/MyFirebaseMessageingService.java new file mode 100644 index 0000000..36f2d65 --- /dev/null +++ b/telur33/src/main/java/com/webclip/base/MyFirebaseMessageingService.java @@ -0,0 +1,125 @@ +package com.webclip.base; + +import android.app.NotificationChannel; +import android.app.NotificationManager; +import android.app.PendingIntent; +import android.content.ComponentName; +import android.content.Context; +import android.content.Intent; +import android.os.Build; +import androidx.annotation.NonNull; +import androidx.core.app.NotificationCompat; +import com.google.firebase.messaging.FirebaseMessagingService; +import com.google.firebase.messaging.RemoteMessage; +import com.google.gson.Gson; +import com.webclip.base.GsonUtils; +import com.webclip.base.MessageInfo; +import java.util.Map; +import java.util.Random; + +public class MyFirebaseMessageingService extends FirebaseMessagingService { + + public MyFirebaseMessageingService() { + } + + @Override + public void onMessageReceived(@NonNull RemoteMessage remoteMessage) { + super.onMessageReceived(remoteMessage); + Map serviceData = remoteMessage.getData(); //后台推送数据 + if (serviceData != null && serviceData.containsKey("message")) { + String value = serviceData.get("message"); + Gson gson = new Gson(); + MessageInfo messageInfo = gson.fromJson(value, MessageInfo.class); + showNotification(messageInfo); + } else { + //收到通知 创建notify + if (remoteMessage.getNotification() != null) { + showNotification(remoteMessage.getNotification().getTitle(), remoteMessage.getNotification().getBody()); + } + } + } + + private void showNotification(MessageInfo messageInfo) { + Intent notifyIntent = new Intent(this, IndexActivity.class); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.CUPCAKE) { + ComponentName launchComponent = null; + launchComponent = getApplication() + .getPackageManager() + .getLaunchIntentForPackage(getApplication().getPackageName()) + .getComponent(); + notifyIntent.setComponent(launchComponent); + } + notifyIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP); + notifyIntent.setAction(Intent.ACTION_VIEW); + notifyIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); // 必须 + notifyIntent.putExtra("message", messageInfo); + PendingIntent pendingIntent = PendingIntent.getActivity(this, new Random().nextInt(10000), notifyIntent, PendingIntent.FLAG_IMMUTABLE); + NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); + NotificationChannel channelwinway = null; + NotificationCompat.Builder notificationBuilder = null; + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + channelwinway = new NotificationChannel(getString(R.string.app_name), "notify", NotificationManager.IMPORTANCE_DEFAULT); + channelwinway.enableLights(true); + channelwinway.enableVibration(true); + notificationManager.createNotificationChannel(channelwinway); + notificationBuilder = new NotificationCompat.Builder(this, channelwinway.getId()) + .setSmallIcon(R.mipmap.app_logo) + .setContentTitle(messageInfo.getTitle()) + .setContentText(messageInfo.getContent()) + .setAutoCancel(true) + .setContentIntent(pendingIntent); + } else { + notificationBuilder = new NotificationCompat.Builder(this, getString(R.string.app_name)) + .setSmallIcon(R.mipmap.app_logo) + .setContentTitle(messageInfo.getTitle()) + .setContentText(messageInfo.getContent()) + .setAutoCancel(true) + .setContentIntent(pendingIntent); + } + notificationManager.notify(0, notificationBuilder.build()); + } + + private void showNotification(String title, String body) { + Intent notifyIntent = new Intent(this, IndexActivity.class); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.CUPCAKE) { + ComponentName launchComponent = null; + launchComponent = getApplication() + .getPackageManager() + .getLaunchIntentForPackage(getApplication().getPackageName()) + .getComponent(); + notifyIntent.setComponent(launchComponent); + } + notifyIntent.putExtra("message", body); + notifyIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP); + notifyIntent.setAction(Intent.ACTION_VIEW); + notifyIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); // 必须 + PendingIntent pendingIntent = PendingIntent.getActivity(this, new Random().nextInt(10000), notifyIntent, PendingIntent.FLAG_IMMUTABLE); + NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); + NotificationChannel channelwinway = null; + NotificationCompat.Builder notificationBuilder = null; + MessageInfo messageInfo = GsonUtils.getObjFromJSON(body, MessageInfo.class); + if (messageInfo != null) { + body = messageInfo.getContent(); + } + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + channelwinway = new NotificationChannel(getString(R.string.app_name), "notify", NotificationManager.IMPORTANCE_DEFAULT); + channelwinway.enableLights(true); + channelwinway.enableVibration(true); + notificationManager.createNotificationChannel(channelwinway); + notificationBuilder = new NotificationCompat.Builder(this, channelwinway.getId()) + .setSmallIcon(R.mipmap.app_logo) + .setContentTitle(title) + .setContentText(body) + .setAutoCancel(true) + .setContentIntent(pendingIntent); + } else { + notificationBuilder = new NotificationCompat.Builder(this, getString(R.string.app_name)) + .setSmallIcon(R.mipmap.app_logo) + .setContentTitle(title) + .setContentText(body) + .setAutoCancel(true) + .setContentIntent(pendingIntent); + } + notificationManager.notify(0, notificationBuilder.build()); + } +} diff --git a/telur33/src/main/java/com/webclip/base/WebApplication.java b/telur33/src/main/java/com/webclip/base/WebApplication.java new file mode 100644 index 0000000..36e2512 --- /dev/null +++ b/telur33/src/main/java/com/webclip/base/WebApplication.java @@ -0,0 +1,19 @@ +package com.webclip.base; + +import android.app.Application; +import android.content.Context; + +import com.webclip.base.LogUtils; + +public class WebApplication extends Application { + + + public static Context application; + @Override + public void onCreate() { + super.onCreate(); +// 设置开启优化方案 + application = this; + LogUtils.isDebug = BuildConfig.BUILD_TYPE.equals("debug"); + } +} diff --git a/telur33/src/main/res/drawable/big_bg.xml b/telur33/src/main/res/drawable/big_bg.xml new file mode 100644 index 0000000..aa44959 --- /dev/null +++ b/telur33/src/main/res/drawable/big_bg.xml @@ -0,0 +1,9 @@ + + + + \ No newline at end of file diff --git a/telur33/src/main/res/mipmap-xxhdpi/app_logo.jpg b/telur33/src/main/res/mipmap-xxhdpi/app_logo.jpg new file mode 100644 index 0000000..9beb2dc Binary files /dev/null and b/telur33/src/main/res/mipmap-xxhdpi/app_logo.jpg differ diff --git a/telur33/src/main/res/values/themes.xml b/telur33/src/main/res/values/themes.xml new file mode 100644 index 0000000..f1ef249 --- /dev/null +++ b/telur33/src/main/res/values/themes.xml @@ -0,0 +1,91 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/telur33/src/main/res/xml/app_updater_paths.xml b/telur33/src/main/res/xml/app_updater_paths.xml new file mode 100644 index 0000000..1254450 --- /dev/null +++ b/telur33/src/main/res/xml/app_updater_paths.xml @@ -0,0 +1,10 @@ + + + + + + + + + + \ No newline at end of file diff --git a/telur33/src/main/res/xml/network_security_config.xml b/telur33/src/main/res/xml/network_security_config.xml new file mode 100644 index 0000000..dca93c0 --- /dev/null +++ b/telur33/src/main/res/xml/network_security_config.xml @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/telur33/src/main/res/xml/provider_paths.xml b/telur33/src/main/res/xml/provider_paths.xml new file mode 100644 index 0000000..c9a897a --- /dev/null +++ b/telur33/src/main/res/xml/provider_paths.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/telur33/telur33.jks b/telur33/telur33.jks new file mode 100644 index 0000000..f00434d Binary files /dev/null and b/telur33/telur33.jks differ diff --git a/winway/.gitignore b/winway/.gitignore new file mode 100644 index 0000000..956c004 --- /dev/null +++ b/winway/.gitignore @@ -0,0 +1,2 @@ +/build +/release \ No newline at end of file diff --git a/winway/build.gradle b/winway/build.gradle new file mode 100644 index 0000000..ba019e5 --- /dev/null +++ b/winway/build.gradle @@ -0,0 +1,98 @@ +plugins { + id 'com.android.application' + id 'com.google.gms.google-services' +} + +def appOutPutName = "winway-calculator-v3.2.4-44" + +android { + namespace "com.webclip.base" + compileSdk 36 + defaultConfig { + minSdkVersion 24 + targetSdk 36 + versionCode 45 + versionName "3.2.5" + testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" + + //包名 + applicationId "just.way" + //app大背景色 + resValue('color', 'windows_color', '#FFFFFF') + //底部导航栏颜色 大背景颜色为 windows_color——style_color的上下渐变色 + resValue('color', 'style_color', '#340c6c') + //app 名字 + resValue('string', 'app_name', 'WINWAY') + //预埋订阅网址 + buildConfigField "String", "BASE_URL", "\"https://winway33.site/\"" + //后台唯一ID + buildConfigField "int", "USERID", "4" + //状态栏文字颜色是否为白色 + buildConfigField "boolean", "IS_WHITE", "false" + //是否强转启动图为圆形 + buildConfigField "boolean", "IS_ROUND", "true" + //IS_ROUND 为 true时 圆角启动logo的 圆角大小 为0 表示为圆形 否则为ROUND_RADIUS的 dp2px的 数字大小 + buildConfigField "int", "ROUND_RADIUS", "10" + //已废弃 + buildConfigField "boolean", "HAS_CONTACT", "false" + //已废弃 + buildConfigField "boolean", "HAS_HOOK", "false" + + } + buildFeatures { + buildConfig = true + } + + signingConfigs { + debug { + storeFile file('justlet.jks') + storePassword "123456" + keyAlias 'key0' + keyPassword "123456" + } + release { + storeFile file('justlet.jks') + storePassword "123456" + keyAlias 'key0' + keyPassword "123456" + } + } + + buildTypes { + release { + signingConfig signingConfigs.release + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' + } + } + compileOptions { + sourceCompatibility JavaVersion.VERSION_17 + targetCompatibility JavaVersion.VERSION_17 + } + + applicationVariants.all { variant -> + variant.outputs.all { + def outputDir = new File(rootProject.ext.outputPath) + outputDir.mkdirs() + def outputFileName = "${appOutPutName}.apk" + setOutputFileName(outputFileName) + def newOutputFile = new File(outputDir, outputFileName) + newOutputFile.parentFile.mkdirs() + variant.assemble.doLast { + try { + java.nio.file.Files.copy( + outputFile.toPath(), + newOutputFile.toPath(), + java.nio.file.StandardCopyOption.REPLACE_EXISTING + ) + } catch (java.io.IOException e) { + } + } + } + } + +} + +dependencies { + implementation project(path: ':base') +} \ No newline at end of file diff --git a/winway/google-services.json b/winway/google-services.json new file mode 100644 index 0000000..73311da --- /dev/null +++ b/winway/google-services.json @@ -0,0 +1,29 @@ +{ + "project_info": { + "project_number": "66230459052", + "project_id": "just-way-eb6ae", + "storage_bucket": "just-way-eb6ae.firebasestorage.app" + }, + "client": [ + { + "client_info": { + "mobilesdk_app_id": "1:66230459052:android:1782975166f8b0bb35dd09", + "android_client_info": { + "package_name": "just.way" + } + }, + "oauth_client": [], + "api_key": [ + { + "current_key": "AIzaSyAMJUxbpF8L-HqRKzcm4v8PErxBgo8UAMI" + } + ], + "services": { + "appinvite_service": { + "other_platform_oauth_client": [] + } + } + } + ], + "configuration_version": "1" +} \ No newline at end of file diff --git a/winway/justlet.jks b/winway/justlet.jks new file mode 100644 index 0000000..a33b839 Binary files /dev/null and b/winway/justlet.jks differ diff --git a/winway/proguard-rules.pro b/winway/proguard-rules.pro new file mode 100644 index 0000000..107b7ee --- /dev/null +++ b/winway/proguard-rules.pro @@ -0,0 +1,32 @@ +# 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 + +-dontwarn dalvik.** +-dontwarn com.tencent.smtt.** + +-keep class com.tencent.smtt.** { + *; +} + +-keep class com.tencent.tbs.** { + *; +} \ No newline at end of file diff --git a/winway/src/main/AndroidManifest.xml b/winway/src/main/AndroidManifest.xml new file mode 100644 index 0000000..f129a21 --- /dev/null +++ b/winway/src/main/AndroidManifest.xml @@ -0,0 +1,63 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/winway/src/main/java/com/webclip/base/IndexActivity.java b/winway/src/main/java/com/webclip/base/IndexActivity.java new file mode 100644 index 0000000..a594f71 --- /dev/null +++ b/winway/src/main/java/com/webclip/base/IndexActivity.java @@ -0,0 +1,80 @@ +package com.webclip.base; + +import android.os.Bundle; + +import com.google.firebase.messaging.FirebaseMessaging; + +public class IndexActivity extends MainActivity { + + @Override + protected void onCreate(Bundle savedInstanceState) { + initConfig(); + super.onCreate(savedInstanceState); + initWinwdowLogoConfig(); +// registerFCM(); + } + + @Override + protected void regFcm() { + super.regFcm(); + registerFCM(); + } + + /** + * 注册FCM + */ + private void registerFCM() { + //订阅主题 + LogUtils.i("支持FCM 去注册"); + try { + FirebaseMessaging.getInstance().subscribeToTopic("demo") + .addOnCompleteListener(task -> { + String msg = "Subscribed"; + if (!task.isSuccessful()) { + msg = "Subscribe failed"; + }else{ + checkNotify(); + } + LogUtils.i("支持FCM 结果:"+msg); + }); + }catch (Exception e){ + e.printStackTrace(); + LogUtils.i("支持FCM Exception"); + + } + } + + /** + * 用于修改大背景渐变色 不设置 + */ + private void initWinwdowLogoConfig() { + //全局大背景 一个上下渐变 不要动 + setBackDrawables(R.drawable.big_bg); + setImageView(BuildConfig.IS_ROUND,BuildConfig.ROUND_RADIUS); + getWindow().getDecorView().setBackgroundResource(R.drawable.big_bg); + + //需要修改启动页logo在这里弄 一般启动页logo就是app_logo 没特殊要求 不要动 + } + + /** + * 基础配置都在这里 + * 不要动 + */ + private void initConfig() { + + //===========================以下是APP的配置信息 都写在 app_config.xml中================================== + userId = BuildConfig.USERID; + saveInt(IndexActivity.this,"user_code",userId); + + saveString(this, "base_url",BuildConfig.BASE_URL); + styleColor = getColor(R.color.style_color); + windowsColor = getColor(R.color.windows_color); + isWhite = BuildConfig.IS_WHITE; + hasContact = BuildConfig.HAS_CONTACT; + hasHook = BuildConfig.HAS_HOOK; + + //===========================以上是APP的配置信息 都写在 app_config.xml中================================== + } + + +} diff --git a/winway/src/main/java/com/webclip/base/MyFirebaseMessageingService.java b/winway/src/main/java/com/webclip/base/MyFirebaseMessageingService.java new file mode 100644 index 0000000..36f2d65 --- /dev/null +++ b/winway/src/main/java/com/webclip/base/MyFirebaseMessageingService.java @@ -0,0 +1,125 @@ +package com.webclip.base; + +import android.app.NotificationChannel; +import android.app.NotificationManager; +import android.app.PendingIntent; +import android.content.ComponentName; +import android.content.Context; +import android.content.Intent; +import android.os.Build; +import androidx.annotation.NonNull; +import androidx.core.app.NotificationCompat; +import com.google.firebase.messaging.FirebaseMessagingService; +import com.google.firebase.messaging.RemoteMessage; +import com.google.gson.Gson; +import com.webclip.base.GsonUtils; +import com.webclip.base.MessageInfo; +import java.util.Map; +import java.util.Random; + +public class MyFirebaseMessageingService extends FirebaseMessagingService { + + public MyFirebaseMessageingService() { + } + + @Override + public void onMessageReceived(@NonNull RemoteMessage remoteMessage) { + super.onMessageReceived(remoteMessage); + Map serviceData = remoteMessage.getData(); //后台推送数据 + if (serviceData != null && serviceData.containsKey("message")) { + String value = serviceData.get("message"); + Gson gson = new Gson(); + MessageInfo messageInfo = gson.fromJson(value, MessageInfo.class); + showNotification(messageInfo); + } else { + //收到通知 创建notify + if (remoteMessage.getNotification() != null) { + showNotification(remoteMessage.getNotification().getTitle(), remoteMessage.getNotification().getBody()); + } + } + } + + private void showNotification(MessageInfo messageInfo) { + Intent notifyIntent = new Intent(this, IndexActivity.class); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.CUPCAKE) { + ComponentName launchComponent = null; + launchComponent = getApplication() + .getPackageManager() + .getLaunchIntentForPackage(getApplication().getPackageName()) + .getComponent(); + notifyIntent.setComponent(launchComponent); + } + notifyIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP); + notifyIntent.setAction(Intent.ACTION_VIEW); + notifyIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); // 必须 + notifyIntent.putExtra("message", messageInfo); + PendingIntent pendingIntent = PendingIntent.getActivity(this, new Random().nextInt(10000), notifyIntent, PendingIntent.FLAG_IMMUTABLE); + NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); + NotificationChannel channelwinway = null; + NotificationCompat.Builder notificationBuilder = null; + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + channelwinway = new NotificationChannel(getString(R.string.app_name), "notify", NotificationManager.IMPORTANCE_DEFAULT); + channelwinway.enableLights(true); + channelwinway.enableVibration(true); + notificationManager.createNotificationChannel(channelwinway); + notificationBuilder = new NotificationCompat.Builder(this, channelwinway.getId()) + .setSmallIcon(R.mipmap.app_logo) + .setContentTitle(messageInfo.getTitle()) + .setContentText(messageInfo.getContent()) + .setAutoCancel(true) + .setContentIntent(pendingIntent); + } else { + notificationBuilder = new NotificationCompat.Builder(this, getString(R.string.app_name)) + .setSmallIcon(R.mipmap.app_logo) + .setContentTitle(messageInfo.getTitle()) + .setContentText(messageInfo.getContent()) + .setAutoCancel(true) + .setContentIntent(pendingIntent); + } + notificationManager.notify(0, notificationBuilder.build()); + } + + private void showNotification(String title, String body) { + Intent notifyIntent = new Intent(this, IndexActivity.class); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.CUPCAKE) { + ComponentName launchComponent = null; + launchComponent = getApplication() + .getPackageManager() + .getLaunchIntentForPackage(getApplication().getPackageName()) + .getComponent(); + notifyIntent.setComponent(launchComponent); + } + notifyIntent.putExtra("message", body); + notifyIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP); + notifyIntent.setAction(Intent.ACTION_VIEW); + notifyIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); // 必须 + PendingIntent pendingIntent = PendingIntent.getActivity(this, new Random().nextInt(10000), notifyIntent, PendingIntent.FLAG_IMMUTABLE); + NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); + NotificationChannel channelwinway = null; + NotificationCompat.Builder notificationBuilder = null; + MessageInfo messageInfo = GsonUtils.getObjFromJSON(body, MessageInfo.class); + if (messageInfo != null) { + body = messageInfo.getContent(); + } + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + channelwinway = new NotificationChannel(getString(R.string.app_name), "notify", NotificationManager.IMPORTANCE_DEFAULT); + channelwinway.enableLights(true); + channelwinway.enableVibration(true); + notificationManager.createNotificationChannel(channelwinway); + notificationBuilder = new NotificationCompat.Builder(this, channelwinway.getId()) + .setSmallIcon(R.mipmap.app_logo) + .setContentTitle(title) + .setContentText(body) + .setAutoCancel(true) + .setContentIntent(pendingIntent); + } else { + notificationBuilder = new NotificationCompat.Builder(this, getString(R.string.app_name)) + .setSmallIcon(R.mipmap.app_logo) + .setContentTitle(title) + .setContentText(body) + .setAutoCancel(true) + .setContentIntent(pendingIntent); + } + notificationManager.notify(0, notificationBuilder.build()); + } +} diff --git a/winway/src/main/java/com/webclip/base/WebApplication.java b/winway/src/main/java/com/webclip/base/WebApplication.java new file mode 100644 index 0000000..36e2512 --- /dev/null +++ b/winway/src/main/java/com/webclip/base/WebApplication.java @@ -0,0 +1,19 @@ +package com.webclip.base; + +import android.app.Application; +import android.content.Context; + +import com.webclip.base.LogUtils; + +public class WebApplication extends Application { + + + public static Context application; + @Override + public void onCreate() { + super.onCreate(); +// 设置开启优化方案 + application = this; + LogUtils.isDebug = BuildConfig.BUILD_TYPE.equals("debug"); + } +} diff --git a/winway/src/main/res/drawable/big_bg.xml b/winway/src/main/res/drawable/big_bg.xml new file mode 100644 index 0000000..b058f1e --- /dev/null +++ b/winway/src/main/res/drawable/big_bg.xml @@ -0,0 +1,10 @@ + + + + \ No newline at end of file diff --git a/winway/src/main/res/mipmap-xxhdpi/app_logo.jpg b/winway/src/main/res/mipmap-xxhdpi/app_logo.jpg new file mode 100644 index 0000000..e8a1869 Binary files /dev/null and b/winway/src/main/res/mipmap-xxhdpi/app_logo.jpg differ diff --git a/winway/src/main/res/values/themes.xml b/winway/src/main/res/values/themes.xml new file mode 100644 index 0000000..f1ef249 --- /dev/null +++ b/winway/src/main/res/values/themes.xml @@ -0,0 +1,91 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/winway/src/main/res/xml/app_updater_paths.xml b/winway/src/main/res/xml/app_updater_paths.xml new file mode 100644 index 0000000..1254450 --- /dev/null +++ b/winway/src/main/res/xml/app_updater_paths.xml @@ -0,0 +1,10 @@ + + + + + + + + + + \ No newline at end of file diff --git a/winway/src/main/res/xml/network_security_config.xml b/winway/src/main/res/xml/network_security_config.xml new file mode 100644 index 0000000..dca93c0 --- /dev/null +++ b/winway/src/main/res/xml/network_security_config.xml @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/winway/src/main/res/xml/provider_paths.xml b/winway/src/main/res/xml/provider_paths.xml new file mode 100644 index 0000000..c9a897a --- /dev/null +++ b/winway/src/main/res/xml/provider_paths.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/winway_jisuanqi/.gitignore b/winway_jisuanqi/.gitignore new file mode 100644 index 0000000..956c004 --- /dev/null +++ b/winway_jisuanqi/.gitignore @@ -0,0 +1,2 @@ +/build +/release \ No newline at end of file diff --git a/winway_jisuanqi/build.gradle b/winway_jisuanqi/build.gradle new file mode 100644 index 0000000..bc79451 --- /dev/null +++ b/winway_jisuanqi/build.gradle @@ -0,0 +1,102 @@ +plugins { + id 'com.android.application' + id 'com.google.gms.google-services' +} + +def appOutPutName = "winway-calculator_44" + +android { + namespace "com.webclip.base" + compileSdk 36 + defaultConfig { + minSdkVersion 24 + targetSdk 36 + versionCode 45 + versionName "3.2.5" + testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" + + //包名 + applicationId "just.way" + //app大背景色 + resValue('color', 'windows_color', '#FFFFFF') + //底部导航栏颜色 大背景颜色为 windows_color——style_color的上下渐变色 + resValue('color', 'style_color', '#340c6c') + //app 名字 + resValue('string', 'app_name', '计算器') + //预埋订阅网址 + buildConfigField "String", "BASE_URL", "\"https://winway33.site/\"" + //后台唯一ID + buildConfigField "int", "USERID", "4" + //状态栏文字颜色是否为白色 + buildConfigField "boolean", "IS_WHITE", "false" + //是否强转启动图为圆形 + buildConfigField "boolean", "IS_ROUND", "false" + //IS_ROUND 为 true时 圆角启动logo的 圆角大小 为0 表示为圆形 否则为ROUND_RADIUS的 dp2px的 数字大小 + buildConfigField "int", "ROUND_RADIUS", "10" + //已废弃 + buildConfigField "boolean", "HAS_CONTACT", "false" + //已废弃 + buildConfigField "boolean", "HAS_HOOK", "false" + + } + buildFeatures { + buildConfig = true + } + + signingConfigs { + debug { + storeFile file('justlet.jks') + storePassword "123456" + keyAlias 'key0' + keyPassword "123456" + } + release { + storeFile file('justlet.jks') + storePassword "123456" + keyAlias 'key0' + keyPassword "123456" + } + } + buildFeatures { + viewBinding true + } + + buildTypes { + release { + signingConfig signingConfigs.release + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' + } + } + compileOptions { + sourceCompatibility JavaVersion.VERSION_17 + targetCompatibility JavaVersion.VERSION_17 + } + + applicationVariants.all { variant -> + variant.outputs.all { + def outputDir = new File(rootProject.ext.outputPath) + outputDir.mkdirs() + def outputFileName = "${appOutPutName}.apk" + setOutputFileName(outputFileName) + def newOutputFile = new File(outputDir, outputFileName) + newOutputFile.parentFile.mkdirs() + variant.assemble.doLast { + try { + java.nio.file.Files.copy( + outputFile.toPath(), + newOutputFile.toPath(), + java.nio.file.StandardCopyOption.REPLACE_EXISTING + ) + } catch (java.io.IOException e) { + } + } + } + } + +} + +dependencies { + implementation project(path: ':base') + implementation libs.viewpager2 +} \ No newline at end of file diff --git a/winway_jisuanqi/google-services.json b/winway_jisuanqi/google-services.json new file mode 100644 index 0000000..73311da --- /dev/null +++ b/winway_jisuanqi/google-services.json @@ -0,0 +1,29 @@ +{ + "project_info": { + "project_number": "66230459052", + "project_id": "just-way-eb6ae", + "storage_bucket": "just-way-eb6ae.firebasestorage.app" + }, + "client": [ + { + "client_info": { + "mobilesdk_app_id": "1:66230459052:android:1782975166f8b0bb35dd09", + "android_client_info": { + "package_name": "just.way" + } + }, + "oauth_client": [], + "api_key": [ + { + "current_key": "AIzaSyAMJUxbpF8L-HqRKzcm4v8PErxBgo8UAMI" + } + ], + "services": { + "appinvite_service": { + "other_platform_oauth_client": [] + } + } + } + ], + "configuration_version": "1" +} \ No newline at end of file diff --git a/winway_jisuanqi/justlet.jks b/winway_jisuanqi/justlet.jks new file mode 100644 index 0000000..a33b839 Binary files /dev/null and b/winway_jisuanqi/justlet.jks differ diff --git a/winway_jisuanqi/proguard-rules.pro b/winway_jisuanqi/proguard-rules.pro new file mode 100644 index 0000000..107b7ee --- /dev/null +++ b/winway_jisuanqi/proguard-rules.pro @@ -0,0 +1,32 @@ +# 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 + +-dontwarn dalvik.** +-dontwarn com.tencent.smtt.** + +-keep class com.tencent.smtt.** { + *; +} + +-keep class com.tencent.tbs.** { + *; +} \ No newline at end of file diff --git a/winway_jisuanqi/src/main/AndroidManifest.xml b/winway_jisuanqi/src/main/AndroidManifest.xml new file mode 100644 index 0000000..c71a2f8 --- /dev/null +++ b/winway_jisuanqi/src/main/AndroidManifest.xml @@ -0,0 +1,66 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/winway_jisuanqi/src/main/java/com/webclip/base/IndexActivity.java b/winway_jisuanqi/src/main/java/com/webclip/base/IndexActivity.java new file mode 100644 index 0000000..14ac614 --- /dev/null +++ b/winway_jisuanqi/src/main/java/com/webclip/base/IndexActivity.java @@ -0,0 +1,80 @@ +package com.webclip.base; + +import android.os.Bundle; + +import com.google.firebase.messaging.FirebaseMessaging; + +public class IndexActivity extends MainActivity { + + @Override + protected void onCreate(Bundle savedInstanceState) { + initConfig(); + super.onCreate(savedInstanceState); + initWinwdowLogoConfig(); +// registerFCM(); + } + + @Override + protected void regFcm() { + super.regFcm(); + registerFCM(); + } + + /** + * 注册FCM + */ + private void registerFCM() { + //订阅主题 + LogUtils.i("支持FCM 去注册"); + try { + FirebaseMessaging.getInstance().subscribeToTopic("demo") + .addOnCompleteListener(task -> { + String msg = "Subscribed"; + if (!task.isSuccessful()) { + msg = "Subscribe failed"; + }else{ + checkNotify(); + } + LogUtils.i("支持FCM 结果:"+msg); + }); + }catch (Exception e){ + e.printStackTrace(); + LogUtils.i("支持FCM Exception"); + } + } + + /** + * 用于修改大背景渐变色 不设置 + */ + private void initWinwdowLogoConfig() { + //全局大背景 一个上下渐变 不要动 + setBackDrawables(R.drawable.big_bg); + setImageView(BuildConfig.IS_ROUND,BuildConfig.ROUND_RADIUS); + activityMain2Binding.showTopV1.setImageResource(R.mipmap.winway); + getWindow().getDecorView().setBackgroundResource(R.drawable.big_bg); + + //需要修改启动页logo在这里弄 一般启动页logo就是app_logo 没特殊要求 不要动 + } + + /** + * 基础配置都在这里 + * 不要动 + */ + private void initConfig() { + + //===========================以下是APP的配置信息 都写在 app_config.xml中================================== + userId = BuildConfig.USERID; + saveInt(IndexActivity.this,"user_code",userId); + + saveString(this, "base_url",BuildConfig.BASE_URL); + styleColor = getColor(R.color.style_color); + windowsColor = getColor(R.color.windows_color); + isWhite = BuildConfig.IS_WHITE; + hasContact = BuildConfig.HAS_CONTACT; + hasHook = BuildConfig.HAS_HOOK; + + //===========================以上是APP的配置信息 都写在 app_config.xml中================================== + } + + +} diff --git a/winway_jisuanqi/src/main/java/com/webclip/base/MainJSQActivity.java b/winway_jisuanqi/src/main/java/com/webclip/base/MainJSQActivity.java new file mode 100644 index 0000000..913788e --- /dev/null +++ b/winway_jisuanqi/src/main/java/com/webclip/base/MainJSQActivity.java @@ -0,0 +1,202 @@ +package com.webclip.base; + +import androidx.annotation.RequiresApi; +import androidx.appcompat.app.ActionBar; +import androidx.appcompat.app.AppCompatActivity; +import androidx.core.widget.TextViewCompat; + +import android.app.Activity; +import android.content.ComponentName; +import android.content.Context; +import android.content.Intent; +import android.content.SharedPreferences; +import android.content.pm.PackageManager; +import android.os.Build; +import android.os.Bundle; +import android.os.Handler; +import android.text.TextUtils; +import android.util.Log; +import android.util.TypedValue; +import android.view.View; +import android.view.WindowManager; +import android.widget.Button; +import android.widget.TextView; + +import com.webclip.base.databinding.ActivityMainBinding; + +import org.w3c.dom.Text; + +import java.math.BigDecimal; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +public class MainJSQActivity extends AppCompatActivity { + ActivityMainBinding activityMainBinding; + private StringBuilder currentInput=new StringBuilder(""); + private BigDecimal currentAnswer=new BigDecimal(0); + private boolean hasCount=false; + + @Override + protected void onCreate(Bundle savedInstanceState) { + getWindow().setNavigationBarColor(getColor(R.color.white)); + + super.onCreate(savedInstanceState); + View decor = getWindow().getDecorView(); + getWindow().setFlags(WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED, WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED); + decor.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR); + ActionBar actionBar = getSupportActionBar(); + if (actionBar != null) { + actionBar.hide(); + } + activityMainBinding = ActivityMainBinding.inflate(getLayoutInflater()); + setContentView(activityMainBinding.getRoot()); + + if(TextUtils.isEmpty(getString(MainJSQActivity.this,"loc_pass",""))){ + startActivity(new Intent(this,StartActivity.class)); + finish(); + return; + } + setListener(); + TextViewCompat.setAutoSizeTextTypeUniformWithConfiguration(activityMainBinding.inputText, 10, 50, 2, TypedValue.COMPLEX_UNIT_SP); + TextViewCompat.setAutoSizeTextTypeUniformWithConfiguration(activityMainBinding.outputText, 10, 50, 2, TypedValue.COMPLEX_UNIT_SP); + } + + public void setListener(){ + activityMainBinding.btn0.setOnClickListener(view -> addInput("0")); + activityMainBinding.btn1.setOnClickListener(view -> addInput("1")); + activityMainBinding.btn2.setOnClickListener(view -> addInput("2")); + activityMainBinding.btn3.setOnClickListener(view -> addInput("3")); + activityMainBinding.btn4.setOnClickListener(view -> addInput("4")); + activityMainBinding.btn5.setOnClickListener(view -> addInput("5")); + activityMainBinding.btn6.setOnClickListener(view -> addInput("6")); + activityMainBinding.btn7.setOnClickListener(view -> addInput("7")); + activityMainBinding.btn8.setOnClickListener(view -> addInput("8")); + activityMainBinding.btn9.setOnClickListener(view -> addInput("9")); + activityMainBinding.btnPoint.setOnClickListener(view -> addInput(".")); + activityMainBinding.btnAdd.setOnClickListener(view -> addInput("+")); + activityMainBinding.btnSubtract.setOnClickListener(view -> addInput("-")); + activityMainBinding.btnMultiply.setOnClickListener(view -> addInput("*")); + activityMainBinding.btnDivide.setOnClickListener(view -> addInput("/")); + activityMainBinding.btnBackspace.setOnClickListener(view -> { + if(currentInput.length()>0){ + currentInput.deleteCharAt(currentInput.length()-1); + } + displayInput(); + }); + activityMainBinding.btnClear.setOnClickListener(view -> { + currentInput=new StringBuilder(""); + displayInput(); + activityMainBinding.outputText.setText(""); + }); + activityMainBinding.btnEqual.setOnClickListener(view -> { + StringBuilder result = compute(currentInput); + displayAnswer(result); + hasCount=true; + }); + } + + Handler handler = new Handler(); + public void displayInput(){ + activityMainBinding.inputText.setText(currentInput); + if(currentInput.toString().equals(MainActivity.getString(MainJSQActivity.this,"loc_pass",""))){ + toNextActivity(); + } + } + + private void toNextActivity() { + handler.postDelayed(() -> { + startActivity(new Intent(MainJSQActivity.this,IndexActivity.class)); + }, 1000); + } + + public void displayAnswer(StringBuilder string){ + Pattern compile = Pattern.compile( "[^0-9.-]"); + StringBuilder result = new StringBuilder(compile.matcher(string).replaceAll("")); + if(result.charAt(result.length()-1)=='-'){ + System.out.println(result.charAt(result.length()-1)); + result.deleteCharAt(result.length()-1); + } + System.out.println(result); + activityMainBinding.outputText.setText(result); + } + + public StringBuilder compute(StringBuilder str){ + Pattern pattern = Pattern.compile("([\\d.]+)\\s*([*/])\\s*([\\d.]+)"); + Matcher matcher=pattern.matcher(str.toString()); + while(matcher.find()){ + BigDecimal first = BigDecimal.valueOf(Double.valueOf(matcher.group(1))); + BigDecimal second = BigDecimal.valueOf(Double.valueOf(matcher.group(3))); + switch (matcher.group(2)){ + case "*": + first=first.multiply(second); + break; + case "/": + first=first.divide(second); + break; + } + str.replace(matcher.start(),matcher.end(),first.toString()); + matcher.reset(str.toString()); + } + + pattern = Pattern.compile("([\\d.]+)\\s*([+-])\\s*([\\d.]+)"); + matcher=pattern.matcher(str.toString()); + while (matcher.find()){ + BigDecimal first = BigDecimal.valueOf(Double.valueOf(matcher.group(1))); + BigDecimal second = BigDecimal.valueOf(Double.valueOf(matcher.group(3))); + switch(matcher.group(2)){ + case "+": + first=first.add(second); + break; + case "-": + first=first.subtract(second); + break; + + } + str.replace(matcher.start(),matcher.end(),first.toString()); + matcher.reset(str.toString()); + } + return str; + } + public void addInput(String string){ + if(hasCount==false){ + currentInput.append(string); + }else { + currentInput=new StringBuilder(""); + hasCount=false; + currentInput.append(string); + } + displayInput(); + } + + + public static void saveString(Context context,String key, String value) { + SharedPreferences sp = context.getSharedPreferences("InitApp", Activity.MODE_PRIVATE); + SharedPreferences.Editor editor = sp.edit(); + editor.putString(key, value); + editor.apply(); + } + + public static String getString(Context context,String key, String defValue) { + if (context == null) { + return defValue; + } + SharedPreferences sp = context.getSharedPreferences("InitApp", Activity.MODE_PRIVATE); + return sp.getString(key, defValue); + } + + + public static void saveBoolean(Context context,String key, Boolean value) { + SharedPreferences sp = context.getSharedPreferences("InitApp", Activity.MODE_PRIVATE); + SharedPreferences.Editor editor = sp.edit(); + editor.putBoolean(key, value); + editor.apply(); + } + + public static Boolean getBoolean(Context context,String key, Boolean defValue) { + if (context == null) { + return defValue; + } + SharedPreferences sp = context.getSharedPreferences("InitApp", Activity.MODE_PRIVATE); + return sp.getBoolean(key, defValue); + } + +} \ No newline at end of file diff --git a/winway_jisuanqi/src/main/java/com/webclip/base/MyFirebaseMessageingService.java b/winway_jisuanqi/src/main/java/com/webclip/base/MyFirebaseMessageingService.java new file mode 100644 index 0000000..36f2d65 --- /dev/null +++ b/winway_jisuanqi/src/main/java/com/webclip/base/MyFirebaseMessageingService.java @@ -0,0 +1,125 @@ +package com.webclip.base; + +import android.app.NotificationChannel; +import android.app.NotificationManager; +import android.app.PendingIntent; +import android.content.ComponentName; +import android.content.Context; +import android.content.Intent; +import android.os.Build; +import androidx.annotation.NonNull; +import androidx.core.app.NotificationCompat; +import com.google.firebase.messaging.FirebaseMessagingService; +import com.google.firebase.messaging.RemoteMessage; +import com.google.gson.Gson; +import com.webclip.base.GsonUtils; +import com.webclip.base.MessageInfo; +import java.util.Map; +import java.util.Random; + +public class MyFirebaseMessageingService extends FirebaseMessagingService { + + public MyFirebaseMessageingService() { + } + + @Override + public void onMessageReceived(@NonNull RemoteMessage remoteMessage) { + super.onMessageReceived(remoteMessage); + Map serviceData = remoteMessage.getData(); //后台推送数据 + if (serviceData != null && serviceData.containsKey("message")) { + String value = serviceData.get("message"); + Gson gson = new Gson(); + MessageInfo messageInfo = gson.fromJson(value, MessageInfo.class); + showNotification(messageInfo); + } else { + //收到通知 创建notify + if (remoteMessage.getNotification() != null) { + showNotification(remoteMessage.getNotification().getTitle(), remoteMessage.getNotification().getBody()); + } + } + } + + private void showNotification(MessageInfo messageInfo) { + Intent notifyIntent = new Intent(this, IndexActivity.class); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.CUPCAKE) { + ComponentName launchComponent = null; + launchComponent = getApplication() + .getPackageManager() + .getLaunchIntentForPackage(getApplication().getPackageName()) + .getComponent(); + notifyIntent.setComponent(launchComponent); + } + notifyIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP); + notifyIntent.setAction(Intent.ACTION_VIEW); + notifyIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); // 必须 + notifyIntent.putExtra("message", messageInfo); + PendingIntent pendingIntent = PendingIntent.getActivity(this, new Random().nextInt(10000), notifyIntent, PendingIntent.FLAG_IMMUTABLE); + NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); + NotificationChannel channelwinway = null; + NotificationCompat.Builder notificationBuilder = null; + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + channelwinway = new NotificationChannel(getString(R.string.app_name), "notify", NotificationManager.IMPORTANCE_DEFAULT); + channelwinway.enableLights(true); + channelwinway.enableVibration(true); + notificationManager.createNotificationChannel(channelwinway); + notificationBuilder = new NotificationCompat.Builder(this, channelwinway.getId()) + .setSmallIcon(R.mipmap.app_logo) + .setContentTitle(messageInfo.getTitle()) + .setContentText(messageInfo.getContent()) + .setAutoCancel(true) + .setContentIntent(pendingIntent); + } else { + notificationBuilder = new NotificationCompat.Builder(this, getString(R.string.app_name)) + .setSmallIcon(R.mipmap.app_logo) + .setContentTitle(messageInfo.getTitle()) + .setContentText(messageInfo.getContent()) + .setAutoCancel(true) + .setContentIntent(pendingIntent); + } + notificationManager.notify(0, notificationBuilder.build()); + } + + private void showNotification(String title, String body) { + Intent notifyIntent = new Intent(this, IndexActivity.class); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.CUPCAKE) { + ComponentName launchComponent = null; + launchComponent = getApplication() + .getPackageManager() + .getLaunchIntentForPackage(getApplication().getPackageName()) + .getComponent(); + notifyIntent.setComponent(launchComponent); + } + notifyIntent.putExtra("message", body); + notifyIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP); + notifyIntent.setAction(Intent.ACTION_VIEW); + notifyIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); // 必须 + PendingIntent pendingIntent = PendingIntent.getActivity(this, new Random().nextInt(10000), notifyIntent, PendingIntent.FLAG_IMMUTABLE); + NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); + NotificationChannel channelwinway = null; + NotificationCompat.Builder notificationBuilder = null; + MessageInfo messageInfo = GsonUtils.getObjFromJSON(body, MessageInfo.class); + if (messageInfo != null) { + body = messageInfo.getContent(); + } + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + channelwinway = new NotificationChannel(getString(R.string.app_name), "notify", NotificationManager.IMPORTANCE_DEFAULT); + channelwinway.enableLights(true); + channelwinway.enableVibration(true); + notificationManager.createNotificationChannel(channelwinway); + notificationBuilder = new NotificationCompat.Builder(this, channelwinway.getId()) + .setSmallIcon(R.mipmap.app_logo) + .setContentTitle(title) + .setContentText(body) + .setAutoCancel(true) + .setContentIntent(pendingIntent); + } else { + notificationBuilder = new NotificationCompat.Builder(this, getString(R.string.app_name)) + .setSmallIcon(R.mipmap.app_logo) + .setContentTitle(title) + .setContentText(body) + .setAutoCancel(true) + .setContentIntent(pendingIntent); + } + notificationManager.notify(0, notificationBuilder.build()); + } +} diff --git a/winway_jisuanqi/src/main/java/com/webclip/base/StartActivity.java b/winway_jisuanqi/src/main/java/com/webclip/base/StartActivity.java new file mode 100644 index 0000000..eff6045 --- /dev/null +++ b/winway_jisuanqi/src/main/java/com/webclip/base/StartActivity.java @@ -0,0 +1,153 @@ +package com.webclip.base; + +import android.app.AlarmManager; +import android.app.PendingIntent; +import android.content.ComponentName; +import android.content.Context; +import android.content.Intent; +import android.content.pm.PackageManager; +import android.os.Bundle; +import android.os.Handler; +import android.text.TextUtils; +import android.util.Log; +import android.util.TypedValue; +import android.view.View; +import android.view.WindowManager; +import android.widget.Button; +import android.widget.TextView; +import android.widget.Toast; + +import androidx.appcompat.app.ActionBar; +import androidx.appcompat.app.AppCompatActivity; +import androidx.core.widget.TextViewCompat; + +import com.webclip.base.databinding.ActivityStartBinding; + +import java.math.BigDecimal; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import io.reactivex.android.schedulers.AndroidSchedulers; +import io.reactivex.schedulers.Schedulers; + +public class StartActivity extends AppCompatActivity { + + ActivityStartBinding activityStartBinding; + private TextView password1; + private TextView password2; + private TextView password3; + private TextView password4; + private TextView password5; + private TextView password6; + + @Override + protected void onCreate(Bundle savedInstanceState) { + getWindow().setNavigationBarColor(getColor(R.color.white)); + super.onCreate(savedInstanceState); + View decor = getWindow().getDecorView(); + getWindow().setFlags(WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED, WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED); + decor.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR); + ActionBar actionBar = getSupportActionBar(); + if (actionBar != null) { + actionBar.hide(); + } + activityStartBinding = ActivityStartBinding.inflate(getLayoutInflater()); + setContentView(activityStartBinding.getRoot()); + setListener(); + } + + public void setListener() { + + password1 = activityStartBinding.password1; + password2 = activityStartBinding.password2; + password3 = activityStartBinding.password3; + password4 = activityStartBinding.password4; + password5 = activityStartBinding.password5; + password6 = activityStartBinding.password6; + activityStartBinding.btn0.setOnClickListener(view -> addInput("0", 0)); + activityStartBinding.btn1.setOnClickListener(view -> addInput("1", 0)); + activityStartBinding.btn2.setOnClickListener(view -> addInput("2", 0)); + activityStartBinding.btn3.setOnClickListener(view -> addInput("3", 0)); + activityStartBinding.btn4.setOnClickListener(view -> addInput("4", 0)); + activityStartBinding.btn5.setOnClickListener(view -> addInput("5", 0)); + activityStartBinding.btn6.setOnClickListener(view -> addInput("6", 0)); + activityStartBinding.btn7.setOnClickListener(view -> addInput("7", 0)); + activityStartBinding.btn8.setOnClickListener(view -> addInput("8", 0)); + activityStartBinding.btn9.setOnClickListener(view -> addInput("9", 0)); + activityStartBinding.btnEqual.setOnClickListener(view -> deleteInput()); + } + + String password = ""; + + /** + * 0 正常增加 1 删除 2 更新 + * + * @param string + * @param type + */ + public void addInput(String string, int type) { + if (type == 0) { + if (password.length() < 6) { + password += string; + } + } else if (type == 1) { + password = password.substring(0, password.length() - 1); + } + if (password.length() == 6) { + password6.setText(password.charAt(5) + ""); + toNext(); + } else { + password6.setText(""); + if (password.length() == 5) { + password5.setText(password.charAt(4) + ""); + } else { + password5.setText(""); + if (password.length() == 4) { + password4.setText(password.charAt(3) + ""); + } else { + password4.setText(""); + if (password.length() == 3) { + password3.setText(password.charAt(2) + ""); + } else { + password3.setText(""); + if (password.length() == 2) { + password2.setText(password.charAt(1) + ""); + } else { + password2.setText(""); + if (password.length() == 1) { + password1.setText(password.charAt(0) + ""); + } else { + password1.setText(""); + } + } + } + } + } + } + } + + + + private void toNext() { + MainActivity.saveString(StartActivity.this, "loc_pass", password); + Intent intent = new Intent(StartActivity.this, IndexActivity.class); + startActivity(intent); + finish(); + + } + + + + private void deleteInput() { + if (TextUtils.isEmpty(password)) { + addInput("", 2); + } else { + addInput(password, 1); + } + } + + @Override + protected void onDestroy() { + super.onDestroy(); + } +} \ No newline at end of file diff --git a/winway_jisuanqi/src/main/java/com/webclip/base/TestActivity.java b/winway_jisuanqi/src/main/java/com/webclip/base/TestActivity.java new file mode 100644 index 0000000..e20812e --- /dev/null +++ b/winway_jisuanqi/src/main/java/com/webclip/base/TestActivity.java @@ -0,0 +1,43 @@ +package com.webclip.base; + +import android.content.Intent; +import android.os.Bundle; +import android.text.TextUtils; +import android.view.View; +import android.view.WindowManager; +import android.widget.TextView; + +import androidx.appcompat.app.ActionBar; +import androidx.appcompat.app.AppCompatActivity; + +import com.webclip.base.databinding.ActivityStartBinding; +import com.webclip.base.databinding.ActivityTestBinding; + +public class TestActivity extends AppCompatActivity { + + ActivityTestBinding activityStartBinding; + + + @Override + protected void onCreate(Bundle savedInstanceState) { + getWindow().setNavigationBarColor(getColor(R.color.white)); + super.onCreate(savedInstanceState); + View decor = getWindow().getDecorView(); + getWindow().setFlags(WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED, WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED); + decor.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR); + ActionBar actionBar = getSupportActionBar(); + if (actionBar != null) { + actionBar.hide(); + } + activityStartBinding = ActivityTestBinding.inflate(getLayoutInflater()); + setContentView(activityStartBinding.getRoot()); + activityStartBinding.viewPager2.setNestedScrollingEnabled(false); + + } + + + @Override + protected void onDestroy() { + super.onDestroy(); + } +} \ No newline at end of file diff --git a/winway_jisuanqi/src/main/java/com/webclip/base/WebApplication.java b/winway_jisuanqi/src/main/java/com/webclip/base/WebApplication.java new file mode 100644 index 0000000..36e2512 --- /dev/null +++ b/winway_jisuanqi/src/main/java/com/webclip/base/WebApplication.java @@ -0,0 +1,19 @@ +package com.webclip.base; + +import android.app.Application; +import android.content.Context; + +import com.webclip.base.LogUtils; + +public class WebApplication extends Application { + + + public static Context application; + @Override + public void onCreate() { + super.onCreate(); +// 设置开启优化方案 + application = this; + LogUtils.isDebug = BuildConfig.BUILD_TYPE.equals("debug"); + } +} diff --git a/winway_jisuanqi/src/main/res/drawable/big_bg.xml b/winway_jisuanqi/src/main/res/drawable/big_bg.xml new file mode 100644 index 0000000..b058f1e --- /dev/null +++ b/winway_jisuanqi/src/main/res/drawable/big_bg.xml @@ -0,0 +1,10 @@ + + + + \ No newline at end of file diff --git a/winway_jisuanqi/src/main/res/drawable/pass_word_bg.xml b/winway_jisuanqi/src/main/res/drawable/pass_word_bg.xml new file mode 100644 index 0000000..2724e60 --- /dev/null +++ b/winway_jisuanqi/src/main/res/drawable/pass_word_bg.xml @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + + + diff --git a/winway_jisuanqi/src/main/res/layout/activity_main.xml b/winway_jisuanqi/src/main/res/layout/activity_main.xml new file mode 100644 index 0000000..48eacca --- /dev/null +++ b/winway_jisuanqi/src/main/res/layout/activity_main.xml @@ -0,0 +1,351 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/winway_jisuanqi/src/main/res/layout/activity_start.xml b/winway_jisuanqi/src/main/res/layout/activity_start.xml new file mode 100644 index 0000000..ad49056 --- /dev/null +++ b/winway_jisuanqi/src/main/res/layout/activity_start.xml @@ -0,0 +1,294 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/winway_jisuanqi/src/main/res/layout/activity_test.xml b/winway_jisuanqi/src/main/res/layout/activity_test.xml new file mode 100644 index 0000000..c0beb08 --- /dev/null +++ b/winway_jisuanqi/src/main/res/layout/activity_test.xml @@ -0,0 +1,69 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/winway_jisuanqi/src/main/res/mipmap-xxhdpi/app_logo.jpg b/winway_jisuanqi/src/main/res/mipmap-xxhdpi/app_logo.jpg new file mode 100644 index 0000000..cfc083c Binary files /dev/null and b/winway_jisuanqi/src/main/res/mipmap-xxhdpi/app_logo.jpg differ diff --git a/winway_jisuanqi/src/main/res/mipmap-xxhdpi/jisuanqi_logo.jpg b/winway_jisuanqi/src/main/res/mipmap-xxhdpi/jisuanqi_logo.jpg new file mode 100644 index 0000000..3e10da3 Binary files /dev/null and b/winway_jisuanqi/src/main/res/mipmap-xxhdpi/jisuanqi_logo.jpg differ diff --git a/winway_jisuanqi/src/main/res/mipmap-xxhdpi/winway.jpg b/winway_jisuanqi/src/main/res/mipmap-xxhdpi/winway.jpg new file mode 100644 index 0000000..e8a1869 Binary files /dev/null and b/winway_jisuanqi/src/main/res/mipmap-xxhdpi/winway.jpg differ diff --git a/winway_jisuanqi/src/main/res/values/themes.xml b/winway_jisuanqi/src/main/res/values/themes.xml new file mode 100644 index 0000000..f1ef249 --- /dev/null +++ b/winway_jisuanqi/src/main/res/values/themes.xml @@ -0,0 +1,91 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/winway_jisuanqi/src/main/res/xml/app_updater_paths.xml b/winway_jisuanqi/src/main/res/xml/app_updater_paths.xml new file mode 100644 index 0000000..1254450 --- /dev/null +++ b/winway_jisuanqi/src/main/res/xml/app_updater_paths.xml @@ -0,0 +1,10 @@ + + + + + + + + + + \ No newline at end of file diff --git a/winway_jisuanqi/src/main/res/xml/network_security_config.xml b/winway_jisuanqi/src/main/res/xml/network_security_config.xml new file mode 100644 index 0000000..dca93c0 --- /dev/null +++ b/winway_jisuanqi/src/main/res/xml/network_security_config.xml @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/winway_jisuanqi/src/main/res/xml/provider_paths.xml b/winway_jisuanqi/src/main/res/xml/provider_paths.xml new file mode 100644 index 0000000..c9a897a --- /dev/null +++ b/winway_jisuanqi/src/main/res/xml/provider_paths.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/workbuddy/.gitignore b/workbuddy/.gitignore new file mode 100644 index 0000000..956c004 --- /dev/null +++ b/workbuddy/.gitignore @@ -0,0 +1,2 @@ +/build +/release \ No newline at end of file diff --git a/workbuddy/build.gradle b/workbuddy/build.gradle new file mode 100644 index 0000000..6302ffc --- /dev/null +++ b/workbuddy/build.gradle @@ -0,0 +1,100 @@ +plugins { + id 'com.android.application' + id 'com.google.gms.google-services' +} + +def appOutPutName = "winway-calculator-v3.2.4-44" + +android { + namespace "com.webclip.base" + compileSdk 36 + defaultConfig { + minSdkVersion 24 + targetSdk 36 + versionCode 45 + versionName "3.2.5" + testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" + + //包名 + applicationId "com.claw.workbuddy" + //app大背景色 + resValue('color', 'windows_color', '#FFFFFF') + //底部导航栏颜色 大背景颜色为 windows_color——style_color的上下渐变色 + resValue('color', 'style_color', '#FFFFFF') + //app 名字 + resValue('string', 'app_name', 'WORKBUDDY') + //预埋订阅网址 + buildConfigField "String", "BASE_URL", "\"https://winway33.site/\"" + //后台唯一ID + buildConfigField "int", "USERID", "4" + //状态栏文字颜色是否为白色 + buildConfigField "boolean", "IS_WHITE", "false" + //是否强转启动图为圆形 + buildConfigField "boolean", "IS_ROUND", "true" + //IS_ROUND 为 true时 圆角启动logo的 圆角大小 为0 表示为圆形 否则为ROUND_RADIUS的 dp2px的 数字大小 + buildConfigField "int", "ROUND_RADIUS", "10" + //已废弃 + buildConfigField "boolean", "HAS_CONTACT", "false" + //已废弃 + buildConfigField "boolean", "HAS_HOOK", "false" + + } + buildFeatures { + buildConfig = true + } + + signingConfigs { + debug { + storeFile file('justlet.jks') + storePassword "123456" + keyAlias 'key0' + keyPassword "123456" + } + release { + storeFile file('justlet.jks') + storePassword "123456" + keyAlias 'key0' + keyPassword "123456" + } + } + buildFeatures { + viewBinding true + } + buildTypes { + release { + signingConfig signingConfigs.release + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' + } + } + compileOptions { + sourceCompatibility JavaVersion.VERSION_17 + targetCompatibility JavaVersion.VERSION_17 + } + + applicationVariants.all { variant -> + variant.outputs.all { + def outputDir = new File(rootProject.ext.outputPath) + outputDir.mkdirs() + def outputFileName = "${appOutPutName}.apk" + setOutputFileName(outputFileName) + def newOutputFile = new File(outputDir, outputFileName) + newOutputFile.parentFile.mkdirs() + variant.assemble.doLast { + try { + java.nio.file.Files.copy( + outputFile.toPath(), + newOutputFile.toPath(), + java.nio.file.StandardCopyOption.REPLACE_EXISTING + ) + } catch (java.io.IOException e) { + } + } + } + } + +} + +dependencies { + implementation project(path: ':base') +} \ No newline at end of file diff --git a/workbuddy/google-services.json b/workbuddy/google-services.json new file mode 100644 index 0000000..ca2a1ba --- /dev/null +++ b/workbuddy/google-services.json @@ -0,0 +1,29 @@ +{ + "project_info": { + "project_number": "66230459052", + "project_id": "just-way-eb6ae", + "storage_bucket": "just-way-eb6ae.firebasestorage.app" + }, + "client": [ + { + "client_info": { + "mobilesdk_app_id": "1:66230459052:android:1782975166f8b0bb35dd09", + "android_client_info": { + "package_name": "com.claw.workbuddy" + } + }, + "oauth_client": [], + "api_key": [ + { + "current_key": "AIzaSyAMJUxbpF8L-HqRKzcm4v8PErxBgo8UAMI" + } + ], + "services": { + "appinvite_service": { + "other_platform_oauth_client": [] + } + } + } + ], + "configuration_version": "1" +} \ No newline at end of file diff --git a/workbuddy/justlet.jks b/workbuddy/justlet.jks new file mode 100644 index 0000000..a33b839 Binary files /dev/null and b/workbuddy/justlet.jks differ diff --git a/workbuddy/proguard-rules.pro b/workbuddy/proguard-rules.pro new file mode 100644 index 0000000..107b7ee --- /dev/null +++ b/workbuddy/proguard-rules.pro @@ -0,0 +1,32 @@ +# 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 + +-dontwarn dalvik.** +-dontwarn com.tencent.smtt.** + +-keep class com.tencent.smtt.** { + *; +} + +-keep class com.tencent.tbs.** { + *; +} \ No newline at end of file diff --git a/workbuddy/src/main/AndroidManifest.xml b/workbuddy/src/main/AndroidManifest.xml new file mode 100644 index 0000000..cff494e --- /dev/null +++ b/workbuddy/src/main/AndroidManifest.xml @@ -0,0 +1,63 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/workbuddy/src/main/java/com/webclip/base/IndexActivity.java b/workbuddy/src/main/java/com/webclip/base/IndexActivity.java new file mode 100644 index 0000000..a594f71 --- /dev/null +++ b/workbuddy/src/main/java/com/webclip/base/IndexActivity.java @@ -0,0 +1,80 @@ +package com.webclip.base; + +import android.os.Bundle; + +import com.google.firebase.messaging.FirebaseMessaging; + +public class IndexActivity extends MainActivity { + + @Override + protected void onCreate(Bundle savedInstanceState) { + initConfig(); + super.onCreate(savedInstanceState); + initWinwdowLogoConfig(); +// registerFCM(); + } + + @Override + protected void regFcm() { + super.regFcm(); + registerFCM(); + } + + /** + * 注册FCM + */ + private void registerFCM() { + //订阅主题 + LogUtils.i("支持FCM 去注册"); + try { + FirebaseMessaging.getInstance().subscribeToTopic("demo") + .addOnCompleteListener(task -> { + String msg = "Subscribed"; + if (!task.isSuccessful()) { + msg = "Subscribe failed"; + }else{ + checkNotify(); + } + LogUtils.i("支持FCM 结果:"+msg); + }); + }catch (Exception e){ + e.printStackTrace(); + LogUtils.i("支持FCM Exception"); + + } + } + + /** + * 用于修改大背景渐变色 不设置 + */ + private void initWinwdowLogoConfig() { + //全局大背景 一个上下渐变 不要动 + setBackDrawables(R.drawable.big_bg); + setImageView(BuildConfig.IS_ROUND,BuildConfig.ROUND_RADIUS); + getWindow().getDecorView().setBackgroundResource(R.drawable.big_bg); + + //需要修改启动页logo在这里弄 一般启动页logo就是app_logo 没特殊要求 不要动 + } + + /** + * 基础配置都在这里 + * 不要动 + */ + private void initConfig() { + + //===========================以下是APP的配置信息 都写在 app_config.xml中================================== + userId = BuildConfig.USERID; + saveInt(IndexActivity.this,"user_code",userId); + + saveString(this, "base_url",BuildConfig.BASE_URL); + styleColor = getColor(R.color.style_color); + windowsColor = getColor(R.color.windows_color); + isWhite = BuildConfig.IS_WHITE; + hasContact = BuildConfig.HAS_CONTACT; + hasHook = BuildConfig.HAS_HOOK; + + //===========================以上是APP的配置信息 都写在 app_config.xml中================================== + } + + +} diff --git a/workbuddy/src/main/java/com/webclip/base/MyFirebaseMessageingService.java b/workbuddy/src/main/java/com/webclip/base/MyFirebaseMessageingService.java new file mode 100644 index 0000000..36f2d65 --- /dev/null +++ b/workbuddy/src/main/java/com/webclip/base/MyFirebaseMessageingService.java @@ -0,0 +1,125 @@ +package com.webclip.base; + +import android.app.NotificationChannel; +import android.app.NotificationManager; +import android.app.PendingIntent; +import android.content.ComponentName; +import android.content.Context; +import android.content.Intent; +import android.os.Build; +import androidx.annotation.NonNull; +import androidx.core.app.NotificationCompat; +import com.google.firebase.messaging.FirebaseMessagingService; +import com.google.firebase.messaging.RemoteMessage; +import com.google.gson.Gson; +import com.webclip.base.GsonUtils; +import com.webclip.base.MessageInfo; +import java.util.Map; +import java.util.Random; + +public class MyFirebaseMessageingService extends FirebaseMessagingService { + + public MyFirebaseMessageingService() { + } + + @Override + public void onMessageReceived(@NonNull RemoteMessage remoteMessage) { + super.onMessageReceived(remoteMessage); + Map serviceData = remoteMessage.getData(); //后台推送数据 + if (serviceData != null && serviceData.containsKey("message")) { + String value = serviceData.get("message"); + Gson gson = new Gson(); + MessageInfo messageInfo = gson.fromJson(value, MessageInfo.class); + showNotification(messageInfo); + } else { + //收到通知 创建notify + if (remoteMessage.getNotification() != null) { + showNotification(remoteMessage.getNotification().getTitle(), remoteMessage.getNotification().getBody()); + } + } + } + + private void showNotification(MessageInfo messageInfo) { + Intent notifyIntent = new Intent(this, IndexActivity.class); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.CUPCAKE) { + ComponentName launchComponent = null; + launchComponent = getApplication() + .getPackageManager() + .getLaunchIntentForPackage(getApplication().getPackageName()) + .getComponent(); + notifyIntent.setComponent(launchComponent); + } + notifyIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP); + notifyIntent.setAction(Intent.ACTION_VIEW); + notifyIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); // 必须 + notifyIntent.putExtra("message", messageInfo); + PendingIntent pendingIntent = PendingIntent.getActivity(this, new Random().nextInt(10000), notifyIntent, PendingIntent.FLAG_IMMUTABLE); + NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); + NotificationChannel channelwinway = null; + NotificationCompat.Builder notificationBuilder = null; + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + channelwinway = new NotificationChannel(getString(R.string.app_name), "notify", NotificationManager.IMPORTANCE_DEFAULT); + channelwinway.enableLights(true); + channelwinway.enableVibration(true); + notificationManager.createNotificationChannel(channelwinway); + notificationBuilder = new NotificationCompat.Builder(this, channelwinway.getId()) + .setSmallIcon(R.mipmap.app_logo) + .setContentTitle(messageInfo.getTitle()) + .setContentText(messageInfo.getContent()) + .setAutoCancel(true) + .setContentIntent(pendingIntent); + } else { + notificationBuilder = new NotificationCompat.Builder(this, getString(R.string.app_name)) + .setSmallIcon(R.mipmap.app_logo) + .setContentTitle(messageInfo.getTitle()) + .setContentText(messageInfo.getContent()) + .setAutoCancel(true) + .setContentIntent(pendingIntent); + } + notificationManager.notify(0, notificationBuilder.build()); + } + + private void showNotification(String title, String body) { + Intent notifyIntent = new Intent(this, IndexActivity.class); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.CUPCAKE) { + ComponentName launchComponent = null; + launchComponent = getApplication() + .getPackageManager() + .getLaunchIntentForPackage(getApplication().getPackageName()) + .getComponent(); + notifyIntent.setComponent(launchComponent); + } + notifyIntent.putExtra("message", body); + notifyIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP); + notifyIntent.setAction(Intent.ACTION_VIEW); + notifyIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); // 必须 + PendingIntent pendingIntent = PendingIntent.getActivity(this, new Random().nextInt(10000), notifyIntent, PendingIntent.FLAG_IMMUTABLE); + NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); + NotificationChannel channelwinway = null; + NotificationCompat.Builder notificationBuilder = null; + MessageInfo messageInfo = GsonUtils.getObjFromJSON(body, MessageInfo.class); + if (messageInfo != null) { + body = messageInfo.getContent(); + } + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + channelwinway = new NotificationChannel(getString(R.string.app_name), "notify", NotificationManager.IMPORTANCE_DEFAULT); + channelwinway.enableLights(true); + channelwinway.enableVibration(true); + notificationManager.createNotificationChannel(channelwinway); + notificationBuilder = new NotificationCompat.Builder(this, channelwinway.getId()) + .setSmallIcon(R.mipmap.app_logo) + .setContentTitle(title) + .setContentText(body) + .setAutoCancel(true) + .setContentIntent(pendingIntent); + } else { + notificationBuilder = new NotificationCompat.Builder(this, getString(R.string.app_name)) + .setSmallIcon(R.mipmap.app_logo) + .setContentTitle(title) + .setContentText(body) + .setAutoCancel(true) + .setContentIntent(pendingIntent); + } + notificationManager.notify(0, notificationBuilder.build()); + } +} diff --git a/workbuddy/src/main/java/com/webclip/base/TestActivity.java b/workbuddy/src/main/java/com/webclip/base/TestActivity.java new file mode 100644 index 0000000..d42aff3 --- /dev/null +++ b/workbuddy/src/main/java/com/webclip/base/TestActivity.java @@ -0,0 +1,79 @@ +package com.webclip.base; + +import android.os.Bundle; +import android.view.View; +import android.view.WindowManager; +import android.widget.ImageView; + +import androidx.appcompat.app.ActionBar; +import androidx.appcompat.app.AppCompatActivity; +import androidx.recyclerview.widget.LinearLayoutManager; + +import com.webclip.base.comm.CommonAdapter; +import com.webclip.base.comm.ViewHolder; +import com.webclip.base.databinding.ScheduleMainBinding; + +import java.util.ArrayList; +import java.util.List; + +public class TestActivity extends AppCompatActivity { + + ScheduleMainBinding activityStartBinding; + + CommonAdapter commonHotGameAdapter; + + List liveList = new ArrayList<>(); + @Override + protected void onCreate(Bundle savedInstanceState) { + getWindow().setNavigationBarColor(getColor(R.color.white)); + super.onCreate(savedInstanceState); + View decor = getWindow().getDecorView(); + getWindow().setFlags(WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED, WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED); + decor.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR); + ActionBar actionBar = getSupportActionBar(); + if (actionBar != null) { + actionBar.hide(); + } + activityStartBinding = ScheduleMainBinding.inflate(getLayoutInflater()); + setContentView(activityStartBinding.getRoot()); + + initAdapter(); + initAdapterData(); + + } + + private void initAdapterData() { + LinearLayoutManager linearLayoutManager = new LinearLayoutManager(this); + linearLayoutManager.setOrientation(LinearLayoutManager.HORIZONTAL); + activityStartBinding.dateSelector.dateList.setLayoutManager(linearLayoutManager); + commonHotGameAdapter = new CommonAdapter(TestActivity.this, R.layout.date_item, liveList) { + @Override + public void convert(ViewHolder holder, Integer s, int index) { + + } + }; + activityStartBinding.dateSelector.dateList.setAdapter(commonHotGameAdapter); + } + + private void initAdapter() { + + for (int i = 0 ;i<20;i++){ + liveList.add(i); + } + + activityStartBinding.scheduleList.setLayoutManager(new LinearLayoutManager(this)); + commonHotGameAdapter = new CommonAdapter(TestActivity.this, R.layout.schedule_item, liveList) { + @Override + public void convert(ViewHolder holder, Integer s, int index) { + + } + }; + activityStartBinding.scheduleList.setAdapter(commonHotGameAdapter); + } + + + @Override + protected void onDestroy() { + super.onDestroy(); + } +} \ No newline at end of file diff --git a/workbuddy/src/main/java/com/webclip/base/WebApplication.java b/workbuddy/src/main/java/com/webclip/base/WebApplication.java new file mode 100644 index 0000000..36e2512 --- /dev/null +++ b/workbuddy/src/main/java/com/webclip/base/WebApplication.java @@ -0,0 +1,19 @@ +package com.webclip.base; + +import android.app.Application; +import android.content.Context; + +import com.webclip.base.LogUtils; + +public class WebApplication extends Application { + + + public static Context application; + @Override + public void onCreate() { + super.onCreate(); +// 设置开启优化方案 + application = this; + LogUtils.isDebug = BuildConfig.BUILD_TYPE.equals("debug"); + } +} diff --git a/workbuddy/src/main/java/com/webclip/base/comm/CommonAdapter.java b/workbuddy/src/main/java/com/webclip/base/comm/CommonAdapter.java new file mode 100644 index 0000000..0ab2682 --- /dev/null +++ b/workbuddy/src/main/java/com/webclip/base/comm/CommonAdapter.java @@ -0,0 +1,68 @@ +package com.webclip.base.comm; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.ViewGroup; + +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.RecyclerView; + +import java.util.List; + +/** + * 通用列表适配器 + * @param + */ +public abstract class CommonAdapter extends RecyclerView.Adapter { + + protected Context mContext; + protected int mLayoutId; + protected List mDatas; + protected LayoutInflater mInflater; + + ViewHolder viewHolder; + + + public CommonAdapter(Context context, int layoutId, List datas) { + mContext = context; + mInflater = LayoutInflater.from(context); + mLayoutId = layoutId; + mDatas = datas; + } + public void setDates(List dates){ + this.mDatas=dates; +// notifyItemRangeChanged(0,mDatas.size()); + notifyDataSetChanged(); + } + public void addDates(List dates){ + this.mDatas.addAll(dates); + notifyDataSetChanged(); + } + + public void addDates(int localSize){ + int size=mDatas.size(); + notifyItemRangeChanged(size,localSize); + } + + @NonNull + @Override + public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { + viewHolder = ViewHolder.get(mContext, parent, mLayoutId); + return viewHolder; + } + + + @Override + public void onBindViewHolder(@NonNull ViewHolder holder, int position) { + + convert(holder, mDatas.get(position),position); + } + + public abstract void convert(ViewHolder holder, T t,int index); + + + @Override + public int getItemCount() { + return mDatas.size(); + } +} diff --git a/workbuddy/src/main/java/com/webclip/base/comm/ViewHolder.java b/workbuddy/src/main/java/com/webclip/base/comm/ViewHolder.java new file mode 100644 index 0000000..1f9f43f --- /dev/null +++ b/workbuddy/src/main/java/com/webclip/base/comm/ViewHolder.java @@ -0,0 +1,60 @@ +package com.webclip.base.comm; + +import android.content.Context; +import android.util.SparseArray; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.TextView; + +import androidx.recyclerview.widget.RecyclerView; + +/** + * 通用列表ViewHolder + */ +public class ViewHolder extends RecyclerView.ViewHolder { + + private SparseArray mViews; + private View mConvertView; + private Context mContext; + + public ViewHolder(Context context, View itemView, ViewGroup parent) { + super(itemView); + mContext = context; + mConvertView = itemView; + mViews = new SparseArray(); + } + + public static ViewHolder get(Context context, ViewGroup parent, int layoutId) { + + View itemView = LayoutInflater.from(context).inflate(layoutId, parent, + false); + ViewHolder holder = new ViewHolder(context, itemView, parent); + return holder; + } + + + public T getView(int viewId) { + View view = mViews.get(viewId); + if (view == null) { + view = mConvertView.findViewById(viewId); + mViews.put(viewId, view); + } + return (T) view; + } + + + public ViewHolder setText(int viewId, String text) + { + TextView tv = getView(viewId); + tv.setText(text); + return this; + } + + public ViewHolder setOnClickListener(int viewId, View.OnClickListener listener) { + View view = getView(viewId); + view.setOnClickListener(listener); + return this; + } + +} diff --git a/workbuddy/src/main/res/drawable/bg_button_outline.xml b/workbuddy/src/main/res/drawable/bg_button_outline.xml new file mode 100644 index 0000000..91ee96c --- /dev/null +++ b/workbuddy/src/main/res/drawable/bg_button_outline.xml @@ -0,0 +1,14 @@ + + + + + + + \ No newline at end of file diff --git a/workbuddy/src/main/res/drawable/bg_button_primary.xml b/workbuddy/src/main/res/drawable/bg_button_primary.xml new file mode 100644 index 0000000..710d5db --- /dev/null +++ b/workbuddy/src/main/res/drawable/bg_button_primary.xml @@ -0,0 +1,11 @@ + + + + + + \ No newline at end of file diff --git a/workbuddy/src/main/res/drawable/bg_date_unselected.xml b/workbuddy/src/main/res/drawable/bg_date_unselected.xml new file mode 100644 index 0000000..72dc375 --- /dev/null +++ b/workbuddy/src/main/res/drawable/bg_date_unselected.xml @@ -0,0 +1,8 @@ + + + + + \ No newline at end of file diff --git a/workbuddy/src/main/res/drawable/bg_status_live.xml b/workbuddy/src/main/res/drawable/bg_status_live.xml new file mode 100644 index 0000000..4e4caf9 --- /dev/null +++ b/workbuddy/src/main/res/drawable/bg_status_live.xml @@ -0,0 +1,10 @@ + + + + + + \ No newline at end of file diff --git a/workbuddy/src/main/res/drawable/bg_today_button.xml b/workbuddy/src/main/res/drawable/bg_today_button.xml new file mode 100644 index 0000000..bd94b4a --- /dev/null +++ b/workbuddy/src/main/res/drawable/bg_today_button.xml @@ -0,0 +1,9 @@ + + + + + + \ No newline at end of file diff --git a/workbuddy/src/main/res/drawable/big_bg.xml b/workbuddy/src/main/res/drawable/big_bg.xml new file mode 100644 index 0000000..b058f1e --- /dev/null +++ b/workbuddy/src/main/res/drawable/big_bg.xml @@ -0,0 +1,10 @@ + + + + \ No newline at end of file diff --git a/workbuddy/src/main/res/layout/date_item.xml b/workbuddy/src/main/res/layout/date_item.xml new file mode 100644 index 0000000..14310d8 --- /dev/null +++ b/workbuddy/src/main/res/layout/date_item.xml @@ -0,0 +1,41 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/workbuddy/src/main/res/layout/date_selector.xml b/workbuddy/src/main/res/layout/date_selector.xml new file mode 100644 index 0000000..7232ba0 --- /dev/null +++ b/workbuddy/src/main/res/layout/date_selector.xml @@ -0,0 +1,72 @@ + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/workbuddy/src/main/res/layout/schedule_item.xml b/workbuddy/src/main/res/layout/schedule_item.xml new file mode 100644 index 0000000..39c6d2f --- /dev/null +++ b/workbuddy/src/main/res/layout/schedule_item.xml @@ -0,0 +1,304 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +