Android Widget按钮服务不响应单击

Android Widget按钮服务不响应单击,android,android-widget,jobintentservice,Android,Android Widget,Jobintentservice,类似的问题:最接近我的问题是,但没有答案 我有一个简单的小部件按钮,按下时应发送通知。在以下情况下,它不起作用: 我在安装时打开应用程序后,立即清除最近的应用程序 随机有时会停止工作(有时在我再次打开应用程序后,所有的点击都会一起触发,导致一堆通知一起被触发。) 从我迄今为止所读到的一切来看,在我看来,悬垂的帐篷似乎正在被清理 除了启动服务而不是活动之外,代码主要取自 WidgetProvider: public class WidgetProvider extends AppWidgetPro

类似的问题:最接近我的问题是,但没有答案

我有一个简单的小部件按钮,按下时应发送通知。在以下情况下,它不起作用:

  • 在安装时打开应用程序后,立即清除最近的应用程序
  • 随机有时会停止工作(有时在我再次打开应用程序后,所有的点击都会一起触发,导致一堆通知一起被触发。)
  • 从我迄今为止所读到的一切来看,在我看来,悬垂的帐篷似乎正在被清理

    除了启动服务而不是活动之外,代码主要取自

    WidgetProvider

    public class WidgetProvider extends AppWidgetProvider {
    
        @RequiresApi(api = Build.VERSION_CODES.O)
        public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
            final int N = appWidgetIds.length;
    
            for (int appWidgetId : appWidgetIds) {
                Intent myIntent = new Intent(context, WidgetService.class);
                myIntent .setAction("SOME_UNIQUE_ACTION");
                PendingIntent pendingIntent = PendingIntent.getForegroundService(context, 0, myIntent, PendingIntent.FLAG_UPDATE_CURRENT);
                RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.widget_layout);
                views.setOnClickPendingIntent(R.id.button, pendingIntent);
                appWidgetManager.updateAppWidget(appWidgetId, views);
            }
        }
    }
    
    public class WidgetService extends JobIntentService {
    
        public WidgetService() {
            super();
        }
    
        @Override
        protected void onHandleWork(@Nullable Intent i) {
            Utils.sendNotification(); // this method works and is tested
        }
    }
    
    WidgetService

    public class WidgetProvider extends AppWidgetProvider {
    
        @RequiresApi(api = Build.VERSION_CODES.O)
        public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
            final int N = appWidgetIds.length;
    
            for (int appWidgetId : appWidgetIds) {
                Intent myIntent = new Intent(context, WidgetService.class);
                myIntent .setAction("SOME_UNIQUE_ACTION");
                PendingIntent pendingIntent = PendingIntent.getForegroundService(context, 0, myIntent, PendingIntent.FLAG_UPDATE_CURRENT);
                RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.widget_layout);
                views.setOnClickPendingIntent(R.id.button, pendingIntent);
                appWidgetManager.updateAppWidget(appWidgetId, views);
            }
        }
    }
    
    public class WidgetService extends JobIntentService {
    
        public WidgetService() {
            super();
        }
    
        @Override
        protected void onHandleWork(@Nullable Intent i) {
            Utils.sendNotification(); // this method works and is tested
        }
    }
    
    我尝试了来自的两个答案,广播方法不起作用,看起来也很间接,所以我添加了
    #onCreate
    实现来调用startForeground,这也不起作用

    @Override
        public void onCreate() {
            super.onCreate();
    
            Utils.sendNotification();
            try {
                startForeground(1, notification);
            } catch (Error e) {
                Log.i(TAG, e.toString());
            }
        }
    }
    

    如何获得每次都能可靠启动服务的按钮?感谢您的帮助。

    停止在概览屏幕上清除应用程序。在某些设备上,这确实会取消未完成的
    pendingent
    对象,对此您无能为力。此外,
    JobIntentService
    的设计并不是为了这样使用——我很惊讶它居然能工作,尤其是在Android 8.0及更高版本上。使用常规
    服务
    @commonware有什么方法可以重置它吗?是否可以在清除应用程序后以某种方式收听发送的系统广播,然后调用
    onUpdate()
    重置挂起内容?感谢您指出关于
    JobIntentService
    。不太好。在某些设备上,制造商已决定让清除应用程序在设置应用程序的应用程序屏幕上执行相当于“强制停止”的操作。当这种情况发生时,你的应用程序将不会再次运行,直到使用某个明确的
    Intent
    启动你的一个组件。通常,这将是用户从启动器导航到您的应用程序。首先,我将用
    服务
    替换
    JobIntentService
    ,看看情况是否有所改善JobIntentService,实际上是使用
    JobScheduler
    调度作业,而不是直接执行工作。这可能是因为你看到工作被取消了,而任务被清除并不是完全“强制停止”。在这种情况下,您可能会更幸运地使用常规
    服务
    “如果应用程序未处于活动状态,则从后台启动服务可能会受到限制”——您有很短的时间可以在后台运行。如果使用的是
    getService()
    pendingent
    ,则应为一分钟。但是,我很高兴您在常规
    服务方面有了更好的运气
    JobIntentService
    主要(如果不是独占的话)用于通过
    enqueueWork()
    调用使其自行运行的情况,而不是用于其他人仅通过
    Intent
    尝试运行它的情况。