I was trying to download an image from a server and save it in the external memory, but in Android 11 it gives me an error when I try to create the file.
I have granted permission to access the external storage.
i searched a bit on the internet and they suggested me to put this code in the manifest, but it didn't work for android 11
android:requestLegacyExternalStorage="true"
manifest
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:requestLegacyExternalStorage="true"
android:roundIcon="#mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="#style/Theme.TestDwonloadImgApp"
android:usesCleartextTraffic="true">
<activity android:name=".MainActivity2">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name=".MainActivity">
</activity>
</application>
MainActivity
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ImageView img = findViewById(R.id.img);
ImmagineInterface ii = RetrofitManager.retrofit.create(ImmagineInterface.class);
Call<ResponseBody> call = ii.downloadFile("/immaginimusei/arte-scienza.jpg");
call.enqueue(new Callback<ResponseBody>() {
#Override
public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
if (response.code() == 200) {
boolean result = writeResponseBody(response.body(), "/immaginimusei/arte-scienza.jpg");
if(result) {
Bitmap bitmap = BitmapFactory.decodeFile(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS).toString() + "/ArtHunter/immaginimusei/arte-scienza.jpg");
img.setImageBitmap(bitmap);
}
}
}
#Override
public void onFailure(Call<ResponseBody> call, Throwable t) {
Bitmap bitmap = BitmapFactory.decodeFile(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS).toString() + "/ArtHunter/immaginimusei/arte-scienza.jpg");
img.setImageBitmap(bitmap);
}
});
}
}
writeResponseBody
public static boolean writeResponseBody(ResponseBody body, String dir1) {
try {
String state = Environment.getExternalStorageState();
if (Environment.MEDIA_MOUNTED.equals(state)) {
// todo change the file location/name according to your needs
String path = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS).toString() + "/ArtHunter";
String path1 = path + dir1;
File f = new File(path1);
String path2 = f.getPath();
String nome = f.getName();
path2 = path2.replaceAll("/" + nome, "");
File directory = new File(path2);
if (!directory.exists())
directory.mkdirs();
File img = new File(path2, nome);
if (img.exists())
return true;
img.createNewFile();
InputStream inputStream = null;
FileOutputStream outputStream = null;
try {
byte[] fileReader = new byte[4096];
inputStream = body.byteStream();
outputStream = new FileOutputStream(img); //error here!
while (true) {
int read = inputStream.read(fileReader);
if (read == -1) {
break;
}
outputStream.write(fileReader, 0, read);
}
outputStream.flush();
return true;
} catch (IOException e) {
e.printStackTrace();
return false;
} finally {
if (inputStream != null) {
inputStream.close();
}
if (outputStream != null) {
outputStream.close();
}
}
}
return false;
} catch (IOException e) {
e.printStackTrace();
return false;
}
}
error
/System.err: java.io.FileNotFoundException: /storage/emulated/0/Download/ArtHunter/immaginimusei/arte-scienza.jpg: open failed: EEXIST (File exists)
W/System.err: at libcore.io.IoBridge.open(IoBridge.java:492)
at java.io.FileOutputStream.<init>(FileOutputStream.java:236)
at java.io.FileOutputStream.<init>(FileOutputStream.java:186)
at com.theapplegeek.testdwonloadimgapp.MainActivity.writeResponseBody(MainActivity.java:93)
at com.theapplegeek.testdwonloadimgapp.MainActivity$1.onResponse(MainActivity.java:47)
at retrofit2.DefaultCallAdapterFactory$ExecutorCallbackCall$1.lambda$onResponse$0$DefaultCallAdapterFactory$ExecutorCallbackCall$1(DefaultCallAdapterFactory.java:89)
at retrofit2.-$$Lambda$DefaultCallAdapterFactory$ExecutorCallbackCall$1$hVGjmafRi6VitDIrPNdoFizVAdk.run(Unknown Source:6)
at android.os.Handler.handleCallback(Handler.java:938)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:245)
at android.app.ActivityThread.main(ActivityThread.java:8004)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:631)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:978)
Caused by: android.system.ErrnoException: open failed: EEXIST (File exists)
at libcore.io.Linux.open(Native Method)
at libcore.io.ForwardingOs.open(ForwardingOs.java:166)
at libcore.io.BlockGuardOs.open(BlockGuardOs.java:254)
W/System.err: at libcore.io.ForwardingOs.open(ForwardingOs.java:166)
at android.app.ActivityThread$AndroidOs.open(ActivityThread.java:7865)
at libcore.io.IoBridge.open(IoBridge.java:478)
... 13 more
In Android 11 android:requestLegacyExternalStorage="true" will simply be ignored, since it was an ad-hoc solution for Android < 11 to not break old apps.
Now, you must use
<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE"/>
Also you could just use SAF to avoid all this 'permissions' hassle. This is what Google recommends for apps that do not need to manage most internal storage data. Refer to:
https://developer.android.com/guide/topics/providers/document-provider
However, if you don't want to break you app and lose all your hard work, consider
if(Environment.isExternalStorageManager())
{
internal = new File("/sdcard");
internalContents = internal.listFiles();
}
else
{
Intent permissionIntent = new Intent(Settings.ACTION_MANAGE_ALL_FILES_ACCESS_PERMISSION);
startActivity(permissionIntent);
}
This will bring up a settings page where you will be able to give storage access to your app. If the app already has permission, then you will be able to access the directory. Place this at the very beginning of onCreate() method after setting layout resource.
It's best not to do this for any future apps you build.
Go to your mobile setting -> apps -> select your app -> permissions -> storage -> select Allow managment of all files
It works for me.
Android has become too complex when it comes to creating folders.
If you want to avoid so many problems and not use things like android:requestLegacyExternalStorage="true" and adding many permissions like MANAGE_EXTERNAL_STORAGE, READ_EXTERNAL_STORAGE, WRITE_EXTERNAL_STORAGE which can be a nightmare, even when it comes to publishing your app to the marketplace.
In addition to that, from Android version 30 onwards, you ca NOT extend android:requestLegacyExternalStorage="true". So you will have problems again.
What is recommended is to start to save your recordings inside applications dedicated folder, because in the future Android will no longer let you create folders anymore, even with legacy methods. You can use standard directories in which to place any file like DIRECTORY_MUSIC, DIRECTORY_PICTURES, etc.
For instance, I created my own method for saving audio recording in Android 33 and it works perfectly. I don't need to add anything to my Manifest.
override fun startRecording(): Boolean {
try {
val recordingStoragePath = "${app.getExternalFilesDir(Environment.DIRECTORY_MUSIC)}"
recordingFilePath = "$recordingStoragePath/${fileRecordingUtils.generateFileName()}"
mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC)
mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP)
// Audio Quality Normal
mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB)
mediaRecorder.setAudioSamplingRate(8000)
// Set path
mediaRecorder.setOutputFile(recordingFilePath)
mediaRecorder.prepare()
mediaRecorder.start()
Toast.makeText(app, "Recording Started", Toast.LENGTH_SHORT).show()
} catch (e: IOException) {
Toast.makeText(app, "Recording Failed. Problem accessing storage.", Toast.LENGTH_SHORT).show()
mediaRecorder.reset()
return false
} catch (e: Exception) {
mediaRecorder.reset()
return false
}
return true
}
Related
I want to save my captured images to a specific directory (/sdcard/DCIM/FokusStacker) with the following method. I have tried different Locations, but none of them worked.
private void capturePicture(){
File dir = new File("/sdcard/DCIM/FokusStacker");
String fileName = "IMG_"+ System.currentTimeMillis();
File file = new File(dir,fileName);
Log.d(TAG, "capturePicture: DIRECTORY: "+dir.getAbsolutePath());
ImageCapture.OutputFileOptions outputFileOptions =
new ImageCapture.OutputFileOptions.Builder(file).build();
imageCapture.takePicture(outputFileOptions, ContextCompat.getMainExecutor(this), new ImageCapture.OnImageSavedCallback() {
#Override
public void onImageSaved(#NonNull ImageCapture.OutputFileResults outputFileResults) {
Log.d(TAG, "onImageSaved: SAVED");
return;
}
#Override
public void onError(#NonNull ImageCaptureException exception) {
Log.d(TAG, "onError: FAILED");
return;
}
});
}
These are the Permission i've included:
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
And i also tried saving it to the internal storage.
Code Snippet for to get the local directoryof the App for the file:
File dir = getApplicationContext().getFilesDir();
Can anyone please guide me how to do this?
I am a little new to android so please, I would appreciate if I can have a detailed procedure.
I am trying to make possible for users to update ann app from device. We have a server where from user can download apk file with new version of an app.
Here is the code which starts after button pressed:
Handler handler = new Handler(Looper.getMainLooper());
Thread thread = new Thread(new Runnable() {
#Override
public void run() {
File folder = new File(getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS).toString());
File file = new File(folder.getAbsolutePath(), "localdb.apk");
final Uri uri = (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) ?
FileProvider.getUriForFile(MainActivity.this, BuildConfig.APPLICATION_ID + ".provider", file) :
Uri.fromFile(file);
if (file.exists())
file.delete();
//url to get app from server
String url = Names.UPDATE_URL;
InputStream input = null;
OutputStream output = null;
HttpURLConnection connection = null;
try {
URL sUrl = new URL(url);
connection = (HttpURLConnection) sUrl.openConnection();
connection.connect();
// download the file
input = connection.getInputStream();
output = new FileOutputStream(file);
byte data[] = new byte[4096];
int count;
while ((count = input.read(data)) != -1) {
// allow canceling with back button
output.write(data, 0, count);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (output != null)
output.close();
if (input != null)
input.close();
} catch (IOException ignored) {
}
if (connection != null)
connection.disconnect();
}
handler.post(new Runnable() {
#Override
public void run() {
Intent install = new Intent(Intent.ACTION_INSTALL_PACKAGE)
.setData(uri)
.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
startActivity(install);
}
});
}
});
thread.start();
Here is what i have in manifest:
...<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="android.permission.QUICKBOOT_POWERON" />
<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES"/>
...
<provider
android:name="androidx.core.content.FileProvider"
android:authorities="ru.mob.myapp.provider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="#xml/provider_paths"/>
</provider>
...
and finally an xml file provider_paths:
<?xml version="1.0" encoding="utf-8"?>
<paths>
<external-path name="external_files" path="."/>
</paths>
So, everything works fine, I download apk with new version, it is named same as already installed,
system asks me to install (update) my application, but when everything is almoust done I get "App is not installed" message without any details.
Does anyone have a solution, hint, adviŅe?
I should generate a .pdf file inside the android data folder to use the Java code below, with the permissions enabled in the XML manifest file. But when I run the code I have the following exception. The application has different permissions within the manifest, It should all be configured correctly, I state that the application I'm testing on an old Android 4. How can I solve this? and what is it due to?
Exception: error: java. I. FileNotFoundException: /data/my.pdf:
open failed: EACCES (Permission denied)
Code:
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE " />
public static Boolean GeneratePDF(String base64) {
Boolean ret = true;
try {
String direttorio=""+Environment.getDataDirectory().getAbsolutePath();
final File dwldsPath = new File(direttorio + "/" + "my.pdf");
byte[] pdfAsBytes = Base64.decode(base64, 0);
FileOutputStream os;
os = new FileOutputStream(dwldsPath, false);
os.write(pdfAsBytes);
os.flush();
os.close();
} catch (Exception ex) {
System.out.println("\n Errore Generazione File: "+ex);
ret = false;
}
return ret;
}
you have to give Write permission at run time.
It can be achieved something as following...
public class MainActivity extends AppCompatActivity implements ActivityCompat.OnRequestPermissionsResultCallback{
private static final int REQUEST_WRITE_PERMISSION = 111;
#Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
if (requestCode == REQUEST_WRITE_PERMISSION && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
GeneratePDF("your String name");
}
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
requestPermission();
}
private void requestPermission() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
requestPermissions(new String[]{android.Manifest.permission.WRITE_EXTERNAL_STORAGE}, REQUEST_WRITE_PERMISSION);
} else {
GeneratePDF("your String name");
}
}
}
Replace this line
String direttorio=""+Environment.getDataDirectory().getAbsolutePath();
To:
String direttorio= Environment.getExternalStorageDirectory().getAbsolutePath();
final File dwldsPath = new File(direttorio + "/" + my.pdf");
if you're using Android 6.0 and above,
there could be 2 ways:
1 if you're making only for demo purpose you can manually give permission to app
by going in settings->apps->permissions. Then allow all permission which are
required.
2 you've to implement runtime permissions so that user can allow it runtime.
I have written codes from the tutorials of SLIDENERD to save info in different areas as internal cache,External cache,Private information and public information with the following codes.
EditText uname,pwd;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
uname=(EditText)findViewById(R.id.editText);
pwd=(EditText)findViewById(R.id.editText3);
}
public void intCache(View view){
File fileDir=getCacheDir();
File myFile=new File(fileDir,"User_info_intCache.txt");
write(myFile);
}
public void extCache(View view){
File fileDir=getExternalCacheDir();
File myFile=new File(fileDir,"User_info_extCache.txt");
write(myFile);
}
public void pvtDir(View view){
File fileDir=getExternalFilesDir("User_Info");
File myFile=new File(fileDir,"User_info_pvtExt.txt");
write(myFile);
}
public void pubDir(View view){
File fileDir= Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS);
File myFile=new File(fileDir,"User_info_pubExt.txt");
write(myFile);
}
private void write(File myFile){
String unameS=uname.getText().toString();
String pwdS=pwd.getText().toString();
FileOutputStream fileOutputStream=null;
try {
fileOutputStream=new FileOutputStream(myFile);
try {
fileOutputStream.write(unameS.getBytes());
fileOutputStream.write(pwdS.getBytes());
} catch (IOException e) {
e.printStackTrace();
}
} catch (FileNotFoundException e) {
e.printStackTrace();
}
finally {
try {
if (fileOutputStream != null) {
fileOutputStream.close();
}
Toast.makeText(this,"data is written to "+myFile.getAbsolutePath(),Toast.LENGTH_LONG).show();
} catch (IOException e) {
e.printStackTrace();
}
}
}
I can see the files user_info_extCache.txt , User_info_pvtExt.txt. I know that internal cache location ( User_info_intCache.txt ) cant be seen.But i can't find the User_info_pubExt.txt file which must be stored in public directory Downloads.I cant see the file created by following code.
File fileDir= Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS);
File myFile=new File(fileDir,"User_info_pubExt.txt");
The toast shows that the file is created by above piece of code under /storage/emulated/0/Download/User_info_pubExt.txt .
I find somewhere that if phone is connected to pc,external storage cant be accessed.So i tried both by removing the mobile from pc.The toast says that file is created.But i cant find it under that folder.
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.iamka.storage">
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:roundIcon="#mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="#style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name=".Main2Activity"></activity>
</application>
Your toast claiming that data is written is on the wrong place. As the toast also displays when there is an exception.
Place the toast in the try block instead. Or yet better after the close() but only if you close().
And place other toasts in the catch blocks to inform the user with e.getMessage().
As for the exception: all the paths exept the last one do not need any read/write permission at all. For the latter you need read/write permission.
But requesting them in manifest is not enough for Android 6+ as then you have to add some code to ask the user to confirm the requested permissions.
Google for runtime permissions.
i am trying to build an application that downloads files (e.g. ".jpg", ".txt") from the web when given a url. its not really meant to be a real world application, more just an exercise to help me become more comfortable with network and io based code. for now i am just pulling the bytes from the url and then converting them to a string and logging that. then from there i want to write this to a file. the problem i am running into now is that im getting a file not found exception stating that access is denied:
07-11 21:03:14.458 19072-20051/com.example.zacharymcdaniel.webdownloader E/AsyncDownload: network errorjava.io.FileNotFoundException: /sdcard/-1157023572 (Permission denied)
java.io.FileNotFoundException: /sdcard/-1157023572 (Permission denied)
at java.io.FileOutputStream.open(Native Method)
at java.io.FileOutputStream.<init>(FileOutputStream.java:221)
at java.io.FileOutputStream.<init>(FileOutputStream.java:169)
at com.example.zacharymcdaniel.webdownloader.AsyncDownload.doInBackground(AsyncDownload.java:60)
at com.example.zacharymcdaniel.webdownloader.AsyncDownload.doInBackground(AsyncDownload.java:23)
at android.os.AsyncTask$2.call(AsyncTask.java:304)
at java.util.concurrent.FutureTask.run(FutureTask.java:237)
at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:243)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1133)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:607)
at java.lang.Thread.run(Thread.java:761)
here is my manifest:
<?xml version="1.0" encoding="utf-8"?>
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:roundIcon="#mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="#style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
and the code for the asynctask implementation i am using to perform the download and write operation:
public class AsyncDownload extends AsyncTask<Void, Void, Void>{
private static final String TAG = "AsyncDownload";
private static final String STORAGE_LOCATION = "/sdcard/"; //android directory picker is needed
private URL url;
private ArrayList<Byte> bytes = new ArrayList<>();
public AsyncDownload(URL url){
this.url = url;
}
#Override
protected Void doInBackground(Void... params){
try{
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
BufferedReader in = new BufferedReader(new InputStreamReader(connection.getInputStream()));
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
int c;
while ((c = in.read()) != -1){
buffer.write(c);
}
Log.i(TAG, buffer.toString());
Random rand = new Random(4L);
String temp = String.valueOf(rand.nextInt());
String finalLocation = STORAGE_LOCATION + temp;
File file = new File(finalLocation);
file.getParentFile().mkdirs();
file.setWritable(true);
file.setReadable(true);
FileOutputStream fOut = new FileOutputStream(file);
fOut.write(buffer.toByteArray());
fOut.flush();
fOut.close();
FileInputStream fIn = new FileInputStream(finalLocation);
String reRead = new String();
int a;
while ((a = fIn.read()) != -1){
reRead += a;
}
Log.i(TAG, reRead);
//this section is for automatic file naming
/*Random rand = new Random(5L);
String fileNumber = String.valueOf(rand.nextInt());
StringBuilder sb = new StringBuilder();
sb.append(fileNumber).append("download"); //definitely needs work
Log.i(TAG, sb.toString());*/
//FileOutputStream fOut = new FileOutputStream()
}catch (IOException ioe){
Log.e(TAG, "network error" + ioe.toString(), ioe);
}
return null;
}
}
i am pretty new to this so i may have made some pretty obvious mistakes. please help solve this error. thank you.
add this to your activity
if (ContextCompat.checkSelfPermission(context,
android.Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(InterviewListActivity.this,
new String[]{android.Manifest.permission.WRITE_EXTERNAL_STORAGE}, REQUEST_CODE_EXT_STORAGE);
}
call this method in your activity
protected void checkPermissions() {
final int writeExternalPermissionCheck = ActivityCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE);
if (writeExternalPermissionCheck != PackageManager.PERMISSION_GRANTED {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},
Constant.REQUEST_CODE_ASK_PERMISSIONS);
}
}
}
and override this method
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults) {
switch (requestCode) {
case Constant.REQUEST_CODE_ASK_PERMISSIONS:
if (grantResults!=null) {
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
//Call ur save method here or change the variable value true
} else {
Logger.toast(this, "Please enable write permission from Apps);
}
}
break;
default:
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
}
}
Hope This helps.
Api level 6.0 or above you need runtime permission