2016-10-09 45 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 
    } 
相关问题