java - 为什么设备进入休眠模式后前台服务停止工作

标签 java android foreground-service

我想创建一个不断检查位置变化并将当前位置放入火力基地的应用程序(例如,运行者的应用程序)。

不幸的是,每次设备进入休眠模式时,前台服务都会停止或暂停。

对于初学者,我想创建一个前台服务,它每秒不断地将信息写入基础(可能是时间戳或简单字符串)。
一段时间后,它只是停止写入 firebase 而不调用 stopself()。

该服务在模拟器上运行良好(即使进入休眠状态),但在真实设备上测试时停止 - 在我的情况下是华为,Android 8.1.0。
我应该怎么做才能强制服务在设备的每个状态下运行?

My MainActivity: 

public class MainActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
             Intent intent = new Intent(this, MyService.class);
            intent.putExtra("action", "start");
            startForegroundService(intent);
        }
        else {
             Intent intent = new Intent(this, MyService.class);
            intent.putExtra("action", "start");
            startService(intent);
        }
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            Intent intent = new Intent(this, MyService.class);
            intent.putExtra("action", "stop");
            startForegroundService(intent);
        }
        else {
            Intent intent = new Intent(this, MyService.class);
            intent.putExtra("action", "stop");
            startService(intent);
        }
    }

}
MyService:  

public class MyService extends Service {

    int i =0;
    private String CHANNEL_ID = "2345";
    @Override
    public void onCreate() {
        super.onCreate();
    }

    public MyService() {
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        startForeground(1000, createNotification());
        String action = intent.getExtras().getString("action"); 
        switch (action){
            case "start":
                final Handler handler = new Handler();
             Runnable runnable = new Runnable() {
             @Override
             public void run() {
                        myfunction();
                 handler.postDelayed(this, 1000);
            }
        };

            break;
            case "stop":
                stopfunction();
                break;
        }
        handler.postDelayed(runnable, 1000);
        return START_NOT_STICKY;
    }

    private void stopfunction() {
        stopSelf();
}

    private void myfunction() {
        FirebaseDatabase database = FirebaseDatabase.getInstance();
        DatabaseReference myRef = database.getReference("locations");
        myRef.child("location").setValue(i);
        i++;
    }

    @Override
    public IBinder onBind(Intent intent) {
        // TODO: Return the communication channel to the service.
        return null;
    }

    @RequiresApi(Build.VERSION_CODES.O)
    private void createChannel(){
        NotificationManager notificationManager = (NotificationManager) this.getSystemService(Context.NOTIFICATION_SERVICE);
        NotificationChannel channel = new NotificationChannel(CHANNEL_ID, getString(R.string.infoTxt),
                NotificationManager.IMPORTANCE_HIGH);
        channel.setShowBadge(false);
        channel.setLockscreenVisibility(Notification.VISIBILITY_PUBLIC);
        notificationManager.createNotificationChannel(channel);
    }

    private Notification createNotification(){
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O){
            createChannel();
        }

        Intent notificationItent = new Intent(this, MainActivity.class);
        notificationItent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
        PendingIntent intent = PendingIntent.getActivity(this, 0, notificationItent, 0);

        return new NotificationCompat.Builder(this, CHANNEL_ID)
                .setColor(ContextCompat.getColor(this, android.R.color.background_dark))
                .setContentIntent(intent)
                .setSmallIcon(R.drawable.ic_launcher_background)
                .setVisibility(NotificationCompat.VISIBILITY_PUBLIC)
                .setOnlyAlertOnce(true)
                .setContentTitle("GPS Location")
                .build();
    }
}

最佳答案

我已经尝试了一切:服务、前台服务、广播接收器、jobSheduler、WorkerManager——没有任何帮助。然后我发现这是一个新的华为功能,叫做“功耗密集型应用程序监视器”。它会杀死所有在后台运行很长时间的应用程序,除非用户授予它特殊权限。
执行此操作的路径:
设置->安全和隐私->位置服务->最近的位置请求:您的应用程序名称->电池->取消选中耗电提示,应用程序启动:手动管理:检查所有三个位置:自动启动,二次启动,运行背景。

我不知道有没有办法以编程方式做到这一点。我认为最好的方法是创建一种帮助 Activity ,并向用户解释如果应用程序无法运行该怎么办。

关于java - 为什么设备进入休眠模式后前台服务停止工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56124944/

相关文章:

java - 使用 Object 类的 clone() 方法克隆对象

java - Spring MVC : Not able to use use validator, 获取 "Injection of autowired dependencies failed"

android - 如何知道用户何时完成移动 RecyclerView 项目?

Android:如何在代码中获取 "listPreferredItemHeight"属性的值?

android - IntentService 的 StartForeground

java - GWT DialogBox 生成其自身的多个副本

java - 如果多次匹配,有没有办法捕获每个组?

android - 如何在屏幕的 0,0,-1 opengl 坐标上绘制黑点?

android - 如何更新自定义布局通知操作?

android - locationListener 在前台服务 30 秒后不起作用