gpt4 book ai didi

android - 前台服务在 didExitRegion 上重新启动

转载 作者:行者123 更新时间:2023-11-29 02:26:51 25 4
gpt4 key购买 nike

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

为了在 Android O 的后台运行它,我使用了前台服务。问题是当应用程序在后台超过 30 分钟,在检测到信标后,当用户退出信标区域并调用 didExitRegion 时,服务会自动终止并重新启动因此没有数据上传到服务器。同样在重新启动后,在第二次 didExitRegion 调用中,它会在未来的某个时间完全随机地停止,它会重新启动但会再次执行相同的循环。

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

First Restart after didExit (图片)
在这里您可以看到从区域 11 切换到区域 9。Midway 应用程序立即关闭并重新触发,但是没有发送任何推送

Exit after second didExit (图片)
接下来:现在退出该区域时,应用程序再次停止在后台。但是这次不会立即重新触发。这是始终发生的确切顺序。

代码 fragment
BeaconScanner.java

        @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;
}

用户.java

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();
}

编辑 1

One thing to note is that the beacons have an overlapping region, i.e a beacon scanner will detect 2 beacons in the region. So the nearest beacon is decided by the greatest value of the timeAverageRssi, the bug specifically crops up, after 30 minutes of inactivity there are region switches i.e beacon 1 was the nearest and then beacon 2 becomes the nearest beacon

最佳答案

我怀疑在 Android 8+ 上使用 Android Beacon Library 2.15 版的前台服务存在错误。虽然我自己没有重现这一点,但理论上 Android 8+ 会阻止使用用于从信标扫描服务传递监控回调的 Intent 服务。

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

关于android - 前台服务在 didExitRegion 上重新启动,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51797562/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com