gpt4 book ai didi

安卓 : How to use mFusedLocationClient callback (resulting location) in current mainthread

转载 作者:行者123 更新时间:2023-11-29 16:55:27 25 4
gpt4 key购买 nike

以下是我的 RecyclerView 适配器,我需要更新其中一个显示当前位置到另一个位置的距离的 TextView

现在,为了获取当前位置,我正在使用 mFusedLocationClient.requestLocationUpdates(mFusedLocationRquest,mLocationCallback,null);

如果我使用下面的代码并且刚刚在具有运行时权限的应用程序中启用了 gps,我将在线面对 NPE:

float distance = updatedLoc.distanceTo(des);

当我在已启用 gps 的情况下打开应用程序时,应用程序不会崩溃(可能是因为在这种情况下最后已知的位置不为空)。

因此,为了确保 updatedLoc 不为空,我想确保我的 TextView 仅在位置回调后更新,这怎么可能?

在此 API 的回调中,createLocationCallback(),我无法正确更新 TextView(尝试使用 holder 作为全局变量,但它很困惑,项目没有正确更新。)

提前致谢。

public class PlaceListAdapter extends RecyclerView.Adapter<PlaceListAdapter.PlaceViewHolder> implements android.location.LocationListener{

private static final long LOCATION_REFRESH_TIME = 2000;
private static final float LOCATION_REFRESH_DISTANCE = 100;
private static final int MY_PERMISSION_ACCESS_COURSE_LOCATION = 1001;
private Context mContext;
private PlaceBuffer mPlaces;
Location updatedLoc = null;
PlaceViewHolder myHolder;
boolean canGetLocation = false;
android.location.LocationListener locationListener;
double lat1,long1;
MySimpleCallback mySimpleCallback;
String dist;
private FusedLocationProviderClient mFusedLocationClient;
private LocationRequest mFusedLocationRquest;
private LocationCallback mLocationCallback;

/**
* Creates a callback for receiving location events.
*/
private void createLocationCallback() {
mLocationCallback = new LocationCallback() {
@Override
public void onLocationResult(LocationResult locationResult) {
super.onLocationResult(locationResult);

updatedLoc = locationResult.getLastLocation();

Log.d("testingvalue",String.valueOf(updatedLoc==null));
//mLastUpdateTime = DateFormat.getTimeInstance().format(new Date());

}
};
}


/**
* Constructor using the context and the db cursor
*
* @param context the calling context/activity
*/
public PlaceListAdapter(Context context, PlaceBuffer places) {
this.mContext = context;
this.mPlaces = places;
mFusedLocationClient = LocationServices.getFusedLocationProviderClient(mContext);

createLocationCallback();
createLocationRequest();

if (ActivityCompat.checkSelfPermission(mContext, android.Manifest.permission.ACCESS_FINE_LOCATION)
!= PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions((Activity) mContext,
new String[]{android.Manifest.permission.ACCESS_FINE_LOCATION},
101);
}

mFusedLocationClient.requestLocationUpdates(mFusedLocationRquest,mLocationCallback,null);

}

private void createLocationRequest() {
mFusedLocationRquest = new LocationRequest();

// Sets the desired interval for active location updates. This interval is
// inexact. You may not receive updates at all if no location sources are available, or
// you may receive them slower than requested. You may also receive updates faster than
// requested if other applications are requesting location at a faster interval.
mFusedLocationRquest.setInterval(100);

// Sets the fastest rate for active location updates. This interval is exact, and your
// application will never receive updates faster than this value.
mFusedLocationRquest.setFastestInterval(100);

mFusedLocationRquest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);

}

/**
* Called when RecyclerView needs a new ViewHolder of the given type to represent an item
*
* @param parent The ViewGroup into which the new View will be added
* @param viewType The view type of the new View
* @return A new PlaceViewHolder that holds a View with the item_place_card layout
*/
@Override
public PlaceViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
// Get the RecyclerView item layout
LayoutInflater inflater = LayoutInflater.from(mContext);
View view = inflater.inflate(R.layout.item_place_card, parent, false);
return new PlaceViewHolder(view);
}

/**
* Binds the data from a particular position in the cursor to the corresponding view holder
*
* @param holder The PlaceViewHolder instance corresponding to the required position
* @param position The current position that needs to be loaded with data
*/
@Override
public void onBindViewHolder(PlaceViewHolder holder, int position) {
String placeName = mPlaces.get(position).getName().toString();
String placeAddress = mPlaces.get(position).getAddress().toString();

double lat = mPlaces.get(position).getLatLng().latitude;
double lng = mPlaces.get(position).getLatLng().longitude;

//Location currentLocation = getCurrentLocation();

//Location currLoc = new GPSTracker(mContext).getLocation();

//Toast.makeText(mContext, "distance is" + dist + "km", Toast.LENGTH_SHORT).show();

Location des = new Location("destination");

des.setLatitude(lat);
des.setLongitude(lng);

float distance = updatedLoc.distanceTo(des);

distance = distance / 1000;

dist = "";
if (distance < 1) {
dist = "less than km away";
} else {
dist = String.format("%.2f", distance) + " km";
}


holder.nameTextView.setText(placeName);
holder.addressTextView.setText(dist);

holder.taskTextView.setText(MainActivity.preference.getString(mPlaces.get(position).getId(), "chv"));
}

public void swapPlaces(PlaceBuffer newPlaces) {
mPlaces = newPlaces;
if (mPlaces != null) {
// Force the RecyclerView to refresh
this.notifyDataSetChanged();

}
}

/**
* Returns the number of items in the cursor
*
* @return Number of items in the cursor, or 0 if null
*/
@Override
public int getItemCount() {
if (mPlaces == null) {
Log.d("countcheck", "zero bro");
return 0;
}
return mPlaces.getCount();

}


@Override
public void onLocationChanged(Location location) {
updatedLoc = location;
}

@Override
public void onStatusChanged(String s, int i, Bundle bundle) {

}

@Override
public void onProviderEnabled(String s) {

}

@Override
public void onProviderDisabled(String s) {

}



/**
* PlaceViewHolder class for the recycler view item
*/
class PlaceViewHolder extends RecyclerView.ViewHolder {

TextView nameTextView;
TextView addressTextView;
TextView taskTextView;

public PlaceViewHolder(View itemView) {
super(itemView);
nameTextView = (TextView) itemView.findViewById(R.id.name_text_view);
addressTextView = (TextView) itemView.findViewById(R.id.address_text_view);
taskTextView = (TextView) itemView.findViewById(R.id.task_text_view);
}

}

}

最佳答案

onBindViewHolder 被调用时,updatedLoc 仍然是 null,这意味着位置提供者还没有收到位置。

您应该将 updatedLoc 包装在 onBindViewHolder 中,以防止出现空情况,如下所示

if(updatedLoc != null){
float distance = updatedLoc.distanceTo(des);
distance = distance / 1000;
dist = "";

if (distance < 1) {
dist = "less than km away";
} else {
dist = String.format("%.2f", distance) + " km";
}
} else {
dist = "Waiting for location...";
}

holder.nameTextView.setText(placeName);
holder.addressTextView.setText(dist);

并且无论何时您收到位置信息,都必须再次调用onBindViewHolder 来计算和显示距离,而不是Waiting for location...

因此您需要更新createLocationCallback 方法。只需添加 notifyDataSetChanged()

private void createLocationCallback() {
mLocationCallback = new LocationCallback() {
@Override
public void onLocationResult(LocationResult locationResult) {
super.onLocationResult(locationResult);

updatedLoc = locationResult.getLastLocation();

Log.d("testingvalue",String.valueOf(updatedLoc==null));
//mLastUpdateTime = DateFormat.getTimeInstance().format(new Date());

notifyDataSetChanged();
}
};
}

关于安卓 : How to use mFusedLocationClient callback (resulting location) in current mainthread,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45209085/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com