如果不在 android studio 打开 google 地图就无法获取位置
Can't get location without opening google maps on android studio
基本上我注意到应用程序中有这种奇怪的反应,我得到 location is null
但是如果我退出应用程序并打开 google 地球地图,请求我的位置并重新进入应用程序,定位服务将工作正常,知道为什么会这样吗?
我确定问题不在许可上,因为我确实检查过它并且它工作得很好,而且手机位置已启用这让我感到困惑为什么它会以这种方式做出反应
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View v= inflater.inflate(R.layout.fragment_find_customer,container,false);
tableLayout = (TableLayout) v.findViewById(R.id.resultsTable);
tableLayout.setStretchAllColumns(true);
// tableLayout.setTextAlignment(View.TEXT_ALIGNMENT_CENTER);
// Button searchNearby = v.findViewById(R.id.resultsTable);
// searchNearby.setOnClickListener(new View.OnClickListener() {
// @Override
// public void onClick(View v) {
// searchRequest = new SearchRequest();
//
// }
// });
EditText editText = (EditText) v.findViewById(R.id.txtEditPostcodeSearch);
Button clear = (Button) v.findViewById(R.id.btnClearText);
clear.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View av) {
editText.setText("");
}
});
if (checkGoogleServices()) {
fusedLocationClient = LocationServices.getFusedLocationProviderClient(getContext());
}
Button searchButton = (Button) v.findViewById(R.id.btnSearchCustomer);
searchButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
EditText searchInput = (EditText) v.findViewById(R.id.txtEditPostcodeSearch);
String search = searchInput.getText().toString();
Log.d("SEARCH", search);
if (searchInput.getText().length() == 0) {
Toast.makeText(getContext(), "Please enter a search", Toast.LENGTH_LONG).show();
return;
}
searchRequest = new SearchRequest();
searchRequest.setTerm(search);
getLocation();
}
});
Button searchNearby = (Button) v.findViewById(R.id.btnSearchNearby);
searchNearby.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
searchRequest = new SearchRequest();
getLocation();
}
});
//
// tableLayout = (TableLayout) findViewById(R.id.resultsTable);
// tableLayout.setStretchAllColumns(true);
//
// Button searchNearby = (Button) findViewById(R.id.btnSearchNearby);
// searchNearby.setOnClickListener(new View.OnClickListener() {
// @Override
// public void onClick(View view) {
// searchRequest = new SearchRequest();
// getLocation();
// }
// });
return v;
}
protected boolean checkGoogleServices() {
GoogleApiAvailability ga = GoogleApiAvailability.getInstance();
int errorCode = ga.isGooglePlayServicesAvailable(getContext());
if (errorCode != SUCCESS && ga.isUserResolvableError(errorCode)) {
// ga.getErrorDialog(this, errorCode, 1000).show();
Log.d("LOC", "ERROR with location services");
return false;
}
return true;
}
private void getLocation() {
if (ContextCompat.checkSelfPermission(getContext(), Manifest.permission.ACCESS_COARSE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
fusedLocationClient.getLastLocation()
.addOnSuccessListener(new OnSuccessListener<Location>() {
@RequiresApi(api = Build.VERSION_CODES.N)
@Override
public void onSuccess(Location location) {
// Got last known location. In some rare situations this can be null.
if (location != null) {
// Logic to handle location object
searchRequest.setLatitude(String.valueOf(location.getLatitude()));
searchRequest.setLongitude(String.valueOf(location.getLongitude()));
userLocation = location;
Log.d("lat", searchRequest.getLatitude());
Log.d("long", searchRequest.getLongitude());
doSearch();
} else {
Log.d("Location", "Location is null");
}
}
})
.addOnFailureListener(new OnFailureListener() {
@RequiresApi(api = Build.VERSION_CODES.N)
@Override
public void onFailure(@NonNull Exception e) {
if (searchRequest != null && searchRequest.getTerm() != null) {
doSearch();
}
}
})
;
} else {
// You can directly ask for the permission.
// The registered ActivityResultCallback gets the result of this request.
requestPermissionLauncher.launch(Manifest.permission.ACCESS_COARSE_LOCATION);
}
}
@RequiresApi(api = Build.VERSION_CODES.N)
private void doSearch() {
View view = getActivity().getCurrentFocus();
if (view != null) {
InputMethodManager imm = (InputMethodManager) getActivity().getSystemService(Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(view.getWindowToken(), 0);
}
int rows = tableLayout.getChildCount();
if (rows > 0) {
tableLayout.removeViews(0, rows);
}
AppActivity a = (AppActivity) getActivity();
CustomerRepository customerRepository = new CustomerRepository(a.getApplication());
customerRepository.search(searchRequest).observe(getViewLifecycleOwner(), customers -> {
Log.d("Found", String.valueOf(customers.size()));
if (customers.size() == 0) {
Toast.makeText(getContext(), "No results found", Toast.LENGTH_LONG).show();
} else {
TableRow[] tableRows = new TableRow[customers.size()];
// calculate distance of each customer from user
for (int i = 0; i < customers.size(); i++) {
Customer customer = customers.get(i);
try {
Location customerLocation = new Location("customer");
customerLocation.setLatitude(Double.valueOf(customer.getLatitude()));
customerLocation.setLongitude(Double.valueOf(customer.getLongitude()));
customer.setDistance(userLocation.distanceTo(customerLocation)*0.000621371f); // convert metres to miles
} catch (NumberFormatException e) {
e.printStackTrace();
} catch (NullPointerException e) {
e.printStackTrace();
customer.setDistance(0);
}
}
// sort by distance ascending
customers.sort((c,d) -> {
if (c.getDistance() < d.getDistance()) {
return -1;
} else if (c.getDistance() > d.getDistance()) {
return 1;
} else {
return 0;
}
});
for (int i = 0; i < customers.size(); i++) {
tableRows[i] = new TableRow(getContext());
tableRows[i].setId(i + 1);
tableRows[i].setLayoutParams(new TableRow.LayoutParams(
TableRow.LayoutParams.MATCH_PARENT,
TableRow.LayoutParams.WRAP_CONTENT
));
tableRows[i].setPadding(0, 20, 80, 20);
tableRows[i].setBackgroundResource(android.R.drawable.list_selector_background);
tableRows[i].setBackgroundResource(R.drawable.table_outline);
TextView customerText = new TextView(getContext());
customerText.setId(i + 111);
customerText.setText(customers.get(i).getName());
customerText.setTextColor(Color.BLACK);
customerText.setPadding(14, 5, 5, 5);
customerText.setTextSize(16);
customerText.setMaxLines(3);
customerText.setTextAlignment(View.TEXT_ALIGNMENT_CENTER);
customerText.setEllipsize(TextUtils.TruncateAt.END);
customerText.setWidth(200);
TextView text2 = new TextView(getContext());
text2.setId(i + 1111);
text2.setText(customers.get(i).getTown());
text2.setEms(4);
text2.setMaxLines(1);
text2.setTextSize(16);
text2.setTextColor(Color.BLACK);
text2.setTextAlignment(TextView.TEXT_ALIGNMENT_CENTER);
text2.setPadding(40, 5, 5, 5);
TextView text3 = new TextView(getContext());
text3.setId(i + 11111);
text3.setText(customers.get(i).getType());
text3.setEms(4);
text3.setMaxLines(1);
text3.setTextColor(Color.BLACK);
text3.setTextAlignment(TextView.TEXT_ALIGNMENT_CENTER);
text3.setTextSize(16);
text3.setPadding(5, 5, 5, 5);
TextView text4 = new TextView(getContext());
text4.setId(i + 111111);
text4.setText(String.valueOf(customers.get(i).getDistance()));
text4.setEms(6);
text4.setMaxLines(2);
text4.setTextColor(Color.BLACK);
text4.setTextAlignment(TextView.TEXT_ALIGNMENT_CENTER);
text4.setTextSize(16);
text4.setPadding(5, 5, 5, 5);
tableRows[i].addView(customerText);
tableRows[i].addView(text2);
tableRows[i].addView(text3);
tableRows[i].addView(text4);
tableLayout.addView(tableRows[i], new TableLayout.LayoutParams(
TableLayout.LayoutParams.MATCH_PARENT,
TableLayout.LayoutParams.WRAP_CONTENT
));
tableRows[i].setClickable(true);
String customerId = customers.get(i).getUuid().toString();
int finalI = i;
tableRows[i].setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
TableRow tr = (TableRow) view;
TextView s = (TextView) tr.getChildAt(0);
String r = s.getText().toString();
Toast.makeText(getContext(), r, Toast.LENGTH_SHORT).show();
Fragment addAppointmentWithExistingCustomerActivity = new AddAppointmentWithExistingCustomerFragment();
FragmentTransaction transaction = requireActivity().getSupportFragmentManager().beginTransaction();
Bundle addBundle = new Bundle();
addBundle.putString(CUSTOMER_ID, customerId);
addAppointmentWithExistingCustomerActivity.setArguments(addBundle);
// Replace whatever is in the fragment_container view with this fragment,
// and add the transaction to the back stack if needed
transaction.replace(R.id.fragment_container, addAppointmentWithExistingCustomerActivity);
transaction.addToBackStack(null);
// Commit the transaction
transaction.commit();
}
});
}
}
});
}
if you want to access location even if the app is not in foreground ,you need to set "Allow all time" in location permission settings.Also include below line in AndroidManifest file.
<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />
您不能简单地依赖最后位置,因为它可能为空...
您可以 request location updates
只要您的最后一个位置为空,而不是完全依赖上一个位置,并且 停止位置更新 一旦您获得位置(仅停止更新如果你想要定位一次)
https://developer.android.com/training/location/request-updates
基本上我注意到应用程序中有这种奇怪的反应,我得到 location is null
但是如果我退出应用程序并打开 google 地球地图,请求我的位置并重新进入应用程序,定位服务将工作正常,知道为什么会这样吗?
我确定问题不在许可上,因为我确实检查过它并且它工作得很好,而且手机位置已启用这让我感到困惑为什么它会以这种方式做出反应
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View v= inflater.inflate(R.layout.fragment_find_customer,container,false);
tableLayout = (TableLayout) v.findViewById(R.id.resultsTable);
tableLayout.setStretchAllColumns(true);
// tableLayout.setTextAlignment(View.TEXT_ALIGNMENT_CENTER);
// Button searchNearby = v.findViewById(R.id.resultsTable);
// searchNearby.setOnClickListener(new View.OnClickListener() {
// @Override
// public void onClick(View v) {
// searchRequest = new SearchRequest();
//
// }
// });
EditText editText = (EditText) v.findViewById(R.id.txtEditPostcodeSearch);
Button clear = (Button) v.findViewById(R.id.btnClearText);
clear.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View av) {
editText.setText("");
}
});
if (checkGoogleServices()) {
fusedLocationClient = LocationServices.getFusedLocationProviderClient(getContext());
}
Button searchButton = (Button) v.findViewById(R.id.btnSearchCustomer);
searchButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
EditText searchInput = (EditText) v.findViewById(R.id.txtEditPostcodeSearch);
String search = searchInput.getText().toString();
Log.d("SEARCH", search);
if (searchInput.getText().length() == 0) {
Toast.makeText(getContext(), "Please enter a search", Toast.LENGTH_LONG).show();
return;
}
searchRequest = new SearchRequest();
searchRequest.setTerm(search);
getLocation();
}
});
Button searchNearby = (Button) v.findViewById(R.id.btnSearchNearby);
searchNearby.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
searchRequest = new SearchRequest();
getLocation();
}
});
//
// tableLayout = (TableLayout) findViewById(R.id.resultsTable);
// tableLayout.setStretchAllColumns(true);
//
// Button searchNearby = (Button) findViewById(R.id.btnSearchNearby);
// searchNearby.setOnClickListener(new View.OnClickListener() {
// @Override
// public void onClick(View view) {
// searchRequest = new SearchRequest();
// getLocation();
// }
// });
return v;
}
protected boolean checkGoogleServices() {
GoogleApiAvailability ga = GoogleApiAvailability.getInstance();
int errorCode = ga.isGooglePlayServicesAvailable(getContext());
if (errorCode != SUCCESS && ga.isUserResolvableError(errorCode)) {
// ga.getErrorDialog(this, errorCode, 1000).show();
Log.d("LOC", "ERROR with location services");
return false;
}
return true;
}
private void getLocation() {
if (ContextCompat.checkSelfPermission(getContext(), Manifest.permission.ACCESS_COARSE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
fusedLocationClient.getLastLocation()
.addOnSuccessListener(new OnSuccessListener<Location>() {
@RequiresApi(api = Build.VERSION_CODES.N)
@Override
public void onSuccess(Location location) {
// Got last known location. In some rare situations this can be null.
if (location != null) {
// Logic to handle location object
searchRequest.setLatitude(String.valueOf(location.getLatitude()));
searchRequest.setLongitude(String.valueOf(location.getLongitude()));
userLocation = location;
Log.d("lat", searchRequest.getLatitude());
Log.d("long", searchRequest.getLongitude());
doSearch();
} else {
Log.d("Location", "Location is null");
}
}
})
.addOnFailureListener(new OnFailureListener() {
@RequiresApi(api = Build.VERSION_CODES.N)
@Override
public void onFailure(@NonNull Exception e) {
if (searchRequest != null && searchRequest.getTerm() != null) {
doSearch();
}
}
})
;
} else {
// You can directly ask for the permission.
// The registered ActivityResultCallback gets the result of this request.
requestPermissionLauncher.launch(Manifest.permission.ACCESS_COARSE_LOCATION);
}
}
@RequiresApi(api = Build.VERSION_CODES.N)
private void doSearch() {
View view = getActivity().getCurrentFocus();
if (view != null) {
InputMethodManager imm = (InputMethodManager) getActivity().getSystemService(Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(view.getWindowToken(), 0);
}
int rows = tableLayout.getChildCount();
if (rows > 0) {
tableLayout.removeViews(0, rows);
}
AppActivity a = (AppActivity) getActivity();
CustomerRepository customerRepository = new CustomerRepository(a.getApplication());
customerRepository.search(searchRequest).observe(getViewLifecycleOwner(), customers -> {
Log.d("Found", String.valueOf(customers.size()));
if (customers.size() == 0) {
Toast.makeText(getContext(), "No results found", Toast.LENGTH_LONG).show();
} else {
TableRow[] tableRows = new TableRow[customers.size()];
// calculate distance of each customer from user
for (int i = 0; i < customers.size(); i++) {
Customer customer = customers.get(i);
try {
Location customerLocation = new Location("customer");
customerLocation.setLatitude(Double.valueOf(customer.getLatitude()));
customerLocation.setLongitude(Double.valueOf(customer.getLongitude()));
customer.setDistance(userLocation.distanceTo(customerLocation)*0.000621371f); // convert metres to miles
} catch (NumberFormatException e) {
e.printStackTrace();
} catch (NullPointerException e) {
e.printStackTrace();
customer.setDistance(0);
}
}
// sort by distance ascending
customers.sort((c,d) -> {
if (c.getDistance() < d.getDistance()) {
return -1;
} else if (c.getDistance() > d.getDistance()) {
return 1;
} else {
return 0;
}
});
for (int i = 0; i < customers.size(); i++) {
tableRows[i] = new TableRow(getContext());
tableRows[i].setId(i + 1);
tableRows[i].setLayoutParams(new TableRow.LayoutParams(
TableRow.LayoutParams.MATCH_PARENT,
TableRow.LayoutParams.WRAP_CONTENT
));
tableRows[i].setPadding(0, 20, 80, 20);
tableRows[i].setBackgroundResource(android.R.drawable.list_selector_background);
tableRows[i].setBackgroundResource(R.drawable.table_outline);
TextView customerText = new TextView(getContext());
customerText.setId(i + 111);
customerText.setText(customers.get(i).getName());
customerText.setTextColor(Color.BLACK);
customerText.setPadding(14, 5, 5, 5);
customerText.setTextSize(16);
customerText.setMaxLines(3);
customerText.setTextAlignment(View.TEXT_ALIGNMENT_CENTER);
customerText.setEllipsize(TextUtils.TruncateAt.END);
customerText.setWidth(200);
TextView text2 = new TextView(getContext());
text2.setId(i + 1111);
text2.setText(customers.get(i).getTown());
text2.setEms(4);
text2.setMaxLines(1);
text2.setTextSize(16);
text2.setTextColor(Color.BLACK);
text2.setTextAlignment(TextView.TEXT_ALIGNMENT_CENTER);
text2.setPadding(40, 5, 5, 5);
TextView text3 = new TextView(getContext());
text3.setId(i + 11111);
text3.setText(customers.get(i).getType());
text3.setEms(4);
text3.setMaxLines(1);
text3.setTextColor(Color.BLACK);
text3.setTextAlignment(TextView.TEXT_ALIGNMENT_CENTER);
text3.setTextSize(16);
text3.setPadding(5, 5, 5, 5);
TextView text4 = new TextView(getContext());
text4.setId(i + 111111);
text4.setText(String.valueOf(customers.get(i).getDistance()));
text4.setEms(6);
text4.setMaxLines(2);
text4.setTextColor(Color.BLACK);
text4.setTextAlignment(TextView.TEXT_ALIGNMENT_CENTER);
text4.setTextSize(16);
text4.setPadding(5, 5, 5, 5);
tableRows[i].addView(customerText);
tableRows[i].addView(text2);
tableRows[i].addView(text3);
tableRows[i].addView(text4);
tableLayout.addView(tableRows[i], new TableLayout.LayoutParams(
TableLayout.LayoutParams.MATCH_PARENT,
TableLayout.LayoutParams.WRAP_CONTENT
));
tableRows[i].setClickable(true);
String customerId = customers.get(i).getUuid().toString();
int finalI = i;
tableRows[i].setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
TableRow tr = (TableRow) view;
TextView s = (TextView) tr.getChildAt(0);
String r = s.getText().toString();
Toast.makeText(getContext(), r, Toast.LENGTH_SHORT).show();
Fragment addAppointmentWithExistingCustomerActivity = new AddAppointmentWithExistingCustomerFragment();
FragmentTransaction transaction = requireActivity().getSupportFragmentManager().beginTransaction();
Bundle addBundle = new Bundle();
addBundle.putString(CUSTOMER_ID, customerId);
addAppointmentWithExistingCustomerActivity.setArguments(addBundle);
// Replace whatever is in the fragment_container view with this fragment,
// and add the transaction to the back stack if needed
transaction.replace(R.id.fragment_container, addAppointmentWithExistingCustomerActivity);
transaction.addToBackStack(null);
// Commit the transaction
transaction.commit();
}
});
}
}
});
}
if you want to access location even if the app is not in foreground ,you need to set "Allow all time" in location permission settings.Also include below line in AndroidManifest file.
<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />
您不能简单地依赖最后位置,因为它可能为空...
您可以 request location updates
只要您的最后一个位置为空,而不是完全依赖上一个位置,并且 停止位置更新 一旦您获得位置(仅停止更新如果你想要定位一次)
https://developer.android.com/training/location/request-updates