Compare commits

..

3 Commits

Author SHA1 Message Date
ZhanGSKen
5714aed761 <autoinstaller>APK 15.0.0 release Publish. 2025-03-15 15:38:45 +08:00
ZhanGSKen
f04f5cf77c 更新安卓适配版本 2025-03-15 15:33:36 +08:00
ZhanGSKen
6ccbaf8c32 更新类库 2025-03-15 15:21:41 +08:00
41 changed files with 180 additions and 469 deletions

View File

@@ -1,8 +1,8 @@
#Created by .winboll/winboll_app_build.gradle
#Thu Mar 20 16:41:52 GMT 2025
stageCount=6
#Sat Mar 15 04:31:43 GMT 2025
stageCount=0
libraryProject=libappbase
baseVersion=15.0
publishVersion=15.0.5
buildCount=4
baseBetaVersion=15.0.6
publishVersion=15.0.0
buildCount=1
baseBetaVersion=15.0.1

View File

@@ -7,7 +7,7 @@
android:name=".App"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/MyAPPBaseTheme"
android:theme="@style/MyAppTheme"
android:resizeableActivity="true">
<activity

View File

@@ -37,10 +37,7 @@ public class MainActivity extends Activity {
cbIsDebugMode.setChecked(GlobalApplication.isDebuging());
mLogView = findViewById(R.id.activitymainLogView1);
if (GlobalApplication.isDebuging()) {
mLogView.start();
ToastUtils.show("LogView start.");
}
if (GlobalApplication.isDebuging()) { mLogView.start(); }
}
@Override
@@ -92,7 +89,7 @@ public class MainActivity extends Activity {
public void onTestSOS(View view) {
Intent intent = new Intent(this, TestDemoService.class);
stopService(intent);
if (App.isDebuging()) {
if(App.isDebuging()) {
SOS.sosToAppBaseBeta(this, TestDemoService.class.getName());
} else {
SOS.sosToAppBase(this, TestDemoService.class.getName());
@@ -110,7 +107,7 @@ public class MainActivity extends Activity {
Intent intent = new Intent(this, TestDemoService.class);
intent.setAction(TestDemoService.ACTION_DISABLE);
startService(intent);
Intent intentStop = new Intent(this, TestDemoService.class);
stopService(intentStop);
}
@@ -119,7 +116,7 @@ public class MainActivity extends Activity {
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);

View File

@@ -179,16 +179,16 @@
</ScrollView>
<cc.winboll.studio.libappbase.LogView
android:layout_height="500dp"
android:layout_width="match_parent"
android:id="@+id/activitymainLogView1"/>
</LinearLayout>
</LinearLayout>
</ScrollView>
<cc.winboll.studio.libappbase.LogView
android:layout_height="300dp"
android:layout_width="match_parent"
android:id="@+id/activitymainLogView1"/>
</LinearLayout>

View File

@@ -1,7 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="colorPrimary">#FF00B322</color>
<color name="colorPrimaryDark">#FF005C12</color>
<color name="colorAccent">#FF8DFFA2</color>
<color name="colorText">#FFFFFB8D</color>
<color name="colorPrimary">#005800FF</color>
<color name="colorPrimaryDark">#005800FF</color>
<color name="colorAccent">#005800FF</color>
</resources>

View File

@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="MyAPPBaseTheme" parent="APPBaseTheme">
<style name="MyAppTheme" parent="APPBaseTheme">
<item name="attrColorPrimary">@color/colorPrimary</item>
<item name="themeGlobalCrashActivity">@style/MyGlobalCrashActivityTheme</item>
</style>

View File

@@ -18,18 +18,18 @@ def genVersionName(def versionName){
}
android {
compileSdkVersion 32
buildToolsVersion "33.0.3"
compileSdkVersion 30
buildToolsVersion "30.0.3"
defaultConfig {
applicationId "cc.winboll.studio.autoinstaller"
minSdkVersion 24
targetSdkVersion 30
minSdkVersion 26
targetSdkVersion 29
versionCode 2
// versionName 更新后需要手动设置
// .winboll/winbollBuildProps.properties 文件的 stageCount=0
// Gradle编译环境下合起来的 versionName 就是 "${versionName}.0"
versionName "5.0"
versionName "15.0"
if(true) {
versionName = genVersionName("${versionName}")
}
@@ -41,30 +41,10 @@ android {
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_11
targetCompatibility JavaVersion.VERSION_11
}
}
dependencies {
api 'cc.winboll.studio:winboll-shared:1.1.0'
api 'io.github.medyo:android-about-page:2.0.0'
api 'com.github.getActivity:ToastUtils:10.5'
api 'com.jcraft:jsch:0.1.55'
api 'org.jsoup:jsoup:1.13.1'
api 'com.squareup.okhttp3:okhttp:4.4.1'
api 'androidx.appcompat:appcompat:1.0.0'
api 'androidx.fragment:fragment:1.0.0'
api 'com.google.android.material:material:1.0.0'
api 'androidx.vectordrawable:vectordrawable-animated:1.0.0'
api 'androidx.lifecycle:lifecycle-livedata:1.0.0'
//api 'cc.winboll.studio:libaes:6.3.2'
//api 'cc.winboll.studio:libapputils:8.3.8'
api fileTree(dir: 'libs', include: ['*.jar'])
implementation 'cc.winboll.studio:libappbase:15.0.2'
implementation 'androidx.appcompat:appcompat:1.1.0'
}

View File

@@ -1,8 +1,8 @@
#Created by .winboll/winboll_app_build.gradle
#Thu Jan 02 02:39:56 HKT 2025
stageCount=4
#Sat Mar 15 15:38:45 HKT 2025
stageCount=1
libraryProject=
baseVersion=5.0
publishVersion=5.0.3
baseVersion=15.0
publishVersion=15.0.0
buildCount=0
baseBetaVersion=5.0.4
baseBetaVersion=15.0.1

View File

@@ -33,7 +33,7 @@
android:persistent="true"
android:supportsRtl="true"
android:requestLegacyExternalStorage="true"
android:theme="@style/Theme.Application">
android:theme="@style/MyAppTheme">
<activity
android:name=".MainActivity"

View File

@@ -5,24 +5,25 @@ package cc.winboll.studio.autoinstaller;
* @Date 2024/04/28 02:39:58
* @Describe 全局应用类
*/
import android.view.Gravity;
import com.hjq.toast.ToastUtils;
import cc.winboll.studio.shared.app.WinBollApplication;
public class App extends WinBollApplication {
import cc.winboll.studio.libappbase.GlobalApplication;
import cc.winboll.studio.libappbase.utils.ToastUtils;
public class App extends GlobalApplication {
public static final String TAG = "App";
@Override
public void onCreate() {
super.onCreate();
setIsDebug(BuildConfig.DEBUG);
setIsDebuging(this, BuildConfig.DEBUG);
// 初始化 Toast 框架
ToastUtils.init(this);
// 设置 Toast 布局样式
ToastUtils.setView(R.layout.toast_custom_view);
//ToastUtils.setView(R.layout.toast_custom_view);
//ToastUtils.setStyle(new WhiteToastStyle());
ToastUtils.setGravity(Gravity.BOTTOM, 0, 200);
//ToastUtils.setGravity(Gravity.BOTTOM, 0, 200);
}
}

View File

@@ -1,7 +1,7 @@
package cc.winboll.studio.autoinstaller;
import android.os.FileObserver;
import cc.winboll.studio.shared.log.LogUtils;
import cc.winboll.studio.libappbase.LogUtils;
public class FileListener extends FileObserver {
public final static String TAG = "FileListener";

View File

@@ -2,6 +2,7 @@ package cc.winboll.studio.autoinstaller;
import android.app.Activity;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.graphics.Color;
import android.net.Uri;
import android.os.Build;
@@ -14,14 +15,14 @@ import android.widget.Switch;
import android.widget.TextClock;
import android.widget.Toast;
import androidx.core.content.FileProvider;
import cc.winboll.studio.shared.log.LogUtils;
import cc.winboll.studio.shared.log.LogView;
import cc.winboll.studio.autoinstaller.MainActivity;
import cc.winboll.studio.autoinstaller.beans.AppConfigs;
import cc.winboll.studio.autoinstaller.services.MainService;
import cc.winboll.studio.autoinstaller.utils.NotificationUtil;
import cc.winboll.studio.autoinstaller.views.ListViewForScrollView;
import com.hjq.toast.ToastUtils;
import cc.winboll.studio.libappbase.LogUtils;
import cc.winboll.studio.libappbase.LogView;
import cc.winboll.studio.libappbase.utils.ToastUtils;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
@@ -136,9 +137,10 @@ public class MainActivity extends Activity {
ToastUtils.show("Installed APP package name is null.");
return;
}
Intent intent = getPackageManager().getLaunchIntentForPackage(mszInstalledPackageName);
if (intent != null) {
ToastUtils.show("startActivity");
startActivity(intent);
} else {
// 若没能获取到启动意图,可进行相应提示等操作,比如跳转到应用商店让用户下载该应用(示例)

View File

@@ -10,11 +10,11 @@ import android.util.JsonReader;
import android.util.JsonWriter;
import cc.winboll.studio.autoinstaller.beans.AppConfigs;
import cc.winboll.studio.autoinstaller.utils.FileUtil;
import cc.winboll.studio.libappbase.LogUtils;
import java.io.IOException;
import java.io.Serializable;
import java.io.StringReader;
import java.io.StringWriter;
import cc.winboll.studio.shared.log.LogUtils;
public class AppConfigs implements Serializable {

View File

@@ -6,7 +6,7 @@ import android.content.Intent;
import android.os.Build;
import cc.winboll.studio.autoinstaller.beans.AppConfigs;
import cc.winboll.studio.autoinstaller.services.MainService;
import cc.winboll.studio.shared.log.LogUtils;
import cc.winboll.studio.libappbase.LogUtils;
/**
* @Author ZhanGSKen@QQ.COM

View File

@@ -12,7 +12,6 @@ import android.os.IBinder;
import android.os.Message;
import android.widget.Toast;
import androidx.core.content.FileProvider;
import cc.winboll.studio.shared.log.LogUtils;
import cc.winboll.studio.autoinstaller.FileListener;
import cc.winboll.studio.autoinstaller.MainActivity;
import cc.winboll.studio.autoinstaller.beans.AppConfigs;
@@ -21,7 +20,8 @@ import cc.winboll.studio.autoinstaller.services.MainService;
import cc.winboll.studio.autoinstaller.utils.NotificationUtil;
import cc.winboll.studio.autoinstaller.utils.PackageUtil;
import cc.winboll.studio.autoinstaller.utils.ServiceUtil;
import com.hjq.toast.ToastUtils;
import cc.winboll.studio.libappbase.LogUtils;
import cc.winboll.studio.libappbase.utils.ToastUtils;
import java.io.File;
import java.lang.ref.WeakReference;
@@ -75,6 +75,7 @@ public class MainService extends Service {
startWatchingFile(appConfigs.getWatchingFilePath());
LogUtils.d(TAG, "running...");
ToastUtils.show("running...");
} else {
LogUtils.d(TAG, "_mIsServiceAlive is " + Boolean.toString(_mIsServiceAlive));

View File

@@ -8,7 +8,7 @@ package cc.winboll.studio.autoinstaller.utils;
import android.content.Context;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import cc.winboll.studio.shared.log.LogUtils;
import cc.winboll.studio.libappbase.LogUtils;
public class PackageUtil {

View File

@@ -132,7 +132,7 @@
</LinearLayout>
<cc.winboll.studio.shared.log.LogView
<cc.winboll.studio.libappbase.LogView
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="200dp"

View File

@@ -0,0 +1,13 @@
<resources xmlns:tools="http://schemas.android.com/tools">
<style name="MyAppTheme" parent="APPBaseTheme">
<item name="attrColorPrimary">@color/colorPrimary</item>
<item name="themeGlobalCrashActivity">@style/MyGlobalCrashActivityTheme</item>
</style>
<style name="MyGlobalCrashActivityTheme" parent="GlobalCrashActivityTheme">
<item name="colorTittle">#FFFFFFFF</item>
<item name="colorTittleBackgound">#FF00A4B3</item>
<item name="colorText">#FFFFFFFF</item>
<item name="colorTextBackgound">#FF000000</item>
</style>
</resources>

View File

@@ -1,14 +0,0 @@
<resources xmlns:tools="http://schemas.android.com/tools">
<!-- Base application theme. -->
<style name="Theme.Application" parent="android:Theme.Material.Light.DarkActionBar">
<!-- Primary brand color. -->
<item name="android:colorPrimary">@color/purple_500</item>
<!-- Secondary brand color. -->
<item name="android:colorSecondary">@color/teal_200</item>
<!-- Status bar color. -->
<item name="android:statusBarColor" tools:targetApi="l">@color/purple_700</item>
<!-- Customize your theme here. -->
</style>
</resources>

View File

@@ -1,12 +1,6 @@
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
repositories {
// Nexus Maven 库地址
// "WinBoll Release"
maven { url "https://nexus.winboll.cc/repository/maven-public/" }
// "WinBoll Snapshot"
maven { url "https://nexus.winboll.cc/repository/maven-snapshots/" }
maven { url 'https://maven.aliyun.com/repository/public/' }
maven { url 'https://maven.aliyun.com/repository/google/' }
maven { url 'https://maven.aliyun.com/repository/gradle-plugin/' }
@@ -15,6 +9,13 @@ buildscript {
maven { url "https://jitpack.io" }
mavenCentral()
google()
// Nexus Maven 库地址
// "WinBoll Release"
maven { url "https://nexus.winboll.cc/repository/maven-public/" }
// "WinBoll Snapshot"
maven { url "https://nexus.winboll.cc/repository/maven-snapshots/" }
mavenLocal()
}
dependencies {
@@ -26,12 +27,6 @@ buildscript {
allprojects {
repositories {
// Nexus Maven 库地址
// "WinBoll Release"
maven { url "https://nexus.winboll.cc/repository/maven-public/" }
// "WinBoll Snapshot"
maven { url "https://nexus.winboll.cc/repository/maven-snapshots/" }
maven { url 'https://maven.aliyun.com/repository/public/' }
maven { url 'https://maven.aliyun.com/repository/google/' }
maven { url 'https://maven.aliyun.com/repository/gradle-plugin/' }
@@ -40,6 +35,13 @@ allprojects {
maven { url "https://jitpack.io" }
mavenCentral()
google()
// Nexus Maven 库地址
// "WinBoll Release"
maven { url "https://nexus.winboll.cc/repository/maven-public/" }
// "WinBoll Snapshot"
maven { url "https://nexus.winboll.cc/repository/maven-snapshots/" }
mavenLocal()
}
ext {

View File

@@ -1,8 +1,8 @@
#Created by .winboll/winboll_app_build.gradle
#Thu Mar 20 16:41:52 GMT 2025
stageCount=6
#Sat Mar 15 04:31:43 GMT 2025
stageCount=0
libraryProject=libappbase
baseVersion=15.0
publishVersion=15.0.5
buildCount=4
baseBetaVersion=15.0.6
publishVersion=15.0.0
buildCount=1
baseBetaVersion=15.0.1

View File

@@ -190,7 +190,6 @@ public class LogView extends RelativeLayout {
// 加载标签表
mListViewTags = findViewById(cc.winboll.studio.libappbase.R.id.tags_listview);
mListViewTags.setVerticalOffset(10);
mTAGListAdapter = new TAGListAdapter(mContext, mapTAGList);
mListViewTags.setAdapter(mTAGListAdapter);

View File

@@ -28,6 +28,6 @@ public class ToastUtils {
}
public static void show(String message) {
Toast.makeText(getInstance().mContext, message, Toast.LENGTH_SHORT).show();
Toast.makeText(getInstance().mContext, "", Toast.LENGTH_SHORT).show();
}
}

View File

@@ -12,9 +12,7 @@ import android.widget.ListView;
import cc.winboll.studio.libappbase.LogUtils;
public class HorizontalListView extends ListView {
public static final String TAG = "HorizontalListView";
int verticalOffset = 0;
public HorizontalListView(Context context) {
super(context);
@@ -27,10 +25,25 @@ public class HorizontalListView extends ListView {
public HorizontalListView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
public void setVerticalOffset(int verticalOffset) {
this.verticalOffset = verticalOffset;
}
// @Override
// protected void onLayout(boolean changed, int l, int t, int r, int b) {
// super.onLayout(changed, l, t, r, b);
// int childCount = getChildCount();
// int left = getPaddingLeft();
// // 获取HorizontalListView的高度
// int viewHeight = getMeasuredHeight() - getPaddingTop() - getPaddingBottom();
// for (int i = 0; i < childCount; i++) {
// View child = getChildAt(i);
// int width = child.getMeasuredWidth();
// int height = child.getMeasuredHeight();
// // 计算子项在垂直方向上的居中偏移量
// int verticalOffset = (viewHeight - height) / 2;
// // 设置子视图的位置,实现水平布局并垂直居中
// child.layout(left, getPaddingTop() + verticalOffset, left + width, getPaddingTop() + verticalOffset + height);
// left += width;
// }
// }
//
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
@@ -39,7 +52,7 @@ public class HorizontalListView extends ListView {
int left = getPaddingLeft();
int viewHeight = getMeasuredHeight() - getPaddingTop() - getPaddingBottom();
LogUtils.d(TAG, String.format("HorizontalListView的高度 %d", viewHeight));
int verticalOffset = 20;
for (int i = 0; i < childCount; i++) {
View child = getChildAt(i);
// 计算每个子视图的宽度和高度
@@ -47,7 +60,7 @@ public class HorizontalListView extends ListView {
int height = child.getMeasuredHeight();
//LogUtils.d(TAG, String.format("child : width %d , height %d", width, height));
// 设置子视图的位置,实现水平布局
child.layout(left, verticalOffset, left + width, verticalOffset + height);
left += width;
}
@@ -55,11 +68,15 @@ public class HorizontalListView extends ListView {
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int newHeightMeasureSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2, MeasureSpec.AT_MOST);
//super.onMeasure(widthMeasureSpec, newHeightMeasureSpec);
int newWidthMeasureSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2, MeasureSpec.AT_MOST);
//LogUtils.d(TAG, String.format("newWidthMeasureSpec %d, newHeightMeasureSpec %d", newWidthMeasureSpec, newHeightMeasureSpec));
super.onMeasure(newWidthMeasureSpec, newHeightMeasureSpec);
// ViewGroup.LayoutParams params = getLayoutParams();
// params.width = getMeasuredWidth();
}
}

View File

@@ -1,13 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<stroke
android:width="1dp"
android:color="#000000" /> <!-- 这里可调整边框宽度和颜色 -->
<solid android:color="@android:color/transparent" />
<corners
android:bottomLeftRadius="6dip"
android:bottomRightRadius="6dip"
android:topLeftRadius="6dip"
android:topRightRadius="6dip" />
</shape>

View File

@@ -10,8 +10,8 @@
<shape android:shape="rectangle" >
<gradient
android:angle="270"
android:endColor="@color/colorAccent"
android:startColor="@color/colorAccent" />
android:endColor="#0F000000"
android:startColor="#0F000000" />
<corners
android:bottomLeftRadius="6dip"
android:bottomRightRadius="6dip"

View File

@@ -5,18 +5,18 @@
android:orientation="horizontal"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:background="@drawable/bg_border_round">
android:background="#FFEEEEEE">
<TextView
android:layout_width="wrap_content"
android:layout_height="@dimen/button_height"
android:layout_marginLeft="5dp"
android:id="@+id/viewlogtagTextView1"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="24dp"
android:layout_marginLeft="5dp"
android:id="@+id/viewlogtagTextView1"/>
<CheckBox
android:layout_width="wrap_content"
android:layout_height="@dimen/button_height"
android:id="@+id/viewlogtagCheckBox1"/>
<CheckBox
android:layout_width="wrap_content"
android:layout_height="24dp"
android:id="@+id/viewlogtagCheckBox1"/>
</LinearLayout>

View File

@@ -72,29 +72,27 @@
android:layout_below="@+id/viewlogRelativeLayoutToolbar"
android:id="@+id/viewlogLinearLayout1"
android:gravity="center_vertical"
android:background="@drawable/bg_shadow">
android:background="#FFC0F4C2">
<CheckBox
android:layout_width="wrap_content"
android:layout_height="@dimen/button_height"
android:layout_height="wrap_content"
android:text="ALL"
android:id="@+id/viewlogCheckBox1"
android:background="@drawable/bg_border_round"
android:layout_marginLeft="5dp"
android:layout_marginRight="5dp"/>
android:id="@+id/viewlogCheckBox1"/>
<HorizontalScrollView
android:layout_width="0dp"
android:layout_height="match_parent"
android:background="@drawable/bg_border"
android:scrollbars="none"
android:padding="5dp"
android:layout_weight="1.0">
android:layout_weight="1.0"
android:background="#FF97F2E3">
<cc.winboll.studio.libappbase.views.HorizontalListView
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:id="@+id/tags_listview"/>
android:background="@drawable/view_border"
android:id="@+id/tags_listview"
android:paddingLeft="10dp"/>
</HorizontalScrollView>

View File

@@ -1,9 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<!-- 定义一个名为text_size_normal的尺寸值为16sp -->
<dimen name="text_size_normal">16sp</dimen>
<!-- 定义一个名为margin_small的尺寸值为8dp -->
<dimen name="margin_small">8dp</dimen>
<!-- 定义一个名为image_width的尺寸值为200dp -->
<dimen name="button_height">24dp</dimen>
</resources>

View File

@@ -41,6 +41,11 @@ android {
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_11
targetCompatibility JavaVersion.VERSION_11
}
}
dependencies {

View File

@@ -1,8 +1,8 @@
#Created by .winboll/winboll_app_build.gradle
#Sat Mar 22 06:01:46 HKT 2025
stageCount=7
#Thu Jan 02 11:13:45 HKT 2025
stageCount=6
libraryProject=
baseVersion=4.0
publishVersion=4.0.6
publishVersion=4.0.5
buildCount=0
baseBetaVersion=4.0.7
baseBetaVersion=4.0.6

View File

@@ -2,9 +2,10 @@
<manifest
xmlns:android="http://schemas.android.com/apk/res/android"
package="cc.winboll.studio.powerbell">
<!-- 拍摄照片和视频 -->
<uses-permission android:name="android.permission.CAMERA"/>
<uses-permission android:name="android.permission.CAMERA" />
<uses-feature android:name="android.hardware.camera" />
<uses-feature android:name="android.hardware.camera.autofocus" />
<!-- 运行前台服务 -->
<uses-permission android:name="android.permission.FOREGROUND_SERVICE"/>
@@ -21,23 +22,6 @@
<!-- MANAGE_EXTERNAL_STORAGE -->
<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE"/>
<!-- 显示通知 -->
<uses-permission android:name="android.permission.POST_NOTIFICATIONS"/>
<uses-feature android:name="android.hardware.camera"/>
<uses-feature android:name="android.hardware.camera.autofocus"/>
<uses-permission android:name="android.permission.FOREGROUND_SERVICE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE"/>
<application
android:name=".GlobalApplication"
android:allowBackup="true"
@@ -50,8 +34,7 @@
<activity
android:name=".MainActivity"
android:launchMode="singleTask"
android:exported="true">
android:launchMode="singleTask">
<intent-filter>

View File

@@ -17,7 +17,7 @@ import cc.winboll.studio.powerbell.activities.AboutActivity;
import cc.winboll.studio.powerbell.activities.BackgroundPictureActivity;
import cc.winboll.studio.powerbell.activities.ClearRecordActivity;
import cc.winboll.studio.powerbell.fragments.MainViewFragment;
import cc.winboll.studio.powerbell.utils.NotificationHelper;
import cc.winboll.studio.powerbell.utils.NotificationUtils;
import cc.winboll.studio.shared.log.LogUtils;
import cc.winboll.studio.shared.log.LogView;
@@ -64,10 +64,8 @@ public class MainActivity extends Activity {
}
showFragment(mMainViewFragment);
// NotificationHelper notificationUtils = new NotificationHelper(this);
// notificationUtils.createNotificationChannels();
NotificationUtils notificationUtils = new NotificationUtils(this);
notificationUtils.createNotificationChannel();
}
void showFragment(Fragment fragment) {
@@ -115,7 +113,7 @@ public class MainActivity extends Activity {
protected void onResume() {
super.onResume();
// 回到窗口自动取消提醒消息
//NotificationHelper.cancelRemindNotification(this);
NotificationUtils.cancelRemindNotification(this);
reloadBackground();
}

View File

@@ -8,7 +8,7 @@ import cc.winboll.studio.powerbell.GlobalApplication;
import cc.winboll.studio.powerbell.fragments.MainViewFragment;
import cc.winboll.studio.powerbell.utils.AppConfigUtils;
import cc.winboll.studio.powerbell.utils.BatteryUtils;
import cc.winboll.studio.powerbell.utils.NotificationHelper;
import cc.winboll.studio.powerbell.utils.NotificationUtils;
public class GlobalApplicationReceiver extends BroadcastReceiver {
@@ -45,7 +45,7 @@ public class GlobalApplicationReceiver extends BroadcastReceiver {
// 新电池状态标志某一个有变化就更新显示信息
if (_mIsCharging != isCharging || _mnTheQuantityOfElectricityOld != nTheQuantityOfElectricity) {
// 电池状态改变先取消旧的提醒消息
//NotificationHelper.cancelRemindNotification(context);
NotificationUtils.cancelRemindNotification(context);
GlobalApplication.getAppCacheUtils(context).addChangingTime(nTheQuantityOfElectricity);
MainViewFragment.sendMsgCurrentValueBattery(nTheQuantityOfElectricity);

View File

@@ -8,17 +8,14 @@ package cc.winboll.studio.powerbell.services;
* Android Service之onStartCommand方法研究
* https://blog.csdn.net/cyp331203/article/details/38920491
*/
import android.app.Notification;
import cc.winboll.studio.powerbell.R;
import android.app.Service;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.IBinder;
import android.widget.RemoteViews;
import cc.winboll.studio.powerbell.GlobalApplication;
import cc.winboll.studio.powerbell.MainActivity;
import cc.winboll.studio.powerbell.R;
import cc.winboll.studio.powerbell.beans.AppConfigBean;
import cc.winboll.studio.powerbell.beans.NotificationMessage;
import cc.winboll.studio.powerbell.handlers.ControlCenterServiceHandler;
@@ -27,12 +24,11 @@ import cc.winboll.studio.powerbell.services.AssistantService;
import cc.winboll.studio.powerbell.threads.RemindThread;
import cc.winboll.studio.powerbell.utils.AppCacheUtils;
import cc.winboll.studio.powerbell.utils.AppConfigUtils;
import cc.winboll.studio.powerbell.utils.NotificationHelper;
import cc.winboll.studio.powerbell.utils.NotificationUtils;
import cc.winboll.studio.powerbell.utils.ServiceUtils;
import cc.winboll.studio.powerbell.utils.StringUtils;
import cc.winboll.studio.shared.log.LogUtils;
import com.hjq.toast.ToastUtils;
import android.graphics.Color;
public class ControlCenterService extends Service {
@@ -47,8 +43,7 @@ public class ControlCenterService extends Service {
AppConfigUtils mAppConfigUtils;
AppCacheUtils mAppCacheUtils;
// 前台服务通知工具
NotificationHelper mNotificationHelper;
Notification notification;
NotificationUtils mNotificationUtils;
RemindThread mRemindThread;
ControlCenterServiceHandler mControlCenterServiceHandler;
MyServiceConnection mMyServiceConnection;
@@ -71,9 +66,7 @@ public class ControlCenterService extends Service {
isServiceRunning = false;
mAppConfigUtils = GlobalApplication.getAppConfigUtils(this);
mAppCacheUtils = GlobalApplication.getAppCacheUtils(this);
mNotificationHelper = new NotificationHelper(ControlCenterService.this);
mNotificationUtils = new NotificationUtils(ControlCenterService.this);
if (mMyServiceConnection == null) {
mMyServiceConnection = new MyServiceConnection();
}
@@ -99,16 +92,10 @@ public class ControlCenterService extends Service {
// 唤醒守护进程
wakeupAndBindAssistant();
// 显示前台通知栏
// 在Service中
NotificationHelper helper = new NotificationHelper(this);
Intent intent = new Intent(this, MainActivity.class);
notification = helper.showForegroundNotification(intent, getString(R.string.app_name), "Service Running, Click to open app");
startForeground(NotificationHelper.FOREGROUND_NOTIFICATION_ID, notification);
// NotificationMessage notificationMessage=createNotificationMessage();
// //Toast.makeText(getApplication(), "", Toast.LENGTH_SHORT).show();
// mNotificationUtils.createForegroundNotification(this, notificationMessage);
// mNotificationUtils.createRemindNotification(this, notificationMessage);
NotificationMessage notificationMessage=createNotificationMessage();
//Toast.makeText(getApplication(), "", Toast.LENGTH_SHORT).show();
mNotificationUtils.createForegroundNotification(this, notificationMessage);
mNotificationUtils.createRemindNotification(this, notificationMessage);
if (mControlCenterServiceReceiver == null) {
// 注册广播接收器
@@ -139,19 +126,19 @@ public class ControlCenterService extends Service {
// 更新前台通知
//
public void updateServiceNotification() {
//mNotificationUtils.updateForegroundNotification(ControlCenterService.this, createNotificationMessage());
mNotificationUtils.updateForegroundNotification(ControlCenterService.this, createNotificationMessage());
}
// 更新前台通知
//
public void updateServiceNotification(NotificationMessage notificationMessage) {
//mNotificationUtils.updateForegroundNotification(ControlCenterService.this, notificationMessage);
mNotificationUtils.updateForegroundNotification(ControlCenterService.this, notificationMessage);
}
// 更新前台通知
//
public void updateRemindNotification(NotificationMessage notificationMessage) {
//mNotificationUtils.updateRemindNotification(ControlCenterService.this, notificationMessage);
mNotificationUtils.updateRemindNotification(ControlCenterService.this, notificationMessage);
}
// 唤醒和绑定守护进程
@@ -247,32 +234,10 @@ public class ControlCenterService extends Service {
}
public void appenRemindMSG(String szRemindMSG) {
String msg = "";
for (int i = 0; i < 20; i++) {
msg += szRemindMSG;
}
NotificationHelper helper = new NotificationHelper(ControlCenterService.this);
Intent intent = new Intent(ControlCenterService.this, MainActivity.class);
helper.showTemporaryNotification(intent, getString(R.string.app_name), msg);
// NotificationMessage notificationMessage = createNotificationMessage();
// notificationMessage.setRemindMSG(szRemindMSG);
// //LogUtils.d(TAG, "notificationMessage : " + notificationMessage.getRemindMSG());
// updateRemindNotification(notificationMessage);
}
// 设置颜色背景
public static RemoteViews setLinearLayoutColor(RemoteViews remoteViews, int viewId, int color) {
remoteViews.setInt(viewId, "setBackgroundColor", color);
return remoteViews;
}
// 设置Drawable背景
public static RemoteViews setLinearLayoutDrawable(RemoteViews remoteViews, int viewId, int drawableRes) {
remoteViews.setInt(viewId, "setBackgroundResource", drawableRes);
return remoteViews;
NotificationMessage notificationMessage = createNotificationMessage();
notificationMessage.setRemindMSG(szRemindMSG);
//LogUtils.d(TAG, "notificationMessage : " + notificationMessage.getRemindMSG());
updateRemindNotification(notificationMessage);
}
//

View File

@@ -193,7 +193,7 @@ public class AppConfigUtils {
//
void saveConfigData() {
// 更新配置先取消一下旧的的提醒消息
//NotificationHelper.cancelRemindNotification(mContext);
NotificationUtils.cancelRemindNotification(mContext);
AppConfigBean.saveBean(mContext, mAppConfigBean);
// 通知活动窗口和服务配置已更新

View File

@@ -1,150 +0,0 @@
package cc.winboll.studio.powerbell.utils;
/**
* @Author ZhanGSKen@AliYun.Com
* @Date 2025/03/22 04:39:40
* @Describe 通知工具类
*/
import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.graphics.BitmapFactory;
import android.os.Build;
import android.widget.RemoteViews;
import androidx.annotation.RequiresApi;
import androidx.core.app.NotificationCompat;
import cc.winboll.studio.powerbell.R;
public class NotificationHelper {
public static final String TAG = "NotificationHelper";
// 渠道ID和名称
private static final String CHANNEL_ID_FOREGROUND = "foreground_channel";
private static final String CHANNEL_NAME_FOREGROUND = "Foreground Service";
private static final String CHANNEL_ID_TEMPORARY = "temporary_channel";
private static final String CHANNEL_NAME_TEMPORARY = "Temporary Notifications";
// 通知ID
public static final int FOREGROUND_NOTIFICATION_ID = 1001;
public static final int TEMPORARY_NOTIFICATION_ID = 2001;
private final Context mContext;
private final NotificationManager mNotificationManager;
public NotificationHelper(Context context) {
mContext = context;
mNotificationManager = context.getSystemService(NotificationManager.class);
createNotificationChannels();
}
@RequiresApi(api = Build.VERSION_CODES.O)
private void createNotificationChannels() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
createForegroundChannel();
createTemporaryChannel();
}
}
@RequiresApi(api = Build.VERSION_CODES.O)
private void createForegroundChannel() {
NotificationChannel channel = new NotificationChannel(
CHANNEL_ID_FOREGROUND,
CHANNEL_NAME_FOREGROUND,
NotificationManager.IMPORTANCE_LOW
);
channel.setDescription("Persistent service notifications");
channel.setSound(null, null);
channel.enableVibration(false);
mNotificationManager.createNotificationChannel(channel);
}
@RequiresApi(api = Build.VERSION_CODES.O)
private void createTemporaryChannel() {
NotificationChannel channel = new NotificationChannel(
CHANNEL_ID_TEMPORARY,
CHANNEL_NAME_TEMPORARY,
NotificationManager.IMPORTANCE_HIGH
);
channel.setDescription("Temporary alert notifications");
channel.setSound(null, null);
channel.enableVibration(true);
channel.setVibrationPattern(new long[]{100, 200, 300, 400});
channel.setBypassDnd(true);
mNotificationManager.createNotificationChannel(channel);
}
// 显示常驻通知(通常用于前台服务)
public Notification showForegroundNotification(Intent intent, String title, String content) {
PendingIntent pendingIntent = createPendingIntent(intent);
Notification notification = new NotificationCompat.Builder(mContext, CHANNEL_ID_FOREGROUND)
.setSmallIcon(R.drawable.ic_launcher)
.setLargeIcon(BitmapFactory.decodeResource(mContext.getResources(), R.drawable.ic_launcher))
.setContentTitle(title)
.setContentText(content)
.setContentIntent(pendingIntent)
.setPriority(NotificationCompat.PRIORITY_LOW)
.setOngoing(true)
.build();
mNotificationManager.notify(FOREGROUND_NOTIFICATION_ID, notification);
return notification;
}
// 显示临时通知(自动消失)
public void showTemporaryNotification(Intent intent, String title, String content) {
PendingIntent pendingIntent = createPendingIntent(intent);
Notification notification = new NotificationCompat.Builder(mContext, CHANNEL_ID_TEMPORARY)
.setSmallIcon(R.drawable.ic_launcher)
.setLargeIcon(BitmapFactory.decodeResource(mContext.getResources(), R.drawable.ic_launcher))
.setContentTitle(title)
.setContentText(content)
.setContentIntent(pendingIntent)
.setPriority(NotificationCompat.PRIORITY_HIGH)
.setAutoCancel(true)
.setVibrate(new long[]{100, 200, 300, 400})
.build();
mNotificationManager.notify(TEMPORARY_NOTIFICATION_ID, notification);
}
// 创建自定义布局通知(可扩展)
public void showCustomNotification(Intent intent, RemoteViews contentView, RemoteViews bigContentView) {
PendingIntent pendingIntent = createPendingIntent(intent);
Notification notification = new NotificationCompat.Builder(mContext, CHANNEL_ID_TEMPORARY)
.setSmallIcon(R.drawable.ic_launcher)
.setContentIntent(pendingIntent)
.setContent(contentView)
.setCustomBigContentView(bigContentView)
.setPriority(NotificationCompat.PRIORITY_HIGH)
.setAutoCancel(true)
.build();
mNotificationManager.notify(TEMPORARY_NOTIFICATION_ID + 1, notification);
}
// 取消所有通知
public void cancelAllNotifications() {
mNotificationManager.cancelAll();
}
// 创建PendingIntent兼容不同API版本
private PendingIntent createPendingIntent(Intent intent) {
int flags = PendingIntent.FLAG_UPDATE_CURRENT;
// if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
// flags |= PendingIntent.FLAG_IMMUTABLE;
// }
return PendingIntent.getActivity(
mContext,
0,
intent,
flags
);
}
}

View File

@@ -18,15 +18,14 @@ import android.media.RingtoneManager;
import android.os.Build;
import android.view.View;
import android.widget.RemoteViews;
import androidx.annotation.RequiresApi;
import cc.winboll.studio.powerbell.MainActivity;
import cc.winboll.studio.powerbell.R;
import cc.winboll.studio.powerbell.beans.NotificationMessage;
import cc.winboll.studio.powerbell.services.ControlCenterService;
public class NotificationUtils2 {
public class NotificationUtils {
public static final String TAG = NotificationHelper.class.getSimpleName();
public static final String TAG = NotificationUtils.class.getSimpleName();
Context mContext;
NotificationManager mNotificationManager;
@@ -46,53 +45,19 @@ public class NotificationUtils2 {
private static String _mszChannelIDRemind = "2";
private static String _mszChannelNameRemind = "Remind";
// public NotificationUtils(Context context) {
// mContext = context;
// mNotificationManager = (NotificationManager) context.getSystemService(
// Context.NOTIFICATION_SERVICE);
// }
public NotificationUtils2(Context context) {
public NotificationUtils(Context context) {
mContext = context;
mNotificationManager = context.getSystemService(NotificationManager.class);
//createNotificationChannels();
mNotificationManager = (NotificationManager) context.getSystemService(
Context.NOTIFICATION_SERVICE);
}
@RequiresApi(api = Build.VERSION_CODES.O)
public void createNotificationChannels() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
createServiceChannel();
createRemindChannel();
}
}
@RequiresApi(api = Build.VERSION_CODES.O)
private void createServiceChannel() {
NotificationChannel channel = new NotificationChannel(
_mszChannelIDService,
_mszChannelNameService,
NotificationManager.IMPORTANCE_LOW
);
channel.setDescription("Background service updates");
channel.setSound(null, null);
channel.enableVibration(false);
mNotificationManager.createNotificationChannel(channel);
}
@RequiresApi(api = Build.VERSION_CODES.O)
private void createRemindChannel() {
NotificationChannel channel = new NotificationChannel(
_mszChannelIDRemind,
_mszChannelNameRemind,
NotificationManager.IMPORTANCE_HIGH
);
channel.setDescription("Critical reminders");
channel.setSound(RingtoneManager.getDefaultUri(RingtoneManager.TYPE_ALARM), null);
channel.enableVibration(true);
channel.setVibrationPattern(new long[]{100, 200, 300, 400});
channel.setBypassDnd(true);
channel.setLockscreenVisibility(Notification.VISIBILITY_PUBLIC);
mNotificationManager.createNotificationChannel(channel);
public void createNotificationChannel() {
NotificationChannel channel1 = new NotificationChannel(_mszChannelIDService, _mszChannelNameService, NotificationManager.IMPORTANCE_DEFAULT);
channel1.setSound(null, null);
mNotificationManager.createNotificationChannel(channel1);
NotificationChannel channel2 = new NotificationChannel(_mszChannelIDRemind, _mszChannelNameRemind, NotificationManager.IMPORTANCE_HIGH);
channel2.setSound(RingtoneManager.getDefaultUri(RingtoneManager.TYPE_RINGTONE), Notification.AUDIO_ATTRIBUTES_DEFAULT);
mNotificationManager.createNotificationChannel(channel2);
}
// 创建并发送服务通知

View File

@@ -1,11 +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:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/ll_notification">
</LinearLayout>

View File

@@ -1,17 +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:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/ll_notification">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Text"
android:id="@+id/info_tv"/>
</LinearLayout>