5

Я запрограммировал приложение для Android, которое загружает образец файла PDF в каталог загрузки с помощью DownloadManager. Вот код:Ошибка загрузки приложений для диспетчера приложений для Android:

@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); 
     } 
    }); 
} 

Теперь, я пытался отладить запустить его из Android Studio на моем Xperia Z3 Android 6.0. Как я нажал на кнопку загрузки, эта ошибка:

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) 

отсоединен от цели VM, адрес: «локальный: 8600», транспорт: «гнездо»

(на третьей линии) его показывает, что у него нет разрешения на запись на внешнем хранилище.

Но мой AndroidManifest настроен правильно:

<?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> 

Что мне нужно сделать?

+0

https://stackoverflow.com/questions/32635704/android-permission-doesnt-work-even-if-i-have-declared-it – CommonsWare

ответ

11

Вы получаете эту ошибку, так как приложение работает на Android 6.0 (уровень API 23). С уровня API> = 23 Вам нужно проверить разрешение во время выполнения. You код просто отлично на уровень ниже 23. Поэтому, пожалуйста, проверьте сначала, если ваш пользователь дал разрешение на использование хранилища:

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

Если нет, то подскажите запрос:

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

Всего вещей внешность как это:

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; 
    } 
} 

И последняя вещь :) получить результат, обратный вызов:

@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); 
     } 
    } 



Или, вы можете просто использовать свой собственный класс PermissionCheck обрабатывать все это выполнение очень легко. Вот класс:

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. 
} 


использование:

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

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

** Обратите внимание, что эти методы вызывают попросят автоматически, а также ваш onRequestPermissionsResult будет обожженным разрешение. :)

+0

Спасибо очень много человек. –

+0

Можете ли вы рассказать мне, что означает 1 в массиве строк? –

+1

На всякий случай, если у кого-то есть проблема с 'Manifest.permission.WRITE_EXTERNAL_STORAGE', используйте' android.Manifest.permission.WRITE_EXTERNAL_STORAGE' вместо –

0

У меня была такая же проблема на моем эмуляторе API 23 (24 и 25 отлично), запускающем приложение Custom Tabs. Я пробовал это решение, а также некоторые другие варианты, и я мог видеть, что мне было предоставлено разрешение, но проблема осталась при любых попытках загрузки. Когда я запустил приложение на реальном устройстве (без запроса на запрос), мне автоматически было предложено разрешить Google доступ к хранилищу, а не к моему приложению. Я удалил код для разрешений времени выполнения и установил разрешение для браузера (по умолчанию на эмуляторе) для доступа к хранилищу, и мое приложение отлично работало. Следующий пост дал некоторое представление о том, что может произойти с эмулятором: Requesting and allowing WRITE_EXTERNAL_STORAGE permission at runtime has no effects on the current session

Смежные вопросы