实现磁贴启动服务功能

This commit is contained in:
ZhanGSKen 2025-02-15 11:30:20 +08:00
parent 825dfb944e
commit 8d2b325172
7 changed files with 145 additions and 39 deletions

View File

@ -1,8 +1,8 @@
#Created by .winboll/winboll_app_build.gradle #Created by .winboll/winboll_app_build.gradle
#Fri Feb 14 13:15:46 GMT 2025 #Sat Feb 15 03:29:17 GMT 2025
stageCount=2 stageCount=2
libraryProject=libappbase libraryProject=libappbase
baseVersion=1.5 baseVersion=1.5
publishVersion=1.5.1 publishVersion=1.5.1
buildCount=41 buildCount=91
baseBetaVersion=1.5.2 baseBetaVersion=1.5.2

View File

@ -45,12 +45,12 @@
</service> </service>
<service
<service android:name=".services.MainService" android:name=".services.MainService"
android:exported="true"/> android:exported="true"/>
<service android:name=".services.AssistantService"/> <service android:name=".services.AssistantService"/>
<receiver android:name="cc.winboll.studio.appbase.receivers.MainReceiver"> <receiver android:name="cc.winboll.studio.appbase.receivers.MainReceiver">
<intent-filter> <intent-filter>
@ -60,7 +60,7 @@
</intent-filter> </intent-filter>
</receiver> </receiver>
<meta-data <meta-data
android:name="android.max_aspect" android:name="android.max_aspect"
android:value="4.0"/> android:value="4.0"/>

View File

@ -4,41 +4,73 @@ package cc.winboll.studio.appbase;
* @Author ZhanGSKen@AliYun.Com * @Author ZhanGSKen@AliYun.Com
* @Date 2025/02/13 19:30:10 * @Date 2025/02/13 19:30:10
*/ */
import android.app.PendingIntent; import android.content.Context;
import android.content.Intent;
import android.os.Build;
import android.service.quicksettings.Tile; import android.service.quicksettings.Tile;
import android.service.quicksettings.TileService; import android.service.quicksettings.TileService;
import android.widget.Toast; import cc.winboll.studio.appbase.beans.MainServiceBean;
import cc.winboll.studio.appbase.services.MainService;
public class MyTileService extends TileService { public class MyTileService extends TileService {
public static final String TAG = "MyTileService";
volatile static MyTileService _MyTileService;
@Override @Override
public void onStartListening() { public void onStartListening() {
super.onStartListening(); super.onStartListening();
_MyTileService = this;
Tile tile = getQsTile(); Tile tile = getQsTile();
tile.setState(Tile.STATE_INACTIVE); MainServiceBean bean = MainServiceBean.loadBean(this, MainServiceBean.class);
tile.setLabel(getString(R.string.tileservice_name)); if (bean != null && bean.isEnable()) {
tile.setIcon(android.graphics.drawable.Icon.createWithResource(this, R.drawable.ic_cloud_outline)); //MainService.startMainService(context);
tile.setState(Tile.STATE_ACTIVE);
tile.setIcon(android.graphics.drawable.Icon.createWithResource(this, R.drawable.ic_cloud));
} else {
//MainService.stopMainService(context);
tile.setState(Tile.STATE_INACTIVE);
tile.setIcon(android.graphics.drawable.Icon.createWithResource(this, R.drawable.ic_cloud_outline));
}
tile.updateTile(); tile.updateTile();
// Tile tile = getQsTile();
// tile.setState(Tile.STATE_INACTIVE);
// tile.setLabel(getString(R.string.tileservice_name));
// tile.setIcon(android.graphics.drawable.Icon.createWithResource(this, R.drawable.ic_cloud_outline));
// tile.updateTile();
} }
@Override @Override
public void onClick() { public void onClick() {
super.onClick(); super.onClick();
Toast.makeText(this, "磁贴被点击", Toast.LENGTH_SHORT).show(); MainServiceBean bean = MainServiceBean.loadBean(this, MainServiceBean.class);
Tile tile = getQsTile(); if (bean == null) {
if (tile.getState() == Tile.STATE_INACTIVE) { bean = new MainServiceBean();
tile.setState(Tile.STATE_ACTIVE); bean.setIsEnable(true);
tile.setIcon(android.graphics.drawable.Icon.createWithResource(this, R.drawable.ic_cloud)); MainServiceBean.saveBean(this, bean);
MainService.startMainService(this);
} else {
if (bean.isEnable()) {
MainService.stopMainService(this);
} else {
MainService.startMainService(this);
}
}
}
public static void updateServiceIconStatus(Context context) {
if (_MyTileService == null) {
return;
}
Tile tile = _MyTileService.getQsTile();
MainServiceBean bean = MainServiceBean.loadBean(context, MainServiceBean.class);
if (bean != null && bean.isEnable()) {
tile.setState(Tile.STATE_ACTIVE);
tile.setIcon(android.graphics.drawable.Icon.createWithResource(context, R.drawable.ic_cloud));
} else { } else {
tile.setState(Tile.STATE_INACTIVE); tile.setState(Tile.STATE_INACTIVE);
tile.setIcon(android.graphics.drawable.Icon.createWithResource(this, R.drawable.ic_cloud_outline)); tile.setIcon(android.graphics.drawable.Icon.createWithResource(context, R.drawable.ic_cloud_outline));
} }
tile.updateTile(); tile.updateTile();
} }
} }

View File

@ -15,6 +15,7 @@ import cc.winboll.studio.appbase.beans.MainServiceBean;
import cc.winboll.studio.appbase.services.AssistantService; import cc.winboll.studio.appbase.services.AssistantService;
import cc.winboll.studio.appbase.services.MainService; import cc.winboll.studio.appbase.services.MainService;
import cc.winboll.studio.libappbase.LogUtils; import cc.winboll.studio.libappbase.LogUtils;
import android.os.Binder;
public class AssistantService extends Service { public class AssistantService extends Service {
@ -22,11 +23,23 @@ public class AssistantService extends Service {
MainServiceBean mMainServiceBean; MainServiceBean mMainServiceBean;
MyServiceConnection mMyServiceConnection; MyServiceConnection mMyServiceConnection;
volatile boolean mIsThreadAlive; MainService mMainService;
boolean isBound = false;
volatile boolean isThreadAlive = false;
public synchronized void setIsThreadAlive(boolean isThreadAlive) {
LogUtils.d(TAG, "setIsThreadAlive(...)");
LogUtils.d(TAG, String.format("isThreadAlive %s", isThreadAlive));
this.isThreadAlive = isThreadAlive;
}
public boolean isThreadAlive() {
return isThreadAlive;
}
@Override @Override
public IBinder onBind(Intent intent) { public IBinder onBind(Intent intent) {
return null; return new MyBinder();
} }
@Override @Override
@ -39,7 +52,7 @@ public class AssistantService extends Service {
mMyServiceConnection = new MyServiceConnection(); mMyServiceConnection = new MyServiceConnection();
} }
// 设置运行参数 // 设置运行参数
mIsThreadAlive = false; setIsThreadAlive(false);
assistantService(); assistantService();
} }
@ -53,7 +66,12 @@ public class AssistantService extends Service {
@Override @Override
public void onDestroy() { public void onDestroy() {
//LogUtils.d(TAG, "onDestroy"); //LogUtils.d(TAG, "onDestroy");
mIsThreadAlive = false; setIsThreadAlive(false);
// 解除绑定
if (isBound) {
unbindService(mMyServiceConnection);
isBound = false;
}
super.onDestroy(); super.onDestroy();
} }
@ -62,10 +80,12 @@ public class AssistantService extends Service {
void assistantService() { void assistantService() {
LogUtils.d(TAG, "assistantService()"); LogUtils.d(TAG, "assistantService()");
mMainServiceBean = MainServiceBean.loadBean(this, MainServiceBean.class); mMainServiceBean = MainServiceBean.loadBean(this, MainServiceBean.class);
LogUtils.d(TAG, String.format("mMainServiceBean.isEnable() %s", mMainServiceBean.isEnable()));
if (mMainServiceBean.isEnable()) { if (mMainServiceBean.isEnable()) {
if (mIsThreadAlive == false) { LogUtils.d(TAG, String.format("mIsThreadAlive %s", isThreadAlive()));
if (isThreadAlive() == false) {
// 设置运行状态 // 设置运行状态
mIsThreadAlive = true; setIsThreadAlive(true);
// 唤醒和绑定主进程 // 唤醒和绑定主进程
wakeupAndBindMain(); wakeupAndBindMain();
} }
@ -76,8 +96,13 @@ public class AssistantService extends Service {
// //
void wakeupAndBindMain() { void wakeupAndBindMain() {
LogUtils.d(TAG, "wakeupAndBindMain()"); LogUtils.d(TAG, "wakeupAndBindMain()");
// 绑定服务的Intent
Intent intent = new Intent(this, MainService.class);
startService(new Intent(this, MainService.class)); startService(new Intent(this, MainService.class));
bindService(new Intent(AssistantService.this, MainService.class), mMyServiceConnection, Context.BIND_IMPORTANT); bindService(intent, mMyServiceConnection, Context.BIND_IMPORTANT);
// startService(new Intent(this, MainService.class));
// bindService(new Intent(AssistantService.this, MainService.class), mMyServiceConnection, Context.BIND_IMPORTANT);
} }
// 主进程与守护进程连接时需要用到此类 // 主进程与守护进程连接时需要用到此类
@ -86,6 +111,9 @@ public class AssistantService extends Service {
@Override @Override
public void onServiceConnected(ComponentName name, IBinder service) { public void onServiceConnected(ComponentName name, IBinder service) {
LogUtils.d(TAG, "onServiceConnected(...)"); LogUtils.d(TAG, "onServiceConnected(...)");
MainService.MyBinder binder = (MainService.MyBinder) service;
mMainService = binder.getService();
isBound = true;
} }
@Override @Override
@ -95,6 +123,16 @@ public class AssistantService extends Service {
if (mMainServiceBean.isEnable()) { if (mMainServiceBean.isEnable()) {
wakeupAndBindMain(); wakeupAndBindMain();
} }
isBound = false;
mMainService = null;
}
}
// 用于返回服务实例的Binder
public class MyBinder extends Binder {
AssistantService getService() {
LogUtils.d(TAG, "AssistantService MyBinder getService()");
return AssistantService.this;
} }
} }
} }

View File

@ -15,6 +15,7 @@ import android.content.ComponentName;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.content.ServiceConnection; import android.content.ServiceConnection;
import android.os.Binder;
import android.os.IBinder; import android.os.IBinder;
import cc.winboll.studio.appbase.beans.MainServiceBean; import cc.winboll.studio.appbase.beans.MainServiceBean;
import cc.winboll.studio.appbase.handlers.MainServiceHandler; import cc.winboll.studio.appbase.handlers.MainServiceHandler;
@ -22,8 +23,7 @@ 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.libappbase.LogUtils; import cc.winboll.studio.libappbase.LogUtils;
import cc.winboll.studio.libappbase.SOS; import cc.winboll.studio.appbase.MyTileService;
import com.hjq.toast.ToastUtils;
public class MainService extends Service { public class MainService extends Service {
@ -39,11 +39,13 @@ public class MainService extends Service {
MainServiceThread mMainServiceThread; MainServiceThread mMainServiceThread;
MainServiceHandler mMainServiceHandler; MainServiceHandler mMainServiceHandler;
MyServiceConnection mMyServiceConnection; MyServiceConnection mMyServiceConnection;
AssistantService mAssistantService;
boolean isBound = false;
MainReceiver mMainReceiver; MainReceiver mMainReceiver;
@Override @Override
public IBinder onBind(Intent intent) { public IBinder onBind(Intent intent) {
return null; return new MyBinder();
} }
public MainServiceThread getRemindThread() { public MainServiceThread getRemindThread() {
@ -92,6 +94,9 @@ public class MainService extends Service {
mMainReceiver.registerAction(this); mMainReceiver.registerAction(this);
} }
startMainServiceThread(); startMainServiceThread();
MyTileService.updateServiceIconStatus(this);
LogUtils.i(TAG, "Main Service Is Start."); LogUtils.i(TAG, "Main Service Is Start.");
} }
} }
@ -107,8 +112,14 @@ public class MainService extends Service {
// } // }
Intent intent = new Intent(this, AssistantService.class); Intent intent = new Intent(this, AssistantService.class);
startService(intent); startService(intent);
LogUtils.d(TAG, "startService(intent)"); // 绑定服务的Intent
bindService(new Intent(this, AssistantService.class), mMyServiceConnection, Context.BIND_IMPORTANT); //Intent intent = new Intent(this, AssistantService.class);
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);
} }
// 开启提醒铃声线程 // 开启提醒铃声线程
@ -144,7 +155,11 @@ public class MainService extends Service {
mMainServiceBean = MainServiceBean.loadBean(this, MainServiceBean.class); mMainServiceBean = MainServiceBean.loadBean(this, MainServiceBean.class);
if (mMainServiceBean.isEnable() == false) { if (mMainServiceBean.isEnable() == false) {
// 设置运行状态 // 设置运行状态
isServiceRunning = false; isServiceRunning = false;// 解除绑定
if (isBound) {
unbindService(mMyServiceConnection);
isBound = false;
}
// 停止守护进程 // 停止守护进程
Intent intent = new Intent(this, AssistantService.class); Intent intent = new Intent(this, AssistantService.class);
stopService(intent); stopService(intent);
@ -157,6 +172,9 @@ public class MainService extends Service {
stopForeground(true); stopForeground(true);
// 停止消息提醒进程 // 停止消息提醒进程
stopRemindThread(); stopRemindThread();
MyTileService.updateServiceIconStatus(this);
super.onDestroy(); super.onDestroy();
//LogUtils.d(TAG, "onDestroy done"); //LogUtils.d(TAG, "onDestroy done");
} }
@ -168,15 +186,31 @@ public class MainService extends Service {
@Override @Override
public void onServiceConnected(ComponentName name, IBinder service) { public void onServiceConnected(ComponentName name, IBinder service) {
LogUtils.d(TAG, "onServiceConnected(...)"); LogUtils.d(TAG, "onServiceConnected(...)");
AssistantService.MyBinder binder = (AssistantService.MyBinder) service;
mAssistantService = binder.getService();
isBound = true;
} }
@Override @Override
public void onServiceDisconnected(ComponentName name) { public void onServiceDisconnected(ComponentName name) {
LogUtils.d(TAG, "onServiceDisconnected(...)"); LogUtils.d(TAG, "onServiceDisconnected(...)");
if (mMainServiceBean.isEnable()) { if (mMainServiceBean.isEnable()) {
// 唤醒守护进程 // 唤醒守护进程
wakeupAndBindAssistant(); wakeupAndBindAssistant();
} }
isBound = false;
mAssistantService = null;
}
}
// 用于返回服务实例的Binder
public class MyBinder extends Binder {
MainService getService() {
LogUtils.d(TAG, "MainService MyBinder getService()");
return MainService.this;
} }
} }

View File

@ -7,6 +7,7 @@ package cc.winboll.studio.appbase.threads;
import android.content.Context; import android.content.Context;
import cc.winboll.studio.appbase.handlers.MainServiceHandler; import cc.winboll.studio.appbase.handlers.MainServiceHandler;
import cc.winboll.studio.libappbase.LogUtils; import cc.winboll.studio.libappbase.LogUtils;
import com.hjq.toast.ToastUtils;
import java.lang.ref.WeakReference; import java.lang.ref.WeakReference;
public class MainServiceThread extends Thread { public class MainServiceThread extends Thread {
@ -38,9 +39,10 @@ public class MainServiceThread extends Thread {
public void run() { public void run() {
LogUtils.d(TAG, "run()"); LogUtils.d(TAG, "run()");
while (!isExist()) { while (!isExist()) {
//ToastUtils.show("run()");
//LogUtils.d(TAG, "run()"); //LogUtils.d(TAG, "run()");
try { try {
Thread.sleep(1000); Thread.sleep(3000);
} catch (InterruptedException e) { } catch (InterruptedException e) {
LogUtils.d(TAG, e, Thread.currentThread().getStackTrace()); LogUtils.d(TAG, e, Thread.currentThread().getStackTrace());
} }

View File

@ -1,8 +1,8 @@
#Created by .winboll/winboll_app_build.gradle #Created by .winboll/winboll_app_build.gradle
#Fri Feb 14 13:15:46 GMT 2025 #Sat Feb 15 03:29:17 GMT 2025
stageCount=2 stageCount=2
libraryProject=libappbase libraryProject=libappbase
baseVersion=1.5 baseVersion=1.5
publishVersion=1.5.1 publishVersion=1.5.1
buildCount=41 buildCount=91
baseBetaVersion=1.5.2 baseBetaVersion=1.5.2