0

Я разрабатываю приложение для Android, которое использует API gof play services geofencing для отправки некоторых данных на сервер всякий раз, когда пользователь вводит геозонность. Приложение отлично работает для геообъектов, где есть Wi-Fi-связь. Мой intentservice не запускается для геообъектов без подключения к Wi-Fi, даже если это место зафиксировано в этом геозонде (я проверил его с помощью приложения карт на том же устройстве). Я думаю, что эта проблема не имеет ничего общего с радиусом геосферы, как я тестировал с 300 метров (он говорит, что 100-150 будет хорошо работать в документации). В developer.android.com говорится: «Наличие Wi-Fi может значительно улучшить точность определения местоположения, поэтому, если Wi-Fi отключен, ваше приложение никогда не сможет получать предупреждения о геозонности в зависимости от нескольких настроек, включая радиус геозоны, модель устройства или версия Android ». Я использую симфонию v75 в качестве тестового устройства, а версия для Android - зефир. делает это с этим связано. Если кто-то сталкивался с подобной проблемой, пожалуйста, помогите. Вот сервис, в котором я создаю геообъекты.Почему геозоны не запускаются без подключения Wi-Fi в геозонде?

public class sendLocation extends Service implements GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener, ResultCallback<Status> { 
dbCreate dbcreate; 
SQLiteDatabase db; 

private String empId; 
public static final float GEOFENCE_RADIUS_IN_METERS = 300; 
protected ArrayList<Geofence> mGeofenceList; 
protected GoogleApiClient mGoogleApiClient; 
public static final HashMap<String, LatLng> LANDMARKS = new HashMap<String, LatLng>(); 
private ScheduledExecutorService scheduledExecutorService; 
private String logUrl="https://abdulhalim.pythonanywhere.com/rams/default/get_att_log.json"; 
//private String logUrl="https://rumytechnologies.com/ramsm/default/get_att_log.json"; 
public String Tag="newtag"; 
private boolean myDeletePermission=false; 
dbUnitSuper dbunit; 
public String unitUri="https://abdulhalim.pythonanywhere.com/rams/default/getUnits.json?client_id="; 
@Nullable 
@Override 
public IBinder onBind(Intent intent) { 
    return null; 
} 
@Override 
public void onCreate() { 
    super.onCreate(); 
    //buildGoogleApiClient(); 
    mGoogleApiClient=new GoogleApiClient.Builder(getApplicationContext()) 
      .addApi(LocationServices.API) 
      .addConnectionCallbacks(this) 
      .addOnConnectionFailedListener(this).build(); 
    //dbcreate=dbCreate.getInstance(this); 

    dbunit=dbUnitSuper.getInstance(sendLocation.this); 
    empId=dbunit.readEmpId(); 
    mGeofenceList = new ArrayList<Geofence>(); 
    populateGeofenceList(); 
    Log.d(Tag,"populate geofencelist is called on oncreate of service"); 
    scheduledExecutorService = Executors.newScheduledThreadPool(1); 
    scheduledExecutorService.scheduleWithFixedDelay(startSend,3,3,   TimeUnit.MINUTES); 
} 
    Runnable startSend=new Runnable() { 
@Override 
public void run() { 
    Log.d(Tag,"runnable is running"); 
    //String[] projection={dbcreate.UNITID}; 
    //Cursor C=db.query(dbcreate.TB_name,projection,null,null,null,null,null); 
    ArrayList<String> unitIds=new ArrayList<>(); 
    dbBufferSuper dbBuffer=dbBufferSuper.getInstance(sendLocation.this); 
    unitIds=dbunit.readUnitIds(); 
    if(isOnLine()) 
    { for(int i=0;i<unitIds.size();i++) { 
     String loopUnitID = unitIds.get(i); 
     JSONObject unitJson = dbBuffer.readBufferLog(loopUnitID); 
     if (unitJson != null) { 
      sendLog send = new sendLog(); 
      send.execute(unitJson); 
     } else { 
      Log.d(Tag, "unitjson returns null for unit "+i); 
     } 
    } 
    getUnitUpdate unitUpdate=new getUnitUpdate(); 
    unitUpdate.execute(empId);} 

} 
}; 
@Override 
public int onStartCommand(Intent intent, int flags, int startId) { 
    if (!mGoogleApiClient.isConnecting() || !mGoogleApiClient.isConnected()) { 
     mGoogleApiClient.connect(); 
    } 
    return super.onStartCommand(intent, flags, startId); 
} 
@Override 
public void onDestroy() { 
    super.onDestroy(); 
    if (mGoogleApiClient.isConnecting() || mGoogleApiClient.isConnected()) { 
     mGoogleApiClient.disconnect(); 
    } 
} 
protected boolean isOnLine() 
{ 
    ConnectivityManager cm= (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE); 
    NetworkInfo netInfo=cm.getActiveNetworkInfo(); 
    if(netInfo!=null&& netInfo.isConnectedOrConnecting()) 
    { 
     return true; 
    } 
    else 
    { 
     return false; 
    } 
} 
public void populateLandmark(){ 

    dbUnitSuper dbunit=dbUnitSuper.getInstance(this); 
    ArrayList<ArrayList<String>> unitInfo=dbunit.readUnitInformation(); 
    if(unitInfo!=null) { 
    for(int i=0;i<unitInfo.size();i++) 
     { 
ArrayList<String> singleUnit=unitInfo.get(i); 
LANDMARKS.put(singleUnit.get(0), 
      new LatLng(Float.parseFloat(singleUnit.get(1)),   Float.parseFloat(singleUnit.get(2))));} 
} 
} 
public void populateGeofenceList() { 
    populateLandmark(); 
    for (Map.Entry<String, LatLng> entry : LANDMARKS.entrySet()) { 
     mGeofenceList.add(new Geofence.Builder() 
       .setRequestId(entry.getKey()) 
       .setCircularRegion(
         entry.getValue().latitude, 
         entry.getValue().longitude, 
         GEOFENCE_RADIUS_IN_METERS 
       ) 
       .setExpirationDuration(Geofence.NEVER_EXPIRE) 
       .setLoiteringDelay(15000) 
       .setNotificationResponsiveness(30000) 
       .setTransitionTypes(Geofence.GEOFENCE_TRANSITION_DWELL) 
       .build()); 

     } 
    int i=mGeofenceList.size(); 
    Log.d(Tag,"number of geofences entered in the geofence list is "+i); 
    } 

@Override 
public void onConnected(@Nullable Bundle bundle) { 

    try { 
     LocationServices.GeofencingApi.addGeofences(
       mGoogleApiClient, 
       getGeofencingRequest(), 
       getGeofencePendingIntent() 
     ).setResultCallback(this); // Result processed in onResult(). 
    } catch (SecurityException securityException) { 
     // Catch exception generated if the app does not use ACCESS_FINE_LOCATION permission. 
     Log.d(Tag," securityException occured while adding in onconnected"); 
    } 
} 
@Override 
public void onConnectionSuspended(int i) { 
    mGoogleApiClient.connect(); 
} 
@Override 
public void onConnectionFailed(@NonNull ConnectionResult connectionResult) { 
} 
private GeofencingRequest getGeofencingRequest() { 
    GeofencingRequest.Builder builder = new GeofencingRequest.Builder(); 
    builder.setInitialTrigger(GeofencingRequest.INITIAL_TRIGGER_DWELL); 
    builder.addGeofences(mGeofenceList); 
    return builder.build(); 
} 
private PendingIntent getGeofencePendingIntent() { 
    Intent intent = new Intent(sendLocation.this, GeofenceTransitionsIntentService.class); 
    // We use FLAG_UPDATE_CURRENT so that we get the same pending intent back when calling addgeoFences() 
    return PendingIntent.getService(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT); 
} 
@Override 
public void onResult(@NonNull Status status) { 
} 
private class pollTask extends AsyncTask<String,Void,String>{ 
    @Override 
    protected String doInBackground(String... params) { 
     return null; 
    } 
} 
private class getUnitUpdate extends AsyncTask<String,Void,String> implements ResultCallback<Status> { 
    HttpsURLConnection https; 
    @Override 
    protected String doInBackground(String... params) { 
     InputStreamReader inputStream = null; 
     BufferedReader reader = null; 
     StringBuilder newSb=new StringBuilder(); 
     newSb.append(unitUri); 
     newSb.append(params[0]); 
     try { 
      URL url=new URL(newSb.toString()); 
      https=(HttpsURLConnection) url.openConnection(); 
      if(https==null) 
      {Log.d(Tag,"urlconnection returns null");} 
      https.setRequestMethod("GET"); 
      https.setDoInput(true); 
      int status =https.getResponseCode(); 
      Log.d(Tag, "getunits Status : " + status); 
      inputStream = new InputStreamReader(https.getInputStream()); 
      reader = new BufferedReader(inputStream); 
      StringBuilder message = new StringBuilder(); 
      String line; 
      while ((line = reader.readLine()) != null) { 
       message.append(line); 
      } 
      return message.toString(); 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } finally { 
      https.disconnect(); 
     } 
     return null; 
    } 
    @Override 
    protected void onPostExecute(String s) { 
     super.onPostExecute(s); 
     Log.d(Tag," updated units are"+s); 
     try { 
      JSONObject jsonRootObject=new JSONObject(s); 
      JSONArray jsonlatArray=jsonRootObject.optJSONArray("Latitude"); 
      JSONArray jsonlonArray=jsonRootObject.optJSONArray("Longitude"); 
      JSONArray jsonuniArray=jsonRootObject.optJSONArray("Unit_Id"); 
      dbUnitSuper unitSuper=dbUnitSuper.getInstance(sendLocation.this); 
      ArrayList<String> unitIds=unitSuper.readUnitIds(); 
      if(jsonuniArray.length()!=unitIds.size()){ 
       //String empId= unitSuper.readEmpId(); 
       //delete the rows in unit database 
       int del= unitSuper.deleteAllUnitInfo(); 
       Log.d(Tag,"number of deleted unit rows are"+del); 
       //populate the unit database again 
       for(int i=0;i<jsonlatArray.length();i++){ 
        String unit_id=jsonuniArray.getString(i); 
        String latitude=jsonlatArray.getString(i); 
        String longitude=jsonlonArray.getString(i); 
        long intest= unitSuper.insertData(empId,unit_id,latitude,longitude); 
        if(intest<0){ 
         // Toast.makeText(MainActivity.this, "insert unsuccessful", Toast.LENGTH_LONG).show(); 
         String rt=Integer.toString(i); 
         Log.d(Tag,"insert unsuccessful "+rt); 
        } 
        else{ 
         // Toast.makeText(MainActivity.this, "successfully inserted a row", Toast.LENGTH_LONG).show(); 
         String rt=Integer.toString(i); 
         Log.d(Tag,"successfully inserted a row "+rt); 
        } 
       } 
      /*remove geofences here 
       removeGeofences(); 
       //clear mgeofencelist arraylist 
       if(mGeofenceList.size()>0){ 
        mGeofenceList.clear(); 
       } 
       //recreate the geofences 
       populateGeofenceList();*/ 
      }else{ 
       Log.d(Tag,"no new units are added or deleted"); 
      } 
     } catch (JSONException e) { 
      e.printStackTrace(); 
     } 
     /*if (!mGoogleApiClient.isConnecting() || !mGoogleApiClient.isConnected()) { 
      Log.d(Tag," entered the if block to recreate the geofences"); 
      mGoogleApiClient.connect(); 
     } 
     else { 
      Log.d(Tag," entered the else block to recreate the geofences"); 
      try { 
       Log.d(Tag," entered the try block to recreate the geofences"); 
       LocationServices.GeofencingApi.addGeofences(
         mGoogleApiClient, 
         getGeofencingRequest(), 
         getGeofencePendingIntent() 
       ).setResultCallback(this); // Result processed in onResult(). 
      } catch (SecurityException securityException) { 
       // Catch exception generated if the app does not use ACCESS_FINE_LOCATION permission. 
       Log.d(Tag,"sequrity exception occured at unit updaate while creating neew geofences"); 
      } 
     }*/ 
    } 
    @Override 
    public void onResult(@NonNull com.google.android.gms.common.api.Status status) { 
     Log.d(Tag,"geofences recreated successfully"); 
    } 
} 
private void removeGeofences(){ 
    LocationServices.GeofencingApi.removeGeofences(
      mGoogleApiClient, 
      // This is the same pending intent that was used in addGeofences(). 
      getGeofencePendingIntent() 
    ).setResultCallback(this); // Result processed in onResult(). 
} 
private class sendLog extends AsyncTask<JSONObject,Void,String>{ 
    HttpsURLConnection https; 
    String loopUnitID; 
    @Override 
    protected String doInBackground(JSONObject... params) { 
     InputStreamReader inputStream = null; 
     BufferedReader reader = null; 
     JSONObject parseUnitIdJson=params[0]; 
     JSONObject rows=parseUnitIdJson.optJSONObject("Row"); 
     loopUnitID=rows.optString("unit_id"); 
     Log.d(Tag,"the unit id parsed in sendlog is "+loopUnitID); 
     String postStr=String.format(params[0].toString()); 
     try { 
      URL url=new URL(logUrl); 
      https=(HttpsURLConnection) url.openConnection(); 
      https.setRequestMethod("POST"); 
      https.setDoInput(true); 
      https.setDoOutput(true); 
      OutputStreamWriter writer=new OutputStreamWriter(https.getOutputStream()); 
      writer.write(postStr); 
      writer.flush(); 
      Log.d(Tag,"data flushed succesfully"); 
      int status =https.getResponseCode(); 
      Log.d(Tag, "Status : " + status); 
      inputStream = new InputStreamReader(https.getInputStream()); 
      reader = new BufferedReader(inputStream); 
      StringBuilder message = new StringBuilder(); 
      String line; 
      while ((line = reader.readLine()) != null) { 
       message.append(line); 
      } 
      Log.d(Tag,"sendLog returns"+message.toString()); 
      return message.toString(); 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } finally { 
      https.disconnect(); 
     } 
     return null; 
    } 
    @Override 
    protected void onPostExecute(String s) { 
     super.onPostExecute(s); 
     try { 
      dbBufferSuper dbBuffer=dbBufferSuper.getInstance(sendLocation.this); 
      JSONObject sendResult=new JSONObject(s); 
      JSONArray suck=sendResult.optJSONArray("result"); 
      Log.d(Tag,"the value read from result is "+suck.get(0)); 
      if(suck.get(0).equals("success")){ 
       Log.d(Tag,"permission granted for deleting a units log i"); 
       int status= dbBuffer.deleteRows(loopUnitID); 
       if(status>0){ 
        Log.d(Tag,"the number of affected rows in deletebufferrows is "+status); 
       } 
       // myDeletePermission=false; 
       /*myDeletePermission=true; 
       if(myDeletePermission==true){ 
        Log.d(Tag,"delete permission is set to true"); 
       }else{ 
        Log.d(Tag,"delete permission is still false after getting success"); 
       }*/ 
      }else {Log.d(Tag,"success is not extracted properly from the json response of sendlog");} 
     } catch (JSONException e) { 
      e.printStackTrace(); 
      Log.d(Tag,"failed to instantiate getattlogs response as json"); 
     } 
    } 
} 
    } 
+0

'Наличие Wi-Fi может значительно улучшить точность определения местоположения. Вы не должны верить в эту глупость. Да в здании, когда нет gps сигала со спутников. Но за пределами только gps является точной. – greenapps

+0

Очень неясно, кто проверяет, находится ли ваше устройство на геофоруме. Скажите, кто это делает. Не забудьте указать, требуется ли WiFi для этого или нет. – greenapps

+0

Я использую приложение Google Maps на своем устройстве, чтобы проверить, находится ли мое устройство в геозонности. Приложение карт показывает, что я нахожусь в геофоруме, он фактически показывает мое текущее местоположение почти точно. И для этого не требуется подключение Wi-Fi. –

ответ

1

Если вы приложение не имеет подключение к Wi-Fi, пожалуйста, убедитесь, что у вас есть надежное соединение для передачи данных, чтобы иметь возможность по-прежнему использовать Geofence.

Как уже упоминались в documentation, что у вас есть,

Если нет достоверных данных соединения, оповещения не могут быть сгенерированы. Это связано с тем, что служба геозондирования зависит от поставщика сетевого местоположения, который, в свою очередь, требует подключения к данным.

Кроме того, если вы предпочитаете отключив Wi-Fi, использовать SettingsApi, чтобы убедиться, что настройки системы устройства настроены правильно для оптимального обнаружения местоположения.

Пожалуйста, проверьте SettingsAPI, в котором было отмечено, что,

При запросе на место службы, настройки системы устройства могут находиться в таком состоянии, что предотвращает приложение от получения данных о местоположении, что ему нужно. Например, сканирование GPS или Wi-Fi может быть отключено.

Просьба ознакомиться с данными документами, и вы также можете проверить ответы в этом сообщении SO - How do I use the Android Geofencing API?. Надеюсь, поможет!

+0

Первый абзац «Если у вас нет приложения wifi, убедитесь, что у вас есть надежное соединение для передачи данных, чтобы иметь возможность использовать Geofence» .... в основном неверно и, по крайней мере, вводит в заблуждение , Для использования Geofencing вам не требуется подключение Wi-Fi или данных. – SimonH