Android Application Architecture: Implements user permission in lifecycle
I have a LocationListener that extends the LiveData class. Starting with Android 6.0, request permissions at runtime. Now, when I try to implement the LiveData class, it requires permission checking in the onActive()
function. I have to make boilerplate code in each activity for the permissions requested and the results received. Is there a way to move like this
The onRequestPermissionsResult
() and checkSelfPermission()
functions to LocationListener ?
Location fragment .java
public class LocationFragment extends LifecycleFragment {
private FragmentLocationBinding binding;
public LocationFragment() {
Required empty public constructor
}
@Override
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
if (ContextCompat.checkSelfPermission(getActivity(),
permission. ACCESS_COARSE_LOCATION)
!= PackageManager.PERMISSION_GRANTED) {
Should we show an explanation?
if (ActivityCompat.shouldShowRequestPermissionRationale(getActivity(),
Manifest.permission.ACCESS_COARSE_LOCATION)) {
Show an explanation 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(getActivity(),
new String[]{Manifest.permission.ACCESS_COARSE_LOCATION},
200);
MY_PERMISSIONS_REQUEST_READ_CONTACTS is an
app-defined int constant. The callback method gets the
result of the request.
}
}
get the viewmodel from activity
LastLocationViewModel lastLocationViewModel = ViewModelProviders.of(getActivity())
.get(LastLocationViewModel.class);
lastLocationViewModel.getLastKnowLocation().observe(this, location -> {
binding.setLocation(location);
});
}
@Override
public void onRequestPermissionsResult(int requestCode,
String permissions[], int[] grantResults) {
switch (requestCode) {
case 200: {
If request is cancelled, the result arrays are empty.
if (grantResults.length > 0
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
Toast.makeText(getActivity(), "Rights Granted", Toast.LENGTH_SHORT).show();
permission was granted, yay! Do the
contacts-related task you need to do.
} 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
}
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
Inflate the layout for this fragment
binding = DataBindingUtil
.inflate(LayoutInflater.from(getActivity()), R.layout.fragment_location, null, false);
return binding.getRoot();
}
}
LastLocationListener.java
public class LastLocationListener extends LiveData<Location> {
private LocationManager locationManager;
private Context context;
private LocationListener listener = new LocationListener() {
@Override
public void onLocationChanged(Location location) {
Log.d("Location Msg", location.toString());
setValue(location);
}
@Override
public void onStatusChanged(String s, int i, Bundle bundle) {
}
@Override
public void onProviderEnabled(String s) {
}
@Override
public void onProviderDisabled(String s) {
}
};
public LastLocationListener(Context context) {
this.context = context;
locationManager = (LocationManager) context.getSystemService(
Context.LOCATION_SERVICE);
}
@Override
protected void onActive() {
if (ActivityCompat.checkSelfPermission(context, permission. ACCESS_FINE_LOCATION)
!= PackageManager.PERMISSION_GRANTED
&& ActivityCompat.checkSelfPermission(context, permission. ACCESS_COARSE_LOCATION)
!= PackageManager.PERMISSION_GRANTED) {
TODO: Consider calling
ActivityCompat#requestPermissions
here to request the missing permissions, and then overriding
public void onRequestPermissionsResult(int requestCode, String[] permissions,
int[] grantResults)
to handle the case where the user grants the permission. See the documentation
for ActivityCompat#requestPermissions for more details.
return;
}
locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, listener);
}
@Override
protected void onInactive() {
locationManager.removeUpdates(listener);
}
}
Solution
when I tried to implements the LiveData Class and it required the permission checking in onActive() function
No, it doesn’t. What you see is a lint warning that you can suppress.
What is required is that you have permission before attempting to use this particular bit of LiveData
.
Is there any way to move such onRequestPermissionsResult() and checkSelfPermission() functions to the LocationListener ?
No.