Sorry, this question has probably been asked multiple times already, but I am struggling with different SDK versions. My app is used as a research instrument and solely installed per .apk directly on tablets, thus no app store. I need to record the answers from users and write them into a text file. And I am having a hard time requesting the permission from users to store the data on the external storage.
I added the following line to AndroidManifest.xml:
<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE"/>
In the MainActivity, I call askForPermissions in the onCreate function:
public void askForPermissions() {
int result = ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE);
if (result != PackageManager.PERMISSION_GRANTED){
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
if (!Environment.isExternalStorageManager()) {
Intent intent = new Intent(Settings.ACTION_MANAGE_ALL_FILES_ACCESS_PERMISSION);
startActivity(intent);
}else{
//TODO no clue, what to do here
}
}else{
if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.WRITE_EXTERNAL_STORAGE)){
Toast.makeText(this, "Permission needed to store the data. Please allow storage functionality.", Toast.LENGTH_LONG).show();
} else {
ActivityCompat.requestPermissions(this,new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},2);
}
}
}
createDir();
}
In API version 30, I use the "Intend" and accordingly the settings screen with the permissions shows up and I can grant writing permissions manually - and this works (directory is generated, data stored ...). First questions: In which cases can it happen that there is no external storage manager (hence the TODO)?
What I am struggling with is SDK < 30. This does not seem to work. I do not get permissions and in the app info, I cannot give the app writing permissions manually. The permissions option is disabled. What is the correct way to request permissions in that case (most preferably directly in the app)?
Sorry for the possible double post. Newbie here.
Try this in manifest:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
Related
we're developping an app that will run as a service. One of the feature would be to download file at given URL (ex PDF) and save it into the download folder so user can load it from a specific application (Avenza Maps).
All the download process should be without any user interaction since it's by a service that run in the background.
i've added the following permission:
AndroidManifest.xml
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE"/>
<application
android:requestLegacyExternalStorage="true"
whatever i'll try i got the following error
java.io.FileNotFoundException: /storage/emulated/0/Download/name.pdf (Permission denied)
how can i get the permission to write on Download folder (this is system Download folder)
without having to open an activity to save the file?
i'll try multiple solution yet(2 day of google) without success
for now as stated we target API 28 (android 9)
we will later target other API since we provide the device to the client so we develop only for the API our device have.
I've recently had to develop an app that downloads voice files to a device. While you can specify permissions in the Android manifest, you must request permissions from the user. I've done so in Java, but a conversion to Kotlin should be simple.
//method is called to check the storage permissions for this app
//ensures the app can write and read files
private void checkStoragePermissions() {
Log.i("Permissions", "Checking Storage Permissions");
int writePermissionCode = ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE);//get current write permission
int readPermissionCode = ContextCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE);//ge current read permission
Log.i("Permissions", "Fetching Read & Write Codes: " + readPermissionCode + "/" + writePermissionCode);
//if permissions to read and write to external storage is not granted
if (writePermissionCode != PackageManager.PERMISSION_GRANTED || readPermissionCode != PackageManager.PERMISSION_GRANTED) {
//request read and write permissions
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, PackageManager.PERMISSION_GRANTED);
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, PackageManager.PERMISSION_GRANTED);
Log.i("Permissions", "Asking For Storage Permissions");
} else {//else: if permissions to read and write is already granted
permissionsGranted = true;//set permissions granted bool to true
}
}
After you've done this the downloading of the files can be done in many ways. It's worth noting that files can't be downloaded to any location on an Android device. Only a specific destinations can be used.
I hope this helps to clear some of your confusion. Happy coding!
how can i get the permission to write on Download folder (this is system Download folder) without having to open an activity to save the file?
The simplest solution is to write somewhere else, where you do not need permissions. The methods on Context that return File objects, like getFilesDir() and getExternalFilesDir(), are your primary candidates.
Beyond that, it appears that your app is pre-installed on some device ("we provide the device to the client"). If you have developed a custom firmware image, you should be able to pre-grant the permission to your app as part of that image. Or, if the device is being distributed already configured (no first-time-power-on onboarding UI), you could manually grant WRITE_EXTERNAL_STORAGE to your app or have a UI automation script do it.
If none of those are options, then you have no choice but to ask the user for permission.
I want to create a file explorer , after a lot searching , I found out that I can't Modify , delete or create files on SD card without SAF(Storage Access Framework) on API 25 and higher.Then I installed Some File Manager for Testing how do They Work. All of Them use SAF except Xiaomi File Manager. Xiaomi's only grants a permission. I captured some screenshots.enter image description here
enter image description here
EDIT 1 : I get all my runtime permissions.
thanks for reading :)
Android defines basically three types of permissions:
Normal Permissions
Signature Permissions
Dangerous Permissions
Both Normal and Dangerous permissions must be defined in the Manifest file. But only Dangerous permissions are checked at runtime, Normal permissions are not.
Normal Permissions
Some permissions are automatically granted to the application. Just we need to declare those permissions in AndroidManifest.xml and it will work fine. Those permissions are called Normal Permissions. An example of a normal permission is INTERNET.
list of Normal Permissions: https://developer.android.com/guide/topics/permissions/overview
Signature Permissions
A permission that the system grants only if the requesting application is signed with the same certificate as the application that declared the permission. If the certificates match, the system automatically grants the permission without notifying the user or asking for the user’s explicit approval.
Dangerous Permissions
Some permissions may affect the users private information, or could potentially affect his data or the operation of other application are called Dangerous Permissions. For example, the ability to read the user’s contacts is a dangerous permission. Some other examples are CONTACTS , CAMERA ,CALENDAR, LOCATION , PHONE , STORAGE , SENSORS , MICROPHONE, etc.
Dangerous permissions must be granted by the user at runtime to the app.
Here is an example for requesting a Dangerous Permissions on runtime :-
First, add permissions to AndroidManifest.xml file
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
then ask for permission from user during runtime, like this:-
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (checkSelfPermission(Manifest.permission.CAMERA)!= PackageManager.PERMISSION_GRANTED) {
if (checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
requestPermissions(new String[]{Manifest.permission.CAMERA,Manifest.permission.WRITE_EXTERNAL_STORAGE}, 1);
}
}else {
dispatchTakePictureIntent();
}
}
Then override the onRequestPermissionsResult method according to your need
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (requestCode == 1){
if (grantResults[0] == PackageManager.PERMISSION_GRANTED){
Toast.makeText(this, "Permission Granted", Toast.LENGTH_SHORT).show();
do your stuff...
}else {
Toast.makeText(this,"Permission Denied",Toast.LENGTH_SHORT).show();
}
}
}
For more information check out this article : https://medium.com/programming-lite/runtime-permissions-in-android-7496a5f3de55
I found it after too many searching in Stack Overflow , So there is a flag that call that dialog and get the uri of the storage ,but this way only works with android 7 to 10.
here is answer of my question :
question answer
Facebook, Evernote, Pocket - all apps get this permission on Android 6.0 automatically, even though they are targeting 23 (targetSdkVersion=23).
There has been a lot of documentation regarding the new Marshmallow permission model. One of them is SYSTEM_ALERT_WINDOW been 'promoted' to 'above dangerous' permission class thus requiring a special user intervention in order for apps to be granted with those. If the app has targetSdkVersion 22 or lower, app gets this permission automatically (if requested in the manifest).
However, I've noticed some apps that get this permission, without needing to send the user to the setting special page of Draw over other apps permission. I saw Facebook, Evernote, Pocket - and perhaps there are more.
Anyone knows how an app can be granted this permission without the user go through Settings -> Apps -> Draw over other apps?
Thanks
It is a new behaviour introduced in Marshmallow 6.0.1.
Every app that requests the SYSTEM_ALERT_WINDOW permission and that is installed through the Play Store (version 6.0.5 or higher is required), will have granted the permission automatically.
If instead the app is sideloaded, the permission is not automatically granted. You can try to download and install the Evernote APK from apkmirror.com. As you can see you need to manually grant the permission in Settings -> Apps -> Draw over other apps.
These are the commits [1] [2] that allow the Play Store to give the automatic grant of the SYSTEM_ALERT_WINDOW permission.
Yeh After Marshmallow come Android make security level more stick, But For SYSTEM_ALERT_WINDOW you can show floating action and anything You can Force user to give permission for it By Following Codes in your onCreate() method.
Put this code after setContentView:
// Check if Android M or higher
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
// Show alert dialog to the user saying a separate permission is needed
// Launch the settings activity if the user prefers
Intent myIntent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION);
startActivity(myIntent);
}
The action ACTION_MANAGE_OVERLAY_PERMISSION directly launches the 'Draw over other apps' permission screen.
Edit:
My Above Code works 100% Correct
But I just found that many guys are still searching that how can allow ACTION_MANAGE_OVERLAY_PERMISSION permanently like If user has allow Permission Once then don't ask it every time he open application so here is a solution for you:
Check if device has API 23+
if 23+ API then check if user has permit or not
if had permit once don't drive him to Settings.ACTION_MANAGE_OVERLAY_PERMISSION and if has not permit yet then ask for runtime permission check
Put below line in your onCreate() method. Put this after setContentView:
checkPermission();
Now put below code in onActivityResult:
#TargetApi(Build.VERSION_CODES.M)
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == ACTION_MANAGE_OVERLAY_PERMISSION_REQUEST_CODE) {
if (!Settings.canDrawOverlays(this)) {
// You don't have permission
checkPermission();
} else {
// Do as per your logic
}
}
}
Now finally the checkPermission method code:
public void checkPermission() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (!Settings.canDrawOverlays(this)) {
Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION,
Uri.parse("package:" + getPackageName()));
startActivityForResult(intent, ACTION_MANAGE_OVERLAY_PERMISSION_REQUEST_CODE);
}
}
}
And don't forget to declare this public variable in your class:
public static int ACTION_MANAGE_OVERLAY_PERMISSION_REQUEST_CODE = 5469;
Now(2019) that Google offers an alternative API to SYSTEM_ALERT_WINDOW in the form of Bubbles in Android Q, Google has decided to eventually deprecate SYSTEM_ALERT_WINDOW in a future Android release.
And Android Go devices will no longer grant this permission
i.e Settings.canDrawOverlays() == false
For those who want to get this permission automatically when the app is downloaded from the Play Store, besides the SYSTEM_ALERT_WINDOW in the Manifest, you should go to this link and request this from Google.
You have to provide some additional information why you need this permission and Google will review and give you the automatically permission.
Bear in mind that before you ask for this, you have to:
Have the SYSTEM_ALERT_WINDOW permission in the Manifest
Prompt the user to grant the SYSTEM_ALERT_WINDOW permission within your app, when not already granted
If I miss something feel free to update the answer
If the app targets API 22 or lower, then Play Store will give the SYSTEM_ALERT_WINDOW permission and others when the user clicks to install (showing an alert) even if its device is Android 6.0
Otherwise, if the app targets API 23 or above, so that permission will be request to grant in run time.
i need permission read and write for my plugin, i try a lot of things.
In manifest
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
but not working after v23 according to others posts, so i try with requestPermission but my app crash and in real use case i don't have any interface.
I'm using RICOH THETA Plug-in SDK
I'm trying to use BitmapFactory and got this error
E/BitmapFactory: Unable to decode stream: java.io.FileNotFoundException: /storage/emulated/0/DCIM/100RICOH/R0010156.JPG (Permission denied)
If someone has any idea how to do it.
Thanks.
Don't worry. THETA Plug-in store grants all permission automatically on instal time. Users do not need to grant permissions manually in actual use case. You need to grant permissions manually only for development time.
The official document describes that
Declaration of Permissions
When installing from the RICOH THETA store, based on the protection level set in the manifest file, permission is automatically granted. During development, use an application that displays the screen such as Vysor, and grant permission from the application settings or from a plug-in dialog window.
You have to give permission manually in android 6 and above use dexter library
Link https://github.com/Karumi/Dexter
in first you should check android version
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (ContextCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED &&
ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED {
// do work
} else {
String[] permissions = new String[]{Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE};
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
requestPermissions(permissions, 100);
}
}
} else {
// do work
}
Facebook, Evernote, Pocket - all apps get this permission on Android 6.0 automatically, even though they are targeting 23 (targetSdkVersion=23).
There has been a lot of documentation regarding the new Marshmallow permission model. One of them is SYSTEM_ALERT_WINDOW been 'promoted' to 'above dangerous' permission class thus requiring a special user intervention in order for apps to be granted with those. If the app has targetSdkVersion 22 or lower, app gets this permission automatically (if requested in the manifest).
However, I've noticed some apps that get this permission, without needing to send the user to the setting special page of Draw over other apps permission. I saw Facebook, Evernote, Pocket - and perhaps there are more.
Anyone knows how an app can be granted this permission without the user go through Settings -> Apps -> Draw over other apps?
Thanks
It is a new behaviour introduced in Marshmallow 6.0.1.
Every app that requests the SYSTEM_ALERT_WINDOW permission and that is installed through the Play Store (version 6.0.5 or higher is required), will have granted the permission automatically.
If instead the app is sideloaded, the permission is not automatically granted. You can try to download and install the Evernote APK from apkmirror.com. As you can see you need to manually grant the permission in Settings -> Apps -> Draw over other apps.
These are the commits [1] [2] that allow the Play Store to give the automatic grant of the SYSTEM_ALERT_WINDOW permission.
Yeh After Marshmallow come Android make security level more stick, But For SYSTEM_ALERT_WINDOW you can show floating action and anything You can Force user to give permission for it By Following Codes in your onCreate() method.
Put this code after setContentView:
// Check if Android M or higher
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
// Show alert dialog to the user saying a separate permission is needed
// Launch the settings activity if the user prefers
Intent myIntent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION);
startActivity(myIntent);
}
The action ACTION_MANAGE_OVERLAY_PERMISSION directly launches the 'Draw over other apps' permission screen.
Edit:
My Above Code works 100% Correct
But I just found that many guys are still searching that how can allow ACTION_MANAGE_OVERLAY_PERMISSION permanently like If user has allow Permission Once then don't ask it every time he open application so here is a solution for you:
Check if device has API 23+
if 23+ API then check if user has permit or not
if had permit once don't drive him to Settings.ACTION_MANAGE_OVERLAY_PERMISSION and if has not permit yet then ask for runtime permission check
Put below line in your onCreate() method. Put this after setContentView:
checkPermission();
Now put below code in onActivityResult:
#TargetApi(Build.VERSION_CODES.M)
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == ACTION_MANAGE_OVERLAY_PERMISSION_REQUEST_CODE) {
if (!Settings.canDrawOverlays(this)) {
// You don't have permission
checkPermission();
} else {
// Do as per your logic
}
}
}
Now finally the checkPermission method code:
public void checkPermission() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (!Settings.canDrawOverlays(this)) {
Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION,
Uri.parse("package:" + getPackageName()));
startActivityForResult(intent, ACTION_MANAGE_OVERLAY_PERMISSION_REQUEST_CODE);
}
}
}
And don't forget to declare this public variable in your class:
public static int ACTION_MANAGE_OVERLAY_PERMISSION_REQUEST_CODE = 5469;
Now(2019) that Google offers an alternative API to SYSTEM_ALERT_WINDOW in the form of Bubbles in Android Q, Google has decided to eventually deprecate SYSTEM_ALERT_WINDOW in a future Android release.
And Android Go devices will no longer grant this permission
i.e Settings.canDrawOverlays() == false
For those who want to get this permission automatically when the app is downloaded from the Play Store, besides the SYSTEM_ALERT_WINDOW in the Manifest, you should go to this link and request this from Google.
You have to provide some additional information why you need this permission and Google will review and give you the automatically permission.
Bear in mind that before you ask for this, you have to:
Have the SYSTEM_ALERT_WINDOW permission in the Manifest
Prompt the user to grant the SYSTEM_ALERT_WINDOW permission within your app, when not already granted
If I miss something feel free to update the answer
If the app targets API 22 or lower, then Play Store will give the SYSTEM_ALERT_WINDOW permission and others when the user clicks to install (showing an alert) even if its device is Android 6.0
Otherwise, if the app targets API 23 or above, so that permission will be request to grant in run time.