Android Manager Error for Application Manager: External Storage Record

I have programmed an Android application that downloads a sample PDF file to the download directory using the DownloadManager. Here is the code:

@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_vertretungsplan); Button dlbutton = (Button) findViewById(R.id.buttondownload); final Context c = this; dlbutton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { DownloadManager.Request request = new DownloadManager.Request(Uri.parse(myurl)); request.setTitle("Vertretungsplan"); request.setDescription("wird heruntergeladen"); request.allowScanningByMediaScanner(); request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED); String filename = URLUtil.guessFileName(myurl, null, MimeTypeMap.getFileExtensionFromUrl(myurl)); request.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, filename); DownloadManager manager = (DownloadManager) c.getSystemService(Context.DOWNLOAD_SERVICE); manager.enqueue(request); } }); } 

Now I tried to debug it from Android Studio on my Xperia Z3 Android 6.0. When I clicked the download button, this error occurs:

 E/AndroidRuntime: FATAL EXCEPTION: main Process: com.example.markwitt.schul_app, PID: 29297 java.lang.SecurityException: No permission to write to /storage/emulated/0/Download/hrpsampletable.pdf: Neither user 10047 nor current process has android.permission.WRITE_EXTERNAL_STORAGE. at android.os.Parcel.readException(Parcel.java:1627) at android.database.DatabaseUtils.readExceptionFromParcel(DatabaseUtils.java:183) at android.database.DatabaseUtils.readExceptionFromParcel(DatabaseUtils.java:135) at android.content.ContentProviderProxy.insert(ContentProviderNative.java:476) at android.content.ContentResolver.insert(ContentResolver.java:1240) at android.app.DownloadManager.enqueue(DownloadManager.java:946) at com.example.markwitt.schul_app.Vertretungsplan$1.onClick(Vertretungsplan.java:59) at android.view.View.performClick(View.java:5280) at android.view.View$PerformClick.run(View.java:21239) at android.os.Handler.handleCallback(Handler.java:739) at android.os.Handler.dispatchMessage(Handler.java:95) at android.os.Looper.loop(Looper.java:224) at android.app.ActivityThread.main(ActivityThread.java:5526) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616) 

Disconnected from the target virtual machine, address: "localhost: 8600", transport: "socket"

(in the third line) he shows me that he does not have permission to write to external storage.

But my AndroidManifest is configured correctly:

 <?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.markwitt.schul_app"> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.INTERNET" /> <application android:launchMode="singleTop" android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:supportsRtl="true" android:theme="@style/AppTheme"> <activity android:name=".Stundenplan"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <activity android:name=".Vertretungsplan"></activity> </application> 

What do I need to do?

+5
source share
2 answers

You get this error because your application runs on Android 6.0 (API level 23). From API level> = 23 you will need to check the resolution at runtime. Your code is great for levels below 23. So first check if your user is allowed to use the repository:

 if (checkSelfPermission(android.Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED) { Log.e("Permission error","You have permission"); return true; } 

If not, request a request:

 ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, REQUEST_CODE); 

All things look like this:

 public boolean haveStoragePermission() { if (Build.VERSION.SDK_INT >= 23) { if (checkSelfPermission(android.Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED) { Log.e("Permission error","You have permission"); return true; } else { Log.e("Permission error","You have asked for permission"); ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 1); return false; } } else { //you dont need to worry about these stuff below api level 23 Log.e("Permission error","You already have the permission"); return true; } } 

And last: get the result by calling back:

  @Override public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) { super.onRequestPermissionsResult(requestCode, permissions, grantResults); if(grantResults[0]== PackageManager.PERMISSION_GRANTED){ //you have the permission now. DownloadManager.Request request = new DownloadManager.Request(Uri.parse(myurl)); request.setTitle("Vertretungsplan"); request.setDescription("wird heruntergeladen"); request.allowScanningByMediaScanner(); request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED); String filename = URLUtil.guessFileName(myurl, null, MimeTypeMap.getFileExtensionFromUrl(myurl)); request.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, filename); DownloadManager manager = (DownloadManager) c.getSystemService(Context.DOWNLOAD_SERVICE); manager.enqueue(request); } } 



Or you can simply use your own PermissionCheck class to very simply handle this entire implementation. Here is the class:

 import android.Manifest; import android.app.Activity; import android.content.Context; import android.content.pm.PackageManager; import android.support.v4.app.ActivityCompat; /** * Created by Tushar on 6/30/2017. */ public class PermissionCheck{ public static boolean readAndWriteExternalStorage(Context context){ if(ActivityCompat.checkSelfPermission(context, Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED || ActivityCompat.checkSelfPermission(context, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED){ ActivityCompat.requestPermissions((Activity) context, new String[]{Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.READ_EXTERNAL_STORAGE}, 1); return false; }else{ return true; } } public static boolean audioRecord(Context context){ if(ActivityCompat.checkSelfPermission(context, Manifest.permission.RECORD_AUDIO) != PackageManager.PERMISSION_GRANTED ){ ActivityCompat.requestPermissions((Activity) context, new String[]{Manifest.permission.RECORD_AUDIO}, 2); return false; }else{ return true; } } public static boolean readAndWriteContacts(Context context){ if(ActivityCompat.checkSelfPermission(context, Manifest.permission.READ_CONTACTS) != PackageManager.PERMISSION_GRANTED || ActivityCompat.checkSelfPermission(context, Manifest.permission.WRITE_CONTACTS) != PackageManager.PERMISSION_GRANTED){ ActivityCompat.requestPermissions((Activity) context, new String[]{Manifest.permission.READ_CONTACTS, Manifest.permission.WRITE_CONTACTS}, 3); return false; }else{ return true; } } public static boolean vibrate(Context context){ if(ActivityCompat.checkSelfPermission(context, Manifest.permission.VIBRATE) != PackageManager.PERMISSION_GRANTED){ ActivityCompat.requestPermissions((Activity) context, new String[]{Manifest.permission.VIBRATE}, 4); return false; }else{ return true; } } public static boolean sendSms(Context context){ if(ActivityCompat.checkSelfPermission(context, Manifest.permission.SEND_SMS) != PackageManager.PERMISSION_GRANTED){ ActivityCompat.requestPermissions((Activity) context, new String[]{Manifest.permission.SEND_SMS}, 5); return false; }else{ return true; } } //Just like this you can implement rest of the permissions. } 


using:

 if(PermissionCheck.readAndWriteExternalStorage(context)){ //Your read write code. } if(PermissionCheck.sendSms(context)){ //Your sms sending code. } 

** Please note that when these methods are called, permissions are automatically requested and your onRequestPermissionsResult will be launched. :)

+12
source

I had the same problem on my API 23 emulator (24 and 25 did fine) on which the Custom Tabs application was created. I tried this solution, as well as some other options, and I could see that I was granted permission, but the problem remained with any download attempts. When I launched the application on a real device (without requesting a request), I was automatically offered to allow Google access to the store, and not to my application. I removed the code for runtime permissions and set the permissions for the browser (by default on the emulator) to access the repository, and my application worked fine. The following publication gave some idea of ​​what might happen to the emulator: Requesting and resolving WRITE_EXTERNAL_STORAGE at run time does not affect the current session

0
source

Source: https://habr.com/ru/post/1259521/


All Articles