我的目标是奥利奥。如您所知,oreo引入了对后台任务执行时间的限制。根据Google的说法,解决方法是将后台任务放在前台。这是我正在尝试执行的操作,但是一旦前台服务运行,它就会在一段时间后被销毁。 首先,手机关闭屏幕,然后再次激活手机,则后台任务继续。有时,前台服务上的onDestroy会在任务没有完成的情况下被调用。
我的目标是让enqueueWork设置所有任务,以便在不调用ondestroy的情况下执行所有任务,并且无需通过电话睡眠模式来中断它。
ForeGroundService
public class ForeGroundService extends JobIntentService {
static final int JOB_ID = 1000;
static final int ONGOING_NOTIFICATION_ID = 33;
static void enqueueWork(Context context, Intent work) {
enqueueWork(context, ForeGroundService.class, JOB_ID, work);
}
Notification.Builder notification;
NotificationManager mNotificationManager;
@RequiresApi(api = Build.VERSION_CODES.O)
void einleitung(String Titel, String Text)
{
Intent notificationIntent = new Intent(this, ForeGroundService.class);
PendingIntent pendingIntent =
PendingIntent.getActivity(this, 0, notificationIntent, 0);
mNotificationManager = (NotificationManager)getSystemService(Context.NOTIFICATION_SERVICE);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
NotificationChannel channel = new NotificationChannel(Titel,
Text,
NotificationManager.IMPORTANCE_HIGH);
channel.setSound(null,null);
mNotificationManager.createNotificationChannel(channel);
}
notification =
new Notification.Builder(this,Titel)
.setContentTitle(Titel)
.setContentText(Text)
.setSmallIcon(R.drawable.kleinesicon)
.setLargeIcon(BitmapFactory.decodeResource(getResources(), R.mipmap.ic_launcher))
.setContentIntent(pendingIntent)
.setTicker("setTicker");
mNotificationManager.notify(ONGOING_NOTIFICATION_ID, notification.build());
startForeground(ONGOING_NOTIFICATION_ID, notification.build());
}
@RequiresApi(api = Build.VERSION_CODES.O)
void vordergrund(String Titel, String Text)
{
notification.setContentTitle(Titel);
notification.setContentText(Text);
mNotificationManager.notify(ONGOING_NOTIFICATION_ID, notification.build());
}
PowerManager.WakeLock wakeLock;
@RequiresApi(api = Build.VERSION_CODES.O)
@Override
protected void onHandleWork(Intent intent) {
if (beginn) {
einleitung("Test", "Test");
beginn = false;
}
PowerManager powerManager = (PowerManager) getSystemService(POWER_SERVICE);
wakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,
"MyWakelockTag");
wakeLock.acquire();
//Do Work
}
@Override
public void onDestroy() {
super.onDestroy();
Intent local = new Intent();
local.setAction("de.test.action");
this.sendBroadcast(local);
stopForeground(true);
//toast("Fertig");
if (wakeLock != null)
wakeLock.release();
}
final Handler mHandler = new Handler();
}
MainActivity
public class MainActivity extends AppCompatActivity {
private int JI = 1000;
private BroadcastReceiver updateUIReciver;
@RequiresApi(api = Build.VERSION_CODES.O)
void somefunction(someparameters)
{
Intent mServiceIntent = new Intent();
mServiceIntent.putExtra...
ForeGroundService.enqueueWork(getBaseContext(),ForeGroundService.class,JI,mServiceIntent);
}
@Override
protected void onDestroy() {
super.onDestroy();
unregisterReceiver(updateUIReciver);
}
@Override
protected void onCreate(Bundle savedInstanceState) {
setTheme(R.style.AppTheme);
super.onCreate(savedInstanceState);
IntentFilter filter = new IntentFilter();
filter.addAction("de.test.action");
updateUIReciver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
ForeGroundService.shouldContinue = false;
}
};
registerReceiver(updateUIReciver,filter);
btnB.setOnClickListener(new View.OnClickListener() {
@RequiresApi(api = Build.VERSION_CODES.O)
public void onClick(View v) {
if (startcondition)
{
Intent startIntent = new Intent(MainActivity.this, MyService.class);
startIntent.setAction(Constants.ACTION.START_ACTION);
startService(startIntent);
Intent serviceIntent = new Intent(MainActivity.this,ForeGroundService.class);
startForegroundService(serviceIntent);
somefunction(someparameters);
}
else
{
Intent stopIntent = new Intent(MainActivity.this, MyService.class);
stopIntent.setAction(Constants.ACTION.STOP_ACTION);
startService(stopIntent);
}
}
});
}
}
编辑:我使它与Sandhya Sasane的解决方案兼容,并且
public int onStartCommand(Intent intent, int flags, int startId)
{
if (beginn) {
executorService = Executors.newFixedThreadPool(1);
beginn = false;
}
final Intent i2 = intent;
executorService.execute(new Runnable(){
@Override
public void run(){
abarbeiten(i2);
}
});
return START_STICKY;
}
重要的是newFixedThreadPool(1)中的1;一次只能运行一个线程
答案 0 :(得分:2)
我的目标是奥利奥。如您所知,oreo引入了对后台任务执行时间的限制。
是的,确实如此。我能理解你,因为google首先使事情变得非常奇怪和复杂……然后又变得复杂……然后又……然后再次……现在像我和你这样的开发人员,以及你的问题和问题,表示结果/结果/证明。
解决方法是-根据google ...
也请节省时间和您自己……Google文档是最糟糕的。.我给出了十分之十的文档。
将后台任务置于前台。
您对前景概念有错误的认识。仔细逐字仔细阅读完整的答案,您的问题将得到解决.. !!
这是我正在尝试做的,但是一旦前台服务运行,它就会在一段时间后被破坏...
现在非常简单...您的概念和实现都错了...,因此,请尝试此处提供的新示例项目和指南,以及从4.0到最新android P的示例工作和经过测试的代码
首先,手机关闭屏幕,然后再次激活手机,则后台任务将继续。有时,前台服务上的onDestroy会在任务没有完成的情况下被调用。
它与前台服务完全无关。...忘记了。
我的目标是让enqueueWork设置所有任务,以便在不调用ondestroy的情况下执行所有任务,并且无需通过电话睡眠模式来中断它。
也忘记了这一点...首先让我们看看前台服务是什么以及如何创建它...
根据我的观点,用户不喜欢显示消息^的永久通知,该消息正在前台运行,并且可能很快会耗尽电池电量^,用户将再次无法将其滑开,只能强制停止或卸载应用程序才能停止它。因此,按照我的实现观点,开发人员必须使用它来实现运行时接收器,因为后扩展设备不欢迎通过扩展Broadcastreceiver
并将其intent条目放入manifest.xml文件实现的静态接收器。即使开发人员尝试执行此操作,也永远不会在后奥利奥设备上调用接收器...,是的,它会在奥利奥设备下调用。因此,仅实现一个ON_BOOT_COMPLETE接收器,然后将其全部保留在服务中即可。
右键单击项目结构,创建一个名为RunnerService的服务,然后生成所有必需的方法。它不需要您手动键入所有代码。示例前台服务:
public class RunnerService extends Service
{
NotificationManager mNotifyManager;
NotificationCompat.Builder mBuilder;
NotificationChannel notificationChannel;
String NOTIFICATION_CHANNEL_ID = "1";
public RunnerService() { }
@Override
public void onCreate()
{
super.onCreate();
Log.d("RUNNER : ", "PROGRAMMED.... \n");
Bitmap IconLg = BitmapFactory.decodeResource(getResources(), R.drawable.ic_launcher_foreground);
mNotifyManager = (NotificationManager) getApplicationContext().getSystemService(NOTIFICATION_SERVICE);
mBuilder = new NotificationCompat.Builder(this, null);
mBuilder.setContentTitle("App Name")
.setContentText("Foreground service...")
.setTicker("Foreground service...")
.setSmallIcon(R.drawable.ic_menu_slideshow)
.setLargeIcon(IconLg)
.setPriority(Notification.PRIORITY_HIGH)
.setVibrate(new long[] {100})
.setVisibility(Notification.VISIBILITY_PUBLIC)
.setOngoing(true)
.setAutoCancel(false);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O)
{
notificationChannel = new NotificationChannel(NOTIFICATION_CHANNEL_ID, "My Notifications", NotificationManager.IMPORTANCE_HIGH);
// Configure the notification channel.
notificationChannel.setDescription("Channel description");
notificationChannel.enableLights(true);
notificationChannel.setLightColor(Color.RED);
notificationChannel.setVibrationPattern(new long[]{100});
notificationChannel.enableVibration(true);
notificationChannel.setLockscreenVisibility(Notification.VISIBILITY_PUBLIC);
mNotifyManager.createNotificationChannel(notificationChannel);
mBuilder.setChannelId(NOTIFICATION_CHANNEL_ID);
startForeground(1, mBuilder.build());
}
else
{
mBuilder.setChannelId(NOTIFICATION_CHANNEL_ID);
mNotifyManager.notify(1, mBuilder.build());
}
}
@Override
public int onStartCommand(Intent intent, int flags, int startId)
{
Log.d("RUNNER : ", "\n IT IS ACTIVE UNTIL NEXT BOOT....");
return START_STICKY;
}
@Override
public void onDestroy()
{
Log.d("RUNNER : ", "\n IT WILL BE AGAIN ACTIVE BY ANDROID OS AUTOMATICALLY, DO NOT WORRY AND DONT CODE TO START IT AGAIN !!....");
super.onDestroy();
}
@Override
public IBinder onBind(Intent intent)
{
// TODO: Return the communication channel to the service.
throw new UnsupportedOperationException("NOT_YET_IMPLEMENTED_BY_DEVELOPER");
}
}
这取决于您要在oreo或post oreo以下定位的是哪个Android……我更喜欢以下所有内容:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O)
{
this.startForegroundService(new Intent(this, RunnerService.class));
}
else
{
this.startService(new Intent(this, RunnerService.class));
}
无论是从MainActivity还是任何ON_BOOT_RECEIVER,或者从任何位置,只要按此处所述启动它即可。
通过从最近的记录中将其删除...它将调用onDestroy,但它永远不会被破坏,您将无法清除通知。这意味着成功。
带有一个带有MainActivity的示例新项目,只是以上述方式调用服务。
是的,您只能在这里提出下一个任务...,我会不断更新和指导...希望您将enqueueWork
概念和所有概念都放在一边,不要再考虑了...
让我们一步一步,让我知道最新消息。...
您应该仅在模拟器上尝试...如果成功,则在实际设备上尝试...再次出现问题...
现在世界上有很多手机制造商,这需要 从Google购买库存Android,因为它是开源的,并对其进行了修改以禁用BOOT上的所有服务。它只会保留Google,WhatsApp,FaceBook,Twitter和主要的市场领导者...好像他们不允许他们那样,没人会购买他们的设备...
示例:
请勿检查BOOT_COMPLETE ...,因为将其修改为android,因此无法正常工作。
然后在操作系统完全来自Google且具有Android操作系统的设备上进行测试。
有把戏……,但是让我们一步一步吧。……一旦你成功了,我会告诉你的。。
UPDATE:3
由于尚不清楚我在做些假设并写出答案的要求是什么?
您可以实现前台执行:
broadcastmanager
广播您自己的事件。onCreate
中,以接收广播context
调用用户定义的类的方法。然后从那里执行所有任务。您可以实现后台执行:
如果您有重复的任务,并且想要在background
中执行它,即使该应用程序已从最近的用户中删除,那么...
forever
,则即使重新启动系统并且即使应用程序不在前台,后台或最近使用中,也会自动触发该作业... 截至目前,我还没有看到对JobIntentService
的任何需求,因此看不到它的静态enqueueWork
方法;解决问题需要更多的分辨率和详细信息。