2016-10-09 46 views
1

我有一個自定義的AsyncTask類,用於檢查設備是否授予位置權限,然後獲取最後一個已知位置。如果沒有權限,則首先請求用戶許可。所以在我的doInBackground函數中,我需要調用mGoogleApiClient.connect(),這將觸發onConnected函數。可以看出,doInBackground需要等待onConnected,否則返回null對象lastKnownLocation。我的問題是我如何讓doInBackground等待onConnected?如何使doInBackground()等待AyncTask類中的另一個函數?

public class GetLocationTask extends AsyncTask<Void, Void, Location> implements GoogleApiClient.ConnectionCallbacks 
    , GoogleApiClient.OnConnectionFailedListener { 

private Context context; 
private Activity activity; 
private GoogleApiClient mGoogleApiClient; 
private Location lastKnownLocation = null; //In case the users reject location permission request, we might initialize the location to something interesting 
public AsyncResponseForLocation delegate = null; 
private static final int MY_PERMISSIONS_REQUEST_ACCESS_FINE_LOCATION = 1; 

public GetLocationTask(Activity activity, Context context) { 
    this.activity = activity; 
    this.context = context; 
} 

@Override 
protected Location doInBackground(Void... params) { 
    if (mGoogleApiClient == null) { 
     mGoogleApiClient = new GoogleApiClient.Builder(context) 
       .addConnectionCallbacks(this) 
       .addOnConnectionFailedListener(this) 
       .addApi(LocationServices.API) 
       .build(); 
    } 
    mGoogleApiClient.connect(); 
    return lastKnownLocation; 
} 

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

    if (ActivityCompat.checkSelfPermission(context, 
      android.Manifest.permission.ACCESS_FINE_LOCATION) 
      != PackageManager.PERMISSION_GRANTED 
      && ActivityCompat.checkSelfPermission(context, 
      android.Manifest.permission.ACCESS_COARSE_LOCATION) 
      != PackageManager.PERMISSION_GRANTED) { 

     ActivityCompat.requestPermissions(activity, 
       new String[]{android.Manifest.permission.ACCESS_FINE_LOCATION}, 
       MY_PERMISSIONS_REQUEST_ACCESS_FINE_LOCATION); 
    } 
    lastKnownLocation = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient); 
} 

@Override 
public void onConnectionSuspended(int i) { 

} 


@Override 
public void onConnectionFailed(@NonNull ConnectionResult connectionResult) { 

} 

@Override 
protected void onPostExecute(Location location) { 
    delegate.processFinish(location); 
} 


public interface AsyncResponseForLocation { 

void processFinish(Location location);} 
+0

我不能使用while(lastKnownLocation == null){}來等待對象,因爲在某些情況下此對象可能爲null。 – Tao

+0

檢查[CompletableFuture](https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/CompletableFuture.html)並使用'get'來「如果需要等待這個未來完成,然後返回結果。「 – VladoDemcak

+0

我終於找到了解決辦法。但也要感謝Lior指出工作流程問題。 我創建了一個變量private boolean onConnectedCompleted = false; 和onConnected(),我添加onConnectedCompleted = true;在最後一次。然後在我的doInBackground中,我只需要檢查這個條件。 – Tao

回答

1

你的流量是不正確,你嘗試獲得位置簽到,如果你有權限,然後......

// Here, thisActivity is the current activity 
if (ContextCompat.checkSelfPermission(thisActivity, 
      Manifest.permission.ACCESS_FINE_LOCATION) 
    != PackageManager.PERMISSION_GRANTED) { 

// Should we show an explanation? 
if (ActivityCompat.shouldShowRequestPermissionRationale(thisActivity, 
     Manifest.permission.ACCESS_FINE_LOCATION)) { 

    // Show an expanation to the user *asynchronously* -- don't block 
    // this thread waiting for the user's response! After the user 
    // sees the explanation, try again to request the permission. 

} else { 

    // No explanation needed, we can request the permission. 

    ActivityCompat.requestPermissions(thisActivity, 
      new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, 
      MY_PERMISSIONS_REQUEST_LOCATION); 

    // MY_PERMISSIONS_REQUEST_LOCATION is an 
    // app-defined int constant. The callback method gets the 
    // result of the request. 
} else{ 
// Run your async task here(you have got location permission already) 
new GetLocationTask(Activity).execute(); 
} 

,你必須處理onRequestPermissionsResult方法,當用戶需要批准您的許可請求:

@Override 
public void onRequestPermissionsResult(int requestCode, 
    String permissions[], int[] grantResults) { 
switch (requestCode) { 
    case MY_PERMISSIONS_REQUEST_LOCATION: { 
     // If request is cancelled, the result arrays are empty. 
     if (grantResults.length > 0 
      && grantResults[0] == PackageManager.PERMISSION_GRANTED) { 

      // permission was granted, Execute the asynctask here 
      new GetLocationTask(Activity).execute(); 
     } else { 

      // permission denied, boo! Disable the 
      // functionality that depends on this permission. 
     } 
     return; 
    } 

    // other 'case' lines to check for other 
    // permissions this app might request 
} 
} 
0

執行每5秒運行一次的檢查條件爲isConnected()的Timertask。

試試下面的代碼

private void startTimer(){ 
      mTimer1 = new Timer(); 
      mTt1 = new TimerTask() { 
       public void run() { 
        mTimerHandler.post(new Runnable() { 
         public void run(){ 
          if(isConnected){ 

          //call the Async task 
           } 
         } 
        }); 
       } 
      }; 

     mTimer1.schedule(mTt1, 1, 5000); 
    } 
0

doInBackground()方法之前添加此。 AsyncTask()將首先執行onPreExecute(),然後執行doInBackground()

@Override 
    protected void onPreExecute() { 
     super.onPreExecute(); 
     // your code hear 
    } 
相關問題