diff --git a/app/build.gradle b/app/build.gradle index 68b9e6c..5d50cca 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -15,7 +15,7 @@ android { defaultConfig { applicationId "cc.winboll.gallery" - minSdkVersion 16 + minSdkVersion 21 targetSdkVersion 30 versionCode 1 versionName "1.0" @@ -58,6 +58,8 @@ android { } dependencies { + implementation 'cc.winboll.studio:libaes:15.15.7' + implementation 'cc.winboll.studio:libappbase:15.15.11' implementation 'androidx.appcompat:appcompat:1.0.0' implementation 'com.google.android.material:material:1.0.0' implementation 'androidx.recyclerview:recyclerview:1.1.0' diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index bd6fbab..debe689 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -13,7 +13,7 @@ android:label="@string/app_name" android:theme="@style/AppTheme" android:resizeableActivity="true" - android:name=".GlobalApplication"> + android:name=".GlobalWinBoLLApplication"> - \ No newline at end of file + diff --git a/app/src/main/java/cc/winboll/gallery/GlobalApplication.java b/app/src/main/java/cc/winboll/gallery/GlobalApplication.java deleted file mode 100644 index fc191db..0000000 --- a/app/src/main/java/cc/winboll/gallery/GlobalApplication.java +++ /dev/null @@ -1,334 +0,0 @@ -package cc.winboll.gallery; - -import android.app.Activity; -import android.app.Application; -import android.content.ClipData; -import android.content.ClipboardManager; -import android.content.Context; -import android.content.Intent; -import android.content.pm.PackageInfo; -import android.content.res.Resources; -import android.graphics.Typeface; -import android.os.Build; -import android.os.Bundle; -import android.os.Handler; -import android.os.Looper; -import android.text.TextUtils; -import android.util.Log; -import android.view.Menu; -import android.view.MenuItem; -import android.view.ViewGroup; -import android.widget.HorizontalScrollView; -import android.widget.ScrollView; -import android.widget.TextView; -import android.widget.Toast; -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.Closeable; -import java.io.File; -import java.io.FileInputStream; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.lang.Thread.UncaughtExceptionHandler; -import java.text.DateFormat; -import java.text.SimpleDateFormat; -import java.util.Arrays; -import java.util.Date; -import java.util.LinkedHashMap; -import java.util.concurrent.atomic.AtomicBoolean; - -public class GlobalApplication extends Application { - - private static Handler MAIN_HANDLER = new Handler(Looper.getMainLooper()); - - @Override - public void onCreate() { - super.onCreate(); - CrashHandler.getInstance().registerGlobal(this); - CrashHandler.getInstance().registerPart(this); - } - - public static void write(InputStream input, OutputStream output) throws IOException { - byte[] buf = new byte[1024 * 8]; - int len; - while ((len = input.read(buf)) != -1) { - output.write(buf, 0, len); - } - } - - public static void write(File file, byte[] data) throws IOException { - File parent = file.getParentFile(); - if (parent != null && !parent.exists()) parent.mkdirs(); - - ByteArrayInputStream input = new ByteArrayInputStream(data); - FileOutputStream output = new FileOutputStream(file); - try { - write(input, output); - } finally { - closeIO(input, output); - } - } - - public static String toString(InputStream input) throws IOException { - ByteArrayOutputStream output = new ByteArrayOutputStream(); - write(input, output); - try { - return output.toString("UTF-8"); - } finally { - closeIO(input, output); - } - } - - public static void closeIO(Closeable... closeables) { - for (Closeable closeable : closeables) { - try { - if (closeable != null) closeable.close(); - } catch (IOException ignored) {} - } - } - - public static class CrashHandler { - - public static final UncaughtExceptionHandler DEFAULT_UNCAUGHT_EXCEPTION_HANDLER = Thread.getDefaultUncaughtExceptionHandler(); - - private static CrashHandler sInstance; - - private PartCrashHandler mPartCrashHandler; - - public static CrashHandler getInstance() { - if (sInstance == null) { - sInstance = new CrashHandler(); - } - return sInstance; - } - - public void registerGlobal(Context context) { - registerGlobal(context, null); - } - - public void registerGlobal(Context context, String crashDir) { - Thread.setDefaultUncaughtExceptionHandler(new UncaughtExceptionHandlerImpl(context.getApplicationContext(), crashDir)); - } - - public void unregister() { - Thread.setDefaultUncaughtExceptionHandler(DEFAULT_UNCAUGHT_EXCEPTION_HANDLER); - } - - public void registerPart(Context context) { - unregisterPart(context); - mPartCrashHandler = new PartCrashHandler(context.getApplicationContext()); - MAIN_HANDLER.postAtFrontOfQueue(mPartCrashHandler); - } - - public void unregisterPart(Context context) { - if (mPartCrashHandler != null) { - mPartCrashHandler.isRunning.set(false); - mPartCrashHandler = null; - } - } - - private static class PartCrashHandler implements Runnable { - - private final Context mContext; - - public AtomicBoolean isRunning = new AtomicBoolean(true); - - public PartCrashHandler(Context context) { - this.mContext = context; - } - - @Override - public void run() { - while (isRunning.get()) { - try { - Looper.loop(); - } catch (final Throwable e) { - e.printStackTrace(); - if (isRunning.get()) { - MAIN_HANDLER.post(new Runnable(){ - - @Override - public void run() { - Toast.makeText(mContext, e.toString(), Toast.LENGTH_LONG).show(); - } - }); - } else { - if (e instanceof RuntimeException) { - throw (RuntimeException)e; - } else { - throw new RuntimeException(e); - } - } - } - } - } - } - - private static class UncaughtExceptionHandlerImpl implements UncaughtExceptionHandler { - - private static DateFormat DATE_FORMAT = new SimpleDateFormat("yyyy_MM_dd-HH_mm_ss"); - - private final Context mContext; - - private final File mCrashDir; - - public UncaughtExceptionHandlerImpl(Context context, String crashDir) { - this.mContext = context; - this.mCrashDir = TextUtils.isEmpty(crashDir) ? new File(mContext.getExternalCacheDir(), "crash") : new File(crashDir); - } - - @Override - public void uncaughtException(Thread thread, Throwable throwable) { - try { - - String log = buildLog(throwable); - writeLog(log); - - try { - Intent intent = new Intent(mContext, CrashActivity.class); - intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); - intent.putExtra(Intent.EXTRA_TEXT, log); - mContext.startActivity(intent); - } catch (Throwable e) { - e.printStackTrace(); - writeLog(e.toString()); - } - - throwable.printStackTrace(); - android.os.Process.killProcess(android.os.Process.myPid()); - System.exit(0); - - } catch (Throwable e) { - if (DEFAULT_UNCAUGHT_EXCEPTION_HANDLER != null) DEFAULT_UNCAUGHT_EXCEPTION_HANDLER.uncaughtException(thread, throwable); - } - } - - private String buildLog(Throwable throwable) { - String time = DATE_FORMAT.format(new Date()); - - String versionName = "unknown"; - long versionCode = 0; - try { - PackageInfo packageInfo = mContext.getPackageManager().getPackageInfo(mContext.getPackageName(), 0); - versionName = packageInfo.versionName; - versionCode = Build.VERSION.SDK_INT >= 28 ? packageInfo.getLongVersionCode() : packageInfo.versionCode; - } catch (Throwable ignored) {} - - LinkedHashMap head = new LinkedHashMap(); - head.put("Time Of Crash", time); - head.put("Device", String.format("%s, %s", Build.MANUFACTURER, Build.MODEL)); - head.put("Android Version", String.format("%s (%d)", Build.VERSION.RELEASE, Build.VERSION.SDK_INT)); - head.put("App Version", String.format("%s (%d)", versionName, versionCode)); - head.put("Kernel", getKernel()); - head.put("Support Abis", Build.VERSION.SDK_INT >= 21 && Build.SUPPORTED_ABIS != null ? Arrays.toString(Build.SUPPORTED_ABIS): "unknown"); - head.put("Fingerprint", Build.FINGERPRINT); - - StringBuilder builder = new StringBuilder(); - - for (String key : head.keySet()) { - if (builder.length() != 0) builder.append("\n"); - builder.append(key); - builder.append(" : "); - builder.append(head.get(key)); - } - - builder.append("\n\n"); - builder.append(Log.getStackTraceString(throwable)); - - return builder.toString(); - } - - private void writeLog(String log) { - String time = DATE_FORMAT.format(new Date()); - File file = new File(mCrashDir, "crash_" + time + ".txt"); - try { - write(file, log.getBytes("UTF-8")); - } catch (Throwable e) { - e.printStackTrace(); - } - } - - private static String getKernel() { - try { - return GlobalApplication.toString(new FileInputStream("/proc/version")).trim(); - } catch (Throwable e) { - return e.getMessage(); - } - } - } - } - - public static final class CrashActivity extends Activity { - - private String mLog; - - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - - setTheme(android.R.style.Theme_DeviceDefault); - setTitle("App Crash"); - - mLog = getIntent().getStringExtra(Intent.EXTRA_TEXT); - - ScrollView contentView = new ScrollView(this); - contentView.setFillViewport(true); - - HorizontalScrollView horizontalScrollView = new HorizontalScrollView(this); - - TextView textView = new TextView(this); - int padding = dp2px(16); - textView.setPadding(padding, padding, padding, padding); - textView.setText(mLog); - textView.setTextIsSelectable(true); - textView.setTypeface(Typeface.DEFAULT); - textView.setLinksClickable(true); - - horizontalScrollView.addView(textView); - contentView.addView(horizontalScrollView, ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT); - - setContentView(contentView); - } - - private void restart() { - Intent intent = getPackageManager().getLaunchIntentForPackage(getPackageName()); - if (intent != null) { - intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); - startActivity(intent); - } - finish(); - android.os.Process.killProcess(android.os.Process.myPid()); - System.exit(0); - } - - private static int dp2px(float dpValue) { - final float scale = Resources.getSystem().getDisplayMetrics().density; - return (int) (dpValue * scale + 0.5f); - } - - @Override - public boolean onCreateOptionsMenu(Menu menu) { - menu.add(0, android.R.id.copy, 0, android.R.string.copy) - .setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM); - return super.onCreateOptionsMenu(menu); - } - - @Override - public boolean onOptionsItemSelected(MenuItem item) { - switch (item.getItemId()) { - case android.R.id.copy: - ClipboardManager cm = (ClipboardManager) getSystemService(Context.CLIPBOARD_SERVICE); - cm.setPrimaryClip(ClipData.newPlainText(getPackageName(), mLog)); - return true; - } - return super.onOptionsItemSelected(item); - } - - @Override - public void onBackPressed() { - restart(); - } - } -} \ No newline at end of file diff --git a/app/src/main/java/cc/winboll/gallery/GlobalWinBoLLApplication.java b/app/src/main/java/cc/winboll/gallery/GlobalWinBoLLApplication.java new file mode 100644 index 0000000..c818669 --- /dev/null +++ b/app/src/main/java/cc/winboll/gallery/GlobalWinBoLLApplication.java @@ -0,0 +1,41 @@ +package cc.winboll.gallery; + +import cc.winboll.studio.libaes.utils.WinBoLLActivityManager; +import cc.winboll.studio.libappbase.GlobalApplication; +import cc.winboll.studio.libappbase.ToastUtils; + +/** + * @Author 豆包&ZhanGSKen + * @Date 2026/04/24 15:23 + */ +public class GlobalWinBoLLApplication extends GlobalApplication { + + public static final String TAG = "GlobalWinBoLLApplication"; + + + @Override + public void onCreate() { + super.onCreate(); + setIsDebugging(BuildConfig.DEBUG); + //setIsDebugging(false); + + WinBoLLActivityManager.init(this); + + // 初始化 Toast 框架 + ToastUtils.init(this); + // 设置 Toast 布局样式 + //ToastUtils.setView(R.layout.view_toast); + //ToastUtils.setStyle(new WhiteToastStyle()); + //ToastUtils.setGravity(Gravity.BOTTOM, 0, 200); + + //CrashHandler.getInstance().registerGlobal(this); + //CrashHandler.getInstance().registerPart(this); + } + + @Override + public void onTerminate() { + super.onTerminate(); + ToastUtils.release(); + } + +} diff --git a/app/src/main/java/cc/winboll/gallery/ImageViewerActivity.java b/app/src/main/java/cc/winboll/gallery/ImageViewerActivity.java index 4901870..926ed09 100644 --- a/app/src/main/java/cc/winboll/gallery/ImageViewerActivity.java +++ b/app/src/main/java/cc/winboll/gallery/ImageViewerActivity.java @@ -8,6 +8,7 @@ import android.view.View.OnClickListener; import android.view.WindowManager; import android.widget.ImageButton; import androidx.viewpager.widget.ViewPager; +import cc.winboll.studio.libappbase.ToastUtils; import java.util.ArrayList; public class ImageViewerActivity extends Activity implements ViewPager.OnPageChangeListener { diff --git a/build.gradle b/build.gradle index 39c57f9..b68fab1 100644 --- a/build.gradle +++ b/build.gradle @@ -11,6 +11,12 @@ buildscript { google() mavenLocal() mavenCentral() + // Nexus Maven 库地址 + // "WinBoLL Release" + maven { url "https://nexus.winboll.cc/repository/maven-public/" } + // "WinBoLL Snapshot" + maven { url "https://nexus.winboll.cc/repository/maven-snapshots/" } + } dependencies { classpath "com.android.tools.build:gradle:$build_gradle_version" @@ -29,6 +35,12 @@ allprojects { mavenLocal() mavenCentral() google() + // Nexus Maven 库地址 + // "WinBoLL Release" + maven { url "https://nexus.winboll.cc/repository/maven-public/" } + // "WinBoLL Snapshot" + maven { url "https://nexus.winboll.cc/repository/maven-snapshots/" } + }