当我将它传递给asyncTask时,Android Location对象返回null

时间:2015-05-21 21:37:06

标签: java android android-asynctask

我将android用户位置lat和经度与json一起发送到服务器,并将其他参数作为location = LocationServices.FusedLocationApi .getLastLocation(mgoogleapiclient); 对象发送到Asynctask(活动的嵌套类)。但是Location对象(在应用程序开头有值)在活动中实例化

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类中返回null。有人能解释一下为什么吗?我是否必须使用单独的类来获取用户位置并将其发送到另一个asynctask或service(从架构的角度来看没有意义)?

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;

        }

但是当我调试它时,我得到了从另一个方法发送到AsyncTask类的注册ID。 我希望我能说清楚。

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

以下是我发送注册ID的方式

{{1}}

2 个答案:

答案 0 :(得分:2)

问题是您在不同时间向AsyncTask发送两组varargs

当您致电execute()时,您应该将所有必要的数据发送到AsyncTask,以便它需要数据。

因此,您需要准备好所有数据,然后通过一次调用将其发送到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()的String参数上调用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;

}

编辑:听起来您应该注册位置监听器以明确请求位置。下面是示例代码,您可以将其用作参考,以便在代码中注册位置侦听器:

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

答案 1 :(得分: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");
        }
    }

这解决了我的Location对象上的空指针异常,我是从here

得到的