简体   繁体   English

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

[英]Android Location object returns null when I pass it to asyncTask

I am sending android user location lat and longitude to server together with registration ID and other parameters as json object in Asynctask(a nested class of the activity). 我正在将android用户位置的经度和纬度以及registration ID和其他参数作为json对象发送到服务器Asynctask(活动的嵌套类)中。 But the Location object(that had values at the start of the app) instantiated in the activity as such 但是在活动中实例化了Location对象(在应用程序的开头具有值)

location = LocationServices.FusedLocationApi
                    .getLastLocation(mgoogleapiclient);

is returning null in the Asynctask Class. 在Asynctask类中返回null。 Can someone explain to me why? 有人可以向我解释原因吗? Do I have to use separate class to get user location and send it in another asynctask or service(which doesn't make sense from architectural standpoint)? 我是否必须使用单独的类来获取用户位置并将其发送到另一个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));
        }

I am retrieving this from the AsyncTask class as such: 我是这样从AsyncTask类检索的:

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

But when I debug it, I am getting the getting the registration ID which I sent to the AsyncTask class from another method. 但是,当我调试它时,我得到的是从另一个方法发送到AsyncTask类的注册ID。 I hope I am making myself clear. 我希望我能使自己清楚。

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

        }

The following is how I sent the registration ID 以下是我发送注册ID的方法

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

The problem is that you are sending two separate sets of varargs to the AsyncTask at different times. 问题是您在不同的时间向AsyncTask发送了两组独立的varargs

You should be sending all necessary data to the AsyncTask when you call execute() in order for it to have the data is needs. 调用execute()时,应该将所有必需的数据发送到AsyncTask,以使其具有需要的数据。

So, you need to get all of the data ready, and send it in one call to execute() , something like this: 因此,您需要准备好所有数据,并通过一次调用将其发送给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();
    }
}

Also, there is no need to call String.valueOf() on your String arguments that are passed in to doInBackground() , so you can remove those calls: 另外,不需要在传递给doInBackground() String参数上调用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: It sounds like you should register a location listener in order to explicitly request a location. 编辑:听起来您应该注册一个位置侦听器以便显式请求一个位置。 Here is sample code that you can use as a reference in order to register a location listener in your code: 以下是示例代码,您可以将其用作参考,以便在代码中注册位置侦听器:

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

This solved the null pointer exception on my Location object, I got it from here 这解决了我的Location对象上的空指针异常,我是从这里得到的

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM