2015-05-21 4 views
1

Я отправляю местоположение пользователя android пользователя lat и longitude на сервер вместе с registration ID и другими параметрами как json объект в Asynctask (вложенный класс активности). Но Расположение объекта (который имел значения в начале приложения) конкретизируется в деятельности как таковойОбъект Android Location возвращает null, когда я передаю его asyncTask

location = LocationServices.FusedLocationApi 
        .getLastLocation(mgoogleapiclient); 

возвращается нуль в AsyncTask классе. Может кто-нибудь объяснить мне, почему? Должен ли я использовать отдельный класс, чтобы получить местоположение пользователя и отправить его в другую асинтезу или службу (что не имеет смысла с архитектурной точки зрения)?

Location mLastLocation = LocationServices.FusedLocationApi.getLastLocation(
       mGoogleApiClient); 
     if (mLastLocation != null) { 
      PostData pdata = new PostData(); 
      double latitude = mLastLocation.getLatitude(); 
      double longitude = mLastLocation.getLongitude(); 
      pdata.execute(String.valueOf(latitude), String.valueOf(longitude)); 
     } 

Я извлечение этого из класса AsyncTask как таковые:

json.put("latitude", String.valueOf(args[1])); 
        json.put("longitude", String.valueOf(args[2])); 

Но когда я его отладку, я набираюсь получать регистрационный номер, который я послал к классу AsyncTask от другого метода. Надеюсь, я проясняю.

@Override 
     protected String doInBackground(String... args) { 
      try { 
       try { 
        URL url; 
        HttpURLConnection urlConn; 
        url = new URL ("myphp.php"); 
        urlConn = (HttpURLConnection)url.openConnection(); 
        urlConn.setDoInput (true); 
        urlConn.setDoOutput (true); 
        urlConn.setUseCaches (false); 
        urlConn.setRequestProperty("Content-Type","application/json"); 
        urlConn.setRequestProperty("Accept", "application/json"); 
        urlConn.setChunkedStreamingMode(0); 
        urlConn.setRequestMethod("POST"); 
        urlConn.connect();     
        //get google account 
        AccountManager am = AccountManager.get(getBaseContext()); // "this" references the current Context 
        Account[] accounts = am.getAccountsByType("com.google"); 

        //Create JSONObject here 
        JSONObject json = new JSONObject(); 
        json.put("regID", String.valueOf(args[0])); 
        json.put("Google account", accounts[0].name); 
        json.put("name", "Amanda"); 
        json.put("tel", "2069994444"); 
        json.put("latitude", String.valueOf(args[1])); 
        json.put("longitude", String.valueOf(args[2])); 

        String postData=json.toString(); 

        // Send POST output. 
        OutputStreamWriter os = new OutputStreamWriter(urlConn.getOutputStream(), "UTF-8"); 
         os.write(postData); 
         Log.i("NOTIFICATION", "Data Sent"); 
         os.close(); 

        BufferedReader reader = new BufferedReader(new InputStreamReader(urlConn.getInputStream())); 
        String msg=""; 
        String line = ""; 
        while ((line = reader.readLine()) != null) { 
         msg += line; } 
        Log.i("msg=",""+msg); 
       } catch (MalformedURLException muex) { 
        // TODO Auto-generated catch block 
        muex.printStackTrace(); 
       } catch (IOException ioex){ 
        ioex.printStackTrace(); 
       } 
      } catch (Exception e) { 
       e.printStackTrace(); 
       Log.e("ERROR", "There is error in this code"); 

      } 
      return null; 

     } 

Ниже показано, как я послал регистрационный номер

gcm = GoogleCloudMessaging.getInstance(this); 
      regid = getRegistrationId(context); 
      if (!regid.isEmpty()) { 
       PostData pd = new PostData();    
       pd.execute(regid); 
      } else { 
       //register 
       registerInBackground(); 
      } 
+0

'getLastLocation()', вероятно, возвращает null. Он делает это довольно часто. Зарегистрируйте слушателя и вызовите свою AsyncTask из обратного вызова 'onLocationChanged()'. –

+0

@ Даниэль благодарит за ответ, но на данный момент мне не повезло. Могу ли я дважды позвонить в Asynctask, чтобы передать идентификатор и передать широту и долготу из двух разных методов? Как получить значения в методе doInBackground (String ... params)? –

+0

У вас возникли проблемы с доступом к объекту JSONObject и Object в AsycTask? Пожалуйста, напишите свой код того, что вы пробовали до сих пор. Вы также можете посмотреть пример кода для регистрации приемника местоположения: http://stackoverflow.com/questions/30191047/access-coarse-location-permission-gives-a-cell-tower-precision-on-android/30315009 # 30315009 –

ответ

2

Проблема заключается в том, что вы отправляете два отдельных набора varargs к AsyncTask в разное время.

Вы должны отправить все необходимые данные в AsyncTask, когда вы вызываете execute(), чтобы иметь необходимые данные.

Таким образом, вы должны получить все данные готовы, и отправить его в одном вызове execute(), что-то вроде этого:

Location mLastLocation = LocationServices.FusedLocationApi.getLastLocation(
     mGoogleApiClient); 

gcm = GoogleCloudMessaging.getInstance(this); 
regid = getRegistrationId(context); 
if (!regid.isEmpty() && mLastLocation != null) { 
    double latitude = mLastLocation.getLatitude(); 
    double longitude = mLastLocation.getLongitude(); 
    PostData pd = new PostData(); 
    pd.execute(regid, String.valueOf(latitude), String.valueOf(longitude)); 
} else { 
    //register if regid is empty 
    if (regid.isEmpty()){ 
     registerInBackground(); 
    } 
} 

Кроме того, нет необходимости вызывать String.valueOf() на ваши аргументы Струнные что пропускаются, чтобы doInBackground(), так что вы можете удалить эти вызовы:

@Override 
protected String doInBackground(String... args) { 
    try { 
     try { 
      URL url; 
      HttpURLConnection urlConn; 
      url = new URL ("myphp.php"); 
      urlConn = (HttpURLConnection)url.openConnection(); 
      urlConn.setDoInput (true); 
      urlConn.setDoOutput (true); 
      urlConn.setUseCaches (false); 
      urlConn.setRequestProperty("Content-Type","application/json"); 
      urlConn.setRequestProperty("Accept", "application/json"); 
      urlConn.setChunkedStreamingMode(0); 
      urlConn.setRequestMethod("POST"); 
      urlConn.connect(); 
      //get google account 
      AccountManager am = AccountManager.get(getBaseContext()); // "this" references the current Context 
      Account[] accounts = am.getAccountsByType("com.google"); 

      //Create JSONObject here 
      JSONObject json = new JSONObject(); 
      json.put("regID", args[0]); //modified 
      json.put("Google account", accounts[0].name); 
      json.put("name", "Amanda"); 
      json.put("tel", "2069994444"); 
      json.put("latitude", args[1]); //modified 
      json.put("longitude", args[2]); //modified 

      String postData=json.toString(); 

      // Send POST output. 
      OutputStreamWriter os = new OutputStreamWriter(urlConn.getOutputStream(), "UTF-8"); 
      os.write(postData); 
      Log.i("NOTIFICATION", "Data Sent"); 
      os.close(); 

      BufferedReader reader = new BufferedReader(new InputStreamReader(urlConn.getInputStream())); 
      String msg=""; 
      String line = ""; 
      while ((line = reader.readLine()) != null) { 
       msg += line; } 
      Log.i("msg=",""+msg); 
     } catch (MalformedURLException muex) { 
      // TODO Auto-generated catch block 
      muex.printStackTrace(); 
     } catch (IOException ioex){ 
      ioex.printStackTrace(); 
     } 
    } catch (Exception e) { 
     e.printStackTrace(); 
     Log.e("ERROR", "There is error in this code"); 

    } 
    return null; 

} 

Edit: Похоже, вы должны зарегистрировать местоположения слушателя для того, чтобы явно запросить местоположение. Вот пример кода, который можно использовать в качестве ссылки для того, чтобы зарегистрировать местоположение слушателя в вашем коде:

public class MainActivity extends Activity implements 
     GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener, LocationListener { 

    LocationRequest mLocationRequest; 
    GoogleApiClient mGoogleApiClient; 

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

     buildGoogleApiClient(); 
     mGoogleApiClient.connect(); 
    } 

    @Override 
    protected void onPause(){ 
     super.onPause(); 
     if (mGoogleApiClient != null) { 
      LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiClient, this); 
     } 
    } 

    protected synchronized void buildGoogleApiClient() { 
     Toast.makeText(this,"buildGoogleApiClient",Toast.LENGTH_SHORT).show(); 
     mGoogleApiClient = new GoogleApiClient.Builder(this) 
       .addConnectionCallbacks(this) 
       .addOnConnectionFailedListener(this) 
       .addApi(LocationServices.API) 
       .build(); 
    } 

    @Override 
    public void onConnected(Bundle bundle) { 
     Toast.makeText(this,"onConnected",Toast.LENGTH_SHORT).show(); 

     mLocationRequest = new LocationRequest(); 
     mLocationRequest.setInterval(10); 
     mLocationRequest.setFastestInterval(10); 
     mLocationRequest.setPriority(LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY); 
     //mLocationRequest.setPriority(LocationRequest.PRIORITY_LOW_POWER); 
     //mLocationRequest.setSmallestDisplacement(0.1F); 

     LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, this); 
    } 

    @Override 
    public void onConnectionSuspended(int i) { 
     Toast.makeText(this,"onConnectionSuspended",Toast.LENGTH_SHORT).show(); 
    } 

    @Override 
    public void onConnectionFailed(ConnectionResult connectionResult) { 
     Toast.makeText(this,"onConnectionFailed",Toast.LENGTH_SHORT).show(); 
    } 

    @Override 
    public void onLocationChanged(Location location) { 

     Log.d("locationtesting", "accuracy: " + location.getAccuracy() + " lat: " + location.getLatitude() + " lon: " + location.getLongitude()); 

     Toast.makeText(this,"Location Changed",Toast.LENGTH_SHORT).show(); 


     //unregister here if you only need one location update: 
     if (mGoogleApiClient != null) { 
      LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiClient, this); 
     } 
    } 
} 
+0

Я пробовал этот подход до и теперь получаю исключение из null-указателя, потому что последнее известное местоположение возвращает null в pd.excecute (regid, String.valueOf (широта), String.valueOf (долгота)); –

+0

@Quantumdroid вам просто нужно убедиться, что 'mLastLocation' не является нулевым, посмотрите на проверку if (! Regid.isEmpty() && mLastLocation! = Null)' и посмотрите на обновление, которое я только что сделал в ответ , –

+0

Я сделал это, но mLastLocation имеет значение null. Я пытаюсь понять, что вызывает это. Я буду обновлять вас, когда я это сделаю. Огромное спасибо. –

0
private void startReceivingLocationUpdates() { 
     if (locationManager == null) { 
      locationManager = (android.location.LocationManager)context.getSystemService(Context.LOCATION_SERVICE); 
     } 

     if (locationManager != null) { 
      try {locationManager.requestLocationUpdates(android.location.LocationManager.NETWORK_PROVIDER, 1000, 0F, 
        (android.location.LocationListener) listener); 
      } 
     catch (SecurityException ex) 
      { 
       Log.i(TAG, "fail to request location update, ignore", ex); 
      } 

      catch (IllegalArgumentException ex) 
      { 
       Log.d(TAG, "provider does not exist " + ex.getMessage()); 
      } 

      try { 
       locationManager.requestLocationUpdates(android.location.LocationManager.GPS_PROVIDER, 1000, 0F, 
         (android.location.LocationListener) listener); 
       //if (listener != null) listener.showGpsOnScreenIndicator(false); 
      } 
      catch (SecurityException ex) { 
       Log.i(TAG, "fail to request location update, ignore", ex); 
       } 

      catch (IllegalArgumentException ex) { 
       Log.d(TAG, "provider does not exist " + ex.getMessage()); 
       } 

      Log.d(TAG, "startReceivingLocationUpdates"); 
     } 
    } 

Это решало исключения нулевого указателя на моем месте расположения объекта, я получил его от here

Смежные вопросы