当前位置: 首页 > 知识库问答 >
问题:

didExitRegion上前台服务重新启动

谭宏盛
2023-03-14

我正在构建一个应用程序来检测Android上的iBeacons。基本功能是通过信标将广告数据存储到设备上,并将其上传到服务器。为此,我正在使用Android信标库。

应用程序在非活动约30分钟后进入区域时发生的事件序列

首先,在didExit(图像)
之后重新启动,在这里您可以看到从区域11切换到区域9。中途应用程序关闭并立即重新触发,但没有发送推送

在第二个didExit(Image)
后退出:当现在从这个区域退出时,应用程序再次停止在后台。但这一次不会立即重新触发。这是一直发生的确切顺序。

        @Override
        public void didExitRegion(Region region) {
            Log.d(TAG, "Exited A Region");
            if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.O)
                notificationHelper.notify(2, notificationHelper.getNotification("BeaconScanner", "Exit Major #"+previousMajor, false));
            else
                utils.dispatchNotification("Exit Major #"+previousMajor, 1);

            Log.e(TAG, "DidSend "+didSend+" has Data "+userData.hasPendingData());
            if(didSend && userData.hasPendingData()) {
                JSONObject data = userData.getJsonFromUser();
                Log.d(TAG, "Timestamp = "+System.currentTimeMillis());
                userData.addTimestamp(""+System.currentTimeMillis());
                userData.requestDataSync(data);
                userData.clearBeaconData();
                Log.d(TAG, data.toString());
                didSend = !didSend;
            }
            previousMajor = -1000;
            lastBeacon = resetBeacon;
        }
JSONObject getJsonFromUser() {
    Log.d(TAG, "Timestamp as in getJsonFromUser "+timestamp);
    JSONObject json = new JSONObject();
    try {
        json.put("email", email);
        json.put("name", name);
        JSONArray beaconArray = new JSONArray();
        for (Beacon beacon : beaconData){
            beaconArray.put(new JSONObject()
                    .put("major", beacon.getId2().toInt())
                    .put("minor", beacon.getId3().toInt())
                    .put("uuid", beacon.getId1().toString())
            );
        }
        json.put("data", beaconArray);
        Log.d(TAG, timestamp);
        json.put("timestamp", ""+System.currentTimeMillis());
        return json;

    } catch (Exception e){
        Log.e(TAG, e.getMessage());
        Crashlytics.log(e.getLocalizedMessage());
    }
    return json;
}

void requestDataSync(final JSONObject json){
    User.syncing = true;
    Crashlytics.log(1, "User.java", "Requesting Auth Token");
    FirebaseUser user = FirebaseAuth.getInstance().getCurrentUser();
    user.getIdToken(true).addOnCompleteListener(new OnCompleteListener<GetTokenResult>() {
        @Override
        public void onComplete(@NonNull Task<GetTokenResult> task) {
            if(task.isSuccessful()){
                final Task<GetTokenResult> t = task;
                Thread thread = new Thread(new Runnable() {
                    @Override
                    public void run() {
                        try {
                            trustAllHosts();
                            URL url = new URL("https://indpulse.com/generatetoken");
                            HttpsURLConnection connection = (HttpsURLConnection) url.openConnection();
                            connection.setHostnameVerifier(DO_NOT_VERIFY);
                            connection.setRequestProperty("Authorization", ""+t.getResult().getToken());
                            connection.setRequestMethod("GET");
                            Log.d(TAG, t.getResult().getToken());
                            connection.setDoOutput(true);
                            connection.connect();
                            BufferedReader br = new BufferedReader(new InputStreamReader(connection.getInputStream()));
                            StringBuilder response = new StringBuilder();
                            String packet;
                            while((packet = br.readLine()) != null){
                                response.append(packet);
                            }
                            JSONObject responseObject = new JSONObject(response.toString());
                            String idToken = responseObject.getString("token");
                            Crashlytics.log(1, "User.java", "Auth Token Acquired");
                            sendData(json, idToken);
                        } catch (MalformedURLException e){
                            Log.e(TAG, "Malformed URL "+e.getLocalizedMessage());
                            Crashlytics.log(e.getLocalizedMessage());
                        } catch (IOException e){
                            Log.e(TAG, "IOExeption "+e.getLocalizedMessage());
                            Crashlytics.log(e.getLocalizedMessage());
                        } catch (JSONException e) {
                            Log.d(TAG,"Json error");
                            Crashlytics.log(e.getLocalizedMessage());
                        }
                    }
                });
                thread.start();
            }
        }
    });

void sendData(JSONObject json, final String idToken){
    final String sJson = json.toString();
    System.out.println(sJson);
    Thread thread = new Thread(new Runnable() {
        @Override
        public void run() {
            try {
                URL url = new URL("https://indpulse.com/android");
                HttpsURLConnection conn = (HttpsURLConnection) url.openConnection();
                conn.setRequestMethod("POST");
                conn.setRequestProperty("Authorization", "Bearer "+idToken);
                conn.setDoOutput(true);
                conn.setDoInput(true);
                conn.connect();

                DataOutputStream os = new DataOutputStream(conn.getOutputStream());
                os.writeBytes(sJson);
                os.flush();
                os.close();

                Log.i(TAG, String.valueOf(conn.getResponseCode()));
                Log.i(TAG , conn.getResponseMessage());


                conn.disconnect();
            } catch (Exception e){
                Log.e("BeaconScanner", e.getLocalizedMessage());
                Crashlytics.log(e.getLocalizedMessage());
            }

            User.syncing = false;
        }
    });

    thread.start();
}

需要注意的一点是,信标有一个重叠区域,即信标扫描仪将在该区域中检测到2个信标。因此,最近的信标由timeaveragerssi的最大值决定,错误特别出现,在30分钟不活动后,有区域切换,即信标1是最近的,然后信标2成为最近的信标

共有1个答案

慕容俭
2023-03-14

我怀疑在Android8+上使用Android Beacon Library版本2.15的前台服务有一个bug。虽然我自己没有重复这个,但理论是Android8+阻止了意图服务的使用,该服务用于从信标扫描服务传递监视回调。

我在库版本2.15.1beta1中基于一个类似的报告问题构建了一个建议的修复程序。请尝试这个修复,看看它是否解决了您的问题。

 类似资料:
  • 我用Android BLE(蓝牙低能)开发了一个应用程序,它工作得很好,但当Android需要更多内存时,我的服务就被干掉了。 > 我正在使用具有单独进程的前台服务。 <接收器Android:name=“.BluetoOthleservice$MyReceiver”/> 为我效劳: 但当我的服务被操作系统杀死时,它就不会重新启动。我已经尝试关闭所有最近的应用程序,但没有得到任何解决方案.... 对

  • 请原谅我没有经验,我对此很陌生。今天早些时候我在数字海洋上为我的世界设置了一个服务器。我运行命令,用java-xmx1024m-xms1024m-jar minecraft_server.1.15.2.jar nogui创建世界,并创建了一个屏幕。它使我能够访问控制台,在那里我可以键入类似/op和其他命令。后来,我关闭了,现在当我试图重新加入时,我不知道如何回到控制台。我有超过1人在服务器上,谁是

  • 我创建了一个跟踪设备移动位置的服务。服务由绑定到它的活动启动,在该活动中有一个“开始跟踪”按钮。当按下这个按钮时,我需要服务在前台启动,这样它就可以存储设备移动到的位置,即使与它绑定的活动已经关闭,或者应用程序被最小化。 以下是我的服务:

  • 我们在Android8.1及以上版本中偶然发现了一个我们以前从未见过的问题,不幸的是,这使得我们的应用程序对我们的用户来说不太方便。在Android 8.1及以上版本中,当用户刷屏杀死应用程序时,后台粘性服务不会重新启动。

  • 我正在开发一个需要从后台启动前台服务的SDK。因为它使用后台定位和蓝牙相关的工作。如果应用程序被杀死,监控正在后台执行。这就是我使用前台服务的原因。有一个条件是从后台启动前台服务。 目前,我的SDK使用服务来处理此作业。但Android 12不支持从后台启动服务。 我正在尝试从以下异常引发的后台启动服务。 如何使用WorkManager解决此问题,我的所有处理都由Service类完成,以及如何将S

  • 问题内容: 我已经从http://jenkins-ci.org/content/thank-you-downloading-windows- installer 下载了“ jenkins-1.501.zip” 。 我已经解压缩了zip文件,并在Windows 7上成功安装了Jenkins。詹金斯的表现不错。我想从控制台停止Jenkins服务。我怎样才能做到这一点?通过控制台/命令行启动和重新启动的