gpt4 book ai didi

android - 继续运行后台服务(Android)

转载 作者:行者123 更新时间:2023-12-03 16:10:29 25 4
gpt4 key购买 nike

我在用户登录后启动了后台服务,即使在 Activity 被“扔到垃圾箱”之后也应该可以工作。服务显示它正在运行的通知,注册两个广播接收器以监视 wifi 和手机状态,并且应该继续运行直到 token 未过期或用户注销。
一切正常,但服务被android杀死。唯一的解决方案真正有效是这篇文章的说明
http://nine-faq.9folders.com/articles/37422-stop-your-huawei-smartphone-from-closing-apps-when-you-lock-the-screen
不幸的是,这种解决方案是 Not Acceptable ,因为它依赖于用户。
由 C# 使用 Xamarin 创建的代码,但如果有人知道如何以编程方式从文章中实现解决方案,即使在其他语言(java,kotlin)中,我也会很高兴提供有用的建议
显现

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
android:versionCode="1"
android:versionName="1.0"
package="com.companyname.com.bgapptest">
<uses-sdk android:minSdkVersion="25" android:targetSdkVersion="28" />
<application android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:roundIcon="@mipmap/ic_launcher_round" android:supportsRtl="true" android:theme="@style/AppTheme">
<service
android:name="com.BGAppTest.BackgroundService"
android:enabled="true"
android:exported="false"/>
</application>
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.CALL_PHONE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS" />
</manifest>
从 Activity 开始服务
Activity
    using System;
using System.Linq;
using Android.App;
using Android.Content;
using Android.Content.PM;
using Android.OS;
using Android.Provider;
using Android.Runtime;
using Android.Support.Design.Widget;
using Android.Support.V7.App;
using Android.Views;
using Android.Widget;
using AlertDialog = Android.Support.V7.App.AlertDialog;

namespace com.BGAppTest
{
[Activity(Label = "@string/app_name", Theme = "@style/AppTheme.NoActionBar", MainLauncher = true)]
public class MainActivity : AppCompatActivity
{
public static string HOPE = "Nothing";
string[] perms = new string[] { "android.permission.ACCESS_FINE_LOCATION", "android.permission.ACCESS_COARSE_LOCATION", "android.permission.ACCESS_NETWORK_STATE", "android.permission.READ_PHONE_STATE","android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS"};

protected override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
SetContentView(Resource.Layout.activity_main);
Android.Support.V7.Widget.Toolbar toolbar = FindViewById<Android.Support.V7.Widget.Toolbar>(Resource.Id.toolbar);
SetSupportActionBar(toolbar);
FloatingActionButton fab = FindViewById<FloatingActionButton>(Resource.Id.fab);
fab.Click += FabOnClick;
HOPE = DateTime.Now.ToString();
StartService();
}

public override bool OnCreateOptionsMenu(IMenu menu)
{
MenuInflater.Inflate(Resource.Menu.menu_main, menu);
return true;
}

public override bool OnOptionsItemSelected(IMenuItem item)
{
int id = item.ItemId;
if (id == Resource.Id.action_settings)
{
return true;
}

return base.OnOptionsItemSelected(item);
}

private void FabOnClick(object sender, EventArgs eventArgs)
{
View view = (View)sender;
Intent service = new Intent(this, typeof(BackgroundService));
StopService(service);
}

protected void IGnoreBatteryActivity()
{
PowerManager m = GetSystemService(PowerService) as PowerManager;
Intent intent = new Intent();
if (m.IsIgnoringBatteryOptimizations(this.PackageName))
{
//intent.SetAction(Settings.ActionIgnoreBatteryOptimizationSettings);
}
else
{
intent.SetAction(Settings.ActionRequestIgnoreBatteryOptimizations);
intent.SetData(Android.Net.Uri.Parse("package:" + PackageName));
StartActivity(intent);

}

}

void StartService()
{
foreach (var p in perms)
{
if (CheckSelfPermission(p) == Permission.Denied)
{
RequestPermissions(perms, 2);
return;
}
}
IGnoreBatteryActivity();
Intent service = new Intent(this, typeof(BackgroundService));
if (Build.VERSION.SdkInt >= BuildVersionCodes.O)
StartForegroundService(service);
else
StartService(service);

}

public override void OnRequestPermissionsResult(int requestCode, string[] permissions, [GeneratedEnum] Permission[] grantResults)
{
base.OnRequestPermissionsResult(requestCode, permissions, grantResults);
if (grantResults.Any(x => x == Permission.Denied))
{
RunOnUiThread(() =>
{
new AlertDialog.Builder(this)
.SetMessage("Uprawnienia są wymagane.Chcesz nadać uprawnienia?")
.SetNegativeButton("Nie", delegate
{
this.FinishAffinity();
})
.SetPositiveButton("Tak", delegate
{
RequestPermissions(perms, requestCode);
})
.SetCancelable(false)
.Create()
.Show();
});
}
else
StartService();
}

}
}
服务
    [Service(Name = "com.BGAppTest.BackgroundService")]
public class BackgroundService : Service
{
NetworkChangeReceiver networkReceiver;
PhoneCallsReceiver receiver;
const int Service_Running_Notification_ID = 937;
public bool isStarted = false;
PowerManager.WakeLock wakeLock;
public BackgroundService()
{

}
[return: GeneratedEnum]
public override StartCommandResult OnStartCommand(Intent intent, [GeneratedEnum] StartCommandFlags flags, int startId)
{
if (isStarted)
return StartCommandResult.Sticky;
isStarted = true;
PowerManager m = GetSystemService(Context.PowerService) as PowerManager;
wakeLock = m.NewWakeLock(WakeLockFlags.Partial, "MYWeakLock");
wakeLock.Acquire();
return StartCommandResult.Sticky;
}
public override void OnCreate()
{
base.OnCreate();
RegisterForegroundService();
RegisterWifiReceiver();
RegisterPhoneReceiver();

}



public void RegisterForegroundService()
{
Notification notification = BuildNotification("Title","Text");
StartForeground(Service_Running_Notification_ID, notification);
}


Notification BuildNotification(string title, string message)
{
NotificationCompat.Builder notificationBuilder = null;
if (Build.VERSION.SdkInt >= BuildVersionCodes.O)
{
String NOTIFICATION_CHANNEL_ID = "com.BGAppTest";
NotificationChannel chan = new NotificationChannel(NOTIFICATION_CHANNEL_ID, "MY_Foreground", NotificationImportance.High);
NotificationManager manager = (NotificationManager)GetSystemService(Context.NotificationService);
manager.CreateNotificationChannel(chan);
notificationBuilder = new NotificationCompat.Builder(this, NOTIFICATION_CHANNEL_ID);
}
else
notificationBuilder = new NotificationCompat.Builder(this);

return notificationBuilder
.SetSmallIcon(Resource.Drawable.ic_mtrl_chip_checked_black)
.SetContentTitle(Resources.GetString(Resource.String.app_name))
.SetContentIntent(BuildIntentToShowMainActivity())
.SetContentTitle(title)
.SetStyle(new NotificationCompat.BigTextStyle().BigText(message))
.SetOngoing(true)
.Build();

}

private PendingIntent BuildIntentToShowMainActivity()
{
var intent = this.PackageManager.GetLaunchIntentForPackage(this.PackageName);
intent.AddFlags(ActivityFlags.ClearTop);
var pendingIntent = PendingIntent.GetActivity(this, 0, intent, PendingIntentFlags.UpdateCurrent);
return pendingIntent;

}


public void RegisterWifiReceiver()
{
var networkReceiver = new NetworkChangeReceiver();
IntentFilter intentFilters = new IntentFilter();
intentFilters.AddAction("android.net.conn.CONNECTIVITY_CHANGE");
RegisterReceiver(networkReceiver, intentFilters);
}
public void RegisterPhoneReceiver()
{
var receiver = new PhoneCallsReceiver();
IntentFilter intentFilters = new IntentFilter();
intentFilters.AddAction("android.intent.action.PHONE_STATE");
RegisterReceiver(receiver, intentFilters);

}

public override IBinder OnBind(Intent intent)
{
return null;
}
#region Session checker
//TODO:przenieść tą fukcionalność do odzielnego serwisu
System.Timers.Timer timers = new System.Timers.Timer();
private void StartTokenExpiredTimer()
{
}

#endregion
public override void OnDestroy()
{
base.OnDestroy();
try
{
UnregisterReceiver(receiver);
UnregisterReceiver(networkReceiver);
}
catch { }

}
}
接收器
using Android.Content;
using Android.Widget;


namespace com.BGAppTestReceivers
{
public class NetworkChangeReceiver: BroadcastReceiver
{

static NetworkChangeReceiver()
{

}
public NetworkChangeReceiver()
{
}
public override async void OnReceive(Context context, Intent intent)
{
Toast.MakeText(context, "BGNetworkChange", ToastLength.Short).Show();

}


}

public class PhoneCallsReceiver : BroadcastReceiver
{

static PhoneCallsReceiver()
{

}
public PhoneCallsReceiver()
{
}
public override async void OnReceive(Context context, Intent intent)
{
Toast.MakeText(context, "BGPhoneChange", ToastLength.Short).Show();
}

}


}
2020 年 9 月 26 日更新
我添加了我的示例应用程序的完整代码,让它尽可能简单
2020 年 9 月 30 日更新
添加 android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONSActionRequestIgnoreBatteryOptimizations

最佳答案

您必须请求许可才能使您的应用免于省电和应用待机模式。
您可以先从 手动尝试设置 > 应用程序 > 特殊应用程序访问 > 电池优化 > 为您的应用程序关闭优化 .
如果它适合您,那么您可以要求用户使用以下权限将您的应用列入白名单

android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS

关于android - 继续运行后台服务(Android),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63882930/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com