From 376879bb742bb4bbbe1bed603d7ca6f438b23cde Mon Sep 17 00:00:00 2001 From: Xisheng-Zhao Date: Wed, 3 Jun 2026 18:10:55 +0800 Subject: [PATCH] Complete public analytics SDK setup --- app/proguard-rules.pro | 12 +++++++++ .../java/ai/multica/app/AppAnalytics.java | 27 ++++++++++++++++++- .../ai/multica/app/ComposePilotActivity.kt | 16 +++++------ app/src/public/AndroidManifest.xml | 3 +++ 4 files changed, 49 insertions(+), 9 deletions(-) create mode 100644 app/src/public/AndroidManifest.xml diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro index 930ec23..40a6715 100644 --- a/app/proguard-rules.pro +++ b/app/proguard-rules.pro @@ -1,2 +1,14 @@ -keep class com.umeng.** { *; } +-keep class org.repackage.** { *; } +-keep class com.uyumao.** { *; } +-keepclassmembers class * { + public (org.json.JSONObject); +} +-keepclassmembers enum * { + public static **[] values(); + public static ** valueOf(java.lang.String); +} +-keep public class **.R$* { + public static final int *; +} -keep class com.posthog.** { *; } diff --git a/app/src/main/java/ai/multica/app/AppAnalytics.java b/app/src/main/java/ai/multica/app/AppAnalytics.java index 759aa6a..f90b14f 100644 --- a/app/src/main/java/ai/multica/app/AppAnalytics.java +++ b/app/src/main/java/ai/multica/app/AppAnalytics.java @@ -33,16 +33,23 @@ public final class AppAnalytics { public static void denyConsent(Context context) { new AnalyticsConsentStore(context).deny(); + submitUmengPolicyGrantResult(context, false); provider.optOut(); } + public static void initializeIfAllowed(Context context) { Context appContext = context.getApplicationContext(); preInitializeIfNeeded(appContext); - if (!new AnalyticsConsentStore(appContext).isGranted()) { + AnalyticsConsentStore consentStore = new AnalyticsConsentStore(appContext); + if (!consentStore.isGranted()) { + if (consentStore.hasDecision()) { + submitUmengPolicyGrantResult(appContext, false); + } Log.i(TAG, "Analytics disabled until user grants consent."); return; } + submitUmengPolicyGrantResult(appContext, true); if (initialized) { trackAppOpenOnce(appContext); return; @@ -72,6 +79,20 @@ public final class AppAnalytics { } } + private static void submitUmengPolicyGrantResult(Context context, boolean granted) { + if (!BuildConfig.UMENG_ENABLED) { + return; + } + try { + Class.forName("com.umeng.commonsdk.UMConfigure") + .getMethod("submitPolicyGrantResult", Context.class, boolean.class) + .invoke(null, context.getApplicationContext(), granted); + Log.i(TAG, "Umeng policy grant result submitted granted=" + granted); + } catch (Throwable error) { + Log.w(TAG, "Umeng policy grant result failed; app launch continues.", error); + } + } + static String selectedRouteForTesting(Context context) { return selectRoute(context); } @@ -149,11 +170,13 @@ public final class AppAnalytics { @Override public void optOut() {} + }; void trackAppOpen(Map properties); void optOut(); + } private static final class UmengAnalyticsProvider implements AnalyticsProvider { @@ -204,6 +227,7 @@ public final class AppAnalytics { @Override public void optOut() {} + } private static final class PostHogAnalyticsProvider implements AnalyticsProvider { @@ -282,6 +306,7 @@ public final class AppAnalytics { } } + private static void invokeSetter(Class configClass, Object config, String methodName, boolean value) { try { configClass.getMethod(methodName, boolean.class).invoke(config, value); diff --git a/app/src/main/java/ai/multica/app/ComposePilotActivity.kt b/app/src/main/java/ai/multica/app/ComposePilotActivity.kt index f04238f..ef64dc2 100644 --- a/app/src/main/java/ai/multica/app/ComposePilotActivity.kt +++ b/app/src/main/java/ai/multica/app/ComposePilotActivity.kt @@ -620,9 +620,9 @@ private fun ComposePilotApp( visible = showAnalyticsConsent, title = if (zh) "允许基础使用统计?" else "Allow basic usage analytics?", message = if (zh) { - "Multi-Casual 只会上报 app_open 启动事件,用于统计用户量和日活。不会采集页面浏览、聊天内容、文件内容、邮箱、Token 或精确位置。中国大陆用户走友盟+,海外用户走 PostHog。你可以选择不同意,应用仍可继续使用。" + "Multi-Casual 只会上报 app_open 启动事件,用于统计用户量和日活。中国大陆用户使用友盟SDK,海外用户使用 PostHog SDK;SDK 可能按各自规则处理设备信息、Android ID、IP 地址和网络状态。我们不会采集页面浏览、聊天内容、文件内容、邮箱、Token 或精确位置。你可以选择不同意,应用仍可继续使用。" } else { - "Multi-Casual only reports the app_open event to measure user count and daily active users. It does not collect page views, chat content, file content, email, tokens, or precise location. Mainland China routes to Umeng+, while global users route to PostHog. You can decline and still use the app." + "Multi-Casual only reports the app_open event to measure user count and daily active users. Mainland China uses the Umeng SDK, while global users use the PostHog SDK; each SDK may process device information, Android ID, IP address, and network state under its own policy. We do not collect page views, chat content, file content, email, tokens, or precise location. You can decline and still use the app." }, cancelText = if (zh) "不同意" else "Decline", confirmText = if (zh) "同意并继续" else "Agree", @@ -3070,7 +3070,7 @@ private fun PilotChatSessions( runCatching { api.createChatSession(workspaceId, agent.id, sessionTitle) } } creating = false - result.onSuccess { + result.onSuccess { session -> title = "" actionText = if (zh) "聊天会话已创建" else "Chat session created" refresh++ @@ -6915,9 +6915,9 @@ private fun PilotIssueForm( } } saving = false - result.onSuccess { + result.onSuccess { saved -> pendingIssueAttachments = emptyList() - onSaved(it) + onSaved(saved) }.onFailure { saveError = "${if (zh) "保存失败" else "Save failed"}: ${it.message ?: it.toString()}" } @@ -12758,11 +12758,11 @@ private fun PilotProjects( } } saving = false - result.onSuccess { + result.onSuccess { saved -> formOpen = false editingProject = null projectQuery = "" - resultText = it.name + resultText = saved.name onRefresh() }.onFailure { resultText = "${if (zh) "项目保存失败" else "Project save failed"}: ${it.message ?: it.toString()}" @@ -19536,7 +19536,7 @@ private fun PilotAutopilotsSettings(api: ApiClient, workspaceId: String, zh: Boo } } saving = false - result.onSuccess { + result.onSuccess { saved -> resultText = if (zh) "已保存" else "Saved" resetForm() refresh++ diff --git a/app/src/public/AndroidManifest.xml b/app/src/public/AndroidManifest.xml new file mode 100644 index 0000000..4e67c13 --- /dev/null +++ b/app/src/public/AndroidManifest.xml @@ -0,0 +1,3 @@ + + +