0

I want to download documents from the links ive scraped on the web, i have a listview listener so when i press one of the item in the list it will return a url, ive set it up so getLink will be the link of the pdf file i want to download and set up filenametoo.

getLink = http://www.phivolcs.dost.gov.ph/images/Flyer-eq-and-eq-hazards.pdf
filename = Flyer-eq-and-eq-hazards.pdf

So i call this inside my listview listener and its suppose to download but its not working. new DownloadFile().execute(getLink, filename);

I have errors like java.io.IOException: open failed: ENOENT (No such file or directory)

insideMain

private class DownloadFile extends AsyncTask<String, Void, Void>{

   @Override
   protected Void doInBackground(String... strings) {
       String fileUrl = strings[0];   // -> getLink = http://www.phivolcs.dost.gov.ph/images/Flyer-eq-and-eq-hazards.pdf
       String fileName = strings[1];  // -> Flyer-eq-and-eq-hazards.pdf
       String extStorageDirectory = Environment.getDataDirectory().toString();
       File folder = new File(extStorageDirectory, "testthreepdf");
       folder.mkdir();

       File pdfFile = new File(folder, fileName);

       try{
           pdfFile.createNewFile();
       }catch (IOException e){
           e.printStackTrace();
       }
       FileDownloader.downloadFile(fileUrl, pdfFile);
       return null;
   }
}

downloadFile

package com.example.boneyflesh.homepage;


import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;

public class FileDownloader {
    private static final int MEGABYTE = 1024 * 1024;

    public static void downloadFile(String fileUrl, File directory) {
        try {

            URL url = new URL(fileUrl);
            HttpURLConnection urlConnection = (HttpURLConnection)  url.openConnection();              
            urlConnection.connect();

            InputStream inputStream = urlConnection.getInputStream();
            FileOutputStream fileOutputStream = new FileOutputStream(directory);
            int totalSize = urlConnection.getContentLength();

            byte[] buffer = new byte[MEGABYTE];
            int bufferLength = 0;
            while ((bufferLength = inputStream.read(buffer)) > 0) {
                fileOutputStream.write(buffer, 0, bufferLength);
            }
            fileOutputStream.close();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

  }

Manifest

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="com.example.boneyflesh.homepage">

<!--
     The ACCESS_COARSE/FINE_LOCATION permissions are not required to use
     Google Maps Android API v2, but you must specify either coarse or fine
     location permissions for the 'MyLocation' functionality. 
-->
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"></uses-permission>
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"></uses-permission>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" ></uses-permission>
<uses-permission android:name="android.permission.READ_PHONE_STATE"></uses-permission>


<application
    android:allowBackup="true"
    android:icon="@mipmap/ic_launcher"
    android:label="@string/app_name"
    android:supportsRtl="true"
    android:theme="@style/AppTheme"
    tools:ignore="AllowBackup">
    <activity android:name=".MainActivity">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />

            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>
    <!--
         The API key for Google Maps-based APIs is defined as a string resource.
         (See the file "res/values/google_maps_api.xml").
         Note that the API key is linked to the encryption key used to sign the APK.
         You need a different API key for each encryption key, including the release key that is used to
         sign the APK for publishing.
         You can define the keys for the debug and release targets in src/debug/ and src/release/. 
    -->
    <meta-data
        android:name="com.google.android.geo.API_KEY"
        android:value="@string/google_maps_key" />

    <activity
        android:name=".MapsActivity"
        android:label="@string/title_activity_maps" />
    <!--
 ATTENTION: This was auto-generated to add Google Play services to your project for
 App Indexing.  See https://g.co/AppIndexing/AndroidStudio for more information.
    -->
    <meta-data
        android:name="com.google.android.gms.version"
        android:value="@integer/google_play_services_version" />

    <activity android:name=".GeohazardResults" />
    <activity android:name=".MineralResults" />
    <activity android:name=".LandformResults" />
    <activity android:name=".Downloads"></activity>
</application>


EDIT

I called useFileAsyncTask(); then i received an error FATAL EXCEPTION: AsyncTask #1

Constructor

protected void useFileAsyncTask() {
    DownloadFile task = new DownloadFile(this);
    task.execute();
}

Asynktask

private class DownloadFile extends AsyncTask<String, Void, Void>{

   private Context myContextRef;

   public DownloadFile(Context context) {
       myContextRef = context;
   }


   @Override
   protected Void doInBackground(String... strings) {

       //String fileUrl = strings[0];   // -> http://maven.apache.org/maven-1.x/maven.pdf
       //String fileName = strings[1];  // -> maven.pdf
       String extStorageDirectory = myContextRef.getFilesDir().toString();
       //String extStorageDirectory = Environment.getDataDirectory().toString();
       File folder = new File(extStorageDirectory, "testthreepdf");
       folder.mkdir();

       File pdfFile = new File(folder, filename);

       try{
           pdfFile.createNewFile();
       }catch (IOException e){
           e.printStackTrace();
       }
       FileDownloader.downloadFile(getLink, pdfFile);
       return null;
   }
   }

downloadFile remains the same.

Boneyflesh
  • 343
  • 1
  • 4
  • 16

1 Answers1

0

Change the line

String extStorageDirectory = Environment.getDataDirectory().toString();

to

String extStorageDirectory = context.getFilesDir().toString();

where context is the Context that you will need to supply to the AsyncTask.

Environment.getDataDirectory() is the system-wide user data directory where you may not create files while ontext.getFilesDir() is the data directory for your app where you may create files.

Cheticamp
  • 61,413
  • 10
  • 78
  • 131
  • sorry but im not quite familiar with `AsyncTask` tried to chang it to `String extStorageDirectory = context.getFilesDir().toString();` says cannot resolve symbol 'context' my options are to create a local variable, field, parameter and reference. what do i do? – Boneyflesh Mar 01 '17 at 07:44
  • You will need to get a `Context` into your `AsyncTask` - several ways to do this, but you can find a way that will work with `AsyncTask` at [getting context in AsyncTask](http://stackoverflow.com/questions/16920942/getting-context-in-asynctask) on Stack Overflow. – Cheticamp Mar 01 '17 at 11:30
  • Your code uses `AsyncTask`. It is the base class for your `DownloadFile` class. You need to add `Context` to the constructor for `DownloadFile`. – Cheticamp Mar 01 '17 at 13:29
  • Ill edit my code for you to check,,i dont know if im doing this right. – Boneyflesh Mar 01 '17 at 14:49
  • nope,,instead of downloading a file i made a `browser intent` so every time i click a link it will open a browser instead, I'm still gonna implement this when someone posts an answer that i can get. – Boneyflesh Mar 02 '17 at 12:44
  • still gives me permission errors,,im using andoid 6.0 by the way. – Boneyflesh Mar 02 '17 at 12:49