5

DownloadManager kullanarak Download dizinine örnek bir PDF dosyası indiren bir Android App programlanmış. İşte kod:Download Manager Android İzinler hata: harici depolama yazın Depolama

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

Şimdi, çalışsaydım Xperia Z3 Android 6.0 Android Studio bunu ayıklamak çalıştırın. Ben indir butonuna tıklandığında gibi , bu hata oluşur:

hedefi VM, adres uzak,
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) 

: 'localhost: 8600', nakliye: 'soket'

(üçüncü satırda) onu harici depolamada yazma izninin olmadığını gösterir.

Ama AndroidManifest doğru bir şekilde kurulmuş:

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

Ne yapmam gerekiyor?

+0

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

cevap

11

Uygulamanız Android 6.0'da çalıştırıldığı için bu hatayı alıyorsunuz (API 23 düzeyinde). API seviyesinden> = 23 Çalışma zamanındaki izni kontrol etmeniz gerekir.

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

toplam şeyler görünüyor: o zaman isteği istemez ise

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

: Kullanıcı depolamayı kullanmaya izin verdiyse You kod aşağıda düzeyde Yani ilk kontrol ediniz 23. için gayet güzel böyle:

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

Ve son şey :) callback'inde tarafından sonucu alırsınız:

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



Veya, sadece çok kolay Tüm bu uygulama işlemek için benim özel sınıf PermissionCheck kullanabilirsiniz.

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


kullanım: İşte sınıftır

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

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

** dikkat edin, bu yöntemler otomatik olarak ve aynı zamanda onRequestPermissionsResult ateş açılacak izinler istenir diyoruz. :)

+0

Çok teşekkür ederim adamım. –

+0

Dize dizisindeki 1 öğesinin ne anlama geldiğini söyleyebilir misiniz? –

+1

Sadece herhangi bir kimse 'Manifest.permission.WRITE_EXTERNAL_STORAGE' ile sorunu varsa, android.Manifest.permission.WRITE_EXTERNAL_STORAGE' yerine –

0

Bu aynı sorunu, bir Özel Sekmeler uygulaması çalıştıran API 23 öykünücemde (24 ve 25 iyi çalıştı) vardı. Bu çözümü ve diğer bazı varyasyonları denedim ve izin verildiğini görebiliyordum ancak sorun herhangi bir indirme denemesinde kaldı. Uygulamayı gerçek bir cihazda çalıştırdığımda (izin istek kodu kodu) Google'ın depolama alanına erişmesine otomatik olarak izin verdim - uygulamam değil. Çalışma zamanı izinleri için kodu kaldırdım ve tarayıcıya erişmek için tarayıcıya (öykünücünde varsayılan) izin verdim ve uygulamanız iyi çalıştı. Aşağıdaki gönderi, öykünücü ile neler olabileceğine dair bazı bilgiler sağladı: Requesting and allowing WRITE_EXTERNAL_STORAGE permission at runtime has no effects on the current session