在用户通过弹出窗口提供权限的同一应用程序会话中访问 GPS 坐标



我希望首次在设备上启动应用程序的用户能够在该会话中访问 GPS 数据。目前,用户必须在提供位置权限后关闭应用程序,然后在应用程序中显示位置数据后重新启动应用程序。 我已经尝试了多种方法来解决此问题。最近,我将requestPermission移动到Fragment1中,这也是LocationManager所在的位置。

public class Fragment1 extends Fragment {
public static final int MY_PERMISSIONS_REQUEST_ACCESS_FINE_LOCATION = 1;
...
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.data_capture, container, false);
requestPermission(v);
permissionAssessment(v);
...
return (v);
}

public void requestPermission(View v) {//This works, only poulates after restart...
int permissionCheck = ContextCompat.checkSelfPermission(getActivity(), Manifest.permission.ACCESS_FINE_LOCATION);
if (permissionCheck != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(getActivity(), new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, REQUEST_FINE_LOCATION);
//conditional here so that if conditionals granted do below, if refused, go away...
}else{
mGpsLocationListener = new GpsLocationListener();
lm = (LocationManager) getActivity().getSystemService(getActivity().LOCATION_SERVICE);
mGpsStatus = lm.getGpsStatus(mGpsStatus);
lm.requestLocationUpdates(LocationManager.GPS_PROVIDER, 1000, 0, mGpsLocationListener);
}
}   

此外,我采用了穴居人的方法,并创建了"permissionAssessment()",它将在requestPermission()之后立即运行,假设也许由于权限可能是由requestPermission()中的用户授予的,我可以运行checkSelfPermission并强制位置服务以这种方式启动。没有雪茄。见下文。

public void permissionAssessment(View v){
int permissionCheck = ContextCompat.checkSelfPermission(getActivity(), Manifest.permission.ACCESS_FINE_LOCATION);
if (permissionCheck == PackageManager.PERMISSION_GRANTED) {
mGpsLocationListener = new GpsLocationListener();
lm = (LocationManager) getActivity().getSystemService(getActivity().LOCATION_SERVICE);
mGpsStatus = lm.getGpsStatus(mGpsStatus);
lm.requestLocationUpdates(LocationManager.GPS_PROVIDER, 1000, 0, mGpsLocationListener);
}
}

请注意,如果设备已经授予了ACCESS_FINE_LOCATION权限,则 permissionAssessment() 工作正常。当使用requestPermission()新安装的权限并且设备上没有预先存在的权限时,它只是不起作用。

此外,仅供参考,此应用程序从与Fragment1关联的选项卡上启动,并不断更新显示的GPS卫星时间。卫星/GPS 数据显示,在用户授予位置权限的会话之后重新启动应用程序后,应用程序正常。我强烈希望 GPS 在用户设置权限的会话中"上线"。如能提出建设性建议,将不胜感激。提前谢谢。

更新,5 年 14 月 2021 日:这就是最终对我有用的东西,

public class MainActivity extends AppCompatActivity {
...
private boolean requestPermissions() {
int iExtStorage = ContextCompat.checkSelfPermission(this, android.Manifest.permission.WRITE_EXTERNAL_STORAGE);
int iCoarseLocation = ContextCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_COARSE_LOCATION);
int iFineLocation = ContextCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_FINE_LOCATION);
List<String> listPermissionsNeeded = new ArrayList<>();
if (iExtStorage != PackageManager.PERMISSION_GRANTED) {
listPermissionsNeeded.add(android.Manifest.permission.WRITE_EXTERNAL_STORAGE);
}
if (iFineLocation != PackageManager.PERMISSION_GRANTED) {
listPermissionsNeeded.add(android.Manifest.permission.ACCESS_FINE_LOCATION);
}
if (iCoarseLocation != PackageManager.PERMISSION_GRANTED) {
listPermissionsNeeded.add(android.Manifest.permission.ACCESS_COARSE_LOCATION);
}
if (!listPermissionsNeeded.isEmpty())
{
ActivityCompat.requestPermissions(this,listPermissionsNeeded.toArray
(new String[listPermissionsNeeded.size()]),REQUEST_ID_MULTIPLE_PERMISSIONS);
return false;
}
getLocation();
return true;
} 
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
switch (requestCode) {
case REQUEST_ID_MULTIPLE_PERMISSIONS: {
if (grantResults.length > 0
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// permission was granted, yay! Do the
// location-related task you need to do.
if (ContextCompat.checkSelfPermission(this,
Manifest.permission.ACCESS_FINE_LOCATION)
== PackageManager.PERMISSION_GRANTED) {
getLocation();
}
if (ContextCompat.checkSelfPermission(this,
Manifest.permission.WRITE_EXTERNAL_STORAGE)
== PackageManager.PERMISSION_GRANTED) {
}
if (ContextCompat.checkSelfPermission(this,
Manifest.permission.ACCESS_FINE_LOCATION)
!= PackageManager.PERMISSION_GRANTED) {
}
if (ContextCompat.checkSelfPermission(this,
Manifest.permission.WRITE_EXTERNAL_STORAGE)
!= PackageManager.PERMISSION_GRANTED) {
}
}
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
return;
}
}
}
...
}

更新 #2,2021 年 5 月 14 日:根据 Sasaki 的补充评论。这是来自片段。

public class dataCapture extends Fragment {
...
private boolean requestPermission(View v) {
int iExtStorage = ContextCompat.checkSelfPermission(getActivity(), android.Manifest.permission.WRITE_EXTERNAL_STORAGE);
int iCoarseLocation = ContextCompat.checkSelfPermission(getActivity(), android.Manifest.permission.ACCESS_COARSE_LOCATION);
int iFineLocation = ContextCompat.checkSelfPermission(getActivity(), android.Manifest.permission.ACCESS_FINE_LOCATION);
List<String> listPermissionsNeeded = new ArrayList<>();
if (iExtStorage != PackageManager.PERMISSION_GRANTED) {
listPermissionsNeeded.add(android.Manifest.permission.WRITE_EXTERNAL_STORAGE);
}
if (iFineLocation != PackageManager.PERMISSION_GRANTED) {
listPermissionsNeeded.add(android.Manifest.permission.ACCESS_FINE_LOCATION);
}
if (iCoarseLocation != PackageManager.PERMISSION_GRANTED) {
listPermissionsNeeded.add(android.Manifest.permission.ACCESS_COARSE_LOCATION);
}
if (!listPermissionsNeeded.isEmpty())
{
requestPermissions(listPermissionsNeeded.toArray
(new String[listPermissionsNeeded.size()]),REQUEST_ID_MULTIPLE_PERMISSIONS);
return false;
}
getLocation();
return true;
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
switch (requestCode) {
case REQUEST_ID_MULTIPLE_PERMISSIONS: {
if (grantResults.length > 0
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
if (ContextCompat.checkSelfPermission(getActivity(),
Manifest.permission.ACCESS_FINE_LOCATION)
== PackageManager.PERMISSION_GRANTED) {
getLocation();
}
if (ContextCompat.checkSelfPermission(getActivity(),
Manifest.permission.WRITE_EXTERNAL_STORAGE)
== PackageManager.PERMISSION_GRANTED) {
}
if (ContextCompat.checkSelfPermission(getActivity(),
Manifest.permission.ACCESS_FINE_LOCATION)
!= PackageManager.PERMISSION_GRANTED) {
}
if (ContextCompat.checkSelfPermission(getActivity(),
Manifest.permission.WRITE_EXTERNAL_STORAGE)
!= PackageManager.PERMISSION_GRANTED) {
}
}
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
return;
}
}
}
...
}

此外,我采用了穴居人的方法,并创建了"permissionAssessment()",它将在requestPermission()之后立即运行,假设可能是因为权限可能是由requestPermission()中的用户授予的。

当用户授予权限时,此方法在第一次时不起作用。 这是因为向用户显示使用ActivityCompat.requestPermissions(...)请求权限的提示。 实际授予/拒绝权限将在稍后阶段用户与提示交互时完成。

这意味着在ActivityCompat.requestPermission(...)之后立即运行的函数permissionAssessment(...)将没有权限,因此不会首次成功运行,并且需要片段"重新加载"。

为了确保运行成功,您必须在ActivityCompat.requestPermission(...)的"成功"回调中调用permissionAssessment(...)。这是使用函数onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults)完成的。

这是我的实现:-

public class Fragment1 extends Fragment {
public static final int REQUEST_FINE_LOCATION_CODE = 1;
...
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.data_capture, container, false);
permissionAssessment(v);
...
return (v);
}

public void permissionAssessment(View v){
int permissionCheck = ContextCompat.checkSelfPermission(getActivity(), Manifest.permission.ACCESS_FINE_LOCATION);
if (permissionCheck == PackageManager.PERMISSION_GRANTED) {
// Permission is granted, proceed to get location.
getLocation()
} else {
// Permission is not granted, request permissions.
// Only the prompt is shown here, nothing else will happen.
ActivityCompat.requestPermissions(getActivity(), new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, REQUEST_FINE_LOCATION_CODE);
}
}

/**
* This Function is responsible for handling what happens when permissions are granted by the user.
*/
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {

if (requestCode == REQUEST_FINE_LOCATION_CODE) {
if (grantResults.length > 0) {
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {

// Permissions Granted!
// Get Location as soon as the permissions are granted.
getLocation();
}
} else {

// Permission Denied by the user
// Show a prompt or do nothing as per your use case.
}
}
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
}

public void getLocation() {
mGpsLocationListener = new GpsLocationListener();
lm = (LocationManager) getActivity().getSystemService(getActivity().LOCATION_SERVICE);
mGpsStatus = lm.getGpsStatus(mGpsStatus);
lm.requestLocationUpdates(LocationManager.GPS_PROVIDER, 1000, 0, mGpsLocationListener);
}

请参考这里

  • https://developer.android.com/guide/topics/permissions/overview 和
  • https://developer.android.com/training/permissions/requesting

最新更新