- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我在 Android 应用程序中实现了地理围栏。我关注了this链接以在应用程序中实现“地理围栏”。我正在使用“Retrofit”库来调用“HTTP”请求。
应用程序具有以下权限:
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
这是我的“IntentService”代码:
public class GeofenceService extends IntentService
{
private static final String TAG = GeofenceService.class.getName();
public static final int GEOFENCE_NOTIFICATION_ID = 0;
public GeofenceService() {
super(TAG);
}
@Override
protected void onHandleIntent(Intent intent) {
// Retrieve the Geofencing intent
GeofencingEvent geofencingEvent = GeofencingEvent.fromIntent(intent);
createLoggerFile();
// Handling errors
if ( geofencingEvent.hasError() ) {
String errorMsg = getErrorString(geofencingEvent.getErrorCode() );
Logger.Important(true, TAG, "onHandleIntent() :: errorMessage : "+errorMsg );
return;
}
// Retrieve GeofenceTrasition
int geoFenceTransition = geofencingEvent.getGeofenceTransition();
// Check if the transition type
if ( geoFenceTransition == Geofence.GEOFENCE_TRANSITION_ENTER ||
geoFenceTransition == Geofence.GEOFENCE_TRANSITION_EXIT ||
geoFenceTransition == Geofence.GEOFENCE_TRANSITION_DWELL)
{
Log.d(TAG, "onHandleIntent() :: geoFenceTransition : " + geoFenceTransition);
// Get the geofence that were triggered
List<Geofence> triggeringGeofences = geofencingEvent.getTriggeringGeofences();
// Create a detail message with Geofences received
String geofenceTransitionDetails = getGeofenceTrasitionDetails(geoFenceTransition, triggeringGeofences );
// Send notification details as a String
sendNotification( geofenceTransitionDetails );
}
}
// Create a detail message with Geofences received
private String getGeofenceTrasitionDetails(int geoFenceTransition, List<Geofence> triggeringGeofences) {
// get the ID of each geofence triggered
ArrayList<String> triggeringGeofencesList = new ArrayList<>();
for ( Geofence geofence : triggeringGeofences ) {
triggeringGeofencesList.add( geofence.getRequestId() );
pingGoogle(); // here is I am pinging google
callingHttpRequest(); // calling Http request. Also I called this request through application class, but still it is not worked in background.
}
String status = null;
if ( geoFenceTransition == Geofence.GEOFENCE_TRANSITION_ENTER )
status = "Entering ";
else if ( geoFenceTransition == Geofence.GEOFENCE_TRANSITION_EXIT )
status = "Exiting ";
else if ( geoFenceTransition == Geofence.GEOFENCE_TRANSITION_DWELL )
status = "Staying ";
return status + TextUtils.join( ", ", triggeringGeofencesList);
}
// Send a notification
private void sendNotification( String msg ) {
Log.d( TAG, "sendNotification: " + msg );
// Intent to start the main Activity
Intent notificationIntent = new Intent(getApplicationContext(), DrawerActivity.class);;
TaskStackBuilder stackBuilder = TaskStackBuilder.create(this);
stackBuilder.addParentStack(DrawerActivity.class);
stackBuilder.addNextIntent(notificationIntent);
PendingIntent notificationPendingIntent = stackBuilder.getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT);
// Creating and sending Notification
NotificationManager notificatioMng =
(NotificationManager) getSystemService( Context.NOTIFICATION_SERVICE );
notificatioMng.notify(
GEOFENCE_NOTIFICATION_ID,
createNotification(msg, notificationPendingIntent));
}
// Create a notification
private Notification createNotification(String msg, PendingIntent notificationPendingIntent) {
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this);
notificationBuilder
.setSmallIcon(R.drawable.ic_phi_notification_logo)
.setLargeIcon(BitmapFactory.decodeResource(getResources(), R.drawable.geo))
.setColor(Converter.getColor(getApplicationContext(), R.color.default_pure_cyan))
.setContentTitle(JsonKey.TRIGGER)
.setContentText(msg)
.setContentIntent(notificationPendingIntent)
.setDefaults(Notification.DEFAULT_LIGHTS | Notification.DEFAULT_VIBRATE | Notification.DEFAULT_SOUND)
.setAutoCancel(true);
return notificationBuilder.build();
}
// Handle errors
private static String getErrorString(int errorCode) {
switch (errorCode) {
case GeofenceStatusCodes.GEOFENCE_NOT_AVAILABLE:
return "GeoFence not available";
case GeofenceStatusCodes.GEOFENCE_TOO_MANY_GEOFENCES:
return "Too many GeoFences";
case GeofenceStatusCodes.GEOFENCE_TOO_MANY_PENDING_INTENTS:
return "Too many pending intents";
default:
return "Unknown error.";
}
}
private void callingHttpRequest() {
HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor();
interceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
OkHttpClient client = new OkHttpClient.Builder()
.addInterceptor(interceptor)
.readTimeout(10, TimeUnit.SECONDS)
.connectTimeout(10 / 2, TimeUnit.SECONDS)
.sslSocketFactory(sslSocketFactory().getSocketFactory())
.build();
Gson gson = new GsonBuilder()
.setLenient()
.create();
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(url)
.client(client)
.addConverterFactory(GsonConverterFactory.create(gson))
.build();
API api = retrofit.create(***.class);
Call<ResponseBody> req = api.callGeofencingTrigger(***);
req.enqueue(new Callback<ResponseBody>() {
@Override
public void onResponse(Call<ResponseBody> call, retrofit2.Response<ResponseBody> response) {
try {
String string = response.body().string();
Log.d (TAG, "onResponse() :: success");
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
public void onFailure(Call<ResponseBody> call, Throwable t) {
t.printStackTrace();
Log.d (TAG, "onFailure() :: t : "t.getMessage());
}
});
}
}
每当设备获得地理围栏触发器时,它都能正常工作并在应用程序处于后台或前台(进入/停留/离开)时或即使用户从最近的任务中终止应用程序时也能发出适当的触发通知。当我调用 HTTP 请求时,当应用程序在前台时它工作正常并且在日志上打印成功。
onResponse() :: success
但是,当应用程序因最近的任务而被终止并且设备收到任何地理围栏触发器(进入/停留/离开)时,HTTP 请求将无法正确执行。它给出:
onFailure() :: t :
</br>java.net.UnknownHostException: Unable to resolve host
"host_name": No address associated with hostname
其中 host_name 是服务器地址。
我 ping google或来自后台服务的 8.8.8.8 ip。仍然面临同样的问题。当应用程序在前台时,这个东西也能正常工作,但在杀死应用程序后它就不起作用了。
那么,为什么会出现这个错误?应用程序不在最近任务中时网络通信不调用吗?
<------------------------------------------------ ---------------------------------------------- ---------------------->
我尝试了以下事情。从@Xavier 和@Stevensen 得到答案后
我正在使用 firebase-jobscheduler在我调用 HTTP
请求的应用程序中。这是我的代码:
在我的 list 中,我添加了以下服务:
<service
android:exported="false"
android:name="com.****.service.TriggerJobService">
<intent-filter>
<action android:name="com.firebase.jobdispatcher.ACTION_EXECUTE"/>
</intent-filter>
</service>
这是我修改后的 GeofenceService 类。我刚刚删除了 callingHttpRequest()
并通过调用 getGeofenceTrasitionDetails()
函数中的 scheduleJob()
函数添加了调度作业。代码也一样。
public class GeofenceService extends IntentService
{
private static final String TAG = GeofenceService.class.getName();
public static final int GEOFENCE_NOTIFICATION_ID = 0;
public GeofenceService() {
super(TAG);
}
@Override
protected void onHandleIntent(Intent intent) {
// Retrieve the Geofencing intent
GeofencingEvent geofencingEvent = GeofencingEvent.fromIntent(intent);
createLoggerFile();
// Handling errors
if ( geofencingEvent.hasError() ) {
String errorMsg = getErrorString(geofencingEvent.getErrorCode() );
Logger.Important(true, TAG, "onHandleIntent() :: errorMessage : "+errorMsg );
return;
}
// Retrieve GeofenceTrasition
int geoFenceTransition = geofencingEvent.getGeofenceTransition();
// Check if the transition type
if ( geoFenceTransition == Geofence.GEOFENCE_TRANSITION_ENTER ||
geoFenceTransition == Geofence.GEOFENCE_TRANSITION_EXIT ||
geoFenceTransition == Geofence.GEOFENCE_TRANSITION_DWELL)
{
Log.d(TAG, "onHandleIntent() :: geoFenceTransition : " + geoFenceTransition);
// Get the geofence that were triggered
List<Geofence> triggeringGeofences = geofencingEvent.getTriggeringGeofences();
// Create a detail message with Geofences received
String geofenceTransitionDetails = getGeofenceTrasitionDetails(geoFenceTransition, triggeringGeofences );
// Send notification details as a String
sendNotification( geofenceTransitionDetails );
}
}
// Create a detail message with Geofences received
private String getGeofenceTrasitionDetails(int geoFenceTransition, List<Geofence> triggeringGeofences) {
// get the ID of each geofence triggered
ArrayList<String> triggeringGeofencesList = new ArrayList<>();
for ( Geofence geofence : triggeringGeofences ) {
triggeringGeofencesList.add( geofence.getRequestId() );
scheduleJob(); // <code>**Here I schedule job**</code>
}
String status = null;
if ( geoFenceTransition == Geofence.GEOFENCE_TRANSITION_ENTER )
status = "Entering ";
else if ( geoFenceTransition == Geofence.GEOFENCE_TRANSITION_EXIT )
status = "Exiting ";
else if ( geoFenceTransition == Geofence.GEOFENCE_TRANSITION_DWELL )
status = "Staying ";
return status + TextUtils.join( ", ", triggeringGeofencesList);
}
// Send a notification
private void sendNotification( String msg ) {
Log.d( TAG, "sendNotification: " + msg );
// Intent to start the main Activity
Intent notificationIntent = new Intent(getApplicationContext(), DrawerActivity.class);;
TaskStackBuilder stackBuilder = TaskStackBuilder.create(this);
stackBuilder.addParentStack(DrawerActivity.class);
stackBuilder.addNextIntent(notificationIntent);
PendingIntent notificationPendingIntent = stackBuilder.getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT);
// Creating and sending Notification
NotificationManager notificatioMng =
(NotificationManager) getSystemService( Context.NOTIFICATION_SERVICE );
notificatioMng.notify(
GEOFENCE_NOTIFICATION_ID,
createNotification(msg, notificationPendingIntent));
}
// Create a notification
private Notification createNotification(String msg, PendingIntent notificationPendingIntent) {
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this);
notificationBuilder
.setSmallIcon(R.drawable.ic_phi_notification_logo)
.setLargeIcon(BitmapFactory.decodeResource(getResources(), R.drawable.geo))
.setColor(Converter.getColor(getApplicationContext(), R.color.default_pure_cyan))
.setContentTitle(JsonKey.TRIGGER)
.setContentText(msg)
.setContentIntent(notificationPendingIntent)
.setDefaults(Notification.DEFAULT_LIGHTS | Notification.DEFAULT_VIBRATE | Notification.DEFAULT_SOUND)
.setAutoCancel(true);
return notificationBuilder.build();
}
// Handle errors
private static String getErrorString(int errorCode) {
switch (errorCode) {
case GeofenceStatusCodes.GEOFENCE_NOT_AVAILABLE:
return "GeoFence not available";
case GeofenceStatusCodes.GEOFENCE_TOO_MANY_GEOFENCES:
return "Too many GeoFences";
case GeofenceStatusCodes.GEOFENCE_TOO_MANY_PENDING_INTENTS:
return "Too many pending intents";
default:
return "Unknown error.";
}
}
private void scheduleJob()
{
Bundle bundle = new Bundle();
FirebaseJobDispatcher dispatcher = new FirebaseJobDispatcher(new GooglePlayDriver(getApplicationContext()));
Job.Builder builder = dispatcher.newJobBuilder();
builder.setExtras(bundle);
builder.setTag(requestId);
builder.setService(TriggerJobService.class);
builder.setTrigger(Trigger.executionWindow(10, 30));
builder.setReplaceCurrent(true);
builder.addConstraint(Constraint.DEVICE_CHARGING);
builder.addConstraint(Constraint.ON_ANY_NETWORK);
builder.addConstraint(Constraint.ON_UNMETERED_NETWORK);
dispatcher.mustSchedule(builder.build());
}
}
这是我的 TriggerJobService 代码:
public class TriggerJobService extends JobService
{
private static final String TAG = TriggerJobService.class.getName();
private int count;
@Override
public boolean onStartJob(JobParameters job)
{
Log.d(TAG, "onStartJob() :: " + job.getTag());
// Return true as there's more work to be done with this job.
//TODO have to send request to cloud
Bundle bundle = job.getExtras();
callingHttpRequest(); // here is I am calling 'HTTP' request
return true;
}
@Override
public boolean onStopJob(JobParameters job)
{
Log.d(TAG, "onStopJob() :: " + job.getTag());
// Return false to drop the job.
return false;
}
private void callingHttpRequest() {
HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor();
interceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
OkHttpClient client = new OkHttpClient.Builder()
.addInterceptor(interceptor)
.readTimeout(10, TimeUnit.SECONDS)
.connectTimeout(10 / 2, TimeUnit.SECONDS)
.sslSocketFactory(sslSocketFactory().getSocketFactory())
.build();
Gson gson = new GsonBuilder()
.setLenient()
.create();
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(url)
.client(client)
.addConverterFactory(GsonConverterFactory.create(gson))
.build();
API api = retrofit.create(***.class);
Call<ResponseBody> req = api.callGeofencingTrigger(***);
req.enqueue(new Callback<ResponseBody>() {
@Override
public void onResponse(Call<ResponseBody> call, retrofit2.Response<ResponseBody> response) {
try {
String string = response.body().string();
Log.d (TAG, "onResponse() :: success");
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
public void onFailure(Call<ResponseBody> call, Throwable t) {
t.printStackTrace();
Log.d (TAG, "onFailure() :: t : "t.getMessage());
}
});
}
}
它再次调用相同的。它工作正常,并在应用程序处于后台或前台(进入/停留/离开)时提供适当的触发通知,或者即使用户从最近的任务中终止了应用程序。它还在安排适当的工作。并调用 HTTP
请求,当应用程序在前台时,它工作正常,并在日志中打印成功。
onResponse() :: success
但是,当应用程序因最近的任务而被终止并且设备获得任何地理围栏触发器(进入/停留/离开)时,应用程序调度作业并且调用 HTTP
请求未正确执行。它给出:
onFailure() :: t :
</br>java.net.UnknownHostException: Unable to resolve host
"host_name": No address associated with hostname
因此,根据@Xavier 和@Stevensen 的回答,如果我的应用程序因最近的任务而终止,则它不会唤醒网络。我尝试使用 firbase-JobSchedule
但仍然面临上述相同的错误。当应用程序从最近的任务中终止时,应用程序是否需要任何特殊的权限
来调用HTTP
请求?或者是 FCM
是更好的选择。但仍然有同样的问题,即使应用程序因最近的任务而终止,FCM
是否仍能正常工作? FCM
会唤醒网络从客户端向服务器发送消息吗?
最佳答案
也许您的应用被 Android 的 hibernate 模式和/或应用待机阻止使用网络。检查Optimizing for Doze and App Standby .
一种可能的解决方案是使用 AlarmManager 设置警报. Android 将安排在允许您使用网络的维护窗口中处理警报。
关于java - 地理围栏 : HTTP request failed while sending through the background service. 给出 UnknownHostException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45506162/
我想知道地理数据、几何数据和数据库系统(例如 Oracle 或 SqlSqerver)中表示空间数据的标准数据类型之间有什么区别? 对我来说看起来是一样的,但我知道肯定有区别。. 最佳答案 首先,地理
我正在寻找用于存储 map 的理想数据库或数据结构的建议。本质上, map 由“道路”组成,如道路、路径等。道路包含节点(具有纬度和经度坐标,有时还有高度。) 任何此类数据库或结构: 应该能够快速(毫
我最近将一些预装的国家和省份形状下载到 Sql Server 2008 中 http://sqlsamplegeo.codeplex.com/ 除了地理列,每个国家和省都有一个“ShapeArea”和
我对google Analytics(分析)地理如何工作(特别是对于出差用户)有疑问。例如,如果我是森尼韦尔市的用户,并且我打开了一个应用程序,则Google ID在用户ID级别的分析将说用户数= 1
我正在使用 Geo::IP 对 IP 地址执行位置查找。一切正常,直到我遇到一个不在地理 IP 查找数据库中的 IP 地址并且程序突然关闭并给出此错误 Can't call method "city"
通用(或设备无关)物理位置的结构是什么?我的猜测是它可能是一个有两个长字段的结构,或者类似的东西。 此外,给定一个目的地位置和两个候选位置,是否有一种简单的算法可以确定哪个候选位置最接近目的地?我并不
我正在使用 d3 geomaps 创建美国的地理 map 。当我将鼠标悬停在状态上时,我希望突出显示该状态。那可能吗?这是我当前的代码:
在geoviews guide for Bokeh ,它指出 Bokeh 仅支持墨卡托投影,但大多数示例投影使用 PlateCarree,然后输出看起来像墨卡托投影。 有人知道图形的投影和输出是怎么回
我有一个geodataframe'all_locations',其中有一个几何列和一个带有点名称的列。在 map 上绘制点工作正常,但我想用位置名称注释这些点。 ['位置'] ['几何'] BUITH
我正在尝试在 Canvas 中缩放 map 。 var projection = d3.geoMercator() projection.fitExtent([[margin.left, margin
我目前正在处理这段代码,一切正常,但是当我用鼠标悬停在一个国家/地区时,我只希望国家/地区名称出现在标签中,而不是相关值。我可以这样做吗?如果是,怎么办? 提前致谢! 这是javascript代码:
我正在尝试在 mac os 上使用 Geodjango,我使用 postgresql 并安装了 GEOS,但出现此错误: dlopen(/usr/local/lib/libgeos_c.dylib,
我正在研究 GeoViews,我想知道我们是否可以将 slider 作为 GeoViews 中等值线图的输入。 我在 gdf 中有另一个变量,它是年份。是否可以使用 slider 显示年度 Tot
我有一个 Geometry (看起来像 WKB) 我的 postgres/postgis 数据库中的对象,我已经转储到 BigQuery 来做一些有趣的事情。我看到它存储为 bytes .我如何构建一
我正在使用 DPM 进行 azure 在线备份,并且想要将冗余从 Geo 更改为 Local,但它显示为灰色。有办法改变吗? 我不想为此创建新的错误,然后我必须再次将所有内容从 DPM 重新上传到 A
我正在实现 Google 地理 map ,我想做的是,例如,如果我单击 US在 map 上,我会将国家/地区名称作为警报(例如,如果我单击美国,我必须将美国作为警报),我最终可以将其用作变量。当我尝试
我正在制作一张具有缩放和平移功能的世界地图。我在某些城市上画了圆圈,圆圈的半径由数据决定。当鼠标悬停在这些圆圈上时,将出现一个工具提示来显示数据。 代码结构为 //在此选择上调用缩放行为 - 让我们调
我需要一个函数来计算一对 WGS 84 之间的距离定位到高精度,我计划使用 boost geometry 中的 geographic 函数. boost geometry Design Rationa
我正在尝试缓冲数据集中半径为 100 公里的点。我正在使用函数 gBuffer来自包裹rgeos .这是我到目前为止所拥有的: head( sampledf ) # postalcode
我正在用 C# 开发一个应用程序,它将使用 SQL Server 2008 中的“地理”数据类型来使用和存储地理位置。我计划使用 Entity Framework ,但很快发现它不支持空间数据。有没有
我是一名优秀的程序员,十分优秀!