簡體   English   中英

當應用程序在后台時,Android Listener 停止運行

[英]Android Listener stop running when app in background

我正在開發一個應用程序,該應用程序將檢測藍牙信號(Sensoro Smart Beacon 設備)並打開活動。 但我希望該應用程序即使在后台應用程序或什至被殺死時仍然能夠檢測到信號。 我使用了前台服務,當我打開應用程序並在活動之間移動時,它會檢測到信號,但是當將應用程序發送到后台並打開其他應用程序時,盡管服務仍在工作,但偵聽器會停止。 我正在打印日志。 System.out.println("Sensoro 2" ); 即使我終止應用程序或打開另一個應用程序,也會繼續打印。 但是 BeaconManagerListener 中的打印日志不起作用。 我嘗試使用后台服務,但它也不起作用。 您能否建議當應用程序在后台或被殺死時,是否有辦法使偵聽器在服務中工作? 這是服務代碼:

public class MyService extends Service {
    public static final String CHANNEL_ID = "ForegroundServiceChannel";
    int service_timer=0;
    Timer timer = new Timer();
    SensoroManager sensoroManager;
    @Override
    public void onCreate() {
        super.onCreate();
    }
    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        sensoroManager = SensoroManager.getInstance(MyService.this);
        String input = intent.getStringExtra("inputExtra");
        System.out.println("Sensoro 2" );
        createNotificationChannel();
        Intent notificationIntent = new Intent(this, MainActivity.class);
        PendingIntent pendingIntent = PendingIntent.getActivity(this,
                0, notificationIntent, 0);
        Notification notification = new NotificationCompat.Builder(this, CHANNEL_ID)
                .setContentTitle("Foreground Service")
                .setContentText(input)
                .setSmallIcon(R.drawable.ic_launcher_background)
                .setContentIntent(pendingIntent)
                .build();
        startForeground(1,notification);
        //do heavy work on a background thread
        //stopSelf();
                if (sensoroManager.isBluetoothEnabled()) {
                    sensoroManager.setCloudServiceEnable(true);
                    /**
                     * Enable SDK service
                     **/
                    try {
                        sensoroManager.startService();

                    } catch (Exception e) {
                        e.printStackTrace(); // Fetch abnormal info
                    }
                }
                else
                {
                    Toast.makeText(MyService.this,"Bluetooth off",Toast.LENGTH_LONG).show();
                }
        new Timer().scheduleAtFixedRate(new TimerTask() {
            @Override
           public void run() {
                //your method
                System.out.println("Sensoro 2" );


                BeaconManagerListener beaconManagerListener = new BeaconManagerListener() {

                    @Override
                    public void onUpdateBeacon(ArrayList<Beacon> beacons) {
                        // Refresh sensor info
                        for (Beacon beacon : beacons
                        ) {
                            System.out.println("Sensoro 3" );
                           // System.out.println("Sensoro" +beacon.getAccuracy());
                        }
                    }

                    @Override
                    public void onNewBeacon(Beacon beacon) {

                        if (beacon.getSerialNumber().equals("0117C59B243C")){
                            System.out.println("Sensoro 3" );
                            System.out.println("Sensoro acc" +beacon.getAccuracy());
                }
            }

                    @Override
                    public void onGoneBeacon(Beacon beacon) {

                        if (beacon.getSerialNumber().equals("0117C59B243C")){
                            System.out.println("Sensoro acc gone");
                            System.out.println("Sensoro acc Timer" +service_timer);
                        }
                    }
                };
                sensoroManager.setBeaconManagerListener(beaconManagerListener);
            }
        }, 0, 2000);



        return START_NOT_STICKY;
    }
    @Override
    public void onDestroy() {
        super.onDestroy();
       // timer.cancel();
    }
    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }
    private void createNotificationChannel() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            NotificationChannel serviceChannel = new NotificationChannel(
                    CHANNEL_ID,
                    "Foreground Service Channel",
                    NotificationManager.IMPORTANCE_DEFAULT
            );
            NotificationManager manager = getSystemService(NotificationManager.class);
            manager.createNotificationChannel(serviceChannel);
        }
    }


}

這是我稱之為的地方:

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        startService();
        }


    public void startService() {
        Intent serviceIntent = new Intent(this, MyService.class);
        serviceIntent.putExtra("inputExtra", "Foreground Service Example in Android");
        System.out.println("Sensoro 1 ");
        ContextCompat.startForegroundService(this, serviceIntent);
    }
    public void stopService() {
        Intent serviceIntent = new Intent(this, MyService2.class);
        stopService(serviceIntent);
    }


    public void movingg(View view) {
        Intent intent=new Intent(this,Usermain.class);
       startActivity(intent);    }
}

解決了

最后,經過多方搜索,我查看了 Android 規章制度頁面

根據谷歌文檔,從 Android 8 開始,所有沒有谷歌認可簽名的應用程序將在幾分鍾后從后台移除。

但解決方案:

  1. 第一種解決方案是在調試模式下運行應用程序
  2. 第二種解決方案是為應用程序分配一個簽名並將其發送給谷歌進行審批

推薦:

  1. 第三種解決方案是從模擬器或android手機中刪除google play服務應用程序

我不知道這是否對你有幫助,但這是我的答案:

public void startService() {
      Intent serviceIntent = new Intent(this, MyService.class);
      serviceIntent.putExtra("inputExtra", "Foreground Service Example in Android");
      System.out.println("Sensoro 1 ");
      startService(serviceIntent);
  }

你可以使用BroadcastReceiver 如果您的應用程序被殺死或在后台,廣播接收器將捕獲藍牙事件

這與您搜索的內容並非 100% 匹配,但這與您想要的內容很接近。

您甚至可以使用在后台運行應用程序的WorkManager WorkManager 有兩種類型。 1) OneTimeWorkRequest 2) PeriodicWorkRequest。

因此,您可以使用PeriodicWorkRequest每 15 分鍾(最小間隔)調用一次,並且您可以在 WorkManager 中添加代碼以檢測藍牙信號。 因此,您可以每隔 15 分鍾檢測一次藍牙信號。

我希望這會幫助你解決你的問題。

我看到你的方法有兩個問題。

首先,您應該檢查特定的信標序列號可能會導致問題。

其次,您使用的 Timer 每 2 秒關閉一次,每次它都會添加一個新的 BeaconManagerListener ,這不應該是這種情況,您應該將偵聽器提取到外面,也許將其設為類成員,然后每次都使用相同的偵聽器而不是不斷創建新的偵聽器,然后替換舊的偵聽器。

另外為什么在 2 秒后添加監聽器我認為應該在調用 sensoroManager.startService() 之前添加

最后,如果不需要每隔幾秒鍾重復一次任務並且可以以 >= 15 分鍾的間隔完成,那么請考慮使用定期工作管理器。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM