Compare commits
133 Commits
contacts-v
...
apputils-v
Author | SHA1 | Date | |
---|---|---|---|
![]() |
20af88fdd2 | ||
![]() |
9a70fe7c0f | ||
![]() |
c62f3f1bea | ||
![]() |
0e339c0f51 | ||
![]() |
c20975cfca | ||
![]() |
ed5f91f299 | ||
![]() |
0031100219 | ||
![]() |
f9e7d362b7 | ||
![]() |
8d9d308c68 | ||
![]() |
d3b12207e0 | ||
![]() |
befea40f61 | ||
![]() |
cc1ca5b092 | ||
![]() |
af77c09415 | ||
![]() |
2968d1dbfa | ||
![]() |
db96ece15f | ||
![]() |
c0347ed706 | ||
![]() |
ad408dfb53 | ||
![]() |
a2e963b53e | ||
![]() |
953da400be | ||
![]() |
165765e0eb | ||
![]() |
f5f88a61b0 | ||
![]() |
2f33574d5c | ||
![]() |
afd93d6871 | ||
![]() |
b7affa477f | ||
![]() |
4f317322fc | ||
![]() |
41c0394c4a | ||
![]() |
d2a84f554b | ||
![]() |
d1e3e27f20 | ||
![]() |
f9242bfc9a | ||
![]() |
bf37eb61bb | ||
![]() |
6fd1513d6b | ||
![]() |
394d75e5a2 | ||
![]() |
378e9168b6 | ||
![]() |
a3fa570b50 | ||
![]() |
5623d2d341 | ||
![]() |
3d9b203760 | ||
![]() |
498a8ae458 | ||
![]() |
9b8d6ad46b | ||
![]() |
482f289df3 | ||
![]() |
28ab4e2859 | ||
![]() |
7662d1c153 | ||
![]() |
ac7b5bb1a2 | ||
![]() |
eeae184e7e | ||
![]() |
fd0cb05812 | ||
![]() |
39b6c0ec89 | ||
![]() |
3b3ddbc8c9 | ||
![]() |
d5f34ad618 | ||
![]() |
3ad1863a5f | ||
![]() |
291080aa15 | ||
![]() |
38aee09f87 | ||
![]() |
89c4d00091 | ||
![]() |
4f57678012 | ||
![]() |
973a0ff94f | ||
![]() |
e04ea7f035 | ||
![]() |
ecbaf639a0 | ||
![]() |
b31e55d8ca | ||
![]() |
80129470d7 | ||
![]() |
7b03e8302a | ||
![]() |
4d321dde84 | ||
![]() |
b3a495ff6a | ||
![]() |
a49b6cbfe0 | ||
![]() |
274a7135e7 | ||
![]() |
00d0871809 | ||
![]() |
bc252041d3 | ||
![]() |
bca31f9079 | ||
![]() |
fb7017a857 | ||
![]() |
050fd46d81 | ||
![]() |
d4ea79b950 | ||
![]() |
06a40a4298 | ||
![]() |
35835d746e | ||
![]() |
5f3d03ba7d | ||
![]() |
1d372ff9ae | ||
![]() |
4a1e398755 | ||
![]() |
107be6d6ad | ||
![]() |
19db567a7d | ||
![]() |
b14add854e | ||
![]() |
104d9fa283 | ||
![]() |
dd041e5d78 | ||
![]() |
2f019ae176 | ||
![]() |
b5b4fbd3f5 | ||
![]() |
548dcf74ed | ||
![]() |
547bf894c6 | ||
![]() |
09e6429726 | ||
![]() |
3ad9bb262e | ||
![]() |
15992da22f | ||
![]() |
7fb4e665f9 | ||
![]() |
6a82889926 | ||
![]() |
7272cc4e5b | ||
![]() |
1f7d112a8a | ||
![]() |
936e214015 | ||
![]() |
46e95d1b1f | ||
![]() |
15173f7af3 | ||
![]() |
6f3b6c40af | ||
![]() |
42ffba69e5 | ||
![]() |
f021e8a1a3 | ||
![]() |
02ce7dedb0 | ||
![]() |
8e290cd5e6 | ||
![]() |
37f2aa5f1b | ||
![]() |
10cc69940b | ||
![]() |
bfdff9ff2f | ||
![]() |
12c6129a61 | ||
![]() |
ea10d1b540 | ||
![]() |
81f6ff592e | ||
![]() |
e6f22e9212 | ||
![]() |
8ce8f383fa | ||
![]() |
35d32b384f | ||
![]() |
85e86ddf05 | ||
![]() |
99bf804625 | ||
![]() |
261259e61e | ||
![]() |
9aaf3433bd | ||
![]() |
b739510951 | ||
![]() |
903359d9a2 | ||
![]() |
69e7e72ed8 | ||
![]() |
a96ba362b4 | ||
![]() |
6447bcf924 | ||
![]() |
18ed325731 | ||
![]() |
16e3d10b63 | ||
![]() |
8b0e8b00ae | ||
![]() |
7f61ff1470 | ||
![]() |
c4e0c23a0c | ||
![]() |
c7d26bbc3d | ||
![]() |
4968bbaeae | ||
![]() |
8e6b06e366 | ||
![]() |
ae7fb2984a | ||
![]() |
a4d009f8fb | ||
![]() |
5a549e9652 | ||
![]() |
e2d71ae088 | ||
![]() |
506d2619f2 | ||
![]() |
17fa805a7f | ||
![]() |
1dcf8cd007 | ||
![]() |
d86d50212e | ||
![]() |
af2e09c02a | ||
![]() |
de6361b19b |
1
.gitignore
vendored
@@ -96,6 +96,7 @@ local.properties
|
|||||||
|
|
||||||
## 忽略模块应用编译配置
|
## 忽略模块应用编译配置
|
||||||
/settings.gradle
|
/settings.gradle
|
||||||
|
/gradle.properties
|
||||||
|
|
||||||
## 忽略 srv 纠结问题
|
## 忽略 srv 纠结问题
|
||||||
/srv/
|
/srv/
|
||||||
|
1
androiddemo/.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
|||||||
|
/build
|
0
androiddemo/app_update_description.txt
Normal file
74
androiddemo/build.gradle
Normal file
@@ -0,0 +1,74 @@
|
|||||||
|
apply plugin: 'com.android.application'
|
||||||
|
apply from: '../.winboll/winboll_app_build.gradle'
|
||||||
|
apply from: '../.winboll/winboll_lint_build.gradle'
|
||||||
|
|
||||||
|
def genVersionName(def versionName){
|
||||||
|
// 检查编译标志位配置
|
||||||
|
assert (winbollBuildProps['stageCount'] != null)
|
||||||
|
assert (winbollBuildProps['baseVersion'] != null)
|
||||||
|
// 保存基础版本号
|
||||||
|
winbollBuildProps.setProperty("baseVersion", "${versionName}");
|
||||||
|
//保存编译标志配置
|
||||||
|
FileOutputStream fos = new FileOutputStream(winbollBuildPropsFile)
|
||||||
|
winbollBuildProps.store(fos, "${winbollBuildPropsDesc}");
|
||||||
|
fos.close();
|
||||||
|
|
||||||
|
// 返回编译版本号
|
||||||
|
return "${versionName}." + winbollBuildProps['stageCount']
|
||||||
|
}
|
||||||
|
|
||||||
|
android {
|
||||||
|
productFlavors {
|
||||||
|
beta {
|
||||||
|
}
|
||||||
|
stage {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
compileSdkVersion 30
|
||||||
|
buildToolsVersion "30.0.3"
|
||||||
|
|
||||||
|
defaultConfig {
|
||||||
|
applicationId "cc.winboll.studio.androiddemo"
|
||||||
|
minSdkVersion 26
|
||||||
|
targetSdkVersion 29
|
||||||
|
versionCode 1
|
||||||
|
// versionName 更新后需要手动设置
|
||||||
|
// .winboll/winbollBuildProps.properties 文件的 stageCount=0
|
||||||
|
// Gradle编译环境下合起来的 versionName 就是 "${versionName}.0"
|
||||||
|
versionName "1.0"
|
||||||
|
if(true) {
|
||||||
|
versionName = genVersionName("${versionName}")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
buildTypes {
|
||||||
|
release {
|
||||||
|
minifyEnabled false
|
||||||
|
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
api fileTree(dir: 'libs', include: ['*.jar'])
|
||||||
|
|
||||||
|
// 吐司类库
|
||||||
|
implementation 'com.github.getActivity:ToastUtils:10.5'
|
||||||
|
|
||||||
|
// Android 类库
|
||||||
|
// https://mvnrepository.com/artifact/com.android.support/support-v4
|
||||||
|
implementation 'com.android.support:support-v4:28.0.0'
|
||||||
|
// https://mvnrepository.com/artifact/com.android.support/support-compat
|
||||||
|
implementation 'com.android.support:support-compat:28.0.0'
|
||||||
|
// https://mvnrepository.com/artifact/com.android.support/support-media-compat
|
||||||
|
implementation 'com.android.support:support-media-compat:28.0.0'
|
||||||
|
// https://mvnrepository.com/artifact/com.android.support/support-core-utils
|
||||||
|
implementation 'com.android.support:support-core-utils:28.0.0'
|
||||||
|
// https://mvnrepository.com/artifact/com.android.support/support-core-ui
|
||||||
|
implementation 'com.android.support:support-core-ui:28.0.0'
|
||||||
|
// https://mvnrepository.com/artifact/com.android.support/support-fragment
|
||||||
|
implementation 'com.android.support:support-fragment:28.0.0'
|
||||||
|
// https://mvnrepository.com/artifact/com.android.support/recyclerview-v7
|
||||||
|
implementation 'com.android.support:recyclerview-v7:28.0.0'
|
||||||
|
}
|
8
androiddemo/build.properties
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
#Created by .winboll/winboll_app_build.gradle
|
||||||
|
#Tue Mar 11 18:02:14 GMT 2025
|
||||||
|
stageCount=0
|
||||||
|
libraryProject=
|
||||||
|
baseVersion=1.0
|
||||||
|
publishVersion=1.0.0
|
||||||
|
buildCount=1
|
||||||
|
baseBetaVersion=1.0.1
|
21
androiddemo/proguard-rules.pro
vendored
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
# 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
|
12
androiddemo/src/beta/AndroidManifest.xml
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools" >
|
||||||
|
|
||||||
|
<application>
|
||||||
|
|
||||||
|
<!-- Put flavor specific code here -->
|
||||||
|
|
||||||
|
</application>
|
||||||
|
|
||||||
|
</manifest>
|
||||||
|
|
7
androiddemo/src/beta/res/values/strings.xml
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<resources>
|
||||||
|
|
||||||
|
|
||||||
|
<string name="app_name">Android Demo +</string>
|
||||||
|
|
||||||
|
</resources>
|
39
androiddemo/src/main/AndroidManifest.xml
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
<?xml version='1.0' encoding='utf-8'?>
|
||||||
|
<manifest
|
||||||
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
package="cc.winboll.studio.androiddemo">
|
||||||
|
|
||||||
|
<application
|
||||||
|
tools:replace="android:appComponentFactory"
|
||||||
|
android:appComponentFactory="android.support.v4.app.CoreComponentFactory"
|
||||||
|
android:icon="@drawable/ic_launcher"
|
||||||
|
android:label="@string/app_name"
|
||||||
|
android:theme="@style/AppTheme"
|
||||||
|
android:resizeableActivity="true"
|
||||||
|
android:name=".GlobalApplication">
|
||||||
|
|
||||||
|
<activity
|
||||||
|
android:name=".MainActivity"
|
||||||
|
android:label="@string/app_name"
|
||||||
|
android:exported="true">
|
||||||
|
|
||||||
|
<intent-filter>
|
||||||
|
|
||||||
|
<action android:name="android.intent.action.MAIN"/>
|
||||||
|
|
||||||
|
<category android:name="android.intent.category.LAUNCHER"/>
|
||||||
|
|
||||||
|
</intent-filter>
|
||||||
|
|
||||||
|
</activity>
|
||||||
|
|
||||||
|
<meta-data
|
||||||
|
android:name="android.max_aspect"
|
||||||
|
android:value="4.0"/>
|
||||||
|
|
||||||
|
<activity android:name=".GlobalApplication$CrashActivity"/>
|
||||||
|
|
||||||
|
</application>
|
||||||
|
|
||||||
|
</manifest>
|
@@ -0,0 +1,334 @@
|
|||||||
|
package cc.winboll.studio.androiddemo;
|
||||||
|
|
||||||
|
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<String, String> head = new LinkedHashMap<String, String>();
|
||||||
|
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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,15 @@
|
|||||||
|
package cc.winboll.studio.androiddemo;
|
||||||
|
|
||||||
|
import android.app.Activity;
|
||||||
|
import android.os.Bundle;
|
||||||
|
|
||||||
|
public class MainActivity extends Activity {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
|
super.onCreate(savedInstanceState);
|
||||||
|
setContentView(R.layout.activity_main);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
BIN
androiddemo/src/main/res/drawable/ic_launcher.png
Normal file
After Width: | Height: | Size: 9.0 KiB |
16
androiddemo/src/main/res/layout/activity_main.xml
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<LinearLayout
|
||||||
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:gravity="center_vertical|center_horizontal">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="Android Demo"
|
||||||
|
android:textAppearance="?android:attr/textAppearanceLarge"/>
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
9
androiddemo/src/main/res/values-v21/styles.xml
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<resources>
|
||||||
|
<style name="AppTheme" parent="@android:style/Theme.Material.Light.DarkActionBar">
|
||||||
|
<item name="android:colorPrimary">@color/colorPrimary</item>
|
||||||
|
<item name="android:colorPrimaryDark">@color/colorPrimaryDark</item>
|
||||||
|
<item name="android:colorAccent">@color/colorAccent</item>
|
||||||
|
<item name="android:navigationBarColor">?android:colorPrimary</item>
|
||||||
|
</style>
|
||||||
|
</resources>
|
6
androiddemo/src/main/res/values/colors.xml
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<resources>
|
||||||
|
<color name="colorPrimary">#009688</color>
|
||||||
|
<color name="colorPrimaryDark">#00796B</color>
|
||||||
|
<color name="colorAccent">#FF9800</color>
|
||||||
|
</resources>
|
4
androiddemo/src/main/res/values/strings.xml
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<resources>
|
||||||
|
<string name="app_name">Android Demo</string>
|
||||||
|
</resources>
|
5
androiddemo/src/main/res/values/styles.xml
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<resources>
|
||||||
|
<style name="AppTheme" parent="@android:style/Theme.Holo.Light.DarkActionBar">
|
||||||
|
</style>
|
||||||
|
</resources>
|
12
androiddemo/src/stage/AndroidManifest.xml
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools" >
|
||||||
|
|
||||||
|
<application>
|
||||||
|
|
||||||
|
<!-- Put flavor specific code here -->
|
||||||
|
|
||||||
|
</application>
|
||||||
|
|
||||||
|
</manifest>
|
||||||
|
|
6
androiddemo/src/stage/res/values/strings.xml
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<resources>
|
||||||
|
|
||||||
|
<!-- Put flavor specific strings here -->
|
||||||
|
|
||||||
|
</resources>
|
1
androidxdemo/.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
|||||||
|
/build
|
0
androidxdemo/app_update_description.txt
Normal file
76
androidxdemo/build.gradle
Normal file
@@ -0,0 +1,76 @@
|
|||||||
|
apply plugin: 'com.android.application'
|
||||||
|
apply from: '../.winboll/winboll_app_build.gradle'
|
||||||
|
apply from: '../.winboll/winboll_lint_build.gradle'
|
||||||
|
|
||||||
|
def genVersionName(def versionName){
|
||||||
|
// 检查编译标志位配置
|
||||||
|
assert (winbollBuildProps['stageCount'] != null)
|
||||||
|
assert (winbollBuildProps['baseVersion'] != null)
|
||||||
|
// 保存基础版本号
|
||||||
|
winbollBuildProps.setProperty("baseVersion", "${versionName}");
|
||||||
|
//保存编译标志配置
|
||||||
|
FileOutputStream fos = new FileOutputStream(winbollBuildPropsFile)
|
||||||
|
winbollBuildProps.store(fos, "${winbollBuildPropsDesc}");
|
||||||
|
fos.close();
|
||||||
|
|
||||||
|
// 返回编译版本号
|
||||||
|
return "${versionName}." + winbollBuildProps['stageCount']
|
||||||
|
}
|
||||||
|
|
||||||
|
android {
|
||||||
|
productFlavors {
|
||||||
|
beta {
|
||||||
|
}
|
||||||
|
stage {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
compileSdkVersion 30
|
||||||
|
buildToolsVersion "30.0.3"
|
||||||
|
|
||||||
|
defaultConfig {
|
||||||
|
applicationId "cc.winboll.studio.androidxdemo"
|
||||||
|
minSdkVersion 26
|
||||||
|
targetSdkVersion 29
|
||||||
|
versionCode 1
|
||||||
|
// versionName 更新后需要手动设置
|
||||||
|
// .winboll/winbollBuildProps.properties 文件的 stageCount=0
|
||||||
|
// Gradle编译环境下合起来的 versionName 就是 "${versionName}.0"
|
||||||
|
versionName "1.0"
|
||||||
|
if(true) {
|
||||||
|
versionName = genVersionName("${versionName}")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
buildTypes {
|
||||||
|
release {
|
||||||
|
minifyEnabled false
|
||||||
|
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
api fileTree(dir: 'libs', include: ['*.jar'])
|
||||||
|
|
||||||
|
// SSH
|
||||||
|
implementation 'com.jcraft:jsch:0.1.55'
|
||||||
|
// Html 解析
|
||||||
|
implementation 'org.jsoup:jsoup:1.13.1'
|
||||||
|
// 二维码类库
|
||||||
|
implementation 'com.google.zxing:core:3.4.1'
|
||||||
|
implementation 'com.journeyapps:zxing-android-embedded:3.6.0'
|
||||||
|
// 应用介绍页类库
|
||||||
|
implementation 'io.github.medyo:android-about-page:2.0.0'
|
||||||
|
// 吐司类库
|
||||||
|
implementation 'com.github.getActivity:ToastUtils:10.5'
|
||||||
|
// 网络连接类库
|
||||||
|
implementation 'com.squareup.okhttp3:okhttp:4.4.1'
|
||||||
|
// Android 类库
|
||||||
|
implementation 'androidx.appcompat:appcompat:1.1.0'
|
||||||
|
implementation 'androidx.viewpager:viewpager:1.0.0'
|
||||||
|
implementation 'androidx.vectordrawable:vectordrawable:1.1.0'
|
||||||
|
implementation 'androidx.vectordrawable:vectordrawable-animated:1.1.0'
|
||||||
|
implementation 'androidx.fragment:fragment:1.1.0'
|
||||||
|
implementation 'com.google.android.material:material:1.4.0'
|
||||||
|
}
|
8
androidxdemo/build.properties
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
#Created by .winboll/winboll_app_build.gradle
|
||||||
|
#Tue Mar 11 18:25:43 GMT 2025
|
||||||
|
stageCount=0
|
||||||
|
libraryProject=
|
||||||
|
baseVersion=1.0
|
||||||
|
publishVersion=1.0.0
|
||||||
|
buildCount=4
|
||||||
|
baseBetaVersion=1.0.1
|
21
androidxdemo/proguard-rules.pro
vendored
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
# 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
|
12
androidxdemo/src/beta/AndroidManifest.xml
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools" >
|
||||||
|
|
||||||
|
<application>
|
||||||
|
|
||||||
|
<!-- Put flavor specific code here -->
|
||||||
|
|
||||||
|
</application>
|
||||||
|
|
||||||
|
</manifest>
|
||||||
|
|
6
androidxdemo/src/beta/res/values/strings.xml
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<resources>
|
||||||
|
|
||||||
|
<string name="app_name">AndroidX Demo +</string>
|
||||||
|
|
||||||
|
</resources>
|
37
androidxdemo/src/main/AndroidManifest.xml
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
<?xml version='1.0' encoding='utf-8'?>
|
||||||
|
<manifest
|
||||||
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
package="cc.winboll.studio.androidxdemo">
|
||||||
|
|
||||||
|
<application
|
||||||
|
android:allowBackup="true"
|
||||||
|
android:icon="@mipmap/ic_launcher"
|
||||||
|
android:roundIcon="@mipmap/ic_launcher_round"
|
||||||
|
android:label="@string/app_name"
|
||||||
|
android:theme="@style/AppTheme"
|
||||||
|
android:resizeableActivity="true"
|
||||||
|
android:name=".GlobalApplication">
|
||||||
|
|
||||||
|
<activity
|
||||||
|
android:name=".MainActivity"
|
||||||
|
android:label="@string/app_name">
|
||||||
|
|
||||||
|
<intent-filter>
|
||||||
|
|
||||||
|
<action android:name="android.intent.action.MAIN"/>
|
||||||
|
|
||||||
|
<category android:name="android.intent.category.LAUNCHER"/>
|
||||||
|
|
||||||
|
</intent-filter>
|
||||||
|
|
||||||
|
</activity>
|
||||||
|
|
||||||
|
<meta-data
|
||||||
|
android:name="android.max_aspect"
|
||||||
|
android:value="4.0"/>
|
||||||
|
|
||||||
|
<activity android:name=".GlobalApplication$CrashActivity"/>
|
||||||
|
|
||||||
|
</application>
|
||||||
|
|
||||||
|
</manifest>
|
@@ -0,0 +1,334 @@
|
|||||||
|
package cc.winboll.studio.androidxdemo;
|
||||||
|
|
||||||
|
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<String, String> head = new LinkedHashMap<String, String>();
|
||||||
|
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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,19 @@
|
|||||||
|
package cc.winboll.studio.androidxdemo;
|
||||||
|
|
||||||
|
import android.os.Bundle;
|
||||||
|
import androidx.appcompat.app.AppCompatActivity;
|
||||||
|
import androidx.appcompat.widget.Toolbar;
|
||||||
|
|
||||||
|
public class MainActivity extends AppCompatActivity {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
|
super.onCreate(savedInstanceState);
|
||||||
|
setContentView(R.layout.activity_main);
|
||||||
|
|
||||||
|
Toolbar toolbar=(Toolbar)findViewById(R.id.toolbar);
|
||||||
|
setSupportActionBar(toolbar);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@@ -0,0 +1,34 @@
|
|||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:aapt="http://schemas.android.com/aapt"
|
||||||
|
android:width="108dp"
|
||||||
|
android:height="108dp"
|
||||||
|
android:viewportHeight="108"
|
||||||
|
android:viewportWidth="108">
|
||||||
|
<path
|
||||||
|
android:fillType="evenOdd"
|
||||||
|
android:pathData="M32,64C32,64 38.39,52.99 44.13,50.95C51.37,48.37 70.14,49.57 70.14,49.57L108.26,87.69L108,109.01L75.97,107.97L32,64Z"
|
||||||
|
android:strokeColor="#00000000"
|
||||||
|
android:strokeWidth="1">
|
||||||
|
<aapt:attr name="android:fillColor">
|
||||||
|
<gradient
|
||||||
|
android:endX="78.5885"
|
||||||
|
android:endY="90.9159"
|
||||||
|
android:startX="48.7653"
|
||||||
|
android:startY="61.0927"
|
||||||
|
android:type="linear">
|
||||||
|
<item
|
||||||
|
android:color="#44000000"
|
||||||
|
android:offset="0.0" />
|
||||||
|
<item
|
||||||
|
android:color="#00000000"
|
||||||
|
android:offset="1.0" />
|
||||||
|
</gradient>
|
||||||
|
</aapt:attr>
|
||||||
|
</path>
|
||||||
|
<path
|
||||||
|
android:fillColor="#FFFFFF"
|
||||||
|
android:fillType="nonZero"
|
||||||
|
android:pathData="M66.94,46.02L66.94,46.02C72.44,50.07 76,56.61 76,64L32,64C32,56.61 35.56,50.11 40.98,46.06L36.18,41.19C35.45,40.45 35.45,39.3 36.18,38.56C36.91,37.81 38.05,37.81 38.78,38.56L44.25,44.05C47.18,42.57 50.48,41.71 54,41.71C57.48,41.71 60.78,42.57 63.68,44.05L69.11,38.56C69.84,37.81 70.98,37.81 71.71,38.56C72.44,39.3 72.44,40.45 71.71,41.19L66.94,46.02ZM62.94,56.92C64.08,56.92 65,56.01 65,54.88C65,53.76 64.08,52.85 62.94,52.85C61.8,52.85 60.88,53.76 60.88,54.88C60.88,56.01 61.8,56.92 62.94,56.92ZM45.06,56.92C46.2,56.92 47.13,56.01 47.13,54.88C47.13,53.76 46.2,52.85 45.06,52.85C43.92,52.85 43,53.76 43,54.88C43,56.01 43.92,56.92 45.06,56.92Z"
|
||||||
|
android:strokeColor="#00000000"
|
||||||
|
android:strokeWidth="1" />
|
||||||
|
</vector>
|
170
androidxdemo/src/main/res/drawable/ic_launcher_background.xml
Normal file
@@ -0,0 +1,170 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:width="108dp"
|
||||||
|
android:height="108dp"
|
||||||
|
android:viewportHeight="108"
|
||||||
|
android:viewportWidth="108">
|
||||||
|
<path
|
||||||
|
android:fillColor="#26A69A"
|
||||||
|
android:pathData="M0,0h108v108h-108z" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M9,0L9,108"
|
||||||
|
android:strokeColor="#33FFFFFF"
|
||||||
|
android:strokeWidth="0.8" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M19,0L19,108"
|
||||||
|
android:strokeColor="#33FFFFFF"
|
||||||
|
android:strokeWidth="0.8" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M29,0L29,108"
|
||||||
|
android:strokeColor="#33FFFFFF"
|
||||||
|
android:strokeWidth="0.8" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M39,0L39,108"
|
||||||
|
android:strokeColor="#33FFFFFF"
|
||||||
|
android:strokeWidth="0.8" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M49,0L49,108"
|
||||||
|
android:strokeColor="#33FFFFFF"
|
||||||
|
android:strokeWidth="0.8" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M59,0L59,108"
|
||||||
|
android:strokeColor="#33FFFFFF"
|
||||||
|
android:strokeWidth="0.8" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M69,0L69,108"
|
||||||
|
android:strokeColor="#33FFFFFF"
|
||||||
|
android:strokeWidth="0.8" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M79,0L79,108"
|
||||||
|
android:strokeColor="#33FFFFFF"
|
||||||
|
android:strokeWidth="0.8" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M89,0L89,108"
|
||||||
|
android:strokeColor="#33FFFFFF"
|
||||||
|
android:strokeWidth="0.8" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M99,0L99,108"
|
||||||
|
android:strokeColor="#33FFFFFF"
|
||||||
|
android:strokeWidth="0.8" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M0,9L108,9"
|
||||||
|
android:strokeColor="#33FFFFFF"
|
||||||
|
android:strokeWidth="0.8" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M0,19L108,19"
|
||||||
|
android:strokeColor="#33FFFFFF"
|
||||||
|
android:strokeWidth="0.8" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M0,29L108,29"
|
||||||
|
android:strokeColor="#33FFFFFF"
|
||||||
|
android:strokeWidth="0.8" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M0,39L108,39"
|
||||||
|
android:strokeColor="#33FFFFFF"
|
||||||
|
android:strokeWidth="0.8" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M0,49L108,49"
|
||||||
|
android:strokeColor="#33FFFFFF"
|
||||||
|
android:strokeWidth="0.8" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M0,59L108,59"
|
||||||
|
android:strokeColor="#33FFFFFF"
|
||||||
|
android:strokeWidth="0.8" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M0,69L108,69"
|
||||||
|
android:strokeColor="#33FFFFFF"
|
||||||
|
android:strokeWidth="0.8" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M0,79L108,79"
|
||||||
|
android:strokeColor="#33FFFFFF"
|
||||||
|
android:strokeWidth="0.8" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M0,89L108,89"
|
||||||
|
android:strokeColor="#33FFFFFF"
|
||||||
|
android:strokeWidth="0.8" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M0,99L108,99"
|
||||||
|
android:strokeColor="#33FFFFFF"
|
||||||
|
android:strokeWidth="0.8" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M19,29L89,29"
|
||||||
|
android:strokeColor="#33FFFFFF"
|
||||||
|
android:strokeWidth="0.8" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M19,39L89,39"
|
||||||
|
android:strokeColor="#33FFFFFF"
|
||||||
|
android:strokeWidth="0.8" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M19,49L89,49"
|
||||||
|
android:strokeColor="#33FFFFFF"
|
||||||
|
android:strokeWidth="0.8" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M19,59L89,59"
|
||||||
|
android:strokeColor="#33FFFFFF"
|
||||||
|
android:strokeWidth="0.8" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M19,69L89,69"
|
||||||
|
android:strokeColor="#33FFFFFF"
|
||||||
|
android:strokeWidth="0.8" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M19,79L89,79"
|
||||||
|
android:strokeColor="#33FFFFFF"
|
||||||
|
android:strokeWidth="0.8" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M29,19L29,89"
|
||||||
|
android:strokeColor="#33FFFFFF"
|
||||||
|
android:strokeWidth="0.8" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M39,19L39,89"
|
||||||
|
android:strokeColor="#33FFFFFF"
|
||||||
|
android:strokeWidth="0.8" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M49,19L49,89"
|
||||||
|
android:strokeColor="#33FFFFFF"
|
||||||
|
android:strokeWidth="0.8" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M59,19L59,89"
|
||||||
|
android:strokeColor="#33FFFFFF"
|
||||||
|
android:strokeWidth="0.8" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M69,19L69,89"
|
||||||
|
android:strokeColor="#33FFFFFF"
|
||||||
|
android:strokeWidth="0.8" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M79,19L79,89"
|
||||||
|
android:strokeColor="#33FFFFFF"
|
||||||
|
android:strokeWidth="0.8" />
|
||||||
|
</vector>
|
38
androidxdemo/src/main/res/layout/activity_main.xml
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<LinearLayout
|
||||||
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:orientation="vertical">
|
||||||
|
|
||||||
|
<com.google.android.material.appbar.AppBarLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">
|
||||||
|
|
||||||
|
<androidx.appcompat.widget.Toolbar
|
||||||
|
android:id="@+id/toolbar"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="?attr/actionBarSize"
|
||||||
|
app:popupTheme="@style/ThemeOverlay.AppCompat.Light"/>
|
||||||
|
|
||||||
|
</com.google.android.material.appbar.AppBarLayout>
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="0dp"
|
||||||
|
android:layout_weight="1.0"
|
||||||
|
android:gravity="center_vertical|center_horizontal">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="AndroidX Demo"
|
||||||
|
android:textAppearance="?android:attr/textAppearanceLarge"/>
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
@@ -0,0 +1,5 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<background android:drawable="@drawable/ic_launcher_background" />
|
||||||
|
<foreground android:drawable="@drawable/ic_launcher_foreground" />
|
||||||
|
</adaptive-icon>
|
@@ -0,0 +1,5 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<background android:drawable="@drawable/ic_launcher_background" />
|
||||||
|
<foreground android:drawable="@drawable/ic_launcher_foreground" />
|
||||||
|
</adaptive-icon>
|
BIN
androidxdemo/src/main/res/mipmap-hdpi/ic_launcher.png
Normal file
After Width: | Height: | Size: 3.0 KiB |
BIN
androidxdemo/src/main/res/mipmap-hdpi/ic_launcher_round.png
Normal file
After Width: | Height: | Size: 4.9 KiB |
BIN
androidxdemo/src/main/res/mipmap-mdpi/ic_launcher.png
Normal file
After Width: | Height: | Size: 2.0 KiB |
BIN
androidxdemo/src/main/res/mipmap-mdpi/ic_launcher_round.png
Normal file
After Width: | Height: | Size: 2.8 KiB |
BIN
androidxdemo/src/main/res/mipmap-xhdpi/ic_launcher.png
Normal file
After Width: | Height: | Size: 4.5 KiB |
BIN
androidxdemo/src/main/res/mipmap-xhdpi/ic_launcher_round.png
Normal file
After Width: | Height: | Size: 6.9 KiB |
BIN
androidxdemo/src/main/res/mipmap-xxhdpi/ic_launcher.png
Normal file
After Width: | Height: | Size: 6.3 KiB |
BIN
androidxdemo/src/main/res/mipmap-xxhdpi/ic_launcher_round.png
Normal file
After Width: | Height: | Size: 10 KiB |
BIN
androidxdemo/src/main/res/mipmap-xxxhdpi/ic_launcher.png
Normal file
After Width: | Height: | Size: 9.0 KiB |
BIN
androidxdemo/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png
Normal file
After Width: | Height: | Size: 15 KiB |
6
androidxdemo/src/main/res/values/colors.xml
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<resources>
|
||||||
|
<color name="colorPrimary">#009688</color>
|
||||||
|
<color name="colorPrimaryDark">#00796B</color>
|
||||||
|
<color name="colorAccent">#FF9800</color>
|
||||||
|
</resources>
|
4
androidxdemo/src/main/res/values/strings.xml
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
<resources>
|
||||||
|
<string name="app_name">AndroidX Demo</string>
|
||||||
|
|
||||||
|
</resources>
|
11
androidxdemo/src/main/res/values/styles.xml
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
<resources>
|
||||||
|
|
||||||
|
<!-- Base application theme. -->
|
||||||
|
<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
|
||||||
|
<!-- Customize your theme here. -->
|
||||||
|
<item name="colorPrimary">@color/colorPrimary</item>
|
||||||
|
<item name="colorPrimaryDark">@color/colorPrimaryDark</item>
|
||||||
|
<item name="colorAccent">@color/colorAccent</item>
|
||||||
|
</style>
|
||||||
|
|
||||||
|
</resources>
|
12
androidxdemo/src/stage/AndroidManifest.xml
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools" >
|
||||||
|
|
||||||
|
<application>
|
||||||
|
|
||||||
|
<!-- Put flavor specific code here -->
|
||||||
|
|
||||||
|
</application>
|
||||||
|
|
||||||
|
</manifest>
|
||||||
|
|
6
androidxdemo/src/stage/res/values/strings.xml
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<resources>
|
||||||
|
|
||||||
|
<!-- Put flavor specific strings here -->
|
||||||
|
|
||||||
|
</resources>
|
@@ -29,7 +29,7 @@ android {
|
|||||||
// versionName 更新后需要手动设置
|
// versionName 更新后需要手动设置
|
||||||
// .winboll/winbollBuildProps.properties 文件的 stageCount=0
|
// .winboll/winbollBuildProps.properties 文件的 stageCount=0
|
||||||
// Gradle编译环境下合起来的 versionName 就是 "${versionName}.0"
|
// Gradle编译环境下合起来的 versionName 就是 "${versionName}.0"
|
||||||
versionName "2.0"
|
versionName "15.0"
|
||||||
if(true) {
|
if(true) {
|
||||||
versionName = genVersionName("${versionName}")
|
versionName = genVersionName("${versionName}")
|
||||||
}
|
}
|
||||||
@@ -45,5 +45,5 @@ android {
|
|||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
api project(':libappbase')
|
api project(':libappbase')
|
||||||
api fileTree(dir: 'libs', include: ['*.jar'])
|
api fileTree(dir: 'libs', include: ['*.jar'])
|
||||||
}
|
}
|
||||||
|
@@ -1,8 +1,8 @@
|
|||||||
#Created by .winboll/winboll_app_build.gradle
|
#Created by .winboll/winboll_app_build.gradle
|
||||||
#Tue Feb 25 16:51:17 HKT 2025
|
#Sat Mar 15 15:30:02 HKT 2025
|
||||||
stageCount=3
|
stageCount=3
|
||||||
libraryProject=libappbase
|
libraryProject=libappbase
|
||||||
baseVersion=2.0
|
baseVersion=15.0
|
||||||
publishVersion=2.0.2
|
publishVersion=15.0.2
|
||||||
buildCount=0
|
buildCount=0
|
||||||
baseBetaVersion=2.0.3
|
baseBetaVersion=15.0.3
|
||||||
|
@@ -7,7 +7,7 @@
|
|||||||
android:name=".App"
|
android:name=".App"
|
||||||
android:icon="@drawable/ic_launcher"
|
android:icon="@drawable/ic_launcher"
|
||||||
android:label="@string/app_name"
|
android:label="@string/app_name"
|
||||||
android:theme="@style/AppTheme"
|
android:theme="@style/MyAppTheme"
|
||||||
android:resizeableActivity="true">
|
android:resizeableActivity="true">
|
||||||
|
|
||||||
<activity
|
<activity
|
||||||
@@ -54,19 +54,25 @@
|
|||||||
<receiver android:name="cc.winboll.studio.appbase.receivers.MainReceiver">
|
<receiver android:name="cc.winboll.studio.appbase.receivers.MainReceiver">
|
||||||
|
|
||||||
<intent-filter>
|
<intent-filter>
|
||||||
|
|
||||||
<action android:name="cc.winboll.studio.appbase.receivers.MainReceiver"/>
|
<action android:name="cc.winboll.studio.appbase.receivers.MainReceiver"/>
|
||||||
|
|
||||||
</intent-filter>
|
</intent-filter>
|
||||||
|
|
||||||
</receiver>
|
</receiver>
|
||||||
|
|
||||||
<receiver
|
<receiver
|
||||||
android:name=".widgets.SOSWidget"
|
android:name=".widgets.APPNewsWidget"
|
||||||
android:exported="true">
|
android:exported="true">
|
||||||
|
|
||||||
<intent-filter>
|
<intent-filter>
|
||||||
<action android:name="cc.winboll.studio.appbase.widgets.SOSWidget.ACTION_WAKEUP_SERVICE"/>
|
|
||||||
<action android:name="cc.winboll.studio.appbase.widgets.SOSWidget.ACTION_RELOAD_REPORT"/>
|
<action android:name="cc.winboll.studio.appbase.widgets.APPNewsWidget.ACTION_WAKEUP_SERVICE"/>
|
||||||
|
|
||||||
|
<action android:name="cc.winboll.studio.appbase.widgets.APPNewsWidget.ACTION_RELOAD_REPORT"/>
|
||||||
|
|
||||||
<action android:name="android.appwidget.action.APPWIDGET_UPDATE"/>
|
<action android:name="android.appwidget.action.APPWIDGET_UPDATE"/>
|
||||||
|
|
||||||
</intent-filter>
|
</intent-filter>
|
||||||
|
|
||||||
<meta-data
|
<meta-data
|
||||||
@@ -75,13 +81,13 @@
|
|||||||
|
|
||||||
</receiver>
|
</receiver>
|
||||||
|
|
||||||
<receiver android:name=".widgets.SOSWidgetClickListener">
|
<receiver android:name=".widgets.APPNewsWidgetClickListener">
|
||||||
|
|
||||||
<intent-filter>
|
<intent-filter>
|
||||||
|
|
||||||
<action android:name="cc.winboll.studio.appbase.widgets.SOSWidgetClickListener.ACTION_PRE"/>
|
<action android:name="cc.winboll.studio.appbase.widgets.APPNewsWidgetClickListener.ACTION_PRE"/>
|
||||||
|
|
||||||
<action android:name="cc.winboll.studio.appbase.widgets.SOSWidgetClickListener.ACTION_NEXT"/>
|
<action android:name="cc.winboll.studio.appbase.widgets.APPNewsWidgetClickListener.ACTION_NEXT"/>
|
||||||
|
|
||||||
</intent-filter>
|
</intent-filter>
|
||||||
|
|
||||||
@@ -91,6 +97,11 @@
|
|||||||
android:name="android.max_aspect"
|
android:name="android.max_aspect"
|
||||||
android:value="4.0"/>
|
android:value="4.0"/>
|
||||||
|
|
||||||
|
<service android:name="cc.winboll.studio.appbase.services.TestDemoBindService"
|
||||||
|
android:exported="true"/>
|
||||||
|
|
||||||
|
<service android:name="cc.winboll.studio.appbase.services.TestDemoService"
|
||||||
|
android:exported="true"/>
|
||||||
|
|
||||||
</application>
|
</application>
|
||||||
|
|
||||||
|
@@ -6,22 +6,23 @@ package cc.winboll.studio.appbase;
|
|||||||
* @Describe APPbase 应用类
|
* @Describe APPbase 应用类
|
||||||
*/
|
*/
|
||||||
import cc.winboll.studio.libappbase.GlobalApplication;
|
import cc.winboll.studio.libappbase.GlobalApplication;
|
||||||
import cc.winboll.studio.libappbase.SOSCSBroadcastReceiver;
|
|
||||||
import android.content.IntentFilter;
|
import android.content.IntentFilter;
|
||||||
|
import cc.winboll.studio.libappbase.sos.SOSCenterServiceReceiver;
|
||||||
|
import cc.winboll.studio.libappbase.sos.SOS;
|
||||||
|
|
||||||
public class App extends GlobalApplication {
|
public class App extends GlobalApplication {
|
||||||
|
|
||||||
public static final String TAG = "App";
|
public static final String TAG = "App";
|
||||||
|
|
||||||
SOSCSBroadcastReceiver mSOSCSBroadcastReceiver;
|
SOSCenterServiceReceiver mSOSCenterServiceReceiver;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onCreate() {
|
public void onCreate() {
|
||||||
super.onCreate();
|
super.onCreate();
|
||||||
GlobalApplication.setIsDebuging(this, BuildConfig.DEBUG);
|
GlobalApplication.setIsDebuging(this, BuildConfig.DEBUG);
|
||||||
mSOSCSBroadcastReceiver = new SOSCSBroadcastReceiver();
|
mSOSCenterServiceReceiver = new SOSCenterServiceReceiver();
|
||||||
IntentFilter intentFilter = new IntentFilter();
|
IntentFilter intentFilter = new IntentFilter();
|
||||||
intentFilter.addAction(SOSCSBroadcastReceiver.ACTION_SOS);
|
intentFilter.addAction(SOS.ACTION_SOS);
|
||||||
registerReceiver(mSOSCSBroadcastReceiver, intentFilter);
|
registerReceiver(mSOSCenterServiceReceiver, intentFilter);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,25 +1,24 @@
|
|||||||
package cc.winboll.studio.appbase;
|
package cc.winboll.studio.appbase;
|
||||||
|
|
||||||
|
import android.app.Activity;
|
||||||
import android.content.ComponentName;
|
import android.content.ComponentName;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.widget.CheckBox;
|
import android.widget.CheckBox;
|
||||||
import androidx.appcompat.app.AppCompatActivity;
|
import android.widget.Toolbar;
|
||||||
import androidx.appcompat.widget.Toolbar;
|
|
||||||
import cc.winboll.studio.appbase.R;
|
import cc.winboll.studio.appbase.R;
|
||||||
import cc.winboll.studio.appbase.services.MainService;
|
import cc.winboll.studio.appbase.services.MainService;
|
||||||
|
import cc.winboll.studio.appbase.services.TestDemoBindService;
|
||||||
|
import cc.winboll.studio.appbase.services.TestDemoService;
|
||||||
import cc.winboll.studio.libappbase.GlobalApplication;
|
import cc.winboll.studio.libappbase.GlobalApplication;
|
||||||
import cc.winboll.studio.libappbase.LogUtils;
|
import cc.winboll.studio.libappbase.LogUtils;
|
||||||
import cc.winboll.studio.libappbase.LogView;
|
import cc.winboll.studio.libappbase.LogView;
|
||||||
import cc.winboll.studio.libappbase.SOS;
|
import cc.winboll.studio.libappbase.sos.SOS;
|
||||||
import cc.winboll.studio.libappbase.SimpleOperateSignalCenterService;
|
import cc.winboll.studio.libappbase.utils.ToastUtils;
|
||||||
import cc.winboll.studio.libappbase.bean.APPSOSBean;
|
|
||||||
import cc.winboll.studio.libappbase.services.TestService;
|
|
||||||
import cc.winboll.studio.libappbase.widgets.StatusWidget;
|
import cc.winboll.studio.libappbase.widgets.StatusWidget;
|
||||||
import com.hjq.toast.ToastUtils;
|
|
||||||
|
|
||||||
public class MainActivity extends AppCompatActivity {
|
public class MainActivity extends Activity {
|
||||||
|
|
||||||
public static final String TAG = "MainActivity";
|
public static final String TAG = "MainActivity";
|
||||||
|
|
||||||
@@ -32,13 +31,16 @@ public class MainActivity extends AppCompatActivity {
|
|||||||
setContentView(R.layout.activity_main);
|
setContentView(R.layout.activity_main);
|
||||||
|
|
||||||
Toolbar toolbar = findViewById(R.id.activitymainToolbar1);
|
Toolbar toolbar = findViewById(R.id.activitymainToolbar1);
|
||||||
setSupportActionBar(toolbar);
|
setActionBar(toolbar);
|
||||||
|
|
||||||
CheckBox cbIsDebugMode = findViewById(R.id.activitymainCheckBox1);
|
CheckBox cbIsDebugMode = findViewById(R.id.activitymainCheckBox1);
|
||||||
cbIsDebugMode.setChecked(GlobalApplication.isDebuging());
|
cbIsDebugMode.setChecked(GlobalApplication.isDebuging());
|
||||||
mLogView = findViewById(R.id.activitymainLogView1);
|
mLogView = findViewById(R.id.activitymainLogView1);
|
||||||
|
|
||||||
if (GlobalApplication.isDebuging()) { mLogView.start(); }
|
if (GlobalApplication.isDebuging()) {
|
||||||
|
mLogView.start();
|
||||||
|
ToastUtils.show("LogView start.");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -68,17 +70,17 @@ public class MainActivity extends AppCompatActivity {
|
|||||||
MainService.stopMainService(this);
|
MainService.stopMainService(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void onTestStopWithoutSettingEnable(View view) {
|
public void onTestStopMainServiceWithoutSettingEnable(View view) {
|
||||||
LogUtils.d(TAG, "onTestStopWithoutSettingEnable");
|
LogUtils.d(TAG, "onTestStopMainServiceWithoutSettingEnable");
|
||||||
stopService(new Intent(this, SimpleOperateSignalCenterService.class));
|
stopService(new Intent(this, MainService.class));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void onTestStartWithString(View view) {
|
public void onTestUseComponentStartService(View view) {
|
||||||
LogUtils.d(TAG, "onTestStartWithString");
|
LogUtils.d(TAG, "onTestUseComponentStartService");
|
||||||
|
|
||||||
// 目标服务的包名和类名
|
// 目标服务的包名和类名
|
||||||
String packageName = this.getPackageName();
|
String packageName = this.getPackageName();
|
||||||
String serviceClassName = SimpleOperateSignalCenterService.class.getName();
|
String serviceClassName = TestDemoService.class.getName();
|
||||||
|
|
||||||
// 构建Intent
|
// 构建Intent
|
||||||
Intent intentService = new Intent();
|
Intent intentService = new Intent();
|
||||||
@@ -87,30 +89,55 @@ public class MainActivity extends AppCompatActivity {
|
|||||||
startService(intentService);
|
startService(intentService);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void onSOS(View view) {
|
public void onTestSOS(View view) {
|
||||||
Intent intent = new Intent(this, TestService.class);
|
Intent intent = new Intent(this, TestDemoService.class);
|
||||||
stopService(intent);
|
stopService(intent);
|
||||||
SOS.sosWinBollService(this, new APPSOSBean(getPackageName(), TestService.class.getName()));
|
if (App.isDebuging()) {
|
||||||
|
SOS.sosToAppBaseBeta(this, TestDemoService.class.getName());
|
||||||
|
} else {
|
||||||
|
SOS.sosToAppBase(this, TestDemoService.class.getName());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void onStartTestService(View view) {
|
public void onSartTestDemoService(View view) {
|
||||||
Intent intent = new Intent(this, TestService.class);
|
Intent intent = new Intent(this, TestDemoService.class);
|
||||||
intent.setAction(SOS.ACTION_SERVICE_ENABLE);
|
intent.setAction(TestDemoService.ACTION_ENABLE);
|
||||||
startService(intent);
|
startService(intent);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void onStopTestService(View view) {
|
public void onStopTestDemoService(View view) {
|
||||||
Intent intent = new Intent(this, TestService.class);
|
Intent intent = new Intent(this, TestDemoService.class);
|
||||||
intent.setAction(SOS.ACTION_SERVICE_DISABLE);
|
intent.setAction(TestDemoService.ACTION_DISABLE);
|
||||||
startService(intent);
|
startService(intent);
|
||||||
|
|
||||||
Intent intentStop = new Intent(this, TestService.class);
|
Intent intentStop = new Intent(this, TestDemoService.class);
|
||||||
stopService(intentStop);
|
stopService(intentStop);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void onStopTestServiceNoSettings(View view) {
|
public void onStopTestDemoServiceNoSettings(View view) {
|
||||||
Intent intent = new Intent(this, TestService.class);
|
Intent intent = new Intent(this, TestDemoService.class);
|
||||||
|
stopService(intent);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onSartTestDemoBindService(View view) {
|
||||||
|
Intent intent = new Intent(this, TestDemoBindService.class);
|
||||||
|
intent.setAction(TestDemoBindService.ACTION_ENABLE);
|
||||||
|
startService(intent);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onStopTestDemoBindService(View view) {
|
||||||
|
Intent intent = new Intent(this, TestDemoBindService.class);
|
||||||
|
intent.setAction(TestDemoBindService.ACTION_DISABLE);
|
||||||
|
startService(intent);
|
||||||
|
|
||||||
|
Intent intentStop = new Intent(this, TestDemoBindService.class);
|
||||||
|
stopService(intentStop);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onStopTestDemoBindServiceNoSettings(View view) {
|
||||||
|
Intent intent = new Intent(this, TestDemoBindService.class);
|
||||||
stopService(intent);
|
stopService(intent);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -35,8 +35,7 @@ public class MainServiceBean extends BaseBean {
|
|||||||
@Override
|
@Override
|
||||||
public void writeThisToJsonWriter(JsonWriter jsonWriter) throws IOException {
|
public void writeThisToJsonWriter(JsonWriter jsonWriter) throws IOException {
|
||||||
super.writeThisToJsonWriter(jsonWriter);
|
super.writeThisToJsonWriter(jsonWriter);
|
||||||
MainServiceBean bean = this;
|
jsonWriter.name("isEnable").value(isEnable());
|
||||||
jsonWriter.name("isEnable").value(bean.isEnable());
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -1,8 +1,8 @@
|
|||||||
package cc.winboll.studio.libappbase.bean;
|
package cc.winboll.studio.appbase.beans;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @Author ZhanGSKen@AliYun.Com
|
* @Author ZhanGSKen@AliYun.Com
|
||||||
* @Date 2025/02/19 13:34:52
|
* @Date 2025/03/07 12:47:22
|
||||||
* @Describe TestServiceBean
|
* @Describe TestServiceBean
|
||||||
*/
|
*/
|
||||||
import android.util.JsonReader;
|
import android.util.JsonReader;
|
||||||
@@ -10,13 +10,13 @@ import android.util.JsonWriter;
|
|||||||
import cc.winboll.studio.libappbase.BaseBean;
|
import cc.winboll.studio.libappbase.BaseBean;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
public class TestServiceBean extends BaseBean {
|
public class TestDemoBindServiceBean extends BaseBean {
|
||||||
|
|
||||||
public static final String TAG = "TestServiceBean";
|
public static final String TAG = "TestServiceBean";
|
||||||
|
|
||||||
boolean isEnable;
|
boolean isEnable;
|
||||||
|
|
||||||
public TestServiceBean() {
|
public TestDemoBindServiceBean() {
|
||||||
this.isEnable = false;
|
this.isEnable = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -30,7 +30,7 @@ public class TestServiceBean extends BaseBean {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getName() {
|
public String getName() {
|
||||||
return TestServiceBean.class.getName();
|
return TestDemoBindServiceBean.class.getName();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
@@ -1,20 +1,22 @@
|
|||||||
package cc.winboll.studio.libappbase.bean;
|
package cc.winboll.studio.appbase.beans;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Author ZhanGSKen@AliYun.Com
|
||||||
|
* @Date 2025/03/07 12:49:21
|
||||||
|
* @Describe TestDemoServiceBean
|
||||||
|
*/
|
||||||
import android.util.JsonReader;
|
import android.util.JsonReader;
|
||||||
import android.util.JsonWriter;
|
import android.util.JsonWriter;
|
||||||
import cc.winboll.studio.libappbase.BaseBean;
|
import cc.winboll.studio.libappbase.BaseBean;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
/**
|
public class TestDemoServiceBean extends BaseBean {
|
||||||
* @Author ZhanGSKen@AliYun.Com
|
|
||||||
* @Date 2025/02/13 04:27:42
|
|
||||||
*/
|
|
||||||
public class SimpleOperateSignalCenterServiceBean extends BaseBean {
|
|
||||||
|
|
||||||
public static final String TAG = "SimpleOperateSignalCenterServiceBean";
|
public static final String TAG = "TestDemoServiceBean";
|
||||||
|
|
||||||
boolean isEnable;
|
boolean isEnable;
|
||||||
|
|
||||||
public SimpleOperateSignalCenterServiceBean() {
|
public TestDemoServiceBean() {
|
||||||
this.isEnable = false;
|
this.isEnable = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -28,7 +30,7 @@ public class SimpleOperateSignalCenterServiceBean extends BaseBean {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getName() {
|
public String getName() {
|
||||||
return SimpleOperateSignalCenterServiceBean.class.getName();
|
return TestDemoServiceBean.class.getName();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
@@ -10,45 +10,45 @@ import android.util.JsonWriter;
|
|||||||
import cc.winboll.studio.libappbase.BaseBean;
|
import cc.winboll.studio.libappbase.BaseBean;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
public class SOSReportBean extends BaseBean {
|
public class WinBollNewsBean extends BaseBean {
|
||||||
|
|
||||||
public static final String TAG = "APPSOSReportBean";
|
public static final String TAG = "WinBollNewsBean";
|
||||||
|
|
||||||
protected String sosReport;
|
protected String message;
|
||||||
|
|
||||||
public SOSReportBean() {
|
public WinBollNewsBean() {
|
||||||
this.sosReport = "";
|
this.message = "";
|
||||||
}
|
}
|
||||||
|
|
||||||
public SOSReportBean(String sosReport) {
|
public WinBollNewsBean(String message) {
|
||||||
this.sosReport = sosReport;
|
this.message = message;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setSosReport(String sosReport) {
|
public void setMessage(String message) {
|
||||||
this.sosReport = sosReport;
|
this.message = message;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getSosReport() {
|
public String getMessage() {
|
||||||
return sosReport;
|
return message;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getName() {
|
public String getName() {
|
||||||
return SOSReportBean.class.getName();
|
return WinBollNewsBean.class.getName();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void writeThisToJsonWriter(JsonWriter jsonWriter) throws IOException {
|
public void writeThisToJsonWriter(JsonWriter jsonWriter) throws IOException {
|
||||||
super.writeThisToJsonWriter(jsonWriter);
|
super.writeThisToJsonWriter(jsonWriter);
|
||||||
jsonWriter.name("sosReport").value(getSosReport());
|
jsonWriter.name("message").value(getMessage());
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean initObjectsFromJsonReader(JsonReader jsonReader, String name) throws IOException {
|
public boolean initObjectsFromJsonReader(JsonReader jsonReader, String name) throws IOException {
|
||||||
if (super.initObjectsFromJsonReader(jsonReader, name)) { return true; } else {
|
if (super.initObjectsFromJsonReader(jsonReader, name)) { return true; } else {
|
||||||
if (name.equals("sosReport")) {
|
if (name.equals("message")) {
|
||||||
setSosReport(jsonReader.nextString());
|
setMessage(jsonReader.nextString());
|
||||||
} else {
|
} else {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
@@ -5,20 +5,21 @@ package cc.winboll.studio.appbase.receivers;
|
|||||||
* @Date 2025/02/13 06:58:04
|
* @Date 2025/02/13 06:58:04
|
||||||
* @Describe 主要广播接收器
|
* @Describe 主要广播接收器
|
||||||
*/
|
*/
|
||||||
import android.appwidget.AppWidgetManager;
|
|
||||||
import android.content.BroadcastReceiver;
|
import android.content.BroadcastReceiver;
|
||||||
import android.content.ComponentName;
|
import android.content.ComponentName;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.content.IntentFilter;
|
import android.content.IntentFilter;
|
||||||
import cc.winboll.studio.appbase.beans.SOSReportBean;
|
import cc.winboll.studio.appbase.beans.WinBollNewsBean;
|
||||||
import cc.winboll.studio.appbase.services.MainService;
|
import cc.winboll.studio.appbase.services.MainService;
|
||||||
import cc.winboll.studio.appbase.widgets.SOSWidget;
|
import cc.winboll.studio.appbase.widgets.APPNewsWidget;
|
||||||
import cc.winboll.studio.libappbase.AppUtils;
|
import cc.winboll.studio.libappbase.AppUtils;
|
||||||
import cc.winboll.studio.libappbase.LogUtils;
|
import cc.winboll.studio.libappbase.LogUtils;
|
||||||
import cc.winboll.studio.libappbase.SOS;
|
import cc.winboll.studio.libappbase.sos.APPModel;
|
||||||
import cc.winboll.studio.libappbase.bean.APPSOSBean;
|
import cc.winboll.studio.libappbase.sos.SOS;
|
||||||
import com.hjq.toast.ToastUtils;
|
import cc.winboll.studio.libappbase.sos.SOSObject;
|
||||||
|
import cc.winboll.studio.libappbase.sos.WinBoll;
|
||||||
|
import cc.winboll.studio.libappbase.utils.ToastUtils;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.lang.ref.WeakReference;
|
import java.lang.ref.WeakReference;
|
||||||
import java.text.SimpleDateFormat;
|
import java.text.SimpleDateFormat;
|
||||||
@@ -27,12 +28,10 @@ import java.util.Date;
|
|||||||
public class MainReceiver extends BroadcastReceiver {
|
public class MainReceiver extends BroadcastReceiver {
|
||||||
|
|
||||||
public static final String TAG = "MainReceiver";
|
public static final String TAG = "MainReceiver";
|
||||||
|
|
||||||
public static final String ACTION_BOOT_COMPLETED = "android.intent.action.BOOT_COMPLETED";
|
public static final String ACTION_BOOT_COMPLETED = "android.intent.action.BOOT_COMPLETED";
|
||||||
|
|
||||||
WeakReference<MainService> mwrService;
|
WeakReference<MainService> mwrService;
|
||||||
// 存储电量指示值,
|
|
||||||
// 用于校验电量消息时的电量变化
|
|
||||||
static volatile int _mnTheQuantityOfElectricityOld = -1;
|
|
||||||
static volatile boolean _mIsCharging = false;
|
|
||||||
|
|
||||||
public MainReceiver(MainService service) {
|
public MainReceiver(MainService service) {
|
||||||
mwrService = new WeakReference<MainService>(service);
|
mwrService = new WeakReference<MainService>(service);
|
||||||
@@ -43,74 +42,62 @@ public class MainReceiver extends BroadcastReceiver {
|
|||||||
String szAction = intent.getAction();
|
String szAction = intent.getAction();
|
||||||
if (szAction.equals(ACTION_BOOT_COMPLETED)) {
|
if (szAction.equals(ACTION_BOOT_COMPLETED)) {
|
||||||
ToastUtils.show("ACTION_BOOT_COMPLETED");
|
ToastUtils.show("ACTION_BOOT_COMPLETED");
|
||||||
} else if (szAction.equals(SOS.ACTION_BIND)) {
|
} else if (szAction.equals(WinBoll.ACTION_BIND)) {
|
||||||
LogUtils.d(TAG, "ACTION_BIND");
|
LogUtils.d(TAG, "ACTION_BIND");
|
||||||
LogUtils.d(TAG, String.format("context.getPackageName() %s", context.getPackageName()));
|
LogUtils.d(TAG, String.format("context.getPackageName() %s", context.getPackageName()));
|
||||||
LogUtils.d(TAG, String.format("intent.getAction() %s", intent.getAction()));
|
LogUtils.d(TAG, String.format("intent.getAction() %s", intent.getAction()));
|
||||||
String SOS = intent.getStringExtra("SOS");
|
String szAPPModel = intent.getStringExtra(WinBoll.EXTRA_APPMODEL);
|
||||||
LogUtils.d(TAG, String.format("SOS %s", SOS));
|
LogUtils.d(TAG, String.format("szAPPModel %s", szAPPModel));
|
||||||
if (SOS != null && SOS.equals("Service")) {
|
if (szAPPModel != null && !szAPPModel.equals("")) {
|
||||||
String szAPPSOSBean = intent.getStringExtra("APPSOSBean");
|
try {
|
||||||
LogUtils.d(TAG, String.format("szAPPSOSBean %s", szAPPSOSBean));
|
APPModel bean = APPModel.parseStringToBean(szAPPModel, APPModel.class);
|
||||||
if (szAPPSOSBean != null && !szAPPSOSBean.equals("")) {
|
if (bean != null) {
|
||||||
try {
|
String szAppPackageName = bean.getAppPackageName();
|
||||||
APPSOSBean bean = APPSOSBean.parseStringToBean(szAPPSOSBean, APPSOSBean.class);
|
LogUtils.d(TAG, String.format("szAppPackageName %s", szAppPackageName));
|
||||||
if (bean != null) {
|
String szAppMainServiveName = bean.getAppMainServiveName();
|
||||||
String sosPackage = bean.getSosPackage();
|
LogUtils.d(TAG, String.format("szAppMainServiveName %s", szAppMainServiveName));
|
||||||
LogUtils.d(TAG, String.format("sosPackage %s", sosPackage));
|
mwrService.get().bindAPPModelConnection(bean);
|
||||||
String sosClassName = bean.getSosClassName();
|
|
||||||
LogUtils.d(TAG, String.format("sosClassName %s", sosClassName));
|
|
||||||
mwrService.get().bindSOSConnection(bean);
|
|
||||||
}
|
|
||||||
} catch (IOException e) {
|
|
||||||
LogUtils.d(TAG, e, Thread.currentThread().getStackTrace());
|
|
||||||
}
|
}
|
||||||
|
} catch (IOException e) {
|
||||||
|
LogUtils.d(TAG, e, Thread.currentThread().getStackTrace());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (intent.getAction().equals(SOS.ACTION_SOS)) {
|
} else if (intent.getAction().equals(SOS.ACTION_SOS)) {
|
||||||
LogUtils.d(TAG, "ACTION_SOS");
|
LogUtils.d(TAG, "ACTION_SOS");
|
||||||
LogUtils.d(TAG, String.format("context.getPackageName() %s", context.getPackageName()));
|
String sos = intent.getStringExtra(SOS.EXTRA_OBJECT);
|
||||||
LogUtils.d(TAG, String.format("intent.getAction() %s", intent.getAction()));
|
LogUtils.d(TAG, String.format("SOS %s", sos));
|
||||||
String SOS = intent.getStringExtra("SOS");
|
if (sos != null && !sos.equals("")) {
|
||||||
LogUtils.d(TAG, String.format("SOS %s", SOS));
|
SOSObject bean = SOS.parseSOSObject(sos);
|
||||||
if (SOS != null && SOS.equals("Service")) {
|
if (bean != null) {
|
||||||
String szAPPSOSBean = intent.getStringExtra("APPSOSBean");
|
String szObjectPackageName = bean.getObjectPackageName();
|
||||||
LogUtils.d(TAG, String.format("szAPPSOSBean %s", szAPPSOSBean));
|
LogUtils.d(TAG, String.format("szObjectPackageName %s", szObjectPackageName));
|
||||||
if (szAPPSOSBean != null && !szAPPSOSBean.equals("")) {
|
String szObjectServiveName = bean.getObjectServiveName();
|
||||||
try {
|
LogUtils.d(TAG, String.format("szObjectServiveName %s", szObjectServiveName));
|
||||||
APPSOSBean bean = APPSOSBean.parseStringToBean(szAPPSOSBean, APPSOSBean.class);
|
|
||||||
if (bean != null) {
|
|
||||||
String sosPackage = bean.getSosPackage();
|
|
||||||
LogUtils.d(TAG, String.format("sosPackage %s", sosPackage));
|
|
||||||
String sosClassName = bean.getSosClassName();
|
|
||||||
LogUtils.d(TAG, String.format("sosClassName %s", sosClassName));
|
|
||||||
|
|
||||||
Intent intentService = new Intent();
|
Intent intentService = new Intent();
|
||||||
intentService.setComponent(new ComponentName(sosPackage, sosClassName));
|
intentService.setComponent(new ComponentName(szObjectPackageName, szObjectServiveName));
|
||||||
context.startService(intentService);
|
context.startService(intentService);
|
||||||
|
|
||||||
String appName = AppUtils.getAppNameByPackageName(context, sosPackage);
|
String appName = AppUtils.getAppNameByPackageName(context, szObjectPackageName);
|
||||||
LogUtils.d(TAG, String.format("appName %s", appName));
|
LogUtils.d(TAG, String.format("appName %s", appName));
|
||||||
SOSReportBean appSOSReportBean = new SOSReportBean(appName);
|
WinBollNewsBean appWinBollNewsBean = new WinBollNewsBean(appName);
|
||||||
SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss");
|
SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss");
|
||||||
String currentTime = sdf.format(new Date());
|
String currentTime = sdf.format(new Date());
|
||||||
StringBuilder sbLine = new StringBuilder();
|
StringBuilder sbLine = new StringBuilder();
|
||||||
sbLine.append("[");
|
sbLine.append("[");
|
||||||
sbLine.append(currentTime);
|
sbLine.append(currentTime);
|
||||||
sbLine.append("] Power to ");
|
sbLine.append("] Power to ");
|
||||||
sbLine.append(appName);
|
sbLine.append(appName);
|
||||||
appSOSReportBean.setSosReport(sbLine.toString());
|
appWinBollNewsBean.setMessage(sbLine.toString());
|
||||||
|
|
||||||
SOSWidget.addAPPSOSReportBean(context, appSOSReportBean);
|
APPNewsWidget.addWinBollNewsBean(context, appWinBollNewsBean);
|
||||||
|
|
||||||
Intent intentWidget = new Intent(context, SOSWidget.class);
|
Intent intentWidget = new Intent(context, APPNewsWidget.class);
|
||||||
intentWidget.setAction(SOSWidget.ACTION_RELOAD_REPORT);
|
intentWidget.setAction(APPNewsWidget.ACTION_RELOAD_REPORT);
|
||||||
context.sendBroadcast(intentWidget);
|
context.sendBroadcast(intentWidget);
|
||||||
}
|
|
||||||
} catch (IOException e) {
|
|
||||||
LogUtils.d(TAG, e, Thread.currentThread().getStackTrace());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
ToastUtils.show(szAction);
|
ToastUtils.show(szAction);
|
||||||
@@ -123,9 +110,7 @@ public class MainReceiver extends BroadcastReceiver {
|
|||||||
IntentFilter filter=new IntentFilter();
|
IntentFilter filter=new IntentFilter();
|
||||||
filter.addAction(ACTION_BOOT_COMPLETED);
|
filter.addAction(ACTION_BOOT_COMPLETED);
|
||||||
filter.addAction(SOS.ACTION_SOS);
|
filter.addAction(SOS.ACTION_SOS);
|
||||||
filter.addAction(SOS.ACTION_BIND);
|
filter.addAction(WinBoll.ACTION_BIND);
|
||||||
filter.addAction(SOS.ACTION_SERVICE_ENABLE);
|
|
||||||
filter.addAction(SOS.ACTION_SERVICE_DISABLE);
|
|
||||||
//filter.addAction(Intent.ACTION_BATTERY_CHANGED);
|
//filter.addAction(Intent.ACTION_BATTERY_CHANGED);
|
||||||
service.registerReceiver(this, filter);
|
service.registerReceiver(this, filter);
|
||||||
}
|
}
|
||||||
|
@@ -23,10 +23,10 @@ import cc.winboll.studio.appbase.handlers.MainServiceHandler;
|
|||||||
import cc.winboll.studio.appbase.receivers.MainReceiver;
|
import cc.winboll.studio.appbase.receivers.MainReceiver;
|
||||||
import cc.winboll.studio.appbase.services.AssistantService;
|
import cc.winboll.studio.appbase.services.AssistantService;
|
||||||
import cc.winboll.studio.appbase.threads.MainServiceThread;
|
import cc.winboll.studio.appbase.threads.MainServiceThread;
|
||||||
import cc.winboll.studio.appbase.widgets.SOSWidget;
|
import cc.winboll.studio.appbase.widgets.APPNewsWidget;
|
||||||
import cc.winboll.studio.libappbase.LogUtils;
|
import cc.winboll.studio.libappbase.LogUtils;
|
||||||
import cc.winboll.studio.libappbase.bean.APPSOSBean;
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import cc.winboll.studio.libappbase.sos.APPModel;
|
||||||
|
|
||||||
public class MainService extends Service {
|
public class MainService extends Service {
|
||||||
|
|
||||||
@@ -45,7 +45,7 @@ public class MainService extends Service {
|
|||||||
AssistantService mAssistantService;
|
AssistantService mAssistantService;
|
||||||
boolean isBound = false;
|
boolean isBound = false;
|
||||||
MainReceiver mMainReceiver;
|
MainReceiver mMainReceiver;
|
||||||
ArrayList<SOSConnection> mSOSConnectionList;
|
ArrayList<APPConnection> mAPPModelConnectionList;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public IBinder onBind(Intent intent) {
|
public IBinder onBind(Intent intent) {
|
||||||
@@ -60,7 +60,7 @@ public class MainService extends Service {
|
|||||||
public void onCreate() {
|
public void onCreate() {
|
||||||
super.onCreate();
|
super.onCreate();
|
||||||
LogUtils.d(TAG, "onCreate()");
|
LogUtils.d(TAG, "onCreate()");
|
||||||
mSOSConnectionList = new ArrayList<SOSConnection>();
|
mAPPModelConnectionList = new ArrayList<APPConnection>();
|
||||||
|
|
||||||
_mControlCenterService = MainService.this;
|
_mControlCenterService = MainService.this;
|
||||||
isServiceRunning = false;
|
isServiceRunning = false;
|
||||||
@@ -101,8 +101,8 @@ public class MainService extends Service {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 启动小部件
|
// 启动小部件
|
||||||
Intent intentTimeWidget = new Intent(this, SOSWidget.class);
|
Intent intentTimeWidget = new Intent(this, APPNewsWidget.class);
|
||||||
intentTimeWidget.setAction(SOSWidget.ACTION_RELOAD_REPORT);
|
intentTimeWidget.setAction(APPNewsWidget.ACTION_RELOAD_REPORT);
|
||||||
this.sendBroadcast(intentTimeWidget);
|
this.sendBroadcast(intentTimeWidget);
|
||||||
|
|
||||||
startMainServiceThread();
|
startMainServiceThread();
|
||||||
@@ -117,21 +117,11 @@ public class MainService extends Service {
|
|||||||
//
|
//
|
||||||
void wakeupAndBindAssistant() {
|
void wakeupAndBindAssistant() {
|
||||||
LogUtils.d(TAG, "wakeupAndBindAssistant()");
|
LogUtils.d(TAG, "wakeupAndBindAssistant()");
|
||||||
// if (ServiceUtils.isServiceAlive(getApplicationContext(), AssistantService.class.getName()) == false) {
|
|
||||||
// startService(new Intent(MainService.this, AssistantService.class));
|
|
||||||
// //LogUtils.d(TAG, "call wakeupAndBindAssistant() : Binding... AssistantService");
|
|
||||||
// bindService(new Intent(MainService.this, AssistantService.class), mMyServiceConnection, Context.BIND_IMPORTANT);
|
|
||||||
// }
|
|
||||||
Intent intent = new Intent(this, AssistantService.class);
|
Intent intent = new Intent(this, AssistantService.class);
|
||||||
startService(intent);
|
startService(intent);
|
||||||
// 绑定服务的Intent
|
// 绑定服务的Intent
|
||||||
//Intent intent = new Intent(this, AssistantService.class);
|
|
||||||
bindService(intent, mMyServiceConnection, Context.BIND_IMPORTANT);
|
bindService(intent, mMyServiceConnection, Context.BIND_IMPORTANT);
|
||||||
|
|
||||||
// Intent intent = new Intent(this, AssistantService.class);
|
|
||||||
// startService(intent);
|
|
||||||
// LogUtils.d(TAG, "startService(intent)");
|
|
||||||
// bindService(new Intent(this, AssistantService.class), mMyServiceConnection, Context.BIND_IMPORTANT);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 开启提醒铃声线程
|
// 开启提醒铃声线程
|
||||||
@@ -192,40 +182,40 @@ public class MainService extends Service {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void bindSOSConnection(APPSOSBean bean) {
|
public void bindAPPModelConnection(APPModel bean) {
|
||||||
LogUtils.d(TAG, "bindSOSConnection(...)");
|
LogUtils.d(TAG, "bindAPPModelConnection(...)");
|
||||||
// 清理旧的绑定链接
|
// 清理旧的绑定链接
|
||||||
for (int i = mSOSConnectionList.size() - 1; i > -1; i--) {
|
for (int i = mAPPModelConnectionList.size() - 1; i > -1; i--) {
|
||||||
SOSConnection item = mSOSConnectionList.get(i);
|
APPConnection item = mAPPModelConnectionList.get(i);
|
||||||
if (item.isBindToAPPSOSBean(bean)) {
|
if (item.isBindToAPP(bean)) {
|
||||||
LogUtils.d(TAG, "Bind Servive exist.");
|
LogUtils.d(TAG, "Bind Servive exist.");
|
||||||
unbindService(item);
|
unbindService(item);
|
||||||
mSOSConnectionList.remove(i);
|
mAPPModelConnectionList.remove(i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 绑定服务
|
// 绑定服务
|
||||||
SOSConnection sosConnection = new SOSConnection();
|
APPConnection appConnection = new APPConnection();
|
||||||
Intent intentService = new Intent();
|
Intent intentService = new Intent();
|
||||||
intentService.setComponent(new ComponentName(bean.getSosPackage(), bean.getSosClassName()));
|
intentService.setComponent(new ComponentName(bean.getAppPackageName(), bean.getAppMainServiveName()));
|
||||||
bindService(intentService, sosConnection, Context.BIND_IMPORTANT);
|
bindService(intentService, appConnection, Context.BIND_IMPORTANT);
|
||||||
mSOSConnectionList.add(sosConnection);
|
mAPPModelConnectionList.add(appConnection);
|
||||||
|
|
||||||
Intent intentWidget = new Intent(this, SOSWidget.class);
|
Intent intentWidget = new Intent(this, APPNewsWidget.class);
|
||||||
intentWidget.setAction(SOSWidget.ACTION_WAKEUP_SERVICE);
|
intentWidget.setAction(APPNewsWidget.ACTION_WAKEUP_SERVICE);
|
||||||
APPSOSBean appSOSBean = new APPSOSBean(bean.getSosPackage(), bean.getSosClassName());
|
APPModel appSOSBean = new APPModel(bean.getAppPackageName(), bean.getAppMainServiveName());
|
||||||
intentWidget.putExtra("APPSOSBean", appSOSBean.toString());
|
intentWidget.putExtra("APPSOSBean", appSOSBean.toString());
|
||||||
sendBroadcast(intentWidget);
|
sendBroadcast(intentWidget);
|
||||||
}
|
}
|
||||||
|
|
||||||
public class SOSConnection implements ServiceConnection {
|
public class APPConnection implements ServiceConnection {
|
||||||
|
|
||||||
ComponentName mComponentName;
|
ComponentName mComponentName;
|
||||||
|
|
||||||
boolean isBindToAPPSOSBean(APPSOSBean bean) {
|
boolean isBindToAPP(APPModel bean) {
|
||||||
return mComponentName != null
|
return mComponentName != null
|
||||||
&& mComponentName.getClassName().equals(bean.getSosClassName())
|
&& mComponentName.getClassName().equals(bean.getAppMainServiveName())
|
||||||
&& mComponentName.getPackageName().equals(bean.getSosPackage());
|
&& mComponentName.getPackageName().equals(bean.getAppPackageName());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -241,13 +231,13 @@ public class MainService extends Service {
|
|||||||
LogUtils.d(TAG, String.format("onServiceDisconnected : \ngetClassName %s\ngetPackageName %s", name.getClassName(), name.getPackageName()));
|
LogUtils.d(TAG, String.format("onServiceDisconnected : \ngetClassName %s\ngetPackageName %s", name.getClassName(), name.getPackageName()));
|
||||||
|
|
||||||
// 尝试无参数启动一下服务
|
// 尝试无参数启动一下服务
|
||||||
String sosPackage = mComponentName.getPackageName();
|
String appPackage = mComponentName.getPackageName();
|
||||||
LogUtils.d(TAG, String.format("sosPackage %s", sosPackage));
|
LogUtils.d(TAG, String.format("appPackage %s", appPackage));
|
||||||
String sosClassName = mComponentName.getClassName();
|
String appMainServiceClassName = mComponentName.getClassName();
|
||||||
LogUtils.d(TAG, String.format("sosClassName %s", sosClassName));
|
LogUtils.d(TAG, String.format("appMainServiceClassName %s", appMainServiceClassName));
|
||||||
|
|
||||||
Intent intentService = new Intent();
|
Intent intentService = new Intent();
|
||||||
intentService.setComponent(new ComponentName(sosPackage, sosClassName));
|
intentService.setComponent(new ComponentName(appPackage, appMainServiceClassName));
|
||||||
startService(intentService);
|
startService(intentService);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -0,0 +1,178 @@
|
|||||||
|
package cc.winboll.studio.appbase.services;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Author ZhanGSKen@AliYun.Com
|
||||||
|
* @Date 2025/03/07 12:45:49
|
||||||
|
* @Describe 启动时申请绑定到APPBase主服务的服务示例
|
||||||
|
*/
|
||||||
|
import android.app.Service;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.os.Binder;
|
||||||
|
import android.os.IBinder;
|
||||||
|
import cc.winboll.studio.appbase.beans.TestDemoBindServiceBean;
|
||||||
|
import cc.winboll.studio.libappbase.LogUtils;
|
||||||
|
import cc.winboll.studio.libappbase.sos.WinBoll;
|
||||||
|
import cc.winboll.studio.appbase.App;
|
||||||
|
import cc.winboll.studio.libappbase.sos.SOS;
|
||||||
|
|
||||||
|
public class TestDemoBindService extends Service {
|
||||||
|
|
||||||
|
public static final String TAG = "TestDemoBindService";
|
||||||
|
|
||||||
|
public static final String ACTION_ENABLE = TestDemoBindService.class.getName() + ".ACTION_ENABLE";
|
||||||
|
public static final String ACTION_DISABLE = TestDemoBindService.class.getName() + ".ACTION_DISABLE";
|
||||||
|
|
||||||
|
volatile static TestThread _TestThread;
|
||||||
|
|
||||||
|
volatile static boolean _IsRunning;
|
||||||
|
|
||||||
|
public synchronized static void setIsRunning(boolean isRunning) {
|
||||||
|
_IsRunning = isRunning;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean isRunning() {
|
||||||
|
return _IsRunning;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public IBinder onBind(Intent intent) {
|
||||||
|
return new MyBinder();
|
||||||
|
}
|
||||||
|
|
||||||
|
public class MyBinder extends Binder {
|
||||||
|
public TestDemoBindService getService() {
|
||||||
|
return TestDemoBindService.this;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onCreate() {
|
||||||
|
super.onCreate();
|
||||||
|
LogUtils.d(TAG, "onCreate()");
|
||||||
|
|
||||||
|
run();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int onStartCommand(Intent intent, int flags, int startId) {
|
||||||
|
LogUtils.d(TAG, "onStartCommand(...)");
|
||||||
|
TestDemoBindServiceBean bean = TestDemoBindServiceBean.loadBean(this, TestDemoBindServiceBean.class);
|
||||||
|
if (bean == null) {
|
||||||
|
bean = new TestDemoBindServiceBean();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (intent.getAction() != null) {
|
||||||
|
if (intent.getAction().equals(ACTION_ENABLE)) {
|
||||||
|
bean.setIsEnable(true);
|
||||||
|
LogUtils.d(TAG, "setIsEnable(true);");
|
||||||
|
TestDemoBindServiceBean.saveBean(this, bean);
|
||||||
|
} else if (intent.getAction().equals(ACTION_DISABLE)) {
|
||||||
|
bean.setIsEnable(false);
|
||||||
|
LogUtils.d(TAG, "setIsEnable(false);");
|
||||||
|
TestDemoBindServiceBean.saveBean(this, bean);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
run();
|
||||||
|
|
||||||
|
return (bean.isEnable()) ? START_STICKY : super.onStartCommand(intent, flags, startId);
|
||||||
|
//return super.onStartCommand(intent, flags, startId);
|
||||||
|
}
|
||||||
|
|
||||||
|
void run() {
|
||||||
|
LogUtils.d(TAG, "run()");
|
||||||
|
TestDemoBindServiceBean bean = TestDemoBindServiceBean.loadBean(this, TestDemoBindServiceBean.class);
|
||||||
|
if (bean == null) {
|
||||||
|
bean = new TestDemoBindServiceBean();
|
||||||
|
TestDemoBindServiceBean.saveBean(this, bean);
|
||||||
|
}
|
||||||
|
if (bean.isEnable()) {
|
||||||
|
LogUtils.d(TAG, "run() bean.isEnable()");
|
||||||
|
TestThread.getInstance(this).start();
|
||||||
|
LogUtils.d(TAG, "_TestThread.start()");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onDestroy() {
|
||||||
|
super.onDestroy();
|
||||||
|
LogUtils.d(TAG, "onDestroy()");
|
||||||
|
TestDemoBindServiceBean bean = TestDemoBindServiceBean.loadBean(this, TestDemoBindServiceBean.class);
|
||||||
|
if (bean == null) {
|
||||||
|
bean = new TestDemoBindServiceBean();
|
||||||
|
}
|
||||||
|
|
||||||
|
TestThread.getInstance(this).setIsExit(true);
|
||||||
|
|
||||||
|
// 预防 APPBase 应用重启绑定失效。
|
||||||
|
// 所以退出时检查本服务是否配置启用,如果启用就发送一个 SOS 信号。
|
||||||
|
// 这样 APPBase 就会用组件方式启动本服务。
|
||||||
|
if (bean.isEnable()) {
|
||||||
|
if (App.isDebuging()) {
|
||||||
|
SOS.sosToAppBaseBeta(this, TestDemoBindService.class.getName());
|
||||||
|
} else {
|
||||||
|
SOS.sosToAppBase(this, TestDemoBindService.class.getName());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_IsRunning = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
static class TestThread extends Thread {
|
||||||
|
|
||||||
|
volatile static TestThread _TestThread;
|
||||||
|
Context mContext;
|
||||||
|
volatile boolean isStarted = false;
|
||||||
|
volatile boolean isExit = false;
|
||||||
|
|
||||||
|
TestThread(Context context) {
|
||||||
|
super();
|
||||||
|
mContext = context;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static synchronized TestThread getInstance(Context context) {
|
||||||
|
if (_TestThread != null) {
|
||||||
|
_TestThread.setIsExit(true);
|
||||||
|
}
|
||||||
|
_TestThread = new TestThread(context);
|
||||||
|
|
||||||
|
return _TestThread;
|
||||||
|
}
|
||||||
|
|
||||||
|
public synchronized void setIsExit(boolean isExit) {
|
||||||
|
this.isExit = isExit;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isExit() {
|
||||||
|
return isExit;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
if (isStarted == false) {
|
||||||
|
isStarted = true;
|
||||||
|
super.run();
|
||||||
|
LogUtils.d(TAG, "run() start");
|
||||||
|
if (App.isDebuging()) {
|
||||||
|
WinBoll.bindToAPPBaseBeta(mContext, TestDemoBindService.class.getName());
|
||||||
|
} else {
|
||||||
|
WinBoll.bindToAPPBase(mContext, TestDemoBindService.class.getName());
|
||||||
|
}
|
||||||
|
|
||||||
|
while (!isExit()) {
|
||||||
|
LogUtils.d(TAG, "run()");
|
||||||
|
|
||||||
|
try {
|
||||||
|
Thread.sleep(1000);
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
LogUtils.d(TAG, e, Thread.currentThread().getStackTrace());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
LogUtils.d(TAG, "run() exit");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -1,23 +1,25 @@
|
|||||||
package cc.winboll.studio.libappbase.services;
|
package cc.winboll.studio.appbase.services;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @Author ZhanGSKen@AliYun.Com
|
* @Author ZhanGSKen@AliYun.Com
|
||||||
* @Date 2025/02/15 20:48:36
|
* @Date 2025/03/07 12:39:24
|
||||||
* @Describe TestService
|
* @Describe 普通服务示例
|
||||||
*/
|
*/
|
||||||
import android.app.Service;
|
import android.app.Service;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.os.Binder;
|
import android.os.Binder;
|
||||||
import android.os.IBinder;
|
import android.os.IBinder;
|
||||||
|
import cc.winboll.studio.appbase.beans.TestDemoServiceBean;
|
||||||
import cc.winboll.studio.libappbase.LogUtils;
|
import cc.winboll.studio.libappbase.LogUtils;
|
||||||
import cc.winboll.studio.libappbase.SOS;
|
import cc.winboll.studio.libappbase.sos.WinBoll;
|
||||||
import cc.winboll.studio.libappbase.bean.APPSOSBean;
|
|
||||||
import cc.winboll.studio.libappbase.bean.TestServiceBean;
|
|
||||||
|
|
||||||
public class TestService extends Service {
|
public class TestDemoService extends Service {
|
||||||
|
|
||||||
public static final String TAG = "TestService";
|
public static final String TAG = "TestDemoService";
|
||||||
|
|
||||||
|
public static final String ACTION_ENABLE = TestDemoService.class.getName() + ".ACTION_ENABLE";
|
||||||
|
public static final String ACTION_DISABLE = TestDemoService.class.getName() + ".ACTION_DISABLE";
|
||||||
|
|
||||||
volatile static TestThread _TestThread;
|
volatile static TestThread _TestThread;
|
||||||
|
|
||||||
@@ -37,8 +39,8 @@ public class TestService extends Service {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public class MyBinder extends Binder {
|
public class MyBinder extends Binder {
|
||||||
public TestService getService() {
|
public TestDemoService getService() {
|
||||||
return TestService.this;
|
return TestDemoService.this;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -54,29 +56,35 @@ public class TestService extends Service {
|
|||||||
@Override
|
@Override
|
||||||
public int onStartCommand(Intent intent, int flags, int startId) {
|
public int onStartCommand(Intent intent, int flags, int startId) {
|
||||||
LogUtils.d(TAG, "onStartCommand(...)");
|
LogUtils.d(TAG, "onStartCommand(...)");
|
||||||
TestServiceBean bean = TestServiceBean.loadBean(this, TestServiceBean.class);
|
TestDemoServiceBean bean = TestDemoServiceBean.loadBean(this, TestDemoServiceBean.class);
|
||||||
if (bean == null) {
|
if (bean == null) {
|
||||||
bean = new TestServiceBean();
|
bean = new TestDemoServiceBean();
|
||||||
}
|
}
|
||||||
if (intent.getAction() != null && intent.getAction().equals(SOS.ACTION_SERVICE_ENABLE)) {
|
|
||||||
bean.setIsEnable(true);
|
if (intent.getAction() != null) {
|
||||||
TestServiceBean.saveBean(this, bean);
|
if (intent.getAction().equals(ACTION_ENABLE)) {
|
||||||
run();
|
bean.setIsEnable(true);
|
||||||
} else if (intent.getAction() != null && intent.getAction().equals(SOS.ACTION_SERVICE_DISABLE)) {
|
LogUtils.d(TAG, "setIsEnable(true);");
|
||||||
bean.setIsEnable(false);
|
TestDemoServiceBean.saveBean(this, bean);
|
||||||
TestServiceBean.saveBean(this, bean);
|
} else if (intent.getAction().equals(ACTION_DISABLE)) {
|
||||||
|
bean.setIsEnable(false);
|
||||||
|
LogUtils.d(TAG, "setIsEnable(false);");
|
||||||
|
TestDemoServiceBean.saveBean(this, bean);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
LogUtils.d(TAG, String.format("TestServiceBean.saveBean setIsEnable %s", bean.isEnable()));
|
|
||||||
|
run();
|
||||||
|
|
||||||
return (bean.isEnable()) ? START_STICKY : super.onStartCommand(intent, flags, startId);
|
return (bean.isEnable()) ? START_STICKY : super.onStartCommand(intent, flags, startId);
|
||||||
//return super.onStartCommand(intent, flags, startId);
|
//return super.onStartCommand(intent, flags, startId);
|
||||||
}
|
}
|
||||||
|
|
||||||
void run() {
|
void run() {
|
||||||
LogUtils.d(TAG, "run()");
|
LogUtils.d(TAG, "run()");
|
||||||
TestServiceBean bean = TestServiceBean.loadBean(this, TestServiceBean.class);
|
TestDemoServiceBean bean = TestDemoServiceBean.loadBean(this, TestDemoServiceBean.class);
|
||||||
if (bean == null) {
|
if (bean == null) {
|
||||||
bean = new TestServiceBean();
|
bean = new TestDemoServiceBean();
|
||||||
TestServiceBean.saveBean(this, bean);
|
TestDemoServiceBean.saveBean(this, bean);
|
||||||
}
|
}
|
||||||
if (bean.isEnable()) {
|
if (bean.isEnable()) {
|
||||||
LogUtils.d(TAG, "run() bean.isEnable()");
|
LogUtils.d(TAG, "run() bean.isEnable()");
|
||||||
@@ -91,7 +99,7 @@ public class TestService extends Service {
|
|||||||
super.onDestroy();
|
super.onDestroy();
|
||||||
LogUtils.d(TAG, "onDestroy()");
|
LogUtils.d(TAG, "onDestroy()");
|
||||||
TestThread.getInstance(this).setIsExit(true);
|
TestThread.getInstance(this).setIsExit(true);
|
||||||
|
|
||||||
_IsRunning = false;
|
_IsRunning = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -130,7 +138,6 @@ public class TestService extends Service {
|
|||||||
isStarted = true;
|
isStarted = true;
|
||||||
super.run();
|
super.run();
|
||||||
LogUtils.d(TAG, "run() start");
|
LogUtils.d(TAG, "run() start");
|
||||||
SOS.bindToAPPService(mContext, new APPSOSBean(mContext.getPackageName(), TestService.class.getName()));
|
|
||||||
|
|
||||||
while (!isExit()) {
|
while (!isExit()) {
|
||||||
LogUtils.d(TAG, "run()");
|
LogUtils.d(TAG, "run()");
|
@@ -12,31 +12,32 @@ import android.content.Context;
|
|||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.widget.RemoteViews;
|
import android.widget.RemoteViews;
|
||||||
import cc.winboll.studio.appbase.R;
|
import cc.winboll.studio.appbase.R;
|
||||||
import cc.winboll.studio.appbase.beans.SOSReportBean;
|
import cc.winboll.studio.appbase.beans.WinBollNewsBean;
|
||||||
import cc.winboll.studio.libappbase.AppUtils;
|
import cc.winboll.studio.libappbase.AppUtils;
|
||||||
import cc.winboll.studio.libappbase.LogUtils;
|
import cc.winboll.studio.libappbase.LogUtils;
|
||||||
import cc.winboll.studio.libappbase.bean.APPSOSBean;
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.text.SimpleDateFormat;
|
import java.text.SimpleDateFormat;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
|
import cc.winboll.studio.libappbase.sos.APPModel;
|
||||||
|
import cc.winboll.studio.libappbase.sos.WinBoll;
|
||||||
|
|
||||||
public class SOSWidget extends AppWidgetProvider {
|
public class APPNewsWidget extends AppWidgetProvider {
|
||||||
|
|
||||||
public static final String TAG = "SOSWidget";
|
public static final String TAG = "APPNewsWidget";
|
||||||
|
|
||||||
public static final String ACTION_WAKEUP_SERVICE = "cc.winboll.studio.appbase.widgets.SOSWidget.ACTION_WAKEUP_SERVICE";
|
public static final String ACTION_WAKEUP_SERVICE = APPNewsWidget.class.getName() + ".ACTION_WAKEUP_SERVICE";
|
||||||
public static final String ACTION_RELOAD_REPORT = "cc.winboll.studio.appbase.widgets.SOSWidget.ACTION_RELOAD_REPORT";
|
public static final String ACTION_RELOAD_REPORT = APPNewsWidget.class.getName() + ".ACTION_RELOAD_REPORT";
|
||||||
|
|
||||||
|
|
||||||
volatile static ArrayList<SOSReportBean> _SOSReportBeanList;
|
volatile static ArrayList<WinBollNewsBean> _WinBollNewsBeanList;
|
||||||
final static int _MAX_PAGES = 10;
|
final static int _MAX_PAGES = 10;
|
||||||
final static int _OnePageLinesCount = 5;
|
final static int _OnePageLinesCount = 5;
|
||||||
volatile static int _CurrentPageIndex = 0;
|
volatile static int _CurrentPageIndex = 0;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
|
public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
|
||||||
initAPPSOSReportBeanList(context);
|
initWinBollNewsBeanList(context);
|
||||||
for (int appWidgetId : appWidgetIds) {
|
for (int appWidgetId : appWidgetIds) {
|
||||||
updateAppWidget(context, appWidgetManager, appWidgetId);
|
updateAppWidget(context, appWidgetManager, appWidgetId);
|
||||||
}
|
}
|
||||||
@@ -45,31 +46,31 @@ public class SOSWidget extends AppWidgetProvider {
|
|||||||
@Override
|
@Override
|
||||||
public void onReceive(Context context, Intent intent) {
|
public void onReceive(Context context, Intent intent) {
|
||||||
super.onReceive(context, intent);
|
super.onReceive(context, intent);
|
||||||
initAPPSOSReportBeanList(context);
|
initWinBollNewsBeanList(context);
|
||||||
if (intent.getAction().equals(ACTION_RELOAD_REPORT)) {
|
if (intent.getAction().equals(ACTION_RELOAD_REPORT)) {
|
||||||
LogUtils.d(TAG, "ACTION_RELOAD_REPORT");
|
LogUtils.d(TAG, "ACTION_RELOAD_REPORT");
|
||||||
AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context);
|
AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context);
|
||||||
int[] appWidgetIds = appWidgetManager.getAppWidgetIds(new ComponentName(context, SOSWidget.class));
|
int[] appWidgetIds = appWidgetManager.getAppWidgetIds(new ComponentName(context, APPNewsWidget.class));
|
||||||
for (int appWidgetId : appWidgetIds) {
|
for (int appWidgetId : appWidgetIds) {
|
||||||
updateAppWidget(context, appWidgetManager, appWidgetId);
|
updateAppWidget(context, appWidgetManager, appWidgetId);
|
||||||
}
|
}
|
||||||
}else if (intent.getAction().equals(ACTION_WAKEUP_SERVICE)) {
|
}else if (intent.getAction().equals(ACTION_WAKEUP_SERVICE)) {
|
||||||
LogUtils.d(TAG, "ACTION_WAKEUP_SERVICE");
|
LogUtils.d(TAG, "ACTION_WAKEUP_SERVICE");
|
||||||
String szAPPSOSBean = intent.getStringExtra("APPSOSBean");
|
String szAPPModel = intent.getStringExtra(WinBoll.EXTRA_APPMODEL);
|
||||||
LogUtils.d(TAG, String.format("szAPPSOSBean %s", szAPPSOSBean));
|
LogUtils.d(TAG, String.format("szAPPModel %s", szAPPModel));
|
||||||
if (szAPPSOSBean != null && !szAPPSOSBean.equals("")) {
|
if (szAPPModel != null && !szAPPModel.equals("")) {
|
||||||
try {
|
try {
|
||||||
APPSOSBean bean = APPSOSBean.parseStringToBean(szAPPSOSBean, APPSOSBean.class);
|
APPModel bean = APPModel.parseStringToBean(szAPPModel, APPModel.class);
|
||||||
if (bean != null) {
|
if (bean != null) {
|
||||||
String sosPackage = bean.getSosPackage();
|
String szAppPackageName = bean.getAppPackageName();
|
||||||
LogUtils.d(TAG, String.format("sosPackage %s", sosPackage));
|
LogUtils.d(TAG, String.format("szAppPackageName %s", szAppPackageName));
|
||||||
String sosClassName = bean.getSosClassName();
|
String szAppMainServiveName = bean.getAppMainServiveName();
|
||||||
LogUtils.d(TAG, String.format("sosClassName %s", sosClassName));
|
LogUtils.d(TAG, String.format("szAppMainServiveName %s", szAppMainServiveName));
|
||||||
|
|
||||||
|
|
||||||
String appName = AppUtils.getAppNameByPackageName(context, sosPackage);
|
String appName = AppUtils.getAppNameByPackageName(context, szAppPackageName);
|
||||||
LogUtils.d(TAG, String.format("appName %s", appName));
|
LogUtils.d(TAG, String.format("appName %s", appName));
|
||||||
SOSReportBean appSOSReportBean = new SOSReportBean(appName);
|
WinBollNewsBean winBollNewsBean = new WinBollNewsBean(appName);
|
||||||
SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss");
|
SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss");
|
||||||
String currentTime = sdf.format(new Date());
|
String currentTime = sdf.format(new Date());
|
||||||
StringBuilder sbLine = new StringBuilder();
|
StringBuilder sbLine = new StringBuilder();
|
||||||
@@ -77,12 +78,12 @@ public class SOSWidget extends AppWidgetProvider {
|
|||||||
sbLine.append(currentTime);
|
sbLine.append(currentTime);
|
||||||
sbLine.append("] Wake up ");
|
sbLine.append("] Wake up ");
|
||||||
sbLine.append(appName);
|
sbLine.append(appName);
|
||||||
appSOSReportBean.setSosReport(sbLine.toString());
|
winBollNewsBean.setMessage(sbLine.toString());
|
||||||
|
|
||||||
addAPPSOSReportBean(context, appSOSReportBean);
|
addWinBollNewsBean(context, winBollNewsBean);
|
||||||
|
|
||||||
AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context);
|
AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context);
|
||||||
int[] appWidgetIds = appWidgetManager.getAppWidgetIds(new ComponentName(context, SOSWidget.class));
|
int[] appWidgetIds = appWidgetManager.getAppWidgetIds(new ComponentName(context, APPNewsWidget.class));
|
||||||
for (int appWidgetId : appWidgetIds) {
|
for (int appWidgetId : appWidgetIds) {
|
||||||
updateAppWidget(context, appWidgetManager, appWidgetId);
|
updateAppWidget(context, appWidgetManager, appWidgetId);
|
||||||
}
|
}
|
||||||
@@ -97,53 +98,53 @@ public class SOSWidget extends AppWidgetProvider {
|
|||||||
//
|
//
|
||||||
// 加入新报告信息
|
// 加入新报告信息
|
||||||
//
|
//
|
||||||
public synchronized static void addAPPSOSReportBean(Context context, SOSReportBean bean) {
|
public synchronized static void addWinBollNewsBean(Context context, WinBollNewsBean bean) {
|
||||||
initAPPSOSReportBeanList(context);
|
initWinBollNewsBeanList(context);
|
||||||
_SOSReportBeanList.add(0, bean);
|
_WinBollNewsBeanList.add(0, bean);
|
||||||
// 控制记录总数
|
// 控制记录总数
|
||||||
while (_SOSReportBeanList.size() > _MAX_PAGES * _OnePageLinesCount) {
|
while (_WinBollNewsBeanList.size() > _MAX_PAGES * _OnePageLinesCount) {
|
||||||
_SOSReportBeanList.remove(_SOSReportBeanList.size() - 1);
|
_WinBollNewsBeanList.remove(_WinBollNewsBeanList.size() - 1);
|
||||||
}
|
}
|
||||||
SOSReportBean.saveBeanList(context, _SOSReportBeanList, SOSReportBean.class);
|
WinBollNewsBean.saveBeanList(context, _WinBollNewsBeanList, WinBollNewsBean.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
synchronized static void initAPPSOSReportBeanList(Context context) {
|
synchronized static void initWinBollNewsBeanList(Context context) {
|
||||||
if (_SOSReportBeanList == null) {
|
if (_WinBollNewsBeanList == null) {
|
||||||
_SOSReportBeanList = new ArrayList<SOSReportBean>();
|
_WinBollNewsBeanList = new ArrayList<WinBollNewsBean>();
|
||||||
SOSReportBean.loadBeanList(context, _SOSReportBeanList, SOSReportBean.class);
|
WinBollNewsBean.loadBeanList(context, _WinBollNewsBeanList, WinBollNewsBean.class);
|
||||||
}
|
}
|
||||||
if (_SOSReportBeanList == null) {
|
if (_WinBollNewsBeanList == null) {
|
||||||
_SOSReportBeanList = new ArrayList<SOSReportBean>();
|
_WinBollNewsBeanList = new ArrayList<WinBollNewsBean>();
|
||||||
SOSReportBean.saveBeanList(context, _SOSReportBeanList, SOSReportBean.class);
|
WinBollNewsBean.saveBeanList(context, _WinBollNewsBeanList, WinBollNewsBean.class);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updateAppWidget(Context context, AppWidgetManager appWidgetManager, int appWidgetId) {
|
private void updateAppWidget(Context context, AppWidgetManager appWidgetManager, int appWidgetId) {
|
||||||
LogUtils.d(TAG, "updateAppWidget(...)");
|
LogUtils.d(TAG, "updateAppWidget(...)");
|
||||||
|
|
||||||
RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.widget_sos);
|
RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.widget_news);
|
||||||
//设置按钮点击事件
|
//设置按钮点击事件
|
||||||
Intent intentPre = new Intent(context, SOSWidgetClickListener.class);
|
Intent intentPre = new Intent(context, APPNewsWidgetClickListener.class);
|
||||||
intentPre.setAction(SOSWidgetClickListener.ACTION_PRE);
|
intentPre.setAction(APPNewsWidgetClickListener.ACTION_PRE);
|
||||||
PendingIntent pendingIntentPre = PendingIntent.getBroadcast(context, 0, intentPre, PendingIntent.FLAG_UPDATE_CURRENT);
|
PendingIntent pendingIntentPre = PendingIntent.getBroadcast(context, 0, intentPre, PendingIntent.FLAG_UPDATE_CURRENT);
|
||||||
views.setOnClickPendingIntent(R.id.widget_button_pre, pendingIntentPre);
|
views.setOnClickPendingIntent(R.id.widget_button_pre, pendingIntentPre);
|
||||||
Intent intentNext = new Intent(context, SOSWidgetClickListener.class);
|
Intent intentNext = new Intent(context, APPNewsWidgetClickListener.class);
|
||||||
intentNext.setAction(SOSWidgetClickListener.ACTION_NEXT);
|
intentNext.setAction(APPNewsWidgetClickListener.ACTION_NEXT);
|
||||||
PendingIntent pendingIntentNext = PendingIntent.getBroadcast(context, 0, intentNext, PendingIntent.FLAG_UPDATE_CURRENT);
|
PendingIntent pendingIntentNext = PendingIntent.getBroadcast(context, 0, intentNext, PendingIntent.FLAG_UPDATE_CURRENT);
|
||||||
views.setOnClickPendingIntent(R.id.widget_button_next, pendingIntentNext);
|
views.setOnClickPendingIntent(R.id.widget_button_next, pendingIntentNext);
|
||||||
|
|
||||||
views.setTextViewText(R.id.infoTextView, getPageInfo());
|
views.setTextViewText(R.id.tv_msg, getPageInfo());
|
||||||
views.setTextViewText(R.id.sosReportTextView, getMessage());
|
views.setTextViewText(R.id.tv_news, getMessage());
|
||||||
appWidgetManager.updateAppWidget(appWidgetId, views);
|
appWidgetManager.updateAppWidget(appWidgetId, views);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String getMessage() {
|
public static String getMessage() {
|
||||||
ArrayList<String> msgTemp = new ArrayList<String>();
|
ArrayList<String> msgTemp = new ArrayList<String>();
|
||||||
if (_SOSReportBeanList != null) {
|
if (_WinBollNewsBeanList != null) {
|
||||||
int start = _OnePageLinesCount * _CurrentPageIndex;
|
int start = _OnePageLinesCount * _CurrentPageIndex;
|
||||||
start = _SOSReportBeanList.size() > start ? start : _SOSReportBeanList.size() - 1;
|
start = _WinBollNewsBeanList.size() > start ? start : _WinBollNewsBeanList.size() - 1;
|
||||||
for (int i = start, j = 0; i < _SOSReportBeanList.size() && j < _OnePageLinesCount && start > -1; i++, j++) {
|
for (int i = start, j = 0; i < _WinBollNewsBeanList.size() && j < _OnePageLinesCount && start > -1; i++, j++) {
|
||||||
msgTemp.add(_SOSReportBeanList.get(i).getSosReport());
|
msgTemp.add(_WinBollNewsBeanList.get(i).getMessage());
|
||||||
}
|
}
|
||||||
String message = String.join("\n", msgTemp);
|
String message = String.join("\n", msgTemp);
|
||||||
return message;
|
return message;
|
||||||
@@ -152,33 +153,33 @@ public class SOSWidget extends AppWidgetProvider {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static void prePage(Context context) {
|
public static void prePage(Context context) {
|
||||||
if (_SOSReportBeanList != null) {
|
if (_WinBollNewsBeanList != null) {
|
||||||
if (_CurrentPageIndex > 0) {
|
if (_CurrentPageIndex > 0) {
|
||||||
_CurrentPageIndex = _CurrentPageIndex - 1;
|
_CurrentPageIndex = _CurrentPageIndex - 1;
|
||||||
}
|
}
|
||||||
Intent intentWidget = new Intent(context, SOSWidget.class);
|
Intent intentWidget = new Intent(context, APPNewsWidget.class);
|
||||||
intentWidget.setAction(SOSWidget.ACTION_RELOAD_REPORT);
|
intentWidget.setAction(APPNewsWidget.ACTION_RELOAD_REPORT);
|
||||||
context.sendBroadcast(intentWidget);
|
context.sendBroadcast(intentWidget);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void nextPage(Context context) {
|
public static void nextPage(Context context) {
|
||||||
if (_SOSReportBeanList != null) {
|
if (_WinBollNewsBeanList != null) {
|
||||||
if ((_CurrentPageIndex + 1) * _OnePageLinesCount < _SOSReportBeanList.size()) {
|
if ((_CurrentPageIndex + 1) * _OnePageLinesCount < _WinBollNewsBeanList.size()) {
|
||||||
_CurrentPageIndex = _CurrentPageIndex + 1;
|
_CurrentPageIndex = _CurrentPageIndex + 1;
|
||||||
}
|
}
|
||||||
Intent intentWidget = new Intent(context, SOSWidget.class);
|
Intent intentWidget = new Intent(context, APPNewsWidget.class);
|
||||||
intentWidget.setAction(SOSWidget.ACTION_RELOAD_REPORT);
|
intentWidget.setAction(APPNewsWidget.ACTION_RELOAD_REPORT);
|
||||||
context.sendBroadcast(intentWidget);
|
context.sendBroadcast(intentWidget);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
String getPageInfo() {
|
String getPageInfo() {
|
||||||
if (_SOSReportBeanList == null) {
|
if (_WinBollNewsBeanList == null) {
|
||||||
return "0/0";
|
return "0/0";
|
||||||
}
|
}
|
||||||
int leftCount = _SOSReportBeanList.size() % _OnePageLinesCount;
|
int leftCount = _WinBollNewsBeanList.size() % _OnePageLinesCount;
|
||||||
int currentPageCount = _SOSReportBeanList.size() / _OnePageLinesCount + (leftCount == 0 ?0: 1);
|
int currentPageCount = _WinBollNewsBeanList.size() / _OnePageLinesCount + (leftCount == 0 ?0: 1);
|
||||||
return String.format("%d/%d", _CurrentPageIndex + 1, currentPageCount);
|
return String.format("%d/%d", _CurrentPageIndex + 1, currentPageCount);
|
||||||
}
|
}
|
||||||
}
|
}
|
@@ -10,11 +10,11 @@ import android.content.Context;
|
|||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import cc.winboll.studio.libappbase.LogUtils;
|
import cc.winboll.studio.libappbase.LogUtils;
|
||||||
|
|
||||||
public class SOSWidgetClickListener extends BroadcastReceiver {
|
public class APPNewsWidgetClickListener extends BroadcastReceiver {
|
||||||
|
|
||||||
public static final String TAG = "SOSWidgetClickListener";
|
public static final String TAG = "APPNewsWidgetClickListener";
|
||||||
public static final String ACTION_PRE = "cc.winboll.studio.appbase.widgets.SOSWidgetClickListener.ACTION_PRE";
|
public static final String ACTION_PRE = APPNewsWidgetClickListener.class.getName() + ".ACTION_PRE";
|
||||||
public static final String ACTION_NEXT = "cc.winboll.studio.appbase.widgets.SOSWidgetClickListener.ACTION_NEXT";
|
public static final String ACTION_NEXT = APPNewsWidgetClickListener.class.getName() + ".ACTION_NEXT";
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onReceive(Context context, Intent intent) {
|
public void onReceive(Context context, Intent intent) {
|
||||||
@@ -25,10 +25,10 @@ public class SOSWidgetClickListener extends BroadcastReceiver {
|
|||||||
}
|
}
|
||||||
if (action.equals(ACTION_PRE)) {
|
if (action.equals(ACTION_PRE)) {
|
||||||
LogUtils.d(TAG, "ACTION_PRE");
|
LogUtils.d(TAG, "ACTION_PRE");
|
||||||
SOSWidget.prePage(context);
|
APPNewsWidget.prePage(context);
|
||||||
} else if (action.equals(ACTION_NEXT)) {
|
} else if (action.equals(ACTION_NEXT)) {
|
||||||
LogUtils.d(TAG, "ACTION_NEXT");
|
LogUtils.d(TAG, "ACTION_NEXT");
|
||||||
SOSWidget.nextPage(context);
|
APPNewsWidget.nextPage(context);
|
||||||
} else {
|
} else {
|
||||||
LogUtils.d(TAG, String.format("action %s", action));
|
LogUtils.d(TAG, String.format("action %s", action));
|
||||||
}
|
}
|
@@ -1,149 +1,194 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
android:orientation="vertical"
|
android:orientation="vertical"
|
||||||
android:gravity="center">
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent">
|
||||||
|
|
||||||
<androidx.appcompat.widget.Toolbar
|
<android.widget.Toolbar
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:id="@+id/activitymainToolbar1"/>
|
android:id="@+id/activitymainToolbar1"/>
|
||||||
|
|
||||||
<LinearLayout
|
<ScrollView
|
||||||
android:orientation="vertical"
|
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="0dp"
|
android:layout_height="0dp"
|
||||||
android:layout_weight="1.0"
|
android:layout_weight="1.0">
|
||||||
android:gravity="center_horizontal">
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:text="Hello, WinBoll!"/>
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:text="Android版本10的代号是“Q”,API级别是29。 Android 10开始谷歌不再公开使用甜品作为版本代号,但内部仍保留了大量与“Q”相关的元素。Android 10本身并没有严格对应某个特定的Java版本,但在开发Android 10应用时,通常可以使用Java 8或更高版本。
|
|
||||||
|
|
||||||
Java 8为Android开发带来了诸如Lambda表达式、方法引用等新特性,能提高开发效率和代码可读性,与Android 10开发适配良好。Java 9及更高版本也可用于Android 10开发,能使用一些新的语言特性和API,但可能需要注意兼容性和配置问题。"/>
|
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:orientation="horizontal"
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:gravity="right|center_vertical">
|
android:orientation="vertical"
|
||||||
|
android:gravity="center">
|
||||||
<CheckBox
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:text="Debug Mode"
|
|
||||||
android:layout_weight="1.0"
|
|
||||||
android:onClick="onSwitchDebugMode"
|
|
||||||
android:id="@+id/activitymainCheckBox1"/>
|
|
||||||
|
|
||||||
<Button
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:text="Test Application CrashReport"
|
|
||||||
android:textAllCaps="false"
|
|
||||||
android:onClick="onTestApplicationCrashReport"/>
|
|
||||||
|
|
||||||
</LinearLayout>
|
|
||||||
|
|
||||||
<ScrollView
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="400dp">
|
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:orientation="vertical"
|
android:orientation="vertical"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="0dp"
|
||||||
android:gravity="right">
|
android:layout_weight="1.0"
|
||||||
|
android:gravity="center_horizontal">
|
||||||
|
|
||||||
<HorizontalScrollView
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="Hello, WinBoll!"/>
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="Android版本10的代号是“Q”,API级别是29。 Android 10开始谷歌不再公开使用甜品作为版本代号,但内部仍保留了大量与“Q”相关的元素。Android 10本身并没有严格对应某个特定的Java版本,但在开发Android 10应用时,通常可以使用Java 8或更高版本。 Java 8为Android开发带来了诸如Lambda表达式、方法引用等新特性,能提高开发效率和代码可读性,与Android 10开发适配良好。Java 9及更高版本也可用于Android 10开发,能使用一些新的语言特性和API,但可能需要注意兼容性和配置问题。"/>
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:orientation="horizontal"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content">
|
android:layout_height="wrap_content"
|
||||||
|
android:gravity="right|center_vertical">
|
||||||
|
|
||||||
|
<CheckBox
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="Debug Mode"
|
||||||
|
android:layout_weight="1.0"
|
||||||
|
android:onClick="onSwitchDebugMode"
|
||||||
|
android:id="@+id/activitymainCheckBox1"/>
|
||||||
|
|
||||||
|
<Button
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="Test Application CrashReport"
|
||||||
|
android:textAllCaps="false"
|
||||||
|
android:onClick="onTestApplicationCrashReport"/>
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<ScrollView
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="400dp">
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:orientation="horizontal"
|
android:orientation="vertical"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content">
|
android:layout_height="wrap_content"
|
||||||
|
android:gravity="right">
|
||||||
|
|
||||||
|
<HorizontalScrollView
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content">
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:orientation="horizontal"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content">
|
||||||
|
|
||||||
|
<Button
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="SartTestDemoService"
|
||||||
|
android:textAllCaps="false"
|
||||||
|
android:onClick="onSartTestDemoService"/>
|
||||||
|
|
||||||
|
<Button
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="StopTestDemoService"
|
||||||
|
android:textAllCaps="false"
|
||||||
|
android:onClick="onStopTestDemoService"/>
|
||||||
|
|
||||||
|
<Button
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="StopTestDemoServiceNoSettings"
|
||||||
|
android:textAllCaps="false"
|
||||||
|
android:onClick="onStopTestDemoServiceNoSettings"/>
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
</HorizontalScrollView>
|
||||||
|
|
||||||
|
<HorizontalScrollView
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content">
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:orientation="horizontal"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content">
|
||||||
|
|
||||||
|
<Button
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="SartTestDemoBindService"
|
||||||
|
android:textAllCaps="false"
|
||||||
|
android:onClick="onSartTestDemoBindService"/>
|
||||||
|
|
||||||
|
<Button
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="StopTestDemoBindService"
|
||||||
|
android:textAllCaps="false"
|
||||||
|
android:onClick="onStopTestDemoBindService"/>
|
||||||
|
|
||||||
|
<Button
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="StopTestDemoBindServiceNoSettings"
|
||||||
|
android:textAllCaps="false"
|
||||||
|
android:onClick="onStopTestDemoBindServiceNoSettings"/>
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
</HorizontalScrollView>
|
||||||
|
|
||||||
|
<Button
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="StartCenter"
|
||||||
|
android:textAllCaps="false"
|
||||||
|
android:onClick="onStartCenter"/>
|
||||||
|
|
||||||
<Button
|
<Button
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:text="StartTestService"
|
android:text="StopCenter"
|
||||||
android:textAllCaps="false"
|
android:textAllCaps="false"
|
||||||
android:onClick="onStartTestService"/>
|
android:onClick="onStopCenter"/>
|
||||||
|
|
||||||
<Button
|
<Button
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:text="StopTestService"
|
android:text="TestStopMainServiceWithoutSettingEnable"
|
||||||
android:textAllCaps="false"
|
android:textAllCaps="false"
|
||||||
android:onClick="onStopTestService"/>
|
android:onClick="onTestStopMainServiceWithoutSettingEnable"/>
|
||||||
|
|
||||||
<Button
|
<Button
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:text="StopTestServiceNoSettings"
|
android:text="TestUseComponentStartService"
|
||||||
android:textAllCaps="false"
|
android:textAllCaps="false"
|
||||||
android:onClick="onStopTestServiceNoSettings"/>
|
android:onClick="onTestUseComponentStartService"/>
|
||||||
|
|
||||||
|
<Button
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="TestSOS"
|
||||||
|
android:textAllCaps="false"
|
||||||
|
android:onClick="onTestSOS"/>
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
</HorizontalScrollView>
|
</ScrollView>
|
||||||
|
|
||||||
<Button
|
<cc.winboll.studio.libappbase.LogView
|
||||||
android:layout_width="wrap_content"
|
android:layout_height="500dp"
|
||||||
android:layout_height="wrap_content"
|
android:layout_width="match_parent"
|
||||||
android:text="StartCenter"
|
android:id="@+id/activitymainLogView1"/>
|
||||||
android:textAllCaps="false"
|
|
||||||
android:onClick="onStartCenter"/>
|
|
||||||
|
|
||||||
<Button
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:text="StopCenter"
|
|
||||||
android:textAllCaps="false"
|
|
||||||
android:onClick="onStopCenter"/>
|
|
||||||
|
|
||||||
<Button
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:text="TestStopWithoutSettingEnable"
|
|
||||||
android:textAllCaps="false"
|
|
||||||
android:onClick="onTestStopWithoutSettingEnable"/>
|
|
||||||
|
|
||||||
<Button
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:text="TestStartWithString"
|
|
||||||
android:textAllCaps="false"
|
|
||||||
android:onClick="onTestStartWithString"/>
|
|
||||||
|
|
||||||
<Button
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:text="SOS"
|
|
||||||
android:textAllCaps="false"
|
|
||||||
android:onClick="onSOS"/>
|
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
</ScrollView>
|
</LinearLayout>
|
||||||
|
|
||||||
<cc.winboll.studio.libappbase.LogView
|
</ScrollView>
|
||||||
android:layout_weight="1.0"
|
|
||||||
android:layout_height="0dp"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:id="@+id/activitymainLogView1"/>
|
|
||||||
|
|
||||||
</LinearLayout>
|
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
|
@@ -11,31 +11,40 @@
|
|||||||
android:orientation="horizontal"
|
android:orientation="horizontal"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:gravity="right">
|
android:gravity="right|center_vertical">
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="0dp"
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:id="@+id/infoTextView"/>
|
|
||||||
|
|
||||||
<Button
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:text="⇦"
|
|
||||||
android:id="@+id/widget_button_pre"/>
|
|
||||||
|
|
||||||
<Button
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
|
android:id="@+id/tv_title"
|
||||||
|
android:layout_weight="1.0"
|
||||||
|
android:text="WinBollNews"
|
||||||
|
android:textStyle="bold"
|
||||||
|
android:textSize="16sp"/>
|
||||||
|
|
||||||
|
<Button
|
||||||
|
android:layout_width="48dp"
|
||||||
|
android:layout_height="48dp"
|
||||||
|
android:text="⇦"
|
||||||
|
android:id="@+id/widget_button_pre"/>
|
||||||
|
|
||||||
|
<Button
|
||||||
|
android:layout_width="48dp"
|
||||||
|
android:layout_height="48dp"
|
||||||
android:text="⇨"
|
android:text="⇨"
|
||||||
android:id="@+id/widget_button_next"/>
|
android:id="@+id/widget_button_next"/>
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:id="@+id/tv_msg"/>
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="0dp"
|
android:layout_height="0dp"
|
||||||
android:id="@+id/sosReportTextView"
|
android:id="@+id/tv_news"
|
||||||
android:layout_weight="1.0"/>
|
android:layout_weight="1.0"/>
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
@@ -1,6 +1,6 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<resources>
|
<resources>
|
||||||
<style name="AppTheme" parent="APPBaseTheme">
|
<style name="MyAppTheme" parent="APPBaseTheme">
|
||||||
<item name="attrColorPrimary">@color/colorPrimary</item>
|
<item name="attrColorPrimary">@color/colorPrimary</item>
|
||||||
<item name="themeGlobalCrashActivity">@style/MyGlobalCrashActivityTheme</item>
|
<item name="themeGlobalCrashActivity">@style/MyGlobalCrashActivityTheme</item>
|
||||||
</style>
|
</style>
|
||||||
|
@@ -3,5 +3,5 @@
|
|||||||
android:minWidth="200dp"
|
android:minWidth="200dp"
|
||||||
android:minHeight="100dp"
|
android:minHeight="100dp"
|
||||||
android:updatePeriodMillis="1000"
|
android:updatePeriodMillis="1000"
|
||||||
android:initialLayout="@layout/widget_sos">
|
android:initialLayout="@layout/widget_news">
|
||||||
</appwidget-provider>
|
</appwidget-provider>
|
||||||
|
@@ -18,18 +18,18 @@ def genVersionName(def versionName){
|
|||||||
}
|
}
|
||||||
|
|
||||||
android {
|
android {
|
||||||
compileSdkVersion 32
|
compileSdkVersion 30
|
||||||
buildToolsVersion "33.0.3"
|
buildToolsVersion "30.0.3"
|
||||||
|
|
||||||
defaultConfig {
|
defaultConfig {
|
||||||
applicationId "cc.winboll.studio.apputils"
|
applicationId "cc.winboll.studio.apputils"
|
||||||
minSdkVersion 21
|
minSdkVersion 26
|
||||||
targetSdkVersion 30
|
targetSdkVersion 29
|
||||||
versionCode 1
|
versionCode 1
|
||||||
// versionName 更新后需要手动设置
|
// versionName 更新后需要手动设置
|
||||||
// 项目模块目录的 build.gradle 文件的 stageCount=0
|
// 项目模块目录的 build.gradle 文件的 stageCount=0
|
||||||
// Gradle编译环境下合起来的 versionName 就是 "${versionName}.0"
|
// Gradle编译环境下合起来的 versionName 就是 "${versionName}.0"
|
||||||
versionName "9.2"
|
versionName "15.0"
|
||||||
if(true) {
|
if(true) {
|
||||||
versionName = genVersionName("${versionName}")
|
versionName = genVersionName("${versionName}")
|
||||||
}
|
}
|
||||||
@@ -41,15 +41,26 @@ android {
|
|||||||
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
|
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
compileOptions {
|
|
||||||
sourceCompatibility JavaVersion.VERSION_17
|
|
||||||
targetCompatibility JavaVersion.VERSION_17
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
api project(':libapputils')
|
api project(':libapputils')
|
||||||
api 'cc.winboll.studio:libappbase:1.0.3'
|
|
||||||
api fileTree(dir: 'libs', include: ['*.jar'])
|
api fileTree(dir: 'libs', include: ['*.jar'])
|
||||||
|
implementation 'cc.winboll.studio:libappbase:15.0.5'
|
||||||
|
|
||||||
|
// 二维码类库
|
||||||
|
implementation 'com.google.zxing:core:3.4.1'
|
||||||
|
implementation 'com.journeyapps:zxing-android-embedded:3.6.0'
|
||||||
|
|
||||||
|
// 网络连接类库
|
||||||
|
//implementation 'com.squareup.okhttp3:okhttp:4.4.1'
|
||||||
|
|
||||||
|
// Html 解析
|
||||||
|
//implementation 'org.jsoup:jsoup:1.13.1'
|
||||||
|
|
||||||
|
// SSH
|
||||||
|
//implementation 'com.jcraft:jsch:0.1.55'
|
||||||
|
|
||||||
|
// 应用介绍页类库
|
||||||
|
//implementation 'io.github.medyo:android-about-page:2.0.0'
|
||||||
}
|
}
|
||||||
|
@@ -1,8 +1,8 @@
|
|||||||
#Created by .winboll/winboll_app_build.gradle
|
#Created by .winboll/winboll_app_build.gradle
|
||||||
#Sat Jan 18 13:03:10 HKT 2025
|
#Tue Mar 18 10:22:27 HKT 2025
|
||||||
stageCount=2
|
stageCount=3
|
||||||
libraryProject=libapputils
|
libraryProject=libapputils
|
||||||
baseVersion=9.2
|
baseVersion=15.0
|
||||||
publishVersion=9.2.1
|
publishVersion=15.0.2
|
||||||
buildCount=0
|
buildCount=0
|
||||||
baseBetaVersion=9.2.2
|
baseBetaVersion=15.0.3
|
||||||
|
@@ -8,7 +8,7 @@
|
|||||||
android:allowBackup="true"
|
android:allowBackup="true"
|
||||||
android:icon="@drawable/ic_winboll"
|
android:icon="@drawable/ic_winboll"
|
||||||
android:label="@string/app_name"
|
android:label="@string/app_name"
|
||||||
android:theme="@style/WinBoll.SupportThemeNoActionBar"
|
android:theme="@style/MyUtilsTheme"
|
||||||
android:supportsRtl="true">
|
android:supportsRtl="true">
|
||||||
|
|
||||||
<activity
|
<activity
|
||||||
@@ -27,10 +27,8 @@
|
|||||||
|
|
||||||
</activity>
|
</activity>
|
||||||
|
|
||||||
<activity android:name=".TestWinBollActivity"/>
|
|
||||||
|
|
||||||
<activity android:name=".TestStringToQrCodeViewActivity"/>
|
<activity android:name=".TestStringToQrCodeViewActivity"/>
|
||||||
|
|
||||||
</application>
|
</application>
|
||||||
|
|
||||||
</manifest>
|
</manifest>
|
||||||
|
@@ -5,27 +5,83 @@ package cc.winboll.studio.apputils;
|
|||||||
* @Date 2024/12/08 15:10:51
|
* @Date 2024/12/08 15:10:51
|
||||||
* @Describe 全局应用类
|
* @Describe 全局应用类
|
||||||
*/
|
*/
|
||||||
import android.view.Gravity;
|
import android.app.Application;
|
||||||
import cc.winboll.studio.libapputils.app.WinBollApplication;
|
import android.content.Context;
|
||||||
import com.hjq.toast.ToastUtils;
|
import android.widget.Toast;
|
||||||
import com.hjq.toast.style.WhiteToastStyle;
|
import cc.winboll.studio.libappbase.GlobalApplication;
|
||||||
|
import cc.winboll.studio.libappbase.LogUtils;
|
||||||
|
import cc.winboll.studio.libapputils.app.MyActivityLifecycleCallbacks;
|
||||||
|
import cc.winboll.studio.libapputils.app.WinBollActivityManager;
|
||||||
|
import cc.winboll.studio.libapputils.bean.DebugBean;
|
||||||
|
|
||||||
public class App extends WinBollApplication {
|
public class App extends GlobalApplication {
|
||||||
|
|
||||||
public static final String TAG = "App";
|
public static final String TAG = "App";
|
||||||
|
|
||||||
public static final String _ACTION_DEBUGVIEW = WinBollApplication.class.getName() + "_ACTION_DEBUGVIEW";
|
public static final String _ACTION_DEBUGVIEW = App.class.getName() + "_ACTION_DEBUGVIEW";
|
||||||
|
|
||||||
|
//static volatile WinBollApplication _WinBollApplication = null;
|
||||||
|
MyActivityLifecycleCallbacks mMyActivityLifecycleCallbacks;
|
||||||
|
|
||||||
|
// 标记当前应用是否处于调试状态
|
||||||
|
static volatile boolean isDebug = false;
|
||||||
|
|
||||||
|
public synchronized static void setIsDebug(boolean isDebug) {
|
||||||
|
App.isDebug = isDebug;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean isDebug() {
|
||||||
|
return isDebug;
|
||||||
|
}
|
||||||
|
|
||||||
|
MyActivityLifecycleCallbacks getMyActivityLifecycleCallbacks() {
|
||||||
|
return mMyActivityLifecycleCallbacks;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Context getApplicationContext() {
|
||||||
|
return super.getApplicationContext();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Application getApplication() {
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onCreate() {
|
public void onCreate() {
|
||||||
super.onCreate();
|
super.onCreate();
|
||||||
// 初始化 Toast 框架
|
// 应用环境初始化, 基本调试环境
|
||||||
//
|
//
|
||||||
ToastUtils.init(this);
|
// 初始化日志模块
|
||||||
// 设置 Toast 布局样式
|
//LogUtils.init(this);
|
||||||
//ToastUtils.setView(R.layout.view_toast);
|
|
||||||
ToastUtils.setStyle(new WhiteToastStyle());
|
|
||||||
ToastUtils.setGravity(Gravity.BOTTOM, 0, 200);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
try {
|
||||||
|
// 初始化 Toast 框架
|
||||||
|
// ToastUtils.init(this);
|
||||||
|
// // 设置 Toast 布局样式
|
||||||
|
// //ToastUtils.setView(R.layout.view_toast);
|
||||||
|
// ToastUtils.setStyle(new WhiteToastStyle());
|
||||||
|
// ToastUtils.setGravity(Gravity.BOTTOM, 0, 200);
|
||||||
|
// 设置应用调试标志
|
||||||
|
DebugBean debugBean = DebugBean.loadBean(this, DebugBean.class);
|
||||||
|
if (debugBean == null) {
|
||||||
|
//ToastUtils.show("debugBean == null");
|
||||||
|
setIsDebug(false);
|
||||||
|
} else {
|
||||||
|
//ToastUtils.show("saveDebugStatus(" + String.valueOf(debugBean.isDebuging()) + ")");
|
||||||
|
setIsDebug(debugBean.isDebuging());
|
||||||
|
}
|
||||||
|
// 应用窗口管理模块参数设置
|
||||||
|
//
|
||||||
|
mMyActivityLifecycleCallbacks = new MyActivityLifecycleCallbacks();
|
||||||
|
registerActivityLifecycleCallbacks(mMyActivityLifecycleCallbacks);
|
||||||
|
// 设置默认 WinBoll 应用 UI 类型
|
||||||
|
WinBollActivityManager.getInstance(this).setWinBollUI_TYPE(WinBollActivityManager.WinBollUI_TYPE.Service);
|
||||||
|
//ToastUtils.show("WinBollUI_TYPE " + getWinBollUI_TYPE());
|
||||||
|
} catch (Exception e) {
|
||||||
|
LogUtils.d(TAG, e, Thread.currentThread().getStackTrace());
|
||||||
|
Toast.makeText(this, e.getMessage(), Toast.LENGTH_SHORT).show();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,28 +1,83 @@
|
|||||||
package cc.winboll.studio.apputils;
|
package cc.winboll.studio.apputils;
|
||||||
|
|
||||||
|
import cc.winboll.studio.apputils.R;
|
||||||
|
import android.app.Activity;
|
||||||
|
import android.content.ComponentName;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
|
import android.content.pm.PackageManager;
|
||||||
|
import android.content.pm.ResolveInfo;
|
||||||
|
import android.net.Uri;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.view.Menu;
|
import android.view.Menu;
|
||||||
import android.view.MenuItem;
|
import android.view.MenuItem;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.widget.Toast;
|
import android.widget.Toast;
|
||||||
import androidx.appcompat.widget.Toolbar;
|
import android.widget.Toolbar;
|
||||||
|
import cc.winboll.studio.libappbase.LogUtils;
|
||||||
|
import cc.winboll.studio.libappbase.LogView;
|
||||||
|
import cc.winboll.studio.libappbase.utils.ToastUtils;
|
||||||
import cc.winboll.studio.libapputils.activities.AssetsHtmlActivity;
|
import cc.winboll.studio.libapputils.activities.AssetsHtmlActivity;
|
||||||
|
import cc.winboll.studio.libapputils.activities.LogActivity;
|
||||||
import cc.winboll.studio.libapputils.activities.QRCodeDecodeActivity;
|
import cc.winboll.studio.libapputils.activities.QRCodeDecodeActivity;
|
||||||
import cc.winboll.studio.libapputils.app.WinBollActivity;
|
import cc.winboll.studio.libapputils.app.AboutActivityFactory;
|
||||||
|
import cc.winboll.studio.libapputils.app.IWinBollActivity;
|
||||||
import cc.winboll.studio.libapputils.app.WinBollActivityManager;
|
import cc.winboll.studio.libapputils.app.WinBollActivityManager;
|
||||||
import cc.winboll.studio.libapputils.log.LogActivity;
|
import cc.winboll.studio.libapputils.bean.APPInfo;
|
||||||
import cc.winboll.studio.libapputils.log.LogUtils;
|
import cc.winboll.studio.libapputils.view.AboutView;
|
||||||
import com.hjq.toast.ToastUtils;
|
import cc.winboll.studio.libapputils.view.YesNoAlertDialog;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
final public class MainActivity extends WinBollActivity {
|
final public class MainActivity extends Activity implements IWinBollActivity {
|
||||||
|
|
||||||
public static final String TAG = "MainActivity";
|
public static final String TAG = "MainActivity";
|
||||||
|
|
||||||
public static final int REQUEST_QRCODEDECODE_ACTIVITY = 0;
|
public static final int REQUEST_QRCODEDECODE_ACTIVITY = 0;
|
||||||
|
|
||||||
|
Toolbar mToolbar;
|
||||||
|
LogView mLogView;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected boolean isEnableDisplayHomeAsUp() {
|
public Activity getActivity() {
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public APPInfo getAppInfo() {
|
||||||
|
String szBranchName = "apputils";
|
||||||
|
|
||||||
|
APPInfo appInfo = AboutActivityFactory.buildDefaultAPPInfo();
|
||||||
|
appInfo.setAppName("APPUtils");
|
||||||
|
appInfo.setAppIcon(cc.winboll.studio.libapputils.R.drawable.ic_winboll);
|
||||||
|
appInfo.setAppDescription("APPUtils Description");
|
||||||
|
appInfo.setAppGitName("APP");
|
||||||
|
appInfo.setAppGitOwner("Studio");
|
||||||
|
appInfo.setAppGitAPPBranch(szBranchName);
|
||||||
|
appInfo.setAppGitAPPSubProjectFolder(szBranchName);
|
||||||
|
appInfo.setAppHomePage("https://www.winboll.cc/studio/details.php?app=APP");
|
||||||
|
appInfo.setAppAPKName("APPUtils");
|
||||||
|
appInfo.setAppAPKFolderName("APPUtils");
|
||||||
|
return appInfo;
|
||||||
|
//return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getTag() {
|
||||||
|
return TAG;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isAddWinBollToolBar() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Toolbar initToolBar() {
|
||||||
|
return findViewById(R.id.activitymainToolbar1);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isEnableDisplayHomeAsUp() {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -31,8 +86,22 @@ final public class MainActivity extends WinBollActivity {
|
|||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
setContentView(R.layout.activity_main);
|
setContentView(R.layout.activity_main);
|
||||||
|
|
||||||
//Toolbar toolbar = findViewById(R.id.activitymainToolbar1);
|
mLogView = findViewById(R.id.logview);
|
||||||
//setActionBar(toolbar);
|
mLogView.start();
|
||||||
|
|
||||||
|
// 初始化工具栏
|
||||||
|
mToolbar = findViewById(R.id.activitymainToolbar1);
|
||||||
|
setActionBar(mToolbar);
|
||||||
|
if (isEnableDisplayHomeAsUp()) {
|
||||||
|
// 显示后退按钮
|
||||||
|
getActionBar().setDisplayHomeAsUpEnabled(true);
|
||||||
|
}
|
||||||
|
getActionBar().setSubtitle(getTag());
|
||||||
|
|
||||||
|
checkResolveActivity();
|
||||||
|
archiveInstance();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// 接收并处理 Intent 数据,函数 Intent 处理接收就直接返回
|
// 接收并处理 Intent 数据,函数 Intent 处理接收就直接返回
|
||||||
//if (prosessIntents(getIntent())) return;
|
//if (prosessIntents(getIntent())) return;
|
||||||
@@ -44,44 +113,94 @@ final public class MainActivity extends WinBollActivity {
|
|||||||
// LogUtils.d(TAG, "BuildConfig.DEBUG : " + Boolean.toString(BuildConfig.DEBUG));
|
// LogUtils.d(TAG, "BuildConfig.DEBUG : " + Boolean.toString(BuildConfig.DEBUG));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
boolean checkResolveActivity() {
|
||||||
|
PackageManager packageManager = getPackageManager();
|
||||||
|
//Intent intent = new Intent("your_action_here");
|
||||||
|
Intent intent = getIntent();
|
||||||
|
if (intent != null) {
|
||||||
|
List<ResolveInfo> resolveInfoList = packageManager.queryIntentActivities(intent, PackageManager.MATCH_DEFAULT_ONLY);
|
||||||
|
if (resolveInfoList.size() > 0) {
|
||||||
|
// 传入的Intent action在Activity清单的intent-filter的action节点里有定义
|
||||||
|
if (intent.getAction() != null) {
|
||||||
|
if (intent.getAction().equals(cc.winboll.studio.libapputils.intent.action.DEBUGVIEW)) {
|
||||||
|
App.setIsDebug(true);
|
||||||
|
//ToastUtils.show!("WinBollApplication.setIsDebug(true) by action : " + intent.getAction());
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
// 传入的Intent action在Activity清单的intent-filter的action节点里没有定义
|
||||||
|
//ToastUtils.show("false : " + intent.getAction());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// action在清单文件中没有声明
|
||||||
|
ToastUtils.show("false");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void archiveInstance() {
|
||||||
|
Intent intent = getIntent();
|
||||||
|
StringBuilder sb = new StringBuilder("\n### Archive Instance ###\n");
|
||||||
|
|
||||||
|
if (intent != null) {
|
||||||
|
ComponentName componentName = intent.getComponent();
|
||||||
|
if (componentName != null) {
|
||||||
|
String packageName = componentName.getPackageName();
|
||||||
|
//Log.d("AppStarter", "启动本应用的应用包名: " + packageName);
|
||||||
|
sb.append("启动本应用的应用包名: \n" + packageName);
|
||||||
|
}
|
||||||
|
|
||||||
|
sb.append("\nImplicit Intent Tracker :\n接收到的 Intent 动作: \n" + intent.getAction());
|
||||||
|
Set<String> categories = intent.getCategories();
|
||||||
|
if (categories != null) {
|
||||||
|
for (String category : categories) {
|
||||||
|
sb.append("\n接收到的 Intent 类别 :\n" + category);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Uri data = intent.getData();
|
||||||
|
if (data != null) {
|
||||||
|
sb.append("\n接收到的 Intent 数据 :\n" + data.toString());
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
sb.append("Intent is null.");
|
||||||
|
}
|
||||||
|
sb.append("\n\n");
|
||||||
|
LogUtils.d(TAG, sb.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onPostCreate(Bundle savedInstanceState) {
|
||||||
|
super.onPostCreate(savedInstanceState);
|
||||||
|
// 缓存当前 activity
|
||||||
|
WinBollActivityManager.getInstance(this).add(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onDestroy() {
|
||||||
|
WinBollActivityManager.getInstance(this).registeRemove(this);
|
||||||
|
super.onDestroy();
|
||||||
|
}
|
||||||
|
|
||||||
public void onTestLogClick(View view) {
|
public void onTestLogClick(View view) {
|
||||||
LogUtils.d(TAG, "onTestLogClick");
|
LogUtils.d(TAG, "onTestLogClick");
|
||||||
Toast.makeText(getApplication(), "onTestLogClick", Toast.LENGTH_SHORT).show();
|
Toast.makeText(getApplication(), "onTestLogClick", Toast.LENGTH_SHORT).show();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void onLogUtilsClick(View view) {
|
public void onLogUtilsClick(View view) {
|
||||||
Intent intent = new Intent(this, LogActivity.class);
|
// Intent intent = new Intent(this, LogActivity.class);
|
||||||
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_DOCUMENT);
|
// intent.addFlags(Intent.FLAG_ACTIVITY_NEW_DOCUMENT);
|
||||||
intent.addFlags(Intent.FLAG_ACTIVITY_MULTIPLE_TASK);
|
// intent.addFlags(Intent.FLAG_ACTIVITY_MULTIPLE_TASK);
|
||||||
startActivity(intent);
|
// startActivity(intent);
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
//WinBollActivityManager.getInstance().printAvtivityListInfo();
|
||||||
protected void onPostCreate(Bundle savedInstanceState) {
|
WinBollActivityManager.getInstance(this).startWinBollActivity(this, LogActivity.class);
|
||||||
super.onPostCreate(savedInstanceState);
|
|
||||||
// setSubTitle("");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onBackPressed() {
|
|
||||||
// exit();
|
|
||||||
}
|
|
||||||
|
|
||||||
// void exit() {
|
|
||||||
// YesNoAlertDialog.OnDialogResultListener listener = new YesNoAlertDialog.OnDialogResultListener(){
|
|
||||||
//
|
|
||||||
// @Override
|
|
||||||
// public void onYes() {
|
|
||||||
// WinBollActivityManager.getInstance(getApplicationContext()).finishAll();
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// @Override
|
|
||||||
// public void onNo() {
|
|
||||||
// }
|
|
||||||
// };
|
|
||||||
// YesNoAlertDialog.show(this, "[ " + getString(R.string.app_name) + " ]", "Exit(Yes/No).\nIs close all activity?", listener);
|
|
||||||
// }
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// 处理传入的 Intent 数据
|
// 处理传入的 Intent 数据
|
||||||
//
|
//
|
||||||
@@ -125,40 +244,88 @@ final public class MainActivity extends WinBollActivity {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getTag() {
|
|
||||||
return TAG;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected boolean isAddWinBollToolBar() {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected Toolbar initToolBar() {
|
|
||||||
return findViewById(R.id.activitymainToolbar1);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean onCreateOptionsMenu(Menu menu) {
|
public boolean onCreateOptionsMenu(Menu menu) {
|
||||||
|
//ToastUtils.show("onCreateOptionsMenu");
|
||||||
getMenuInflater().inflate(R.menu.toolbar_main, menu);
|
getMenuInflater().inflate(R.menu.toolbar_main, menu);
|
||||||
|
if (isAddWinBollToolBar()) {
|
||||||
|
//ToastUtils.show("mIWinBoll.isAddWinBollToolBar()");
|
||||||
|
getMenuInflater().inflate(R.menu.toolbar_winboll_shared_main, menu);
|
||||||
|
}
|
||||||
|
if (App.isDebug()) {
|
||||||
|
getMenuInflater().inflate(R.menu.toolbar_studio_debug, menu);
|
||||||
|
}
|
||||||
|
|
||||||
return super.onCreateOptionsMenu(menu);
|
return super.onCreateOptionsMenu(menu);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean onOptionsItemSelected(MenuItem item) {
|
public boolean onOptionsItemSelected(MenuItem item) {
|
||||||
if (item.getItemId() == R.id.item_testwinboll) {
|
if (item.getItemId() == R.id.item_exit) {
|
||||||
WinBollActivityManager.getInstance(this).startWinBollActivity(this, TestWinBollActivity.class);
|
exit();
|
||||||
|
return true;
|
||||||
|
} else if (item.getItemId() == R.id.item_about) {
|
||||||
|
AboutActivityFactory.showAboutActivity(this, getAppInfo());
|
||||||
|
return true;
|
||||||
} else if (item.getItemId() == R.id.item_teststringtoqrcodeview) {
|
} else if (item.getItemId() == R.id.item_teststringtoqrcodeview) {
|
||||||
WinBollActivityManager.getInstance(this).startWinBollActivity(this, TestStringToQrCodeViewActivity.class);
|
WinBollActivityManager.getInstance(this).startWinBollActivity(this, TestStringToQrCodeViewActivity.class);
|
||||||
} else if (item.getItemId() == R.id.item_testqrcodedecodeactivity) {
|
} else if (item.getItemId() == R.id.item_testqrcodedecodeactivity) {
|
||||||
Intent intent = new Intent(this, QRCodeDecodeActivity.class);
|
Intent intent = new Intent(this, QRCodeDecodeActivity.class);
|
||||||
startActivityForResult(intent, REQUEST_QRCODEDECODE_ACTIVITY);
|
startActivityForResult(intent, REQUEST_QRCODEDECODE_ACTIVITY);
|
||||||
|
} else if (item.getItemId() == R.id.item_testcrashreport) {
|
||||||
|
for (int i = Integer.MIN_VALUE; i < Integer.MAX_VALUE; i++) {
|
||||||
|
getString(i);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
} else if (item.getItemId() == R.id.item_log) {
|
||||||
|
WinBollActivityManager.getInstance(this).startWinBollActivity(this, LogActivity.class);
|
||||||
|
return true;
|
||||||
|
} else if (item.getItemId() == R.id.item_exitdebug) {
|
||||||
|
//AboutView.setApp2NormalMode(this);
|
||||||
|
return true;
|
||||||
|
} else if (item.getItemId() == android.R.id.home) {
|
||||||
|
WinBollActivityManager.getInstance(this).finish(this);
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
return super.onOptionsItemSelected(item);
|
return super.onOptionsItemSelected(item);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void about() {
|
||||||
|
// Intent intent = new Intent(this, AboutActivity.class);
|
||||||
|
// intent.putExtra(AboutActivity.EXTRA_APPINFO, AboutActivityFactory.buildAPPBranchInfo(this));
|
||||||
|
// WinBollActivityManager.getInstance(this).startWinBollActivity(this, intent, AboutActivity.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
void exit() {
|
||||||
|
YesNoAlertDialog.OnDialogResultListener listener = new YesNoAlertDialog.OnDialogResultListener(){
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onYes() {
|
||||||
|
WinBollActivityManager.getInstance(getApplicationContext()).finishAll();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onNo() {
|
||||||
|
}
|
||||||
|
};
|
||||||
|
YesNoAlertDialog.show(this, "[ " + getString(R.string.app_name) + " ]", "Exit(Yes/No).\nIs close all activity?", listener);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onBackPressed() {
|
||||||
|
if (WinBollActivityManager.getInstance(getApplicationContext()).isFirstIWinBollActivity(this)) {
|
||||||
|
exit();
|
||||||
|
} else {
|
||||||
|
WinBollActivityManager.getInstance(this).finish(this);
|
||||||
|
super.onBackPressed();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onTestAboutActivity(View view) {
|
||||||
|
about();
|
||||||
|
}
|
||||||
|
|
||||||
public void onTestJavascriptHtmlActivity(View view) {
|
public void onTestJavascriptHtmlActivity(View view) {
|
||||||
Intent intent = new Intent(this, AssetsHtmlActivity.class);
|
Intent intent = new Intent(this, AssetsHtmlActivity.class);
|
||||||
intent.putExtra(AssetsHtmlActivity.EXTRA_HTMLFILENAME, "javascript_test.html");
|
intent.putExtra(AssetsHtmlActivity.EXTRA_HTMLFILENAME, "javascript_test.html");
|
||||||
@@ -166,17 +333,25 @@ final public class MainActivity extends WinBollActivity {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
|
protected void onResume() {
|
||||||
switch (requestCode) {
|
super.onResume();
|
||||||
case REQUEST_QRCODEDECODE_ACTIVITY : {
|
mLogView.start();
|
||||||
String text = data.getStringExtra(QRCodeDecodeActivity.EXTRA_RESULT);
|
|
||||||
ToastUtils.show(text);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default : {
|
|
||||||
ToastUtils.show(String.format("%d, %d", requestCode, resultCode));
|
|
||||||
super.onActivityResult(requestCode, resultCode, data);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*@Override
|
||||||
|
protected void onActivithyResult(int requestCode, int resultCode, Intent data) {
|
||||||
|
switch (requestCode) {
|
||||||
|
case REQUEST_QRCODEDECODE_ACTIVITY : {
|
||||||
|
if (data != null) {
|
||||||
|
String text = data.getStringExtra(QRCodeDecodeActivity.EXTRA_RESULT);
|
||||||
|
ToastUtils.show(text);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default : {
|
||||||
|
//ToastUtils.show(String.format("%d, %d", requestCode, resultCode));
|
||||||
|
super.prosessActivityResult(requestCode, resultCode, data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}*/
|
||||||
}
|
}
|
||||||
|
@@ -1,37 +1,50 @@
|
|||||||
package cc.winboll.studio.apputils;
|
package cc.winboll.studio.apputils;
|
||||||
|
|
||||||
import android.os.Bundle;
|
|
||||||
import androidx.appcompat.widget.Toolbar;
|
|
||||||
import cc.winboll.studio.libapputils.app.WinBollActivity;
|
|
||||||
import cc.winboll.studio.libapputils.view.StringToQrCodeView;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @Author ZhanGSKen@QQ.COM
|
* @Author ZhanGSKen@QQ.COM
|
||||||
* @Date 2025/01/17 19:50:46
|
* @Date 2025/01/17 19:50:46
|
||||||
*/
|
*/
|
||||||
public class TestStringToQrCodeViewActivity extends WinBollActivity {
|
import cc.winboll.studio.apputils.R;
|
||||||
|
import android.app.Activity;
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.widget.Toolbar;
|
||||||
|
import cc.winboll.studio.libapputils.app.IWinBollActivity;
|
||||||
|
import cc.winboll.studio.libapputils.bean.APPInfo;
|
||||||
|
import cc.winboll.studio.libapputils.view.StringToQrCodeView;
|
||||||
|
|
||||||
|
public class TestStringToQrCodeViewActivity extends Activity implements IWinBollActivity {
|
||||||
|
|
||||||
public static final String TAG = "TestStringToQrCodeViewActivity";
|
public static final String TAG = "TestStringToQrCodeViewActivity";
|
||||||
|
|
||||||
StringToQrCodeView mStringToQrCodeView;
|
StringToQrCodeView mStringToQrCodeView;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Activity getActivity() {
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public APPInfo getAppInfo() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getTag() {
|
public String getTag() {
|
||||||
return TAG;
|
return TAG;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Toolbar initToolBar() {
|
public Toolbar initToolBar() {
|
||||||
return findViewById(R.id.activityteststringtoqrcodeviewToolbar1);
|
return findViewById(R.id.activityteststringtoqrcodeviewToolbar1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected boolean isEnableDisplayHomeAsUp() {
|
public boolean isEnableDisplayHomeAsUp() {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected boolean isAddWinBollToolBar() {
|
public boolean isAddWinBollToolBar() {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -41,10 +54,4 @@ public class TestStringToQrCodeViewActivity extends WinBollActivity {
|
|||||||
setContentView(R.layout.activity_teststringtoqrcodeview);
|
setContentView(R.layout.activity_teststringtoqrcodeview);
|
||||||
mStringToQrCodeView = findViewById(R.id.activityteststringtoqrcodeviewStringToQrCodeView1);
|
mStringToQrCodeView = findViewById(R.id.activityteststringtoqrcodeviewStringToQrCodeView1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onPostCreate(Bundle savedInstanceState) {
|
|
||||||
super.onPostCreate(savedInstanceState);
|
|
||||||
setSubTitle(TAG);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@@ -1,52 +0,0 @@
|
|||||||
package cc.winboll.studio.apputils;
|
|
||||||
|
|
||||||
import android.content.Intent;
|
|
||||||
import android.os.Bundle;
|
|
||||||
import android.view.View;
|
|
||||||
import androidx.appcompat.widget.Toolbar;
|
|
||||||
import cc.winboll.studio.libapputils.activities.AssetsHtmlActivity;
|
|
||||||
import cc.winboll.studio.libapputils.app.WinBollActivity;
|
|
||||||
import cc.winboll.studio.libapputils.app.WinBollActivityManager;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @Author ZhanGSKen@QQ.COM
|
|
||||||
* @Date 2025/01/13 15:09:46
|
|
||||||
*/
|
|
||||||
public class TestWinBollActivity extends WinBollActivity {
|
|
||||||
|
|
||||||
public static final String TAG = "TestWinBollActivity";
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getTag() {
|
|
||||||
return TAG;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected Toolbar initToolBar() {
|
|
||||||
return findViewById(R.id.activitytestwinbollToolbar1);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected boolean isEnableDisplayHomeAsUp() {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected boolean isAddWinBollToolBar() {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onCreate(Bundle savedInstanceState) {
|
|
||||||
super.onCreate(savedInstanceState);
|
|
||||||
setContentView(R.layout.activity_testwinboll);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onPostCreate(Bundle savedInstanceState) {
|
|
||||||
super.onPostCreate(savedInstanceState);
|
|
||||||
setSubTitle(TAG);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
@@ -5,7 +5,7 @@
|
|||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent">
|
android:layout_height="match_parent">
|
||||||
|
|
||||||
<androidx.appcompat.widget.Toolbar
|
<android.widget.Toolbar
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:id="@+id/activitymainToolbar1"/>
|
android:id="@+id/activitymainToolbar1"/>
|
||||||
@@ -27,7 +27,7 @@
|
|||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:text="TestLog"
|
android:text="TestLog"
|
||||||
android:textAllCaps="false"
|
android:textAllCaps="false"
|
||||||
android:onClick="onTestLogClick"/>
|
android:onClick="onTestLogClick"/>
|
||||||
|
|
||||||
<Button
|
<Button
|
||||||
@@ -39,20 +39,27 @@
|
|||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:orientation="horizontal"
|
android:orientation="horizontal"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:gravity="right">
|
android:gravity="right">
|
||||||
|
|
||||||
<Button
|
<Button
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:textAllCaps="false"
|
android:textAllCaps="false"
|
||||||
android:text="Test Javascript Html Activity"
|
android:text="Test Javascript Html Activity"
|
||||||
android:onClick="onTestJavascriptHtmlActivity"/>
|
android:onClick="onTestJavascriptHtmlActivity"/>
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
|
<cc.winboll.studio.libappbase.LogView
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="0dp"
|
||||||
|
android:text="Button"
|
||||||
|
android:id="@+id/logview"
|
||||||
|
android:layout_weight="1.0"/>
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
|
@@ -6,7 +6,7 @@
|
|||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent">
|
android:layout_height="match_parent">
|
||||||
|
|
||||||
<androidx.appcompat.widget.Toolbar
|
<android.widget.Toolbar
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:id="@+id/activityteststringtoqrcodeviewToolbar1"/>
|
android:id="@+id/activityteststringtoqrcodeviewToolbar1"/>
|
||||||
|
@@ -7,7 +7,7 @@
|
|||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:background="#FF36B5B3">
|
android:background="#FF36B5B3">
|
||||||
|
|
||||||
<androidx.appcompat.widget.Toolbar
|
<android.widget.Toolbar
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:id="@+id/activitytestwinbollToolbar1"/>
|
android:id="@+id/activitytestwinbollToolbar1"/>
|
||||||
|
@@ -1,32 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<LinearLayout
|
|
||||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:background="@drawable/shape_gradient"
|
|
||||||
android:gravity="center"
|
|
||||||
android:orientation="vertical"
|
|
||||||
android:padding="10dp">
|
|
||||||
|
|
||||||
<LinearLayout
|
|
||||||
android:orientation="horizontal"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content">
|
|
||||||
|
|
||||||
<ImageView
|
|
||||||
android:layout_width="40dp"
|
|
||||||
android:layout_height="40dp"
|
|
||||||
android:src="@drawable/ic_launcher"/>
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@android:id/message"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_margin="10dp"
|
|
||||||
android:textColor="#FF000000"
|
|
||||||
android:textSize="16sp"/>
|
|
||||||
|
|
||||||
</LinearLayout>
|
|
||||||
|
|
||||||
</LinearLayout>
|
|
@@ -3,14 +3,14 @@
|
|||||||
xmlns:app="http://schemas.android.com/apk/res-auto">
|
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||||
<item
|
<item
|
||||||
android:id="@+id/item_testwinboll"
|
android:id="@+id/item_testwinboll"
|
||||||
android:title="TestWinBollActivity"
|
android:title="TestWinBollActivity"/>
|
||||||
app:showAsAction="ifRoom"/>
|
|
||||||
<item
|
<item
|
||||||
android:id="@+id/item_teststringtoqrcodeview"
|
android:id="@+id/item_teststringtoqrcodeview"
|
||||||
android:title="TestStringToQrCodeViewActivity"
|
android:title="TestStringToQrCodeViewActivity"/>
|
||||||
app:showAsAction="ifRoom"/>
|
|
||||||
<item
|
<item
|
||||||
android:id="@+id/item_testqrcodedecodeactivity"
|
android:id="@+id/item_testqrcodedecodeactivity"
|
||||||
android:title="TestQRCodeDecodeActivity"
|
android:title="TestQRCodeDecodeActivity"/>
|
||||||
app:showAsAction="ifRoom"/>
|
<item
|
||||||
|
android:id="@+id/item_testcrashreport"
|
||||||
|
android:title="TestCrashReportActivity"/>
|
||||||
</menu>
|
</menu>
|
||||||
|
@@ -4,7 +4,4 @@
|
|||||||
<color name="colorPrimary">#FF196ABC</color>
|
<color name="colorPrimary">#FF196ABC</color>
|
||||||
<color name="colorPrimaryDark">#FF002B57</color>
|
<color name="colorPrimaryDark">#FF002B57</color>
|
||||||
<color name="colorAccent">#FF80BFFF</color>
|
<color name="colorAccent">#FF80BFFF</color>
|
||||||
<color name="colorToastFrame">#FFA9A9A9</color>
|
|
||||||
<color name="colorToastShadow">#FF000000</color>
|
|
||||||
<color name="colorToastBackgroung">#FFFFFFFF</color>
|
|
||||||
</resources>
|
</resources>
|
||||||
|
@@ -1,3 +1,14 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<resources>
|
<resources>
|
||||||
|
<style name="MyUtilsTheme" parent="APPBaseTheme">
|
||||||
|
<item name="attrColorPrimary">@color/colorPrimary</item>
|
||||||
|
<item name="themeGlobalCrashActivity">@style/MyUtilsGlobalCrashActivityTheme</item>
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<style name="MyUtilsGlobalCrashActivityTheme" parent="GlobalCrashActivityTheme">
|
||||||
|
<item name="colorTittle">#FFFFFFFF</item>
|
||||||
|
<item name="colorTittleBackgound">#FF00A4B3</item>
|
||||||
|
<item name="colorText">#FFFFFFFF</item>
|
||||||
|
<item name="colorTextBackgound">#FF000000</item>
|
||||||
|
</style>
|
||||||
</resources>
|
</resources>
|
||||||
|
13
build.gradle
@@ -9,13 +9,14 @@ buildscript {
|
|||||||
maven { url "https://jitpack.io" }
|
maven { url "https://jitpack.io" }
|
||||||
mavenCentral()
|
mavenCentral()
|
||||||
google()
|
google()
|
||||||
mavenLocal()
|
|
||||||
// Nexus Maven 库地址
|
// Nexus Maven 库地址
|
||||||
// "WinBoll Release"
|
// "WinBoll Release"
|
||||||
maven { url "https://nexus.winboll.cc/repository/maven-public/" }
|
maven { url "https://nexus.winboll.cc/repository/maven-public/" }
|
||||||
// "WinBoll Snapshot"
|
// "WinBoll Snapshot"
|
||||||
maven { url "https://nexus.winboll.cc/repository/maven-snapshots/" }
|
maven { url "https://nexus.winboll.cc/repository/maven-snapshots/" }
|
||||||
|
|
||||||
|
mavenLocal()
|
||||||
}
|
}
|
||||||
dependencies {
|
dependencies {
|
||||||
classpath 'com.android.tools.build:gradle:7.2.1'
|
classpath 'com.android.tools.build:gradle:7.2.1'
|
||||||
@@ -26,13 +27,6 @@ buildscript {
|
|||||||
|
|
||||||
allprojects {
|
allprojects {
|
||||||
repositories {
|
repositories {
|
||||||
maven {
|
|
||||||
url "https://mirrors.tencent.com/repository/maven/tencent_public/"
|
|
||||||
}
|
|
||||||
maven {
|
|
||||||
url "https://mirrors.tencent.com/repository/maven/tencent_public_snapshots"
|
|
||||||
}
|
|
||||||
|
|
||||||
maven { url 'https://maven.aliyun.com/repository/public/' }
|
maven { url 'https://maven.aliyun.com/repository/public/' }
|
||||||
maven { url 'https://maven.aliyun.com/repository/google/' }
|
maven { url 'https://maven.aliyun.com/repository/google/' }
|
||||||
maven { url 'https://maven.aliyun.com/repository/gradle-plugin/' }
|
maven { url 'https://maven.aliyun.com/repository/gradle-plugin/' }
|
||||||
@@ -41,13 +35,14 @@ allprojects {
|
|||||||
maven { url "https://jitpack.io" }
|
maven { url "https://jitpack.io" }
|
||||||
mavenCentral()
|
mavenCentral()
|
||||||
google()
|
google()
|
||||||
mavenLocal()
|
|
||||||
// Nexus Maven 库地址
|
// Nexus Maven 库地址
|
||||||
// "WinBoll Release"
|
// "WinBoll Release"
|
||||||
maven { url "https://nexus.winboll.cc/repository/maven-public/" }
|
maven { url "https://nexus.winboll.cc/repository/maven-public/" }
|
||||||
// "WinBoll Snapshot"
|
// "WinBoll Snapshot"
|
||||||
maven { url "https://nexus.winboll.cc/repository/maven-snapshots/" }
|
maven { url "https://nexus.winboll.cc/repository/maven-snapshots/" }
|
||||||
|
|
||||||
|
mavenLocal()
|
||||||
}
|
}
|
||||||
ext {
|
ext {
|
||||||
// 定义全局变量,常用于版本管理
|
// 定义全局变量,常用于版本管理
|
||||||
|
19
gradle.properties-android-demo
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
# 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
|
||||||
|
# When configured, Gradle will run in incubating parallel mode.
|
||||||
|
# This option should only be used with decoupled projects. More details, visit
|
||||||
|
# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec: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=false
|
||||||
|
# Automatically convert third-party libraries to use AndroidX
|
||||||
|
android.enableJetifier=false
|
@@ -6,7 +6,7 @@
|
|||||||
# http://www.gradle.org/docs/current/userguide/build_environment.html
|
# http://www.gradle.org/docs/current/userguide/build_environment.html
|
||||||
# Specifies the JVM arguments used for the daemon process.
|
# Specifies the JVM arguments used for the daemon process.
|
||||||
# The setting is particularly useful for tweaking memory settings.
|
# The setting is particularly useful for tweaking memory settings.
|
||||||
org.gradle.jvmargs=-Xmx4096m
|
org.gradle.jvmargs=-Xmx2048m
|
||||||
# When configured, Gradle will run in incubating parallel mode.
|
# When configured, Gradle will run in incubating parallel mode.
|
||||||
# This option should only be used with decoupled projects. More details, visit
|
# This option should only be used with decoupled projects. More details, visit
|
||||||
# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
|
# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
|
||||||
@@ -17,10 +17,3 @@ org.gradle.jvmargs=-Xmx4096m
|
|||||||
android.useAndroidX=true
|
android.useAndroidX=true
|
||||||
# Automatically convert third-party libraries to use AndroidX
|
# Automatically convert third-party libraries to use AndroidX
|
||||||
android.enableJetifier=true
|
android.enableJetifier=true
|
||||||
|
|
||||||
org.gradle.caching=true
|
|
||||||
|
|
||||||
android.disableAutomaticComponentCreation=true
|
|
||||||
|
|
||||||
android.injected.testOnly=false
|
|
||||||
|
|
@@ -20,13 +20,5 @@ android {
|
|||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
api 'com.github.getActivity:ToastUtils:10.5'
|
|
||||||
|
|
||||||
api 'androidx.appcompat:appcompat:1.3.1'
|
|
||||||
api 'androidx.vectordrawable:vectordrawable:1.1.0'
|
|
||||||
api 'androidx.vectordrawable:vectordrawable-animated:1.1.0'
|
|
||||||
api 'androidx.fragment:fragment:1.1.0'
|
|
||||||
api 'com.google.android.material:material:1.1.0'
|
|
||||||
|
|
||||||
api fileTree(dir: 'libs', include: ['*.jar'])
|
api fileTree(dir: 'libs', include: ['*.jar'])
|
||||||
}
|
}
|
||||||
|
@@ -1,8 +1,8 @@
|
|||||||
#Created by .winboll/winboll_app_build.gradle
|
#Created by .winboll/winboll_app_build.gradle
|
||||||
#Tue Feb 25 16:51:09 HKT 2025
|
#Sat Mar 15 15:29:07 HKT 2025
|
||||||
stageCount=3
|
stageCount=3
|
||||||
libraryProject=libappbase
|
libraryProject=libappbase
|
||||||
baseVersion=2.0
|
baseVersion=15.0
|
||||||
publishVersion=2.0.2
|
publishVersion=15.0.2
|
||||||
buildCount=0
|
buildCount=0
|
||||||
baseBetaVersion=2.0.3
|
baseBetaVersion=15.0.3
|
||||||
|
@@ -73,6 +73,18 @@
|
|||||||
|
|
||||||
</receiver>
|
</receiver>
|
||||||
|
|
||||||
|
<service android:name="cc.winboll.studio.libappbase.sos.SOSCenter"/>
|
||||||
|
|
||||||
|
<receiver android:name="cc.winboll.studio.libappbase.sos.SOSCenterServiceReceiver">
|
||||||
|
|
||||||
|
<intent-filter>
|
||||||
|
|
||||||
|
<action android:name="cc.winboll.studio.libappbase.sos.SOSCenterServiceReceiver"/>
|
||||||
|
|
||||||
|
</intent-filter>
|
||||||
|
|
||||||
|
</receiver>
|
||||||
|
|
||||||
</application>
|
</application>
|
||||||
|
|
||||||
</manifest>
|
</manifest>
|
@@ -6,17 +6,13 @@ package cc.winboll.studio.libappbase;
|
|||||||
* @Describe 全局应用类
|
* @Describe 全局应用类
|
||||||
*/
|
*/
|
||||||
import android.app.Application;
|
import android.app.Application;
|
||||||
import android.content.ComponentName;
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
|
||||||
import android.content.SharedPreferences;
|
import android.content.SharedPreferences;
|
||||||
import android.content.pm.ApplicationInfo;
|
import android.content.pm.ApplicationInfo;
|
||||||
import android.content.pm.PackageManager;
|
import android.content.pm.PackageManager;
|
||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
import android.os.Looper;
|
import android.os.Looper;
|
||||||
import android.view.Gravity;
|
import cc.winboll.studio.libappbase.utils.ToastUtils;
|
||||||
import com.hjq.toast.ToastUtils;
|
|
||||||
import com.hjq.toast.style.WhiteToastStyle;
|
|
||||||
|
|
||||||
public class GlobalApplication extends Application {
|
public class GlobalApplication extends Application {
|
||||||
|
|
||||||
@@ -78,8 +74,8 @@ public class GlobalApplication extends Application {
|
|||||||
ToastUtils.init(this);
|
ToastUtils.init(this);
|
||||||
// 设置 Toast 布局样式
|
// 设置 Toast 布局样式
|
||||||
//ToastUtils.setView(R.layout.toast_custom_view);
|
//ToastUtils.setView(R.layout.toast_custom_view);
|
||||||
ToastUtils.setStyle(new WhiteToastStyle());
|
//ToastUtils.setStyle(new WhiteToastStyle());
|
||||||
ToastUtils.setGravity(Gravity.BOTTOM, 0, 200);
|
//ToastUtils.setGravity(Gravity.BOTTOM, 0, 200);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String getAppName(Context context) {
|
public static String getAppName(Context context) {
|
||||||
|
@@ -21,11 +21,9 @@ import android.view.MenuItem;
|
|||||||
import android.widget.LinearLayout;
|
import android.widget.LinearLayout;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
import android.widget.Toast;
|
import android.widget.Toast;
|
||||||
import androidx.appcompat.widget.Toolbar;
|
|
||||||
import cc.winboll.studio.libappbase.R;
|
import cc.winboll.studio.libappbase.R;
|
||||||
import androidx.appcompat.app.AppCompatActivity;
|
|
||||||
|
|
||||||
public final class GlobalCrashActivity extends AppCompatActivity implements MenuItem.OnMenuItemClickListener {
|
public final class GlobalCrashActivity extends Activity implements MenuItem.OnMenuItemClickListener {
|
||||||
|
|
||||||
private static final int MENUITEM_COPY = 0;
|
private static final int MENUITEM_COPY = 0;
|
||||||
private static final int MENUITEM_RESTART = 1;
|
private static final int MENUITEM_RESTART = 1;
|
||||||
@@ -47,10 +45,10 @@ public final class GlobalCrashActivity extends AppCompatActivity implements Menu
|
|||||||
setContentView(R.layout.activity_globalcrash);
|
setContentView(R.layout.activity_globalcrash);
|
||||||
mGlobalCrashReportView = findViewById(R.id.activityglobalcrashGlobalCrashReportView1);
|
mGlobalCrashReportView = findViewById(R.id.activityglobalcrashGlobalCrashReportView1);
|
||||||
mGlobalCrashReportView.setReport(mLog);
|
mGlobalCrashReportView.setReport(mLog);
|
||||||
setSupportActionBar(mGlobalCrashReportView.getToolbar());
|
setActionBar(mGlobalCrashReportView.getToolbar());
|
||||||
|
|
||||||
getSupportActionBar().setTitle(CrashHandler.TITTLE);
|
getActionBar().setTitle(CrashHandler.TITTLE);
|
||||||
getSupportActionBar().setSubtitle(GlobalApplication.getAppName(getApplicationContext()));
|
getActionBar().setSubtitle(GlobalApplication.getAppName(getApplicationContext()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@@ -15,8 +15,8 @@ import android.view.Menu;
|
|||||||
import android.view.MenuItem;
|
import android.view.MenuItem;
|
||||||
import android.widget.LinearLayout;
|
import android.widget.LinearLayout;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
import androidx.appcompat.widget.Toolbar;
|
|
||||||
import cc.winboll.studio.libappbase.R;
|
import cc.winboll.studio.libappbase.R;
|
||||||
|
import android.widget.Toolbar;
|
||||||
|
|
||||||
public class GlobalCrashReportView extends LinearLayout {
|
public class GlobalCrashReportView extends LinearLayout {
|
||||||
|
|
||||||
|
@@ -1,24 +0,0 @@
|
|||||||
package cc.winboll.studio.libappbase;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @Author ZhanGSKen@QQ.COM
|
|
||||||
* @Date 2025/02/04 10:20:16
|
|
||||||
* @Describe WinBoll Activity 接口
|
|
||||||
*/
|
|
||||||
import androidx.appcompat.app.AppCompatActivity;
|
|
||||||
import androidx.appcompat.widget.Toolbar;
|
|
||||||
import cc.winboll.studio.libappbase.bean.APPInfo;
|
|
||||||
|
|
||||||
public interface IWinBollActivity {
|
|
||||||
|
|
||||||
public static final String TAG = "IWinBollActivity";
|
|
||||||
|
|
||||||
// 获取当前具有 IWinBoll 特征的 AppCompatActivity 活动窗口
|
|
||||||
AppCompatActivity getActivity();
|
|
||||||
|
|
||||||
abstract public APPInfo getAppInfo();
|
|
||||||
abstract public String getTag();
|
|
||||||
abstract Toolbar initToolBar();
|
|
||||||
abstract boolean isEnableDisplayHomeAsUp();
|
|
||||||
abstract boolean isAddWinBollToolBar();
|
|
||||||
}
|
|
@@ -38,7 +38,7 @@ public class LogUtils {
|
|||||||
static volatile boolean _IsInited = false;
|
static volatile boolean _IsInited = false;
|
||||||
static Context _mContext;
|
static Context _mContext;
|
||||||
// 日志显示时间格式
|
// 日志显示时间格式
|
||||||
static SimpleDateFormat mSimpleDateFormat = new SimpleDateFormat("[yyyyMMdd_HHmmSS]", Locale.getDefault());
|
static SimpleDateFormat mSimpleDateFormat = new SimpleDateFormat("[yyyyMMdd_HHmmss_SSS]", Locale.getDefault());
|
||||||
// 应用日志文件夹
|
// 应用日志文件夹
|
||||||
static File _mfLogCacheDir;
|
static File _mfLogCacheDir;
|
||||||
static File _mfLogDataDir;
|
static File _mfLogDataDir;
|
||||||
|
@@ -16,16 +16,15 @@ import android.view.View;
|
|||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
import android.widget.AdapterView;
|
import android.widget.AdapterView;
|
||||||
import android.widget.ArrayAdapter;
|
import android.widget.ArrayAdapter;
|
||||||
|
import android.widget.BaseAdapter;
|
||||||
import android.widget.CheckBox;
|
import android.widget.CheckBox;
|
||||||
import android.widget.RelativeLayout;
|
import android.widget.RelativeLayout;
|
||||||
import android.widget.ScrollView;
|
import android.widget.ScrollView;
|
||||||
import android.widget.Spinner;
|
import android.widget.Spinner;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
import androidx.annotation.NonNull;
|
|
||||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
|
||||||
import androidx.recyclerview.widget.RecyclerView;
|
|
||||||
import cc.winboll.studio.libappbase.LogUtils;
|
import cc.winboll.studio.libappbase.LogUtils;
|
||||||
import cc.winboll.studio.libappbase.R;
|
import cc.winboll.studio.libappbase.R;
|
||||||
|
import cc.winboll.studio.libappbase.views.HorizontalListView;
|
||||||
import java.text.Collator;
|
import java.text.Collator;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
@@ -51,7 +50,7 @@ public class LogView extends RelativeLayout {
|
|||||||
Spinner mLogLevelSpinner;
|
Spinner mLogLevelSpinner;
|
||||||
ArrayAdapter<CharSequence> mLogLevelSpinnerAdapter;
|
ArrayAdapter<CharSequence> mLogLevelSpinnerAdapter;
|
||||||
// 标签列表
|
// 标签列表
|
||||||
RecyclerView recyclerView;
|
HorizontalListView mListViewTags;
|
||||||
|
|
||||||
public LogView(Context context) {
|
public LogView(Context context) {
|
||||||
super(context);
|
super(context);
|
||||||
@@ -190,11 +189,9 @@ public class LogView extends RelativeLayout {
|
|||||||
cbALLTAG.setChecked(isAllSelect);
|
cbALLTAG.setChecked(isAllSelect);
|
||||||
|
|
||||||
// 加载标签表
|
// 加载标签表
|
||||||
recyclerView = findViewById(cc.winboll.studio.libappbase.R.id.viewlogRecyclerView1);
|
mListViewTags = findViewById(cc.winboll.studio.libappbase.R.id.tags_listview);
|
||||||
LinearLayoutManager layoutManager = new LinearLayoutManager(mContext, LinearLayoutManager.HORIZONTAL, false);
|
mTAGListAdapter = new TAGListAdapter(mContext, mapTAGList);
|
||||||
recyclerView.setLayoutManager(layoutManager);
|
mListViewTags.setAdapter(mTAGListAdapter);
|
||||||
mTAGListAdapter = new TAGListAdapter(mapTAGList);
|
|
||||||
recyclerView.setAdapter(mTAGListAdapter);
|
|
||||||
|
|
||||||
// 可以添加点击监听器来处理勾选框状态变化后的逻辑,比如获取当前勾选情况等
|
// 可以添加点击监听器来处理勾选框状态变化后的逻辑,比如获取当前勾选情况等
|
||||||
mTAGListAdapter.notifyDataSetChanged();
|
mTAGListAdapter.notifyDataSetChanged();
|
||||||
@@ -305,15 +302,32 @@ public class LogView extends RelativeLayout {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public class TAGListAdapter extends RecyclerView.Adapter<TAGListAdapter.ViewHolder> {
|
public class TAGListAdapter extends BaseAdapter {
|
||||||
|
|
||||||
|
private Context context;
|
||||||
private Map<String, Boolean> mapOrigin;
|
private Map<String, Boolean> mapOrigin;
|
||||||
private List<TAGItemModel> itemList;
|
private List<TAGItemModel> itemList;
|
||||||
|
|
||||||
public TAGListAdapter(Map<String, Boolean> map) {
|
public TAGListAdapter(Context context, Map<String, Boolean> map) {
|
||||||
|
this.context = context;
|
||||||
mapOrigin = map;
|
mapOrigin = map;
|
||||||
loadMap(mapOrigin);
|
loadMap(mapOrigin);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getCount() {
|
||||||
|
return itemList.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object getItem(int p) {
|
||||||
|
return itemList.get(p);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long getItemId(int p) {
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
void loadMap(Map<String, Boolean> map) {
|
void loadMap(Map<String, Boolean> map) {
|
||||||
itemList = new ArrayList<TAGItemModel>();
|
itemList = new ArrayList<TAGItemModel>();
|
||||||
@@ -329,16 +343,20 @@ public class LogView extends RelativeLayout {
|
|||||||
loadMap(mapOrigin);
|
loadMap(mapOrigin);
|
||||||
super.notifyDataSetChanged();
|
super.notifyDataSetChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
@NonNull
|
|
||||||
@Override
|
@Override
|
||||||
public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
|
public View getView(int position, View convertView, ViewGroup parent) {
|
||||||
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.view_logtag, parent, false);
|
ViewHolder holder;
|
||||||
return new ViewHolder(view);
|
if (convertView == null) {
|
||||||
}
|
convertView = LayoutInflater.from(context).inflate(R.layout.item_logtag, parent, false);
|
||||||
|
holder = new ViewHolder();
|
||||||
|
holder.tvText = convertView.findViewById(R.id.viewlogtagTextView1);
|
||||||
|
holder.cbChecked = convertView.findViewById(R.id.viewlogtagCheckBox1);
|
||||||
|
convertView.setTag(holder);
|
||||||
|
} else {
|
||||||
|
holder = (ViewHolder) convertView.getTag();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
|
|
||||||
final TAGItemModel item = itemList.get(position);
|
final TAGItemModel item = itemList.get(position);
|
||||||
holder.tvText.setText(item.getTag());
|
holder.tvText.setText(item.getTag());
|
||||||
holder.cbChecked.setChecked(item.isChecked());
|
holder.cbChecked.setChecked(item.isChecked());
|
||||||
@@ -349,22 +367,13 @@ public class LogView extends RelativeLayout {
|
|||||||
LogUtils.setTAGListEnable(item.getTag(), ((CheckBox)v).isChecked());
|
LogUtils.setTAGListEnable(item.getTag(), ((CheckBox)v).isChecked());
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
return convertView;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
public class ViewHolder {
|
||||||
public int getItemCount() {
|
|
||||||
return itemList.size();
|
|
||||||
}
|
|
||||||
|
|
||||||
public class ViewHolder extends RecyclerView.ViewHolder {
|
|
||||||
TextView tvText;
|
TextView tvText;
|
||||||
CheckBox cbChecked;
|
CheckBox cbChecked;
|
||||||
|
|
||||||
public ViewHolder(@NonNull View itemView) {
|
|
||||||
super(itemView);
|
|
||||||
tvText = itemView.findViewById(R.id.viewlogtagTextView1);
|
|
||||||
cbChecked = itemView.findViewById(R.id.viewlogtagCheckBox1);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -1,57 +0,0 @@
|
|||||||
package cc.winboll.studio.libappbase;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @Author ZhanGSKen@AliYun.Com
|
|
||||||
* @Date 2025/02/13 21:09:36
|
|
||||||
* @Describe SOS 组件
|
|
||||||
*/
|
|
||||||
import android.content.ComponentName;
|
|
||||||
import android.content.Context;
|
|
||||||
import android.content.Intent;
|
|
||||||
import android.content.ServiceConnection;
|
|
||||||
import android.os.IBinder;
|
|
||||||
import cc.winboll.studio.libappbase.bean.APPSOSBean;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
|
|
||||||
public class SOS {
|
|
||||||
|
|
||||||
public static final String TAG = "SOS";
|
|
||||||
|
|
||||||
public static final String ACTION_SOS = SOS.class.getName() + ".ACTION_SOS";
|
|
||||||
public static final String ACTION_BIND = SOS.class.getName() + ".ACTION_BIND";
|
|
||||||
public static final String ACTION_SERVICE_ENABLE = SOS.class.getName() + ".ACTION_SERVICE_ENABLE";
|
|
||||||
public static final String ACTION_SERVICE_DISABLE = SOS.class.getName() + ".ACTION_SERVICE_DISENABLE";
|
|
||||||
|
|
||||||
public static void sosWinBollService(Context context, APPSOSBean bean) {
|
|
||||||
Intent intent = new Intent(ACTION_SOS);
|
|
||||||
intent.putExtra("SOS", "Service");
|
|
||||||
intent.putExtra("APPSOSBean", bean.toString());
|
|
||||||
String szToPackage = "";
|
|
||||||
if (GlobalApplication.isDebuging()) {
|
|
||||||
szToPackage = "cc.winboll.studio.appbase.beta";
|
|
||||||
} else {
|
|
||||||
szToPackage = "cc.winboll.studio.appbase";
|
|
||||||
}
|
|
||||||
intent.setPackage(szToPackage);
|
|
||||||
context.sendBroadcast(intent);
|
|
||||||
|
|
||||||
LogUtils.d(TAG, String.format("Send ACTION_SOS To WinBoll. (szToPackage : %s)", szToPackage));
|
|
||||||
//ToastUtils.show("SOS Send To WinBoll");
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void bindToAPPService(Context context, APPSOSBean bean) {
|
|
||||||
Intent intent = new Intent(ACTION_BIND);
|
|
||||||
intent.putExtra("SOS", "Service");
|
|
||||||
intent.putExtra("APPSOSBean", bean.toString());
|
|
||||||
String szToPackage = "";
|
|
||||||
if (GlobalApplication.isDebuging()) {
|
|
||||||
szToPackage = "cc.winboll.studio.appbase.beta";
|
|
||||||
} else {
|
|
||||||
szToPackage = "cc.winboll.studio.appbase";
|
|
||||||
}
|
|
||||||
intent.setPackage(szToPackage);
|
|
||||||
context.sendBroadcast(intent);
|
|
||||||
LogUtils.d(TAG, String.format("Send ACTION_BIND To WinBoll. (szToPackage : %s)", szToPackage));
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@@ -1,32 +0,0 @@
|
|||||||
package cc.winboll.studio.libappbase;
|
|
||||||
|
|
||||||
import android.content.BroadcastReceiver;
|
|
||||||
import android.content.Context;
|
|
||||||
import android.content.Intent;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @Author ZhanGSKen@AliYun.Com
|
|
||||||
* @Date 2025/02/12 23:44:57
|
|
||||||
* @Describe 简单信号通信中心接收器
|
|
||||||
*/
|
|
||||||
public class SOSCSBroadcastReceiver extends BroadcastReceiver {
|
|
||||||
|
|
||||||
public static final String TAG = "SOSCSBroadcastReceiver";
|
|
||||||
public static final String ACTION_SOS = SOSCSBroadcastReceiver.class.getName() + ".ACTION_SOS";
|
|
||||||
|
|
||||||
//ISOSAPP mISOSAPP;
|
|
||||||
|
|
||||||
public SOSCSBroadcastReceiver() {
|
|
||||||
//mISOSAPP = iSOSAPP;
|
|
||||||
}
|
|
||||||
@Override
|
|
||||||
public void onReceive(Context context, Intent intent) {
|
|
||||||
String action = intent.getAction();
|
|
||||||
if (action.equals(ACTION_SOS)) {
|
|
||||||
LogUtils.d(TAG, "ACTION_SOS");
|
|
||||||
//mISOSAPP.helpISOSService(intent);
|
|
||||||
} else {
|
|
||||||
LogUtils.d(TAG, String.format("%s", action));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@@ -0,0 +1,3 @@
|
|||||||
|
package cc.winboll.studio.libappbase;
|
||||||
|
|
||||||
|
|
@@ -1,87 +0,0 @@
|
|||||||
package cc.winboll.studio.libappbase.bean;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @Author ZhanGSKen@AliYun.Com
|
|
||||||
* @Date 2025/02/17 00:29:29
|
|
||||||
* @Describe APPSOSReportBean
|
|
||||||
*/
|
|
||||||
import android.util.JsonReader;
|
|
||||||
import android.util.JsonWriter;
|
|
||||||
import cc.winboll.studio.libappbase.BaseBean;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.Serializable;
|
|
||||||
|
|
||||||
public class APPSOSBean extends BaseBean {
|
|
||||||
|
|
||||||
public static final String TAG = "APPSOSBean";
|
|
||||||
|
|
||||||
protected String sosPackage;
|
|
||||||
protected String sosClassName;
|
|
||||||
|
|
||||||
public APPSOSBean() {
|
|
||||||
this.sosPackage = "";
|
|
||||||
this.sosClassName = "";
|
|
||||||
}
|
|
||||||
|
|
||||||
public APPSOSBean(String sosPackage, String sosClassName) {
|
|
||||||
this.sosPackage = sosPackage;
|
|
||||||
this.sosClassName = sosClassName;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setSosPackage(String sosPackage) {
|
|
||||||
this.sosPackage = sosPackage;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getSosPackage() {
|
|
||||||
return sosPackage;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setSosClassName(String sosClassName) {
|
|
||||||
this.sosClassName = sosClassName;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getSosClassName() {
|
|
||||||
return sosClassName;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getName() {
|
|
||||||
return APPSOSBean.class.getName();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void writeThisToJsonWriter(JsonWriter jsonWriter) throws IOException {
|
|
||||||
super.writeThisToJsonWriter(jsonWriter);
|
|
||||||
jsonWriter.name("sosPackage").value(getSosPackage());
|
|
||||||
jsonWriter.name("sosClassName").value(getSosClassName());
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean initObjectsFromJsonReader(JsonReader jsonReader, String name) throws IOException {
|
|
||||||
if (super.initObjectsFromJsonReader(jsonReader, name)) { return true; } else {
|
|
||||||
if (name.equals("sosPackage")) {
|
|
||||||
setSosPackage(jsonReader.nextString());
|
|
||||||
} else if (name.equals("sosClassName")) {
|
|
||||||
setSosClassName(jsonReader.nextString());
|
|
||||||
} else {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public BaseBean readBeanFromJsonReader(JsonReader jsonReader) throws IOException {
|
|
||||||
jsonReader.beginObject();
|
|
||||||
while (jsonReader.hasNext()) {
|
|
||||||
String name = jsonReader.nextName();
|
|
||||||
if (!initObjectsFromJsonReader(jsonReader, name)) {
|
|
||||||
jsonReader.skipValue();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// 结束 JSON 对象
|
|
||||||
jsonReader.endObject();
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
}
|
|
@@ -0,0 +1,86 @@
|
|||||||
|
package cc.winboll.studio.libappbase.sos;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Author ZhanGSKen@AliYun.Com
|
||||||
|
* @Date 2025/03/02 10:28:08
|
||||||
|
* @Describe APPModel
|
||||||
|
*/
|
||||||
|
import android.util.JsonReader;
|
||||||
|
import android.util.JsonWriter;
|
||||||
|
import cc.winboll.studio.libappbase.BaseBean;
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
public class APPModel extends BaseBean {
|
||||||
|
|
||||||
|
public static final String TAG = "APPModel";
|
||||||
|
|
||||||
|
String appPackageName;
|
||||||
|
String appMainServiveName;
|
||||||
|
|
||||||
|
public APPModel() {
|
||||||
|
this.appPackageName = "";
|
||||||
|
this.appMainServiveName = "";
|
||||||
|
}
|
||||||
|
|
||||||
|
public APPModel(String appPackageName, String appMainServiveName) {
|
||||||
|
this.appPackageName = appPackageName;
|
||||||
|
this.appMainServiveName = appMainServiveName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAppPackageName(String appPackageName) {
|
||||||
|
this.appPackageName = appPackageName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getAppPackageName() {
|
||||||
|
return appPackageName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAppMainServiveName(String appMainServiveName) {
|
||||||
|
this.appMainServiveName = appMainServiveName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getAppMainServiveName() {
|
||||||
|
return appMainServiveName;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getName() {
|
||||||
|
return APPModel.class.getName();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void writeThisToJsonWriter(JsonWriter jsonWriter) throws IOException {
|
||||||
|
super.writeThisToJsonWriter(jsonWriter);
|
||||||
|
jsonWriter.name("appPackageName").value(getAppPackageName());
|
||||||
|
jsonWriter.name("appMainServiveName").value(getAppMainServiveName());
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean initObjectsFromJsonReader(JsonReader jsonReader, String name) throws IOException {
|
||||||
|
if (super.initObjectsFromJsonReader(jsonReader, name)) { return true; } else {
|
||||||
|
if (name.equals("appPackageName")) {
|
||||||
|
setAppPackageName(jsonReader.nextString());
|
||||||
|
} else if (name.equals("appMainServiveName")) {
|
||||||
|
setAppMainServiveName(jsonReader.nextString());
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BaseBean readBeanFromJsonReader(JsonReader jsonReader) throws IOException {
|
||||||
|
jsonReader.beginObject();
|
||||||
|
while (jsonReader.hasNext()) {
|
||||||
|
String name = jsonReader.nextName();
|
||||||
|
if (!initObjectsFromJsonReader(jsonReader, name)) {
|
||||||
|
jsonReader.skipValue();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 结束 JSON 对象
|
||||||
|
jsonReader.endObject();
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,59 @@
|
|||||||
|
package cc.winboll.studio.libappbase.sos;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Author ZhanGSKen@AliYun.Com
|
||||||
|
* @Date 2025/03/02 09:36:29
|
||||||
|
* @Describe WinBoll 应用 SOS 机理保护类
|
||||||
|
*/
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.Intent;
|
||||||
|
import cc.winboll.studio.libappbase.LogUtils;
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
public class SOS {
|
||||||
|
|
||||||
|
public static final String TAG = "SOS";
|
||||||
|
|
||||||
|
public static final String ACTION_SOS = SOS.class.getName() + ".ACTION_SOS";
|
||||||
|
public static final String EXTRA_OBJECT = "EXTRA_OBJECT";
|
||||||
|
|
||||||
|
public static void sosToAppBase(Context context, String sosService) {
|
||||||
|
LogUtils.d(TAG, "sosToAppBase()");
|
||||||
|
String szToPackage = "cc.winboll.studio.appbase";
|
||||||
|
sos(context, szToPackage, sosService);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void sosToAppBaseBeta(Context context, String sosService) {
|
||||||
|
LogUtils.d(TAG, "sosToAppBaseBeta()");
|
||||||
|
String szToPackage = "cc.winboll.studio.appbase.beta";
|
||||||
|
sos(context, szToPackage, sosService);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
static void sos(Context context, String szToPackage, String sosService) {
|
||||||
|
LogUtils.d(TAG, "sos(...)");
|
||||||
|
Intent intent = new Intent(ACTION_SOS);
|
||||||
|
intent.putExtra(EXTRA_OBJECT, genSOSObject(context.getPackageName(), sosService));
|
||||||
|
intent.setPackage(szToPackage);
|
||||||
|
LogUtils.d(TAG, String.format("ACTION_SOS :\nTo Package : %sSOS Service : %s\n", szToPackage, sosService));
|
||||||
|
context.sendBroadcast(intent);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static SOSObject parseSOSObject(String szSOSObject) {
|
||||||
|
try {
|
||||||
|
return SOSObject.parseStringToBean(szSOSObject, SOSObject.class);
|
||||||
|
} catch (IOException e) {
|
||||||
|
LogUtils.d(TAG, e, Thread.currentThread().getStackTrace());
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String sosObjectToString(SOSObject object) {
|
||||||
|
return object.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String genSOSObject(String objectPackageName, String objectServiveName) {
|
||||||
|
return (new SOSObject(objectPackageName, objectServiveName)).toString();
|
||||||
|
}
|
||||||
|
}
|