diff --git a/appbase/src/beta/AndroidManifest.xml b/appbase/src/beta/AndroidManifest.xml
index 26dcaf0..f8f4deb 100644
--- a/appbase/src/beta/AndroidManifest.xml
+++ b/appbase/src/beta/AndroidManifest.xml
@@ -10,6 +10,14 @@
tools:replace="android:icon"
android:icon="@drawable/ic_winboll_beta">
+
+
+
+
\ No newline at end of file
diff --git a/appbase/src/beta/res/values/strings.xml b/appbase/src/beta/res/values/strings.xml
index 49fc4c9..7aa8e1f 100644
--- a/appbase/src/beta/res/values/strings.xml
+++ b/appbase/src/beta/res/values/strings.xml
@@ -2,5 +2,8 @@
APPBase+
+ 邮件设置
+ 异常邮件接收设置
+ 快捷方式不可用
diff --git a/appbase/src/beta/res/xml/shortcuts.xml b/appbase/src/beta/res/xml/shortcuts.xml
new file mode 100644
index 0000000..dc09e5c
--- /dev/null
+++ b/appbase/src/beta/res/xml/shortcuts.xml
@@ -0,0 +1,16 @@
+
+
+
+
+
+
+
diff --git a/appbase/src/main/java/cc/winboll/studio/appbase/App.java b/appbase/src/main/java/cc/winboll/studio/appbase/App.java
index 39c7e3c..ed1c15c 100644
--- a/appbase/src/main/java/cc/winboll/studio/appbase/App.java
+++ b/appbase/src/main/java/cc/winboll/studio/appbase/App.java
@@ -55,7 +55,9 @@ public class App extends GlobalApplication {
this,
getPackageName(),
stackTraceStr,
- CrashActivity.class
+ CrashActivity.class,
+ "APPBase",
+ "studio@winboll.cc"
);
}
}
diff --git a/appbase/src/main/java/cc/winboll/studio/appbase/MainActivity.java b/appbase/src/main/java/cc/winboll/studio/appbase/MainActivity.java
index b26c08e..be83a7f 100644
--- a/appbase/src/main/java/cc/winboll/studio/appbase/MainActivity.java
+++ b/appbase/src/main/java/cc/winboll/studio/appbase/MainActivity.java
@@ -1,12 +1,8 @@
package cc.winboll.studio.appbase;
import android.app.Activity;
-import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
-import android.content.pm.ShortcutInfo;
-import android.content.pm.ShortcutManager;
-import android.graphics.drawable.Icon;
import android.net.Uri;
import android.os.Bundle;
import android.view.Menu;
@@ -69,31 +65,11 @@ public class MainActivity extends Activity {
/**
* 注册桌面图标静态快捷方式
* 长按桌面图标后显示快捷菜单,点击可直接打开异常邮件接收设置页面
+ * 静态快捷方式已通过 res/xml/shortcuts.xml 配置,此处无需动态注册
*/
private void setupShortcuts() {
- if (!"cc.winboll.studio.appbase.beta".equals(getPackageName())) {
- return;
- }
-
- ShortcutManager shortcutManager = getSystemService(ShortcutManager.class);
- if (shortcutManager == null) {
- return;
- }
-
- Intent intent = new Intent(this, APPExcetionMailSettingsActivity.class);
- intent.setAction(Intent.ACTION_VIEW);
- intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
-
- ShortcutInfo shortcut = new ShortcutInfo.Builder(this, "exception_mail_settings")
- .setShortLabel("邮件设置")
- .setLongLabel("异常邮件接收设置")
- .setIcon(Icon.createWithResource(this, R.drawable.ic_winboll))
- .setIntent(intent)
- .build();
-
- shortcutManager.setDynamicShortcuts(
- java.util.Arrays.asList(shortcut)
- );
+ // 静态快捷方式仅在 beta 渠道生效,通过 AndroidManifest.xml 中的 meta-data 配置
+ // beta 渠道使用 res/xml/shortcuts.xml 定义快捷方式
}
/**
diff --git a/libappbase/src/main/java/cc/winboll/studio/libappbase/utils/CrashHandleNotifyUtils.java b/libappbase/src/main/java/cc/winboll/studio/libappbase/utils/CrashHandleNotifyUtils.java
index 06f9d73..29b10de 100644
--- a/libappbase/src/main/java/cc/winboll/studio/libappbase/utils/CrashHandleNotifyUtils.java
+++ b/libappbase/src/main/java/cc/winboll/studio/libappbase/utils/CrashHandleNotifyUtils.java
@@ -67,11 +67,15 @@ public class CrashHandleNotifyUtils {
* @param hostPackageName 宿主应用包名
* @param errorLog 崩溃日志内容
* @param reportCrashActivity 崩溃详情跳转Activity类
+ * @param appAPKName 应用APK名称(用于邮件标题)
+ * @param emailTo 邮件接收者地址
*/
public static void handleUncaughtException(final android.app.Application hostApp,
final String hostPackageName,
final String errorLog,
- final Class> reportCrashActivity) {
+ final Class> reportCrashActivity,
+ final String appAPKName,
+ final String emailTo) {
LogUtils.d(TAG, "handleUncaughtException 进入方法");
if (hostApp == null || TextUtils.isEmpty(hostPackageName) || TextUtils.isEmpty(errorLog)) {
LogUtils.e(TAG, "handleUncaughtException 参数为空校验不通过");
@@ -87,7 +91,14 @@ public class CrashHandleNotifyUtils {
sCrashLogCacheFilePath = crashLogFilePath;
final Intent shareIntent = new Intent(hostApp, ShareLogActivity.class);
shareIntent.putExtra(ShareLogActivity.EXTRA_CRASH_LOG_FILEPATH, crashLogFilePath);
- shareIntent.putExtra(ShareLogActivity.EXTRA_CRASH_LOG_SUBJECT, "崩溃日志");
+ String subject = "崩溃日志";
+ if (appAPKName != null && !appAPKName.isEmpty()) {
+ subject = appAPKName + " - 崩溃日志";
+ }
+ shareIntent.putExtra(ShareLogActivity.EXTRA_CRASH_LOG_SUBJECT, subject);
+ if (emailTo != null && !emailTo.isEmpty()) {
+ shareIntent.putExtra(ShareLogActivity.EXTRA_CRASH_LOG_EMAIL_TO, emailTo);
+ }
shareIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
final PendingIntent sharePendingIntent = createSharePendingIntent(hostApp, shareIntent);
sendCrashNotification(hostApp, hostPackageName, hostAppName, errorLog, reportCrashActivity, sharePendingIntent);
@@ -109,7 +120,21 @@ public class CrashHandleNotifyUtils {
LogUtils.w(TAG, "未携带宿主包名,默认使用应用自身包名");
}
final String errorLog = intent.getStringExtra(CrashHandler.EXTRA_CRASH_LOG);
- handleUncaughtException(hostApp, hostPackageName, errorLog, reportCrashActivity);
+ handleUncaughtException(hostApp, hostPackageName, errorLog, reportCrashActivity, null, null);
+ }
+
+ /**
+ * 重载兼容方法:适配原有调用方式
+ * @param hostApp 宿主Application实例
+ * @param hostPackageName 宿主应用包名
+ * @param errorLog 崩溃日志内容
+ * @param reportCrashActivity 崩溃详情跳转Activity类
+ */
+ public static void handleUncaughtException(final android.app.Application hostApp,
+ final String hostPackageName,
+ final String errorLog,
+ final Class> reportCrashActivity) {
+ handleUncaughtException(hostApp, hostPackageName, errorLog, reportCrashActivity, null, null);
}
/**
@@ -355,7 +380,7 @@ public class CrashHandleNotifyUtils {
.setWhen(System.currentTimeMillis())
.setPriority(Notification.PRIORITY_DEFAULT);
if (shareIntent != null) {
- builder.addAction(android.R.drawable.ic_menu_send, "分享日志", shareIntent);
+ builder.addAction(android.R.drawable.ic_menu_send, "发送日志给开发组", shareIntent);
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
return builder.build();
diff --git a/libappbase/src/main/java/cc/winboll/studio/libappbase/utils/ShareLogActivity.java b/libappbase/src/main/java/cc/winboll/studio/libappbase/utils/ShareLogActivity.java
index a9edd48..b7a7662 100644
--- a/libappbase/src/main/java/cc/winboll/studio/libappbase/utils/ShareLogActivity.java
+++ b/libappbase/src/main/java/cc/winboll/studio/libappbase/utils/ShareLogActivity.java
@@ -2,6 +2,9 @@ package cc.winboll.studio.libappbase.utils;
import android.app.Activity;
import android.content.Intent;
+import android.content.pm.PackageInfo;
+import android.content.pm.PackageManager;
+import android.os.Build;
import android.os.Bundle;
import android.util.Log;
import android.widget.Toast;
@@ -21,6 +24,7 @@ public class ShareLogActivity extends Activity {
public static final String TAG = "ShareLogActivity";
public static final String EXTRA_CRASH_LOG_FILEPATH = "crash_log_filepath";
public static final String EXTRA_CRASH_LOG_SUBJECT = "crash_log_subject";
+ public static final String EXTRA_CRASH_LOG_EMAIL_TO = "crash_log_email_to";
@Override
protected void onCreate(final Bundle savedInstanceState) {
@@ -43,10 +47,40 @@ public class ShareLogActivity extends Activity {
}
final String subject = intent.getStringExtra(EXTRA_CRASH_LOG_SUBJECT);
- handleShareCrashLog(crashLogFilePath, subject);
+ final String emailTo = intent.getStringExtra(EXTRA_CRASH_LOG_EMAIL_TO);
+ handleShareCrashLog(crashLogFilePath, subject, emailTo);
}
- private void handleShareCrashLog(final String crashLogFilePath, final String subject) {
+ private String getAppInfo() {
+ StringBuilder sb = new StringBuilder();
+ sb.append("========== 应用信息 ==========\n");
+ try {
+ PackageInfo pkgInfo = getPackageManager().getPackageInfo(getPackageName(), 0);
+ sb.append("应用包名: ").append(getPackageName()).append("\n");
+ sb.append("版本名称: ").append(pkgInfo.versionName).append("\n");
+ sb.append("版本号: ").append(pkgInfo.versionCode).append("\n");
+ } catch (PackageManager.NameNotFoundException e) {
+ sb.append("应用包名: ").append(getPackageName()).append("\n");
+ sb.append("版本信息: 获取失败\n");
+ }
+ sb.append("\n");
+ return sb.toString();
+ }
+
+ private String getDeviceInfo() {
+ StringBuilder sb = new StringBuilder();
+ sb.append("========== 设备信息 ==========\n");
+ sb.append("设备制造商: ").append(Build.MANUFACTURER).append("\n");
+ sb.append("设备型号: ").append(Build.MODEL).append("\n");
+ sb.append("设备名称: ").append(Build.DEVICE).append("\n");
+ sb.append("Android版本: ").append(Build.VERSION.RELEASE).append("\n");
+ sb.append("Android API: ").append(Build.VERSION.SDK_INT).append("\n");
+ sb.append("系统指纹: ").append(Build.FINGERPRINT).append("\n");
+ sb.append("\n");
+ return sb.toString();
+ }
+
+ private void handleShareCrashLog(final String crashLogFilePath, final String subject, final String emailTo) {
Log.d(TAG, "handleShareCrashLog crashLogFilePath = " + crashLogFilePath);
final File crashLogFile = new File(crashLogFilePath);
@@ -67,16 +101,25 @@ public class ShareLogActivity extends Activity {
}
final String logContent = sb.toString();
- final Intent shareIntent = new Intent(Intent.ACTION_SEND);
- shareIntent.setType("text/plain");
- shareIntent.putExtra(Intent.EXTRA_TEXT, logContent);
+ final StringBuilder emailContent = new StringBuilder();
+ emailContent.append(getAppInfo());
+ emailContent.append(getDeviceInfo());
+ emailContent.append("========== 崩溃日志 ==========\n");
+ emailContent.append(logContent);
+
+ final Intent shareIntent = new Intent(Intent.ACTION_SENDTO);
+ shareIntent.setData(android.net.Uri.parse("mailto:"));
+ shareIntent.putExtra(Intent.EXTRA_TEXT, emailContent.toString());
if (subject != null && !subject.isEmpty()) {
shareIntent.putExtra(Intent.EXTRA_SUBJECT, subject);
} else {
shareIntent.putExtra(Intent.EXTRA_SUBJECT, "崩溃日志");
}
+ if (emailTo != null && !emailTo.isEmpty()) {
+ shareIntent.putExtra(Intent.EXTRA_EMAIL, new String[]{emailTo});
+ }
- startActivity(Intent.createChooser(shareIntent, "分享日志到"));
+ startActivity(Intent.createChooser(shareIntent, "发送日志到"));
Log.d(TAG, "handleShareCrashLog 分享成功");
} catch (Exception e) {
Log.e(TAG, "handleShareCrashLog 异常", e);