簡體   English   中英

當我將其傳遞給asyncTask時,Android Location對象返回null

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

我正在將android用戶位置的經度和緯度以及registration ID和其他參數作為json對象發送到服務器Asynctask(活動的嵌套類)中。 但是在活動中實例化了Location對象(在應用程序的開頭具有值)

location = LocationServices.FusedLocationApi
                    .getLastLocation(mgoogleapiclient);

在Asynctask類中返回null。 有人可以向我解釋原因嗎? 我是否必須使用單獨的類來獲取用戶位置並將其發送到另一個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類的注冊ID。 我希望我能使自己清楚。

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

        }

以下是我發送注冊ID的方法

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

問題是您在不同的時間向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();
    }
}

另外,不需要在傳遞給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;

}

編輯:聽起來您應該注冊一個位置偵聽器以便顯式請求一個位置。 以下是示例代碼,您可以將其用作參考,以便在代碼中注冊位置偵聽器:

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

這解決了我的Location對象上的空指針異常,我是從這里得到的

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM