重构主应用架构

This commit is contained in:
ZhanGSKen 2025-02-19 03:17:49 +08:00
parent c226a92ffe
commit e7c614ebec
31 changed files with 861 additions and 421 deletions

View File

@ -1,8 +1,8 @@
#Created by .winboll/winboll_app_build.gradle
#Mon Feb 17 12:10:03 HKT 2025
#Tue Feb 18 19:15:30 GMT 2025
stageCount=3
libraryProject=libappbase
baseVersion=1.5
publishVersion=1.5.2
buildCount=0
buildCount=58
baseBetaVersion=1.5.3

View File

@ -61,12 +61,38 @@
</receiver>
<receiver
android:name=".widgets.SOSWidget"
android:exported="true">
<intent-filter>
<action android:name="cc.winboll.studio.appbase.widgets.SOSWidget.ACTION_SOS"/>
<action android:name="cc.winboll.studio.appbase.widgets.SOSWidget.ACTION_RELOAD_REPORT" />
<action android:name="android.appwidget.action.APPWIDGET_UPDATE"/>
</intent-filter>
<meta-data
android:name="android.appwidget.provider"
android:resource="@xml/widget_provider_info_sos"/>
</receiver>
<receiver android:name=".widgets.SOSWidgetClickListener">
<intent-filter>
<action android:name="cc.winboll.studio.appbase.widgets.SOSWidgetClickListener.ACTION_PRE"/>
<action android:name="cc.winboll.studio.appbase.widgets.SOSWidgetClickListener.ACTION_NEXT"/>
</intent-filter>
</receiver>
<meta-data
android:name="android.max_aspect"
android:value="4.0"/>
<service android:name="cc.winboll.studio.appbase.services.TestService"
android:exported="true"/>
</application>

View File

@ -9,15 +9,15 @@ import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;
import cc.winboll.studio.appbase.R;
import cc.winboll.studio.appbase.services.MainService;
import cc.winboll.studio.appbase.services.TestService;
import cc.winboll.studio.libappbase.GlobalApplication;
import cc.winboll.studio.libappbase.LogUtils;
import cc.winboll.studio.libappbase.LogView;
import cc.winboll.studio.libappbase.SOS;
import cc.winboll.studio.libappbase.SimpleOperateSignalCenterService;
import cc.winboll.studio.libappbase.widgets.APPSOSReportWidget;
import com.hjq.toast.ToastUtils;
import cc.winboll.studio.libappbase.bean.APPSOSBean;
import cc.winboll.studio.libappbase.services.TestService;
import cc.winboll.studio.libappbase.widgets.StatusWidget;
import com.hjq.toast.ToastUtils;
public class MainActivity extends AppCompatActivity {
@ -41,6 +41,14 @@ public class MainActivity extends AppCompatActivity {
if (GlobalApplication.isDebuging()) { mLogView.start(); }
}
@Override
protected void onDestroy() {
super.onDestroy();
Intent intentAPPWidget = new Intent(this, StatusWidget.class);
intentAPPWidget.setAction(StatusWidget.ACTION_STATUS_UPDATE);
sendBroadcast(intentAPPWidget);
}
@Override
protected void onResume() {
LogUtils.d(TAG, "onResume");
@ -83,39 +91,23 @@ public class MainActivity extends AppCompatActivity {
Intent intent = new Intent(this, TestService.class);
stopService(intent);
SOS.sosWinBollService(this, new APPSOSBean(getPackageName(), TestService.class.getName()));
// Intent intentTimeWidget = new Intent(this, TimeWidget.class);
// intentTimeWidget.setAction(TimeWidget.UPDATE_TIME_ACTION);
// intentTimeWidget.putExtra("appName", "TestName");
// sendBroadcast(intentTimeWidget);
//
}
// public void sos() {
// // 创建Intent对象指定广播的action
// Intent intent = new Intent(SOSCSBroadcastReceiver.ACTION_SOS);
// // 目标服务的包名和类名
// String packageName = this.getPackageName();
// String serviceClassName = SimpleOperateSignalCenterService.class.getName();
// intent.putExtra(ISOSAPP.EXTRA_PACKAGE, packageName);
// intent.putExtra(ISOSAPP.EXTRA_SERVICE, serviceClassName);
// // 发送广播
// sendBroadcast(intent);
// LogUtils.d(TAG, "onSOS");
// }
//
// public void sos2() {
// // 创建Intent对象指定广播的action
// Intent intent = new Intent(SOSCSBroadcastReceiver.ACTION_SOS);
// // 目标服务的包名和类名
// String packageName = this.getPackageName();
// String serviceClassName = SimpleOperateSignalCenterService.class.getName();
// intent.putExtra(ISOSAPP.EXTRA_PACKAGE, packageName);
// intent.putExtra(ISOSAPP.EXTRA_SERVICE, serviceClassName);
// // 发送广播
// sendBroadcast(intent);
// LogUtils.d(TAG, "onSOS2");
// }
public void onStartTestService(View view) {
Intent intent = new Intent(this, TestService.class);
startService(intent);
}
public void onStopTestService(View view) {
Intent intent = new Intent(this, TestService.class);
stopService(intent);
}
public void onUpdateAPPWidget(View view) {
Intent intentAPPWidget = new Intent(this, StatusWidget.class);
intentAPPWidget.setAction(StatusWidget.ACTION_STATUS_UPDATE);
sendBroadcast(intentAPPWidget);
}
}

View File

@ -1,4 +1,4 @@
package cc.winboll.studio.libappbase.bean;
package cc.winboll.studio.appbase.beans;
/**
* @Author ZhanGSKen@AliYun.Com
@ -10,17 +10,17 @@ import android.util.JsonWriter;
import cc.winboll.studio.libappbase.BaseBean;
import java.io.IOException;
public class APPSOSReportBean extends BaseBean {
public class SOSReportBean extends BaseBean {
public static final String TAG = "APPSOSReportBean";
protected String sosReport;
public APPSOSReportBean() {
public SOSReportBean() {
this.sosReport = "";
}
public APPSOSReportBean(String sosReport) {
public SOSReportBean(String sosReport) {
this.sosReport = sosReport;
}
@ -34,7 +34,7 @@ public class APPSOSReportBean extends BaseBean {
@Override
public String getName() {
return APPSOSReportBean.class.getName();
return SOSReportBean.class.getName();
}
@Override

View File

@ -24,7 +24,7 @@ import cc.winboll.studio.appbase.receivers.MainReceiver;
import cc.winboll.studio.appbase.services.AssistantService;
import cc.winboll.studio.appbase.threads.MainServiceThread;
import cc.winboll.studio.libappbase.LogUtils;
import cc.winboll.studio.libappbase.widgets.APPSOSReportWidget;
import cc.winboll.studio.appbase.widgets.SOSWidget;
public class MainService extends Service {
@ -96,8 +96,8 @@ public class MainService extends Service {
}
// 启动小部件
Intent intentTimeWidget = new Intent(this, APPSOSReportWidget.class);
intentTimeWidget.setAction(APPSOSReportWidget.ACTION_RELOAD_SOS_REPORT);
Intent intentTimeWidget = new Intent(this, SOSWidget.class);
intentTimeWidget.setAction(SOSWidget.ACTION_RELOAD_REPORT);
this.sendBroadcast(intentTimeWidget);
startMainServiceThread();

View File

@ -1,42 +1,3 @@
package cc.winboll.studio.appbase.services;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import cc.winboll.studio.libappbase.LogUtils;
/**
* @Author ZhanGSKen@AliYun.Com
* @Date 2025/02/15 20:48:36
* @Describe TestService
*/
public class TestService extends Service {
public static final String TAG = "TestService";
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public void onCreate() {
super.onCreate();
LogUtils.d(TAG, "onCreate()");
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
LogUtils.d(TAG, "onStartCommand(...)");
return super.onStartCommand(intent, flags, startId);
}
@Override
public void onDestroy() {
super.onDestroy();
LogUtils.d(TAG, "onDestroy()");
}
}

View File

@ -0,0 +1,192 @@
package cc.winboll.studio.appbase.widgets;
/**
* @Author ZhanGSKen@AliYun.Com
* @Date 2025/02/15 14:41:25
* @Describe TimeWidget
*/
import android.app.PendingIntent;
import android.appwidget.AppWidgetManager;
import android.appwidget.AppWidgetProvider;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.widget.RemoteViews;
import cc.winboll.studio.appbase.R;
import cc.winboll.studio.appbase.beans.SOSReportBean;
import cc.winboll.studio.libappbase.AppUtils;
import cc.winboll.studio.libappbase.LogUtils;
import cc.winboll.studio.libappbase.bean.APPSOSBean;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
public class SOSWidget extends AppWidgetProvider {
public static final String TAG = "SOSWidget";
public static final String ACTION_SOS = "cc.winboll.studio.appbase.widgets.SOSWidget.ACTION_SOS";
public static final String ACTION_RELOAD_REPORT = "cc.winboll.studio.appbase.widgets.SOSWidget.ACTION_RELOAD_REPORT";
volatile static ArrayList<SOSReportBean> _SOSReportBeanList;
final static int _MAX_PAGES = 10;
final static int _OnePageLinesCount = 5;
volatile static int _CurrentPageIndex = 0;
@Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
initAPPSOSReportBeanList(context);
for (int appWidgetId : appWidgetIds) {
updateAppWidget(context, appWidgetManager, appWidgetId);
}
}
@Override
public void onReceive(Context context, Intent intent) {
super.onReceive(context, intent);
initAPPSOSReportBeanList(context);
if (intent.getAction().equals(ACTION_SOS)) {
LogUtils.d(TAG, "ACTION_SOS");
LogUtils.d(TAG, String.format("context.getPackageName() %s", context.getPackageName()));
LogUtils.d(TAG, String.format("intent.getAction() %s", intent.getAction()));
String SOS = intent.getStringExtra("SOS");
LogUtils.d(TAG, String.format("SOS %s", SOS));
if (SOS != null && SOS.equals("Service")) {
String szAPPSOSBean = intent.getStringExtra("APPSOSBean");
LogUtils.d(TAG, String.format("szAPPSOSBean %s", szAPPSOSBean));
if (szAPPSOSBean != null && !szAPPSOSBean.equals("")) {
try {
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();
intentService.setComponent(new ComponentName(sosPackage, sosClassName));
context.startService(intentService);
String appName = AppUtils.getAppNameByPackageName(context, sosPackage);
LogUtils.d(TAG, String.format("appName %s", appName));
SOSReportBean appSOSReportBean = new SOSReportBean(appName);
SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss");
String currentTime = sdf.format(new Date());
StringBuilder sbLine = new StringBuilder();
sbLine.append("[");
sbLine.append(currentTime);
sbLine.append("] Power to ");
sbLine.append(appName);
appSOSReportBean.setSosReport(sbLine.toString());
addAPPSOSReportBean(context, appSOSReportBean);
AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context);
int[] appWidgetIds = appWidgetManager.getAppWidgetIds(new ComponentName(context, SOSWidget.class));
for (int appWidgetId : appWidgetIds) {
updateAppWidget(context, appWidgetManager, appWidgetId);
}
}
} catch (IOException e) {
LogUtils.d(TAG, e, Thread.currentThread().getStackTrace());
}
}
}
} else if (intent.getAction().equals(ACTION_RELOAD_REPORT)) {
LogUtils.d(TAG, "ACTION_RELOAD_REPORT");
AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context);
int[] appWidgetIds = appWidgetManager.getAppWidgetIds(new ComponentName(context, SOSWidget.class));
for (int appWidgetId : appWidgetIds) {
updateAppWidget(context, appWidgetManager, appWidgetId);
}
}
}
//
// 加入新报告信息
//
void addAPPSOSReportBean(Context context, SOSReportBean bean) {
initAPPSOSReportBeanList(context);
_SOSReportBeanList.add(0, bean);
// 控制记录总数
while (_SOSReportBeanList.size() > _MAX_PAGES * _OnePageLinesCount) {
_SOSReportBeanList.remove(_SOSReportBeanList.size() - 1);
}
SOSReportBean.saveBeanList(context, _SOSReportBeanList, SOSReportBean.class);
}
void initAPPSOSReportBeanList(Context context) {
if (_SOSReportBeanList == null) {
_SOSReportBeanList = new ArrayList<SOSReportBean>();
SOSReportBean.loadBeanList(context, _SOSReportBeanList, SOSReportBean.class);
}
if (_SOSReportBeanList == null) {
_SOSReportBeanList = new ArrayList<SOSReportBean>();
SOSReportBean.saveBeanList(context, _SOSReportBeanList, SOSReportBean.class);
}
}
private void updateAppWidget(Context context, AppWidgetManager appWidgetManager, int appWidgetId) {
LogUtils.d(TAG, "updateAppWidget(...)");
RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.widget_sos);
//设置按钮点击事件
Intent intentPre = new Intent(context, SOSWidgetClickListener.class);
intentPre.setAction(SOSWidgetClickListener.ACTION_PRE);
PendingIntent pendingIntentPre = PendingIntent.getBroadcast(context, 0, intentPre, PendingIntent.FLAG_UPDATE_CURRENT);
views.setOnClickPendingIntent(R.id.widget_button_pre, pendingIntentPre);
Intent intentNext = new Intent(context, SOSWidgetClickListener.class);
intentNext.setAction(SOSWidgetClickListener.ACTION_NEXT);
PendingIntent pendingIntentNext = PendingIntent.getBroadcast(context, 0, intentNext, PendingIntent.FLAG_UPDATE_CURRENT);
views.setOnClickPendingIntent(R.id.widget_button_next, pendingIntentNext);
views.setTextViewText(R.id.infoTextView, getPageInfo());
views.setTextViewText(R.id.sosReportTextView, getMessage());
appWidgetManager.updateAppWidget(appWidgetId, views);
}
public static String getMessage() {
ArrayList<String> msgTemp = new ArrayList<String>();
if (_SOSReportBeanList != null) {
int start = _OnePageLinesCount * _CurrentPageIndex;
start = _SOSReportBeanList.size() > start ? start : _SOSReportBeanList.size() - 1;
for (int i = start, j = 0; i < _SOSReportBeanList.size() && j < _OnePageLinesCount; i++, j++) {
msgTemp.add(_SOSReportBeanList.get(i).getSosReport());
}
String message = String.join("\n", msgTemp);
return message;
}
return "";
}
public static void prePage(Context context) {
if (_SOSReportBeanList != null) {
if (_CurrentPageIndex > 0) {
_CurrentPageIndex = _CurrentPageIndex - 1;
}
Intent intentWidget = new Intent(context, SOSWidget.class);
intentWidget.setAction(SOSWidget.ACTION_RELOAD_REPORT);
context.sendBroadcast(intentWidget);
}
}
public static void nextPage(Context context) {
if (_SOSReportBeanList != null) {
if ((_CurrentPageIndex + 1) * _OnePageLinesCount < _SOSReportBeanList.size()) {
_CurrentPageIndex = _CurrentPageIndex + 1;
}
Intent intentWidget = new Intent(context, SOSWidget.class);
intentWidget.setAction(SOSWidget.ACTION_RELOAD_REPORT);
context.sendBroadcast(intentWidget);
}
}
String getPageInfo() {
if (_SOSReportBeanList == null) {
return "0/0";
}
int leftCount = _SOSReportBeanList.size() % _OnePageLinesCount;
int currentPageCount = _SOSReportBeanList.size() / _OnePageLinesCount + (leftCount == 0 ?0: 1);
return String.format("%d/%d", _CurrentPageIndex + 1, currentPageCount);
}
}

View File

@ -1,4 +1,4 @@
package cc.winboll.studio.libappbase.widgets;
package cc.winboll.studio.appbase.widgets;
/**
* @Author ZhanGSKen@AliYun.Com
@ -10,11 +10,11 @@ import android.content.Context;
import android.content.Intent;
import cc.winboll.studio.libappbase.LogUtils;
public class WidgetButtonClickListener extends BroadcastReceiver {
public class SOSWidgetClickListener extends BroadcastReceiver {
public static final String TAG = "WidgetButtonClickListener";
public static final String ACTION_PRE = "cc.winboll.studio.libappbase.widgets.WidgetButtonClickListener.ACTION_PRE";
public static final String ACTION_NEXT = "cc.winboll.studio.libappbase.widgets.WidgetButtonClickListener.ACTION_NEXT";
public static final String TAG = "SOSWidgetClickListener";
public static final String ACTION_PRE = "cc.winboll.studio.appbase.widgets.SOSWidgetClickListener.ACTION_PRE";
public static final String ACTION_NEXT = "cc.winboll.studio.appbase.widgets.SOSWidgetClickListener.ACTION_NEXT";
@Override
public void onReceive(Context context, Intent intent) {
@ -25,10 +25,10 @@ public class WidgetButtonClickListener extends BroadcastReceiver {
}
if (action.equals(ACTION_PRE)) {
LogUtils.d(TAG, "ACTION_PRE");
APPSOSReportWidget.prePage(context);
SOSWidget.prePage(context);
} else if (action.equals(ACTION_NEXT)) {
LogUtils.d(TAG, "ACTION_NEXT");
APPSOSReportWidget.nextPage(context);
SOSWidget.nextPage(context);
} else {
LogUtils.d(TAG, String.format("action %s", action));
}

View File

@ -47,47 +47,88 @@
</LinearLayout>
<LinearLayout
android:orientation="vertical"
<ScrollView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="right">
android:layout_height="400dp">
<Button
android:layout_width="wrap_content"
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="StartCenter"
android:textAllCaps="false"
android:onClick="onStartCenter"/>
android:gravity="right">
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="StopCenter"
android:textAllCaps="false"
android:onClick="onStopCenter"/>
<HorizontalScrollView
android:layout_width="match_parent"
android:layout_height="wrap_content">
<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"/>
<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="SOS"
android:onClick="onSOS"/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="StartTestService"
android:textAllCaps="false"
android:onClick="onStartTestService"/>
</LinearLayout>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="StopTestService"
android:textAllCaps="false"
android:onClick="onStopTestService"/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="UpdateAPPWidget"
android:textAllCaps="false"
android:onClick="onUpdateAPPWidget"/>
</LinearLayout>
</HorizontalScrollView>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="StartCenter"
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>
</ScrollView>
<cc.winboll.studio.libappbase.LogView
android:layout_weight="1.0"

View File

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

View File

@ -3,5 +3,5 @@
android:minWidth="200dp"
android:minHeight="100dp"
android:updatePeriodMillis="1000"
android:initialLayout="@layout/widget_layout">
android:initialLayout="@layout/widget_sos">
</appwidget-provider>

View File

@ -1,8 +1,8 @@
#Created by .winboll/winboll_app_build.gradle
#Mon Feb 17 12:09:50 HKT 2025
#Tue Feb 18 19:15:30 GMT 2025
stageCount=3
libraryProject=libappbase
baseVersion=1.5
publishVersion=1.5.2
buildCount=0
buildCount=58
baseBetaVersion=1.5.3

View File

@ -6,6 +6,9 @@
<!-- 拥有完全的网络访问权限 -->
<uses-permission android:name="android.permission.INTERNET"/>
<!-- 发送持久广播 -->
<uses-permission android:name="android.permission.BROADCAST_STICKY"/>
<application>
<activity
@ -18,45 +21,58 @@
android:label="GlobalCrashActivity"
android:launchMode="standard"/>
<service android:name=".SimpleOperateSignalCenterService"
android:exported="true">
</service>
<activity android:name=".LogActivity"/>
<service
android:name=".SimpleOperateSignalCenterService"
android:exported="true">
</service>
<service
android:name=".services.TestService"
android:exported="true"/>
<receiver android:name=".receiver.MyBroadcastReceiver">
<intent-filter>
<action android:name="cc.winboll.studio.libappbase.action.SOS" />
</intent-filter>
</receiver>
<receiver android:name="cc.winboll.studio.libappbase.receiver.WinBollReceiver"
android:exported="true">
<intent-filter>
<action android:name="cc.winboll.studio.libappbase.WinBoll.ACTION_SOS"/>
<action android:name="cc.winboll.studio.libappbase.action.SOS"/>
</intent-filter>
</receiver>
<receiver android:name=".widgets.APPSOSReportWidget"
<receiver
android:name=".widgets.StatusWidget"
android:exported="true">
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
<action android:name="cc.winboll.studio.libappbase.widgets.APPSOSReportWidget.ACTION_ADD_SOS_REPORT" />
<action android:name="android.appwidget.action.APPWIDGET_UPDATE"/>
<action android:name="cc.winboll.studio.libappbase.widgets.StatusWidget.ACTION_STATUS_UPDATE"/>
</intent-filter>
<meta-data
android:name="android.appwidget.provider"
android:resource="@xml/appwidget_provider_info" />
android:resource="@xml/widget_provider_info_status"/>
</receiver>
<receiver android:name=".widgets.WidgetButtonClickListener">
<receiver
android:name=".widgets.StatusWidgetClickListener"
android:exported="true">
<intent-filter>
<action android:name="cc.winboll.studio.libappbase.widgets.WidgetButtonClickListener.ACTION_PRE" />
<action android:name="cc.winboll.studio.libappbase.widgets.WidgetButtonClickListener.ACTION_NEXT" />
<action android:name="cc.winboll.studio.libappbase.widgets.StatusWidgetClickListener.ACTION_IVAPP"/>
</intent-filter>
</receiver>
</application>
</manifest>

View File

@ -12,7 +12,8 @@ import cc.winboll.studio.libappbase.bean.APPSOSBean;
public class SOS {
public static final String TAG = "SOS";
public static final String ACTION_SOS = "cc.winboll.studio.libappbase.WinBoll.ACTION_SOS";
public static final String ACTION_SOS = "cc.winboll.studio.appbase.widgets.SOSWidget.ACTION_SOS";
public static void sosWinBollService(Context context, APPSOSBean bean) {
Intent intent = new Intent(ACTION_SOS);

View File

@ -1,15 +0,0 @@
package cc.winboll.studio.libappbase;
/**
* @Author ZhanGSKen@AliYun.Com
* @Date 2025/02/15 12:14:45
* @Describe WinBoll
*/
public class WinBoll {
public static final String TAG = "WinBoll";
public static final String ACTION_SOS = WinBoll.class.getName() + ".ACTION_SOS";
}

View File

@ -1,79 +0,0 @@
package cc.winboll.studio.libappbase.receiver;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import cc.winboll.studio.libappbase.LogUtils;
import cc.winboll.studio.libappbase.WinBoll;
import cc.winboll.studio.libappbase.AppUtils;
import cc.winboll.studio.libappbase.widgets.APPSOSReportWidget;
import cc.winboll.studio.libappbase.bean.APPSOSBean;
import java.io.IOException;
import cc.winboll.studio.libappbase.bean.APPSOSReportBean;
import java.text.SimpleDateFormat;
import java.util.Date;
/**
* @Author ZhanGSKen@AliYun.Com
* @Date 2025/02/15 12:17:32
* @Describe WinBollReceiver
*/
public class WinBollReceiver extends BroadcastReceiver {
public static final String TAG = "WinBollReceiver";
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (action.equals(WinBoll.ACTION_SOS)) {
LogUtils.d(TAG, String.format("context.getPackageName() %s", context.getPackageName()));
LogUtils.d(TAG, String.format("action %s", action));
String SOS = intent.getStringExtra("SOS");
LogUtils.d(TAG, String.format("SOS %s", SOS));
if (SOS != null && SOS.equals("Service")) {
String szAPPSOSBean = intent.getStringExtra("APPSOSBean");
LogUtils.d(TAG, String.format("szAPPSOSBean %s", szAPPSOSBean));
if (szAPPSOSBean != null && !szAPPSOSBean.equals("")) {
try {
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();
intentService.setComponent(new ComponentName(sosPackage, sosClassName));
context.startService(intentService);
String appName = AppUtils.getAppNameByPackageName(context, sosPackage);
LogUtils.d(TAG, String.format("appName %s", appName));
APPSOSReportBean appSOSReportBean = new APPSOSReportBean(appName);
SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss");
String currentTime = sdf.format(new Date());
StringBuilder sbLine = new StringBuilder();
sbLine.append("[");
sbLine.append(currentTime);
sbLine.append("] Power to ");
sbLine.append(appName);
appSOSReportBean.setSosReport(sbLine.toString());
Intent intentAPPSOSReportWidget = new Intent(context, APPSOSReportWidget.class);
intentAPPSOSReportWidget.setAction(APPSOSReportWidget.ACTION_ADD_SOS_REPORT);
intentAPPSOSReportWidget.putExtra("APPSOSReportBean", appSOSReportBean.toString());
context.sendBroadcast(intentAPPSOSReportWidget);
}
} catch (IOException e) {
LogUtils.d(TAG, e, Thread.currentThread().getStackTrace());
}
}
}
} else {
LogUtils.d(TAG, String.format("action %s", action));
}
}
}

View File

@ -0,0 +1,93 @@
package cc.winboll.studio.libappbase.services;
/**
* @Author ZhanGSKen@AliYun.Com
* @Date 2025/02/15 20:48:36
* @Describe TestService
*/
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.os.Binder;
import android.os.IBinder;
import cc.winboll.studio.libappbase.LogUtils;
import cc.winboll.studio.libappbase.widgets.StatusWidget;
public class TestService extends Service {
public static final String TAG = "TestService";
TestThread mTestThread;
@Override
public IBinder onBind(Intent intent) {
return new MyBinder();
}
public class MyBinder extends Binder {
public TestService getService() {
return TestService.this;
}
}
@Override
public void onCreate() {
super.onCreate();
LogUtils.d(TAG, "onCreate()");
mTestThread = new TestThread();
mTestThread.start();
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
LogUtils.d(TAG, "onStartCommand(...)");
return super.onStartCommand(intent, flags, startId);
}
@Override
public void onDestroy() {
super.onDestroy();
LogUtils.d(TAG, "onDestroy()");
mTestThread.setIsExit(true);
}
class TestThread extends Thread {
volatile boolean isExit = false;
public void setIsExit(boolean isExit) {
this.isExit = isExit;
}
public boolean isExit() {
return isExit;
}
@Override
public void run() {
super.run();
LogUtils.d(TAG, "run() start");
Intent intentStart = new Intent(TestService.this, StatusWidget.class);
intentStart.setAction(StatusWidget.ACTION_STATUS_UPDATE);
sendBroadcast(intentStart);
while (!isExit) {
//LogUtils.d(TAG, "run()");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
LogUtils.d(TAG, e, Thread.currentThread().getStackTrace());
}
}
Intent intentStop = new Intent(TestService.this, StatusWidget.class);
intentStop.setAction(StatusWidget.ACTION_STATUS_UPDATE);
sendBroadcast(intentStop);
LogUtils.d(TAG, "run() exit");
}
}
}

View File

@ -0,0 +1,48 @@
package cc.winboll.studio.libappbase.utils;
/**
* @Author ZhanGSKen@AliYun.Com
* @Date 2025/02/17 19:38:20
* @Describe 服务工具集
*/
import android.app.ActivityManager;
import android.content.Context;
import android.content.Intent;
import android.os.Build;
import android.util.Log;
import cc.winboll.studio.libappbase.LogUtils;
import java.util.List;
public class ServiceUtils {
public static final String TAG = "ServiceUtils";
/**
* 检查指定服务是否正在运行
* @param context 上下文
* @param serviceClass 服务类
* @return true 如果服务正在运行否则返回 false
*/
public static boolean isServiceRunning(Context context, String serviceClassName) {
ActivityManager activityManager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
if (activityManager == null) {
return false;
}
List<ActivityManager.RunningServiceInfo> runningServices;
// if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
// Intent intent = new Intent(context, serviceClass);
// runningServices = activityManager.getRunningServices(100, intent);
// } else {
runningServices = activityManager.getRunningServices(100);
//}
for (ActivityManager.RunningServiceInfo serviceInfo : runningServices) {
if (serviceClassName.equals(serviceInfo.service.getClassName())) {
LogUtils.d(TAG, "Service is running: " + serviceInfo.service.getClassName());
return true;
}
}
LogUtils.d(TAG, "Service is not running: " + serviceClassName);
return false;
}
}

View File

@ -1,163 +0,0 @@
package cc.winboll.studio.libappbase.widgets;
/**
* @Author ZhanGSKen@AliYun.Com
* @Date 2025/02/15 14:41:25
* @Describe TimeWidget
*/
import android.app.PendingIntent;
import android.appwidget.AppWidgetManager;
import android.appwidget.AppWidgetProvider;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.widget.RemoteViews;
import cc.winboll.studio.libappbase.LogUtils;
import cc.winboll.studio.libappbase.R;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import cc.winboll.studio.libappbase.bean.APPSOSReportBean;
import java.io.IOException;
public class APPSOSReportWidget extends AppWidgetProvider {
public static final String TAG = "APPSOSReportWidget";
public static final String ACTION_ADD_SOS_REPORT = "cc.winboll.studio.libappbase.widgets.APPSOSReportWidget.ACTION_ADD_SOS_REPORT";
public static final String ACTION_RELOAD_SOS_REPORT = "cc.winboll.studio.libappbase.widgets.APPSOSReportWidget.ACTION_RELOAD_SOS_REPORT";
volatile static ArrayList<APPSOSReportBean> _APPSOSReportBeanList;
final static int _MAX_PAGES = 10;
final static int _OnePageLinesCount = 5;
volatile static int _CurrentPageIndex = 0;
@Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
initAPPSOSReportBeanList(context);
for (int appWidgetId : appWidgetIds) {
updateAppWidget(context, appWidgetManager, appWidgetId);
}
}
@Override
public void onReceive(Context context, Intent intent) {
super.onReceive(context, intent);
initAPPSOSReportBeanList(context);
if (intent.getAction().equals(ACTION_ADD_SOS_REPORT)) {
LogUtils.d(TAG, "ACTION_ADD_SOS_REPORT");
String szAPPSOSReportBean = intent.getStringExtra("APPSOSReportBean");
LogUtils.d(TAG, String.format("szAPPSOSBean %s", szAPPSOSReportBean));
if (szAPPSOSReportBean != null && !szAPPSOSReportBean.equals("")) {
try {
APPSOSReportBean bean = APPSOSReportBean.parseStringToBean(szAPPSOSReportBean, APPSOSReportBean.class);
if (bean != null) {
addAPPSOSReportBean(context, bean);
AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context);
int[] appWidgetIds = appWidgetManager.getAppWidgetIds(new ComponentName(context, APPSOSReportWidget.class));
for (int appWidgetId : appWidgetIds) {
updateAppWidget(context, appWidgetManager, appWidgetId);
}
}
} catch (IOException e) {
LogUtils.d(TAG, e, Thread.currentThread().getStackTrace());
}
}
} else if (intent.getAction().equals(ACTION_RELOAD_SOS_REPORT)) {
LogUtils.d(TAG, "ACTION_RELOAD_SOS_REPORT");
AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context);
int[] appWidgetIds = appWidgetManager.getAppWidgetIds(new ComponentName(context, APPSOSReportWidget.class));
for (int appWidgetId : appWidgetIds) {
updateAppWidget(context, appWidgetManager, appWidgetId);
}
}
}
//
// 加入新报告信息
//
void addAPPSOSReportBean(Context context, APPSOSReportBean bean) {
initAPPSOSReportBeanList(context);
_APPSOSReportBeanList.add(0, bean);
// 控制记录总数
while (_APPSOSReportBeanList.size() > _MAX_PAGES * _OnePageLinesCount) {
_APPSOSReportBeanList.remove(_APPSOSReportBeanList.size() - 1);
}
APPSOSReportBean.saveBeanList(context, _APPSOSReportBeanList, APPSOSReportBean.class);
}
void initAPPSOSReportBeanList(Context context) {
if (_APPSOSReportBeanList == null) {
_APPSOSReportBeanList = new ArrayList<APPSOSReportBean>();
APPSOSReportBean.loadBeanList(context, _APPSOSReportBeanList, APPSOSReportBean.class);
}
if (_APPSOSReportBeanList == null) {
_APPSOSReportBeanList = new ArrayList<APPSOSReportBean>();
APPSOSReportBean.saveBeanList(context, _APPSOSReportBeanList, APPSOSReportBean.class);
}
}
private void updateAppWidget(Context context, AppWidgetManager appWidgetManager, int appWidgetId) {
LogUtils.d(TAG, "updateAppWidget(...)");
RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.widget_layout);
//设置按钮点击事件
Intent intentPre = new Intent(context, WidgetButtonClickListener.class);
intentPre.setAction(WidgetButtonClickListener.ACTION_PRE);
PendingIntent pendingIntentPre = PendingIntent.getBroadcast(context, 0, intentPre, PendingIntent.FLAG_UPDATE_CURRENT);
views.setOnClickPendingIntent(R.id.widget_button_pre, pendingIntentPre);
Intent intentNext = new Intent(context, WidgetButtonClickListener.class);
intentNext.setAction(WidgetButtonClickListener.ACTION_NEXT);
PendingIntent pendingIntentNext = PendingIntent.getBroadcast(context, 0, intentNext, PendingIntent.FLAG_UPDATE_CURRENT);
views.setOnClickPendingIntent(R.id.widget_button_next, pendingIntentNext);
views.setTextViewText(R.id.infoTextView, getPageInfo());
views.setTextViewText(R.id.sosReportTextView, getMessage());
appWidgetManager.updateAppWidget(appWidgetId, views);
}
public static String getMessage() {
ArrayList<String> msgTemp = new ArrayList<String>();
if (_APPSOSReportBeanList != null) {
int start = _OnePageLinesCount * _CurrentPageIndex;
start = _APPSOSReportBeanList.size() > start ? start : _APPSOSReportBeanList.size() - 1;
for (int i = start, j = 0; i < _APPSOSReportBeanList.size() && j < _OnePageLinesCount; i++, j++) {
msgTemp.add(_APPSOSReportBeanList.get(i).getSosReport());
}
String message = String.join("\n", msgTemp);
return message;
}
return "";
}
public static void prePage(Context context) {
if (_APPSOSReportBeanList != null) {
if (_CurrentPageIndex > 0) {
_CurrentPageIndex = _CurrentPageIndex - 1;
}
Intent intentAPPSOSReportWidget = new Intent(context, APPSOSReportWidget.class);
intentAPPSOSReportWidget.setAction(APPSOSReportWidget.ACTION_RELOAD_SOS_REPORT);
context.sendBroadcast(intentAPPSOSReportWidget);
}
}
public static void nextPage(Context context) {
if (_APPSOSReportBeanList != null) {
if ((_CurrentPageIndex + 1) * _OnePageLinesCount < _APPSOSReportBeanList.size()) {
_CurrentPageIndex = _CurrentPageIndex + 1;
}
Intent intentAPPSOSReportWidget = new Intent(context, APPSOSReportWidget.class);
intentAPPSOSReportWidget.setAction(APPSOSReportWidget.ACTION_RELOAD_SOS_REPORT);
context.sendBroadcast(intentAPPSOSReportWidget);
}
}
String getPageInfo() {
if (_APPSOSReportBeanList == null) {
return "0/0";
}
int leftCount = _APPSOSReportBeanList.size() % _OnePageLinesCount;
int currentPageCount = _APPSOSReportBeanList.size() / _OnePageLinesCount + (leftCount == 0 ?0: 1);
return String.format("%d/%d", _CurrentPageIndex + 1, currentPageCount);
}
}

View File

@ -0,0 +1,63 @@
package cc.winboll.studio.libappbase.widgets;
/**
* @Author ZhanGSKen@AliYun.Com
* @Date 2025/02/17 20:32:12
*/
import android.app.PendingIntent;
import android.appwidget.AppWidgetManager;
import android.appwidget.AppWidgetProvider;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.widget.RemoteViews;
import cc.winboll.studio.libappbase.LogUtils;
import cc.winboll.studio.libappbase.R;
import cc.winboll.studio.libappbase.utils.ServiceUtils;
import com.hjq.toast.ToastUtils;
import android.content.ServiceConnection;
import android.os.IBinder;
import cc.winboll.studio.libappbase.services.TestService;
public class StatusWidget extends AppWidgetProvider {
public static final String TAG = "StatusWidget";
public static final String ACTION_STATUS_UPDATE = "cc.winboll.studio.libappbase.widgets.APPWidget.ACTION_STATUS_UPDATE";
@Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
for (int appWidgetId : appWidgetIds) {
updateAppWidget(context, appWidgetManager, appWidgetId);
}
}
@Override
public void onReceive(Context context, Intent intent) {
super.onReceive(context, intent);
if (intent.getAction().equals(ACTION_STATUS_UPDATE)) {
AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context);
int[] appWidgetIds = appWidgetManager.getAppWidgetIds(new ComponentName(context, StatusWidget.class));
for (int appWidgetId : appWidgetIds) {
updateAppWidget(context, appWidgetManager, appWidgetId);
}
}
}
private void updateAppWidget(Context context, AppWidgetManager appWidgetManager, int appWidgetId) {
RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.widget_status);
//设置按钮点击事件
Intent intentAppButton = new Intent(context, StatusWidgetClickListener.class);
intentAppButton.setAction(StatusWidgetClickListener.ACTION_IVAPP);
PendingIntent pendingIntentAppButton = PendingIntent.getBroadcast(context, 0, intentAppButton, PendingIntent.FLAG_UPDATE_CURRENT);
views.setOnClickPendingIntent(R.id.ivapp, pendingIntentAppButton);
boolean isActive = ServiceUtils.isServiceRunning(context, TestService.class.getName());
if (isActive) {
views.setImageViewResource(R.id.ivapp, cc.winboll.studio.libappbase.R.drawable.ic_launcher);
} else {
views.setImageViewResource(R.id.ivapp, cc.winboll.studio.libappbase.R.drawable.ic_launcher_disable);
}
appWidgetManager.updateAppWidget(appWidgetId, views);
}
}

View File

@ -0,0 +1,33 @@
package cc.winboll.studio.libappbase.widgets;
/**
* @Author ZhanGSKen@AliYun.Com
* @Date 2025/02/17 20:33:53
* @Describe APPWidgetClickListener
*/
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import cc.winboll.studio.libappbase.LogUtils;
import com.hjq.toast.ToastUtils;
public class StatusWidgetClickListener extends BroadcastReceiver {
public static final String TAG = "APPWidgetClickListener";
public static final String ACTION_IVAPP = "cc.winboll.studio.libappbase.widgets.StatusWidgetClickListener.ACTION_IVAPP";
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (action == null) {
LogUtils.d(TAG, String.format("action %s", action));
return;
}
if (action.equals(ACTION_IVAPP)) {
ToastUtils.show("ACTION_LAUNCHER");
} else {
LogUtils.d(TAG, String.format("action %s", action));
}
}
}

View File

@ -1,11 +1,13 @@
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportHeight="24"
android:viewportWidth="24">
<path
android:fillColor="#ff000000"
android:pathData="M16.61,15.15C16.15,15.15 15.77,14.78 15.77,14.32S16.15,13.5 16.61,13.5H16.61C17.07,13.5 17.45,13.86 17.45,14.32C17.45,14.78 17.07,15.15 16.61,15.15M7.41,15.15C6.95,15.15 6.57,14.78 6.57,14.32C6.57,13.86 6.95,13.5 7.41,13.5H7.41C7.87,13.5 8.24,13.86 8.24,14.32C8.24,14.78 7.87,15.15 7.41,15.15M16.91,10.14L18.58,7.26C18.67,7.09 18.61,6.88 18.45,6.79C18.28,6.69 18.07,6.75 18,6.92L16.29,9.83C14.95,9.22 13.5,8.9 12,8.91C10.47,8.91 9,9.24 7.73,9.82L6.04,6.91C5.95,6.74 5.74,6.68 5.57,6.78C5.4,6.87 5.35,7.08 5.44,7.25L7.1,10.13C4.25,11.69 2.29,14.58 2,18H22C21.72,14.59 19.77,11.7 16.91,10.14H16.91Z"/>
</vector>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android"
android:clickable="true"
android:layout_width="24dp"
android:layout_height="24dp">
<item android:drawable="@drawable/ic_launcher_background"/>
<item
android:left="0dp"
android:top="0dp"
android:right="0dp"
android:bottom="0dp"
android:drawable="@drawable/ic_launcher_foreground"/>
</layer-list>

View 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:viewportWidth="108"
android:viewportHeight="108">
<path
android:fillColor="#FF005C12"
android:pathData="M0,0h108v108h-108z" />
<path
android:fillColor="#00000000"
android:pathData="M9,0L9,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,0L19,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M29,0L29,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M39,0L39,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M49,0L49,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M59,0L59,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M69,0L69,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M79,0L79,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M89,0L89,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M99,0L99,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,9L108,9"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,19L108,19"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,29L108,29"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,39L108,39"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,49L108,49"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,59L108,59"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,69L108,69"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,79L108,79"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,89L108,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,99L108,99"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,29L89,29"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,39L89,39"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,49L89,49"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,59L89,59"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,69L89,69"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,79L89,79"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M29,19L29,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M39,19L39,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M49,19L49,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M59,19L59,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M69,19L69,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M79,19L79,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
</vector>

View File

@ -0,0 +1,13 @@
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android"
android:clickable="true"
android:layout_width="24dp"
android:layout_height="24dp">
<item android:drawable="@drawable/ic_launcher_background"/>
<item
android:left="0dp"
android:top="0dp"
android:right="0dp"
android:bottom="0dp"
android:drawable="@drawable/ic_launcher_foreground_disable"/>
</layer-list>

View File

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportHeight="24"
android:viewportWidth="24">
<path
android:fillColor="#FFFFFFFF"
android:pathData="M16.61,15.15C16.15,15.15 15.77,14.78 15.77,14.32S16.15,13.5 16.61,13.5H16.61C17.07,13.5 17.45,13.86 17.45,14.32C17.45,14.78 17.07,15.15 16.61,15.15M7.41,15.15C6.95,15.15 6.57,14.78 6.57,14.32C6.57,13.86 6.95,13.5 7.41,13.5H7.41C7.87,13.5 8.24,13.86 8.24,14.32C8.24,14.78 7.87,15.15 7.41,15.15M16.91,10.14L18.58,7.26C18.67,7.09 18.61,6.88 18.45,6.79C18.28,6.69 18.07,6.75 18,6.92L16.29,9.83C14.95,9.22 13.5,8.9 12,8.91C10.47,8.91 9,9.24 7.73,9.82L6.04,6.91C5.95,6.74 5.74,6.68 5.57,6.78C5.4,6.87 5.35,7.08 5.44,7.25L7.1,10.13C4.25,11.69 2.29,14.58 2,18H22C21.72,14.59 19.77,11.7 16.91,10.14H16.91Z"/>
</vector>

View File

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportHeight="24"
android:viewportWidth="24">
<path
android:fillColor="#FF808080"
android:pathData="M16.61,15.15C16.15,15.15 15.77,14.78 15.77,14.32S16.15,13.5 16.61,13.5H16.61C17.07,13.5 17.45,13.86 17.45,14.32C17.45,14.78 17.07,15.15 16.61,15.15M7.41,15.15C6.95,15.15 6.57,14.78 6.57,14.32C6.57,13.86 6.95,13.5 7.41,13.5H7.41C7.87,13.5 8.24,13.86 8.24,14.32C8.24,14.78 7.87,15.15 7.41,15.15M16.91,10.14L18.58,7.26C18.67,7.09 18.61,6.88 18.45,6.79C18.28,6.69 18.07,6.75 18,6.92L16.29,9.83C14.95,9.22 13.5,8.9 12,8.91C10.47,8.91 9,9.24 7.73,9.82L6.04,6.91C5.95,6.74 5.74,6.68 5.57,6.78C5.4,6.87 5.35,7.08 5.44,7.25L7.1,10.13C4.25,11.69 2.29,14.58 2,18H22C21.72,14.59 19.77,11.7 16.91,10.14H16.91Z"/>
</vector>

View File

@ -0,0 +1,15 @@
<?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="40dp"
android:layout_height="40dp">
<ImageView
android:layout_width="40dp"
android:layout_height="40dp"
android:id="@+id/ivapp"/>
</LinearLayout>

View File

@ -1,5 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<attr name="attrColorPrimary" format="color" />
<attr name="themeGlobalCrashActivity" format="reference"/>

View File

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

View File

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
android:minWidth="40dp"
android:minHeight="40dp"
android:updatePeriodMillis="1000"
android:initialLayout="@layout/widget_status"
android:resizeMode="none">
</appwidget-provider>