永无止境的后台服务 - Java for Android
Never Ending Background Service - Java for Android
我想让这个服务成为一个永无止境的服务,即使应用程序被用户杀死。该服务随应用程序启动 - 当它在后台时,该服务仍在运行 - 但当我清除 phone 上的后台任务时,它也会被杀死。我希望最后一部分有所不同,希望此服务在设备上保留 运行...这可能吗?感谢帮助
public class BackgroundService extends Service {
public static Runnable runnable = null;
public Context context = this;
public Handler handler = null;
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public void onCreate() {
final PackageManager manager = getPackageManager();
//Packages instalados no dispositivo
List<ApplicationInfo> packages = manager.getInstalledApplications(PackageManager.GET_META_DATA);
for (ApplicationInfo info : packages) {
Log.i("Info", "Installed package:" + info.packageName);
}
for (int i = 0; i < packages.size(); i++) {
if(packages.get(i).sourceDir.startsWith("/data/app/")){
//Non System Apps
Log.i("Info", "Installed package /NON SYSTEM/:" + packages.get(i).packageName);
}else{
//system Apps
Log.i("Info", "Installed package !/SYSTEM/!:" + packages.get(i).packageName);
}}
handler = new Handler();
runnable = new Runnable() {
public void run() {
final ActivityManager am = (ActivityManager) getBaseContext().getSystemService(ACTIVITY_SERVICE);
String currentApp ="";
// The first in the list of RunningTasks is always the foreground task.
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP) {
UsageStatsManager usm = (UsageStatsManager) getSystemService(USAGE_STATS_SERVICE);
long time = System.currentTimeMillis();
List<UsageStats> appList = usm.queryUsageStats(UsageStatsManager.INTERVAL_DAILY,
time - 1000 * 1000, time);
if (appList != null && appList.size() > 0) {
SortedMap<Long, UsageStats> mySortedMap = new TreeMap<Long, UsageStats>();
for (UsageStats usageStats : appList) {
mySortedMap.put(usageStats.getLastTimeUsed(),
usageStats);
}
if (mySortedMap != null && !mySortedMap.isEmpty()) {
currentApp = mySortedMap.get(
mySortedMap.lastKey()).getPackageName();
}
}
} else {
ActivityManager.RunningTaskInfo foregroundTaskInfo = am.getRunningTasks(1).get(0);
currentApp = foregroundTaskInfo.topActivity.getPackageName();
}
boolean ApiLigaIsRunning = false;
if (currentApp.contains("maps")) {
ApiLigaIsRunning = true;
Log.i("CHOOSEN APP IS RUNNING ","YES!!!!!!!!!!! " + currentApp);
Handler handler2 = new Handler();
final String finalCurrentApp = currentApp;
handler2.postDelayed(new Runnable() {
public void run() {
Intent openMe = new Intent(getApplicationContext(), LoginActivity.class);
openMe.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(openMe);
am.killBackgroundProcesses(finalCurrentApp);
}
}, 200);
}
Toast.makeText(context, "Service is running", Toast.LENGTH_LONG).show();
List<ActivityManager.RunningAppProcessInfo> appProcesses = am.getRunningAppProcesses();
for(ActivityManager.RunningAppProcessInfo appProcess : appProcesses){
if(appProcess.importance == ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND){
if (ApiLigaIsRunning == true)
Log.i("Foreground App ", appProcess.processName);
else
Log.i("Not Working! ", appProcess.processName);
}
handler.postDelayed(runnable,200);
}
}
};
handler.postDelayed(runnable, 200);
}
@Override
public void onDestroy() {
Toast.makeText(this, "Service stopped", Toast.LENGTH_LONG).show();
}
}
这是我的清单文件:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="***************">
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.KILL_BACKGROUND_PROCESSES" />
<uses-permission android:name="android.permission.REAL_GET_TASKS" />
<uses-permission android:name="android.permission.GET_TASKS"/>
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="android.permission.GET_TOP_ACTIVITY_INFO"/>
<uses-permission android:name="android.permission.INSTANT_APP_FOREGROUND_SERVICE"/>
<uses-permission android:name="android.permission.PACKAGE_USAGE_STATS" tools:ignore="ProtectedPermissions" />
<application
android:allowBackup="true"
android:icon="@mipmap/icon"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
android:name=".LoginActivity"
android:theme="@style/AppTheme.Dark">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<service
android:name=".BackgroundService"
android:exported="true"
android:enabled="true"
/>
</application>
永无止境的后台服务是不可能的,但你可以限制关闭服务
因为这会占用更多不允许的电池
1- 使用前台服务
这将使服务成为 运行 带有 Notification Like Music App
2- 使用START_STICKY
这将使您的服务在它终止时启动
Broadcoast Receiver
是有可能的。但是因为奥利奥 (API 26) 你只能用 Job Scheduler
.
In most cases, apps can work around these limitations by using
JobScheduler jobs. This approach lets an app arrange to perform work
when the app isn't actively running, but still gives the system the
leeway to schedule these jobs in a way that doesn't affect the user
experience. Android 8.0 offers several improvements to JobScheduler
that make it easier to replace services and broadcast receivers with
scheduled jobs.
查看更多信息:https://developer.android.com/about/versions/oreo/background
我想让这个服务成为一个永无止境的服务,即使应用程序被用户杀死。该服务随应用程序启动 - 当它在后台时,该服务仍在运行 - 但当我清除 phone 上的后台任务时,它也会被杀死。我希望最后一部分有所不同,希望此服务在设备上保留 运行...这可能吗?感谢帮助
public class BackgroundService extends Service {
public static Runnable runnable = null;
public Context context = this;
public Handler handler = null;
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public void onCreate() {
final PackageManager manager = getPackageManager();
//Packages instalados no dispositivo
List<ApplicationInfo> packages = manager.getInstalledApplications(PackageManager.GET_META_DATA);
for (ApplicationInfo info : packages) {
Log.i("Info", "Installed package:" + info.packageName);
}
for (int i = 0; i < packages.size(); i++) {
if(packages.get(i).sourceDir.startsWith("/data/app/")){
//Non System Apps
Log.i("Info", "Installed package /NON SYSTEM/:" + packages.get(i).packageName);
}else{
//system Apps
Log.i("Info", "Installed package !/SYSTEM/!:" + packages.get(i).packageName);
}}
handler = new Handler();
runnable = new Runnable() {
public void run() {
final ActivityManager am = (ActivityManager) getBaseContext().getSystemService(ACTIVITY_SERVICE);
String currentApp ="";
// The first in the list of RunningTasks is always the foreground task.
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP) {
UsageStatsManager usm = (UsageStatsManager) getSystemService(USAGE_STATS_SERVICE);
long time = System.currentTimeMillis();
List<UsageStats> appList = usm.queryUsageStats(UsageStatsManager.INTERVAL_DAILY,
time - 1000 * 1000, time);
if (appList != null && appList.size() > 0) {
SortedMap<Long, UsageStats> mySortedMap = new TreeMap<Long, UsageStats>();
for (UsageStats usageStats : appList) {
mySortedMap.put(usageStats.getLastTimeUsed(),
usageStats);
}
if (mySortedMap != null && !mySortedMap.isEmpty()) {
currentApp = mySortedMap.get(
mySortedMap.lastKey()).getPackageName();
}
}
} else {
ActivityManager.RunningTaskInfo foregroundTaskInfo = am.getRunningTasks(1).get(0);
currentApp = foregroundTaskInfo.topActivity.getPackageName();
}
boolean ApiLigaIsRunning = false;
if (currentApp.contains("maps")) {
ApiLigaIsRunning = true;
Log.i("CHOOSEN APP IS RUNNING ","YES!!!!!!!!!!! " + currentApp);
Handler handler2 = new Handler();
final String finalCurrentApp = currentApp;
handler2.postDelayed(new Runnable() {
public void run() {
Intent openMe = new Intent(getApplicationContext(), LoginActivity.class);
openMe.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(openMe);
am.killBackgroundProcesses(finalCurrentApp);
}
}, 200);
}
Toast.makeText(context, "Service is running", Toast.LENGTH_LONG).show();
List<ActivityManager.RunningAppProcessInfo> appProcesses = am.getRunningAppProcesses();
for(ActivityManager.RunningAppProcessInfo appProcess : appProcesses){
if(appProcess.importance == ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND){
if (ApiLigaIsRunning == true)
Log.i("Foreground App ", appProcess.processName);
else
Log.i("Not Working! ", appProcess.processName);
}
handler.postDelayed(runnable,200);
}
}
};
handler.postDelayed(runnable, 200);
}
@Override
public void onDestroy() {
Toast.makeText(this, "Service stopped", Toast.LENGTH_LONG).show();
}
}
这是我的清单文件:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="***************">
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.KILL_BACKGROUND_PROCESSES" />
<uses-permission android:name="android.permission.REAL_GET_TASKS" />
<uses-permission android:name="android.permission.GET_TASKS"/>
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="android.permission.GET_TOP_ACTIVITY_INFO"/>
<uses-permission android:name="android.permission.INSTANT_APP_FOREGROUND_SERVICE"/>
<uses-permission android:name="android.permission.PACKAGE_USAGE_STATS" tools:ignore="ProtectedPermissions" />
<application
android:allowBackup="true"
android:icon="@mipmap/icon"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
android:name=".LoginActivity"
android:theme="@style/AppTheme.Dark">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<service
android:name=".BackgroundService"
android:exported="true"
android:enabled="true"
/>
</application>
永无止境的后台服务是不可能的,但你可以限制关闭服务
因为这会占用更多不允许的电池
1- 使用前台服务
这将使服务成为 运行 带有 Notification Like Music App
2- 使用START_STICKY
这将使您的服务在它终止时启动
Broadcoast Receiver
是有可能的。但是因为奥利奥 (API 26) 你只能用 Job Scheduler
.
In most cases, apps can work around these limitations by using JobScheduler jobs. This approach lets an app arrange to perform work when the app isn't actively running, but still gives the system the leeway to schedule these jobs in a way that doesn't affect the user experience. Android 8.0 offers several improvements to JobScheduler that make it easier to replace services and broadcast receivers with scheduled jobs.
查看更多信息:https://developer.android.com/about/versions/oreo/background