I know that android 6.0 requires runtime permissions. Could you please help me implement runtime permissions for Bluetooth? I tried using the example on https://developer.android.com/training/permissions/requesting.html but was getting a bunch of errors. Thanks.
You can easily create a Permit object to start requesting permission(s) from user.
Firstly initialize the Permit object passing your activity
Permit permit=new Permit(MainActivity.this);
Then attach a listner to this object
permit.setOnPermitStatusListner(new Permit.OnPermitStatusListner()
{
#Override
public void onAllPermitsGranded()
{
// ALL PERMITS ACCEPTED
}
#Override
public void onSomePermitsDenied(ArrayList<String> deniedPermits)
{
// SOME PERMITS ACCEPTED
}
#Override
public void onAllPermitsDenied()
{
// ALL PERMITS DENIED
}
});
Then ask for what all permissions you need to work(Must be declared in the Manifest)
permit.askPermitsFor(Manifest.permission.BLUETOOTH,Manifest.permission.BLUETOOTH_ADMIN,Manifest.permission.<Other BT permissions>);
You need to add this library to work with Permit object. Here is the complete documentation : https://github.com/sangeethnandakumar/TestTube
Related
What permission do we need to use instead of WRITE_EXTERNAL_STORAGE in Android 13 app on Android 13 device? I have read through the documentation but not able to get what permission we need to use. The function which needs this is a photo picker which access the images, before it used to ask for permission on Android 12, but once the app was upgraded to Android 13 and used on an Android 13 app, the photo picker stopped working. It uses the permission WRITE_EXTERNAL_STORAGE which is not required anymore. But what needs to be used instead of this?
The function is from a library - react-native-image-crop-picker
#ReactMethod
public void openPicker(final ReadableMap options, final Promise promise) {
final Activity activity = getCurrentActivity();
if (activity == null) {
promise.reject(E_ACTIVITY_DOES_NOT_EXIST, "Activity doesn't exist");
return;
}
setConfiguration(options);
resultCollector.setup(promise, multiple);
initiatePicker(activity);
permissionsCheck(activity, promise, Collections.singletonList(Manifest.permission.WRITE_EXTERNAL_STORAGE), new Callable<Void>() {
#Override
public Void call() {
return null;
}
});
}
Use react-native-permissions for managing the permissions.
The docs are quite simple, kindly go through this.
Some permission changes were required for this in the react-native-image-cropper library - https://github.com/ivpusic/react-native-image-crop-picker/pull/1852
I was wondering, how to handle the runtime permission in capsulated objects.
So, let's say we have a loggerobject which needs to write to disk.
The only thing the objects should do is writing to the disk.
Shall this object also handle runtime permissions?
Shall the object be in the beginning unable to write (by a flag) and the flag will swap if we get the permission?
I will be glad to know, how some of you do this.
Thank you!
The permission is granted for the whole app, not for individual objects.
If you get the permission for your app once, you don't need to request it again and again.
In your case you can check and request the necessary permissions before writing to a file or even before the creation of your object.
The best practice is to request the permissions in the context just before using the features which require the permissions.
Check my library for handling permissions easily. Just get a reference of context and you can request permissions from anywhere.
https://github.com/nabinbhandari/Android-Permissions
There is no one clear answer for your question. Your question is related to the software architecture in general. So there might be a lot of different opinions. I will give you mine.
Often times you want a class to have a single responsibility and do only one job. Therefore, a logger only logs messages but it doesn't care a lot about permissions.
So I would say it's often a question about how to design your API and make it easy to work with.
For example, let's say we have an interface for Logger:
interface Logger {
void d(String tag, String message);
}
Then we introduce a concrete implementation called FileLogger:
final class FileLogger implements Logger {
#Override
public void d(String tag, String message) {
// write a message to a file somehow
}
}
The question here is should FileLogger#d fails with SecurityException if the permission has not been granted yet? Or should it just warn a developer somehow?
Personally, in this case I would modify FileLogger to not fail if the permission has not been granted yet, but the permission itself must be granted in another part of the application.
final class FileLogger implements Logger {
#Override
public void d(String tag, String messsage) {
if (ContextCompat.checkSelfPermission(context, Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED) {
// write a log to a file
}
}
}
Let's take a look at another example. Imagine we have an interface called LocationApi:
interface LocationApi {
#Nullable
Location getLastLocation();
}
A user must grant a permission to the application so it can obtain his last location. Is it a critical to fail immediately if the app doesn't have a permission? I would say yes!
The implementation of this interface would look something like this:
final class LocationApiImpl implements LocationApi {
#Nullable
public Location getLastLocation() {
if (ContextCompat.checkSelfPermission(..) != PackageManager.PERMISSION_GRANTED) {
throw new SecurityException();
}
// obtain a location
}
}
P.S. There is a special annotation RequiresPermission that can help you to indicate that a method requires a permission, otherwise it might throw SecurityException.
Then we can modify LocationApi interface like this:
interface LocationApi {
#RequiresPermission(Manifest.permission.ACCESS_FINE_LOCATION)
#Nullable
Location getLastLocation();
}
I really struggle with this since a while :( as I need an solution that works within UNITY3D.
I need to check if the user has given the permission to access the Android device camera (and location on a second level).
Normally the app start by asking for this permissions at launch, but if the user denies the access for the camera I need to know and check that later.
Otherwise the user could hit the camera UI button I made and try to access the camera via webcamtexture... and that leads into a crash of the app.
Since Android API 23 you cannot ignore or already grant permissions by changing the android manifest like I tried after reading several posts about that.
Thank's to everyone who has an idea to solve this.
Check this library: https://github.com/sanukin39/UniAndroidPermission
In that library I got these methods to check and request Permission.
public static void requestPermission(String permissionStr){
if(!hasPermission(permissionStr)) {
UnityPlayer.currentActivity.requestPermissions(new String[]{permissionStr}, 0);
}
}
public static boolean hasPermission(String permissionStr) {
if(Build.VERSION.SDK_INT < 23) {
return true;
}
Context context = UnityPlayer.currentActivity.getApplicationContext();
return context.checkCallingOrSelfPermission(permissionStr) == PackageManager.PERMISSION_GRANTED;
}
Hope it helps:)
I've seen SO question Can you request permissions synchronously in Android Marshmallow (API 23)'s runtime permissions model?. The answer is no.
Hence, I added a code as below (simplified version):
public class MyActivity ... {
private boolean hasGotPermissionRequestResult = false;
#Override
public void onCreate(...) {
if (ContextCompat.checkSelfPermission(...) == PackageManager.PERMISSION_DENIED) {
ActivityCompat.requestPermission(...);
while (!hasGotPermissionRequestResult) {}
}
}
#Override
public void onRequestPermissionResult(...) {
// whether granted or not
hasGotPermissionRequestResult = true;
}
}
However, I am not sure whether my approach is nice, safe and efficient.
Well, what you trying to achieve simply ain't possible, however there are several ways to overcome this:
Only trigger the method you wanna call when the permission is granted.
If you'd like to make the User only uses your app because that particular permission is so important that your app will not function without it, then use an educated screen to tell the users why you would want to use this permission in an intro screen kinda way.
I've created a library just for this kind of scenario where the library simplify the Permissions for you, it can be also used as a stand Alone Activity that has an Intro to your permission. you could check it out in Github PermissionHelper Github
I'm using Google's EasyPermissions library. In my app I have two buttons, one to record video and one to capture image. Since both require Camera Permissions they are both annotated with #AfterPermissionGranted.
So my method to record video looks like this :
#Override
#AfterPermissionGranted(RC_CAMERA_PERM)
public void openCameraToRecordVideo() {
if (EasyPermissions.hasPermissions(this, Manifest.permission.CAMERA, Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
// Code here
}
And similarly for taking pictures :
#Override
#AfterPermissionGranted(RC_CAMERA_PERM)
public void openCameraToCaptureImage() {
if (EasyPermissions.hasPermissions(this, Manifest.permission.CAMERA, Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
// Code here
}
They are both annotated with Permissions since I don't know which one user will click first.
What happens is when user clicks one button and accepts the permissions then both methods run one after the other. Which is obviously not the behavior I want.
I'd really appreciate any help on how to handle this situation.
Thank you.
Remove AfterPermissionGranted from both openCameraX function. Defined a private field lastAction. Write a new function openCamera with a AfterPermissionGranted annotation that check is lastAction is set and if so, call related function. In each openCameraX, check if you have camera permission and if not, update lastAction and start request camera permission.
Actually, what you are doing is asking the same permission two times with different function name so remove either openCameraToCaptureImage() method or openCameraToRecordVideo() method.