VictorGalisson
VictorGalisson

Reputation: 715

App crashes when enqueuing request to DownloadManager

I'm trying to make an app that download an iCal file using DownloadManager. After some research, I can't find a solution to my issue. Using the Android Studio debugger, I found out the app crashes when enqeuing the request. Here the error I get in the Android Monitor :

 java.lang.SecurityException: Permission Denial: writing com.android.providers.downloads.DownloadProvider uri content://downloads/my_downloads from pid=5082, uid=10208 requires android.permission.INTERNET, or grantUriPermission()

I don't understand why it requires the android.permission.INTERNET which is already given, as shown in my AndroidManifest below :

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="galisson.esiea.pst3.smartwatch">

<application
    android:allowBackup="true"
    android:icon="@drawable/smartwatch"
    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>

    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />


</application>

Here is my MainActivity :

public class MainActivity extends AppCompatActivity {

     EditText url;
     Button buttonAdd;

     @Override
     protected void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
         setContentView(R.layout.activity_main);

         url = (EditText) findViewById(R.id.editTextLink);
         buttonAdd = (Button) findViewById(R.id.buttonADD);

         buttonAdd.setOnClickListener(new View.OnClickListener() {
             @Override
             public void onClick(View v) {
                 if(!url.getText().toString().isEmpty()) {
                     Uri iCalURI = Uri.parse(url.getText().toString());

                     DownloadData(iCalURI);

                 }
             }
         });


     }

     private void DownloadData(Uri p_uri) {

         DownloadManager manager = (DownloadManager) getSystemService(Context.DOWNLOAD_SERVICE);
         DownloadManager.Request request = new DownloadManager.Request(p_uri);

         request.setDescription("iCal Calendar downloading");
         request.setTitle("iCal calendar");
         request.setAllowedNetworkTypes(DownloadManager.Request.NETWORK_WIFI | DownloadManager.Request.NETWORK_MOBILE);                      //Restrict the types of networks over which this download may proceed.
         request.setAllowedOverRoaming(false);                                                                                               //Set whether this download may proceed over a roaming connection.
         request.allowScanningByMediaScanner();
         request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);
         request.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, "iCal_tmp.ics");

         manager.enqueue(request);           //this is where it crashes

         return;
     }
  }

Is my problem with the permission or the request in itself?

Upvotes: 1

Views: 1950

Answers (1)

JavadBadirkhanly
JavadBadirkhanly

Reputation: 645

First of grant permissions which you need.

public boolean isStoragePermissionGranted() {
    if (Build.VERSION.SDK_INT >= 23) {
        if (checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE)
                == PackageManager.PERMISSION_GRANTED) {
            Log.v(TAG, "Permission is granted");

            writeFilesToSdCard();
            return true;
        } else {

            Log.v(TAG, "Permission is revoked");
            ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 1);
            return false;
        }
    } else { //permission is automatically granted on sdk<23 upon installation
        writeFilesToSdCard();
        return true;
    }
}

Then request it with overrided method.

@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
    super.onRequestPermissionsResult(requestCode, permissions, grantResults);
    if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
        Log.v(TAG, "Permission: " + permissions[0] + "was " + grantResults[0]);
        //resume tasks needing this permission
    }
}

NOTE: Don't forget putting permissions in manifest outside of <application> tag.

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.myproject">

    <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" />

    <application
        //
    </application>

</manifest>

Upvotes: 4

Related Questions