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

Accessing GPS coordinates in same application session in which permission was provided by the user via popup window

我希望首次在设备上启动应用程序的用户能够在该会话中访问 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 卫星时间。 Satellite/GPS 在用户授予位置权限的会话之后重新启动应用程序后,数据显示正常。我强烈希望 GPS 在用户设置权限的会话中“上线”。建设性的建议将不胜感激。提前致谢。

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

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;
        }
    }
  }
...
}

In addition, I took the caveman approach, and created "permissionAssessment()" that would run immediately following requestPermission() assuming that perhaps since permissions were likely granted by the user in requestPermission().

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

这意味着在 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);
}

请参考这个