I am working on the it should download the file from server and store in the sdcard .
But I getting the exception : java.io.filenotfoundexception (permission denied)
public class MainActivity extends ActionBarActivity {
// usually, subclasses of AsyncTask are declared inside the activity class.
// that way, you can easily modify the UI thread from here
private class DownloadTask extends AsyncTask<String, Integer, String> {
private Context context;
private PowerManager.WakeLock mWakeLock;
File file,sdcard;
public DownloadTask(Context context) {
this.context = context;
}
#Override
protected String doInBackground(String... sUrl) {
System.out.print("BAckground");
InputStream input = null;
OutputStream output = null;
HttpURLConnection connection = null;
try {
URL url = new URL(sUrl[0]);
connection = (HttpURLConnection) url.openConnection();
connection.connect();
// expect HTTP 200 OK, so we don't mistakenly save error report
// instead of the file
if (connection.getResponseCode() != HttpURLConnection.HTTP_OK) {
return "Server returned HTTP " + connection.getResponseCode()
+ " " + connection.getResponseMessage();
}
// this will be useful to display download percentage
// might be -1: server did not report the length
int fileLength = connection.getContentLength();
// download the file
input = connection.getInputStream(); '
GEtting exception in line '
output = new FileOutputStream("sdcard/file.mp3");
byte data[] = new byte[4096];
long total = 0;
int count;
while ((count = input.read(data)) != -1) {
// allow canceling with back button
if (isCancelled()) {
input.close();
return null;
}
total += count;
// publishing the progress....
if (fileLength > 0) // only if total length is known
publishProgress((int) (total * 100 / fileLength));
output.write(data, 0, count);
}
} catch (Exception e) {
return e.toString();
} finally {
try {
if (output != null)
output.close();
if (input != null)
input.close();
} catch (IOException ignored) {
}
if (connection != null)
connection.disconnect();
}
return null;
}
Try this
File root = new File(Environment.getExternalStorageDirectory(), "file.mp3");
if (!root.exists()) {
root.mkdirs();
}
output = new FileOutputStream(root);
and add permission on manifest file as
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
Try this code:
File yourFile = new File(Environment.getExternalStorageDirectory(),"yourfile.txt");
// replace yourfile.txt with "file.mp3" your file name
if(!yourFile.exists()) {
yourFile.createNewFile();
}
FileOutputStream output = new FileOutputStream(yourFile, false);
Also do not forget to add this permission in manifest file.
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
You also need to check weather your sdcard is mounted or not,
if (Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState())) {
// Mounted
}
else {
}
Do like this,
File root = new File(Environment.getExternalStorageDirectory(), "file.mp3");
if (!root.exists()) {
root.mkdirs();
}
output = new FileOutputStream(root);
And add this permission in Android menfestfile.
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
Related
I used the code below in executor service to download a file from URL. It downloads the file but size is 0 bytes. code works fine when I use asyncTask. but when I put it in executor service doesn't work.
Any ideas why the download won't be complete?
onCreate:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ExecutorService pool = Executors.newSingleThreadExecutor();
Button btn = findViewById(R.id.btn);
String url = "https://file-examples-com.github.io/uploads/2017/10/file_example_JPG_100kB.jpg";
btn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
pool.execute(new NetworkService(url));
}
});
NetworkService class:
private class NetworkService implements Runnable {
private String url;
public NetworkService(String url) {
this.url = url;
}
#Override
public void run() {
dlFile(url);
}
private String dlFile(String surl) {
try {
InputStream input = null;
OutputStream output = null;
HttpURLConnection connection = null;
try {
URL url = new URL(surl);
connection = (HttpURLConnection) url.openConnection();
connection.connect();
if (connection.getResponseCode() != HttpURLConnection.HTTP_OK)
return "Server returned HTTP " + connection.getResponseCode() + " " + connection.getResponseMessage();
input = connection.getInputStream();
String title = URLUtil.guessFileName(String.valueOf(url), null, null);
output = new FileOutputStream(Environment.getExternalStorageDirectory().toString() + "/" + title);
} catch (Exception e) {
return e.toString();
} finally {
try {
if (output != null)
output.close();
if (input != null)
input.close();
} catch (IOException ignored) {
}
if (connection != null)
connection.disconnect();
}
} finally {
}
return null;
}
}
There are a couple of things you should do and verify.
1 - First of all, make sure you have granted the required permissions to save file to the storage.
READ_EXTERNAL_STORAGE
WRITE_EXTERNAL_STORAGE
INTERNET
2 - Add android:requestLegacyExternalStorage="true" to your manifest file's application tag for android 10 and later versions.
3 - Correct your FileOutputStream initialisation, because
val direct = File(Environment.getExternalStorageDirectory().toString() + "/test_files")
You are creating a path above in test_files Folder, but in FileOutputStream you have specified different path. So, the correct line should be
output = FileOutputStream( direct + "/" + title)
And finally, add the following line after output = line to write image to the buffer, because you are reading the InputStream but you are not writing it on the buffer. That is why, it only create the path in storage, but do not write file to that path.
val buf = ByteArray(1024)
var len: Int
while (input.read(buf).also { len = it } > 0) {
output.write(buf, 0, len)
}
PS: I have written the code in Kotlin and tested it on Android 10, It works fine.
I hope this helps. Please don't forget to accept the answer if it help.
Hi friends have lot of confusion.
First thing is it's not storing in on my device instead of it stores on my emulator under this path data/data/com.customfonts/files/Robotoo.ttf. Then when I try to get file throwing Runtime Exception file not found because it's searching under data/user/0/com.customfonts/Robotoo.ttf instead of searching data.data/com.customfonts/files/Robotoo.ttf.
getDirectory.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view)
{
new DownloadingTask().execute();
Log.i("FilePAthFirst",""+getFilesDir());
}
});
btnGETDATA.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
String filename="Robotoo.ttf";
getTypeface(filename);
}
});
private Typeface getTypeface(String filename)
{
Typeface font;
try
{
font = Typeface.createFromFile(getFilesDir() +"/"+filename);
Log.i("FOnt found",""+font);
}
catch (Exception e)
{
e.printStackTrace();
return null;
}
return font;
}
private class DownloadingTask extends AsyncTask<Void,Void,Void>{
#Override
protected Void doInBackground(Void... voids) {
try {
URL url = new URL(fonturl);
HttpURLConnection c = (HttpURLConnection) url.openConnection();
c.setRequestMethod("GET");
c.connect();
FileOutputStream fos = new FileOutputStream(getApplicationContext().getFilesDir()+ "Robotoo.ttf");
Log.i("Download","complete");
Log.i("FOS",""+fos.toString());
InputStream is = c.getInputStream();
byte[] buffer = new byte[1024];
int len1 = 0;
while ((len1 = is.read(buffer)) != -1) {
fos.write(buffer, 0, len1);
}
fos.close();
is.close();
}
catch (Exception e) {
e.printStackTrace();
outputFile = null;
Log.e("Error", "Download Error Exception " + e.getMessage());
}
return null;
}
}
Harmonize the code to get the file path for saving the file and loading the file.
To load the tff also use getApplicationContext().getFilesDir()+filename
I used your same code, which is in answer it working fine, May be you can check you have permission for the internet in Manifest <uses-permission android:name="android.permission.INTERNET"></uses-permission>, if you already have this, You can wait till onPostExecute of your AsyncTask and check you are getting any error.
Internal storage
And For internal storage, It will not be constant as data.data/com.customfonts/files/ from Android 6.0, It will be dynamic, We should not hard code the path(You are doing that is correct)
Refer this Offical Doc
Edited: Forgot to Add earlier that to writing a file in internal storage as per doc we should use openFileOutput so I am using that.
private class DownloadingTask extends AsyncTask<Void,Void,Void> {
#Override
protected Void doInBackground(Void... voids) {
try {
URL url = new URL("[your url here]");
HttpURLConnection c = (HttpURLConnection) url.openConnection();
c.setRequestMethod("GET");
c.connect();
Log.d("sdsdfds", "doInBackground: " + getApplicationContext().getFilesDir());
FileOutputStream fos = getApplicationContext().openFileOutput("Robotoo4.ttf", MODE_PRIVATE);
Log.i("Download","complete");
Log.i("FOS",""+fos.toString());
InputStream is = c.getInputStream();
byte[] buffer = new byte[4 * 1024];
int len1 = 0;
while ((len1 = is.read(buffer)) != -1) {
fos.write(buffer, 0, len1);
}
fos.close();
is.close();
}
catch (Exception e) {
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(Void aVoid) {
super.onPostExecute(aVoid);
File file = new File(getFilesDir() + "/" + "Robotoo4.ttf");
Log.d("", "onPostExecute: " + file.exists() + " " + file.getAbsolutePath() + " Length " + file.length() );
}
}
protected void doDownload(final String urlLink, final String fileName) {
Thread dx = new Thread() {
public void run() {
File root = android.os.Environment.getExternalStorageDirectory();
File dir = new File (root.getAbsolutePath() + "/Content2/");
if(dir.exists()==false) {
dir.mkdirs();
}
//Save the path as a string value
try
{
URL url = new URL(urlLink);
Log.i("FILE_NAME", "File name is "+imageFile);
Log.i("FILE_URLLINK", "File URL is "+url);
URLConnection connection = url.openConnection();
connection.connect();
// this will be useful so that you can show a typical 0-100% progress bar
int fileLength = connection.getContentLength();
// download the file
InputStream input = new BufferedInputStream(url.openStream());
OutputStream output = new FileOutputStream(dir+"/"+imageFile);
byte data[] = new byte[1024];
long total = 0;
int count;
while ((count = input.read(data)) != -1) {
total += count;
output.write(data, 0, count);
}
output.flush();
output.close();
input.close();
}
catch (Exception e)
{
e.printStackTrace();
Log.i("ERROR ON DOWNLOADING FILES", "ERROR IS" +e);
}
}
};
dx.start();
}
through this, I cannot download the file from the server.
How to solve this problem?
First of all you should use Async-Task.
Here is how you can do this
final DownloadTask downloadTask = new DownloadTask(YourActivity.this);
downloadTask.execute("the url to the file you want to download");
// usually, subclasses of AsyncTask are declared inside the activity class.
// that way, you can easily modify the UI thread from here
private class DownloadTask extends AsyncTask<String, Integer, String> {
private Context context;
public DownloadTask(Context context) {
this.context = context;
}
#Override
protected String doInBackground(String... sUrl) {
InputStream input = null;
OutputStream output = null;
HttpURLConnection connection = null;
try {
URL url = new URL(sUrl[0]);
connection = (HttpURLConnection) url.openConnection();
connection.connect();
// expect HTTP 200 OK, so we don't mistakenly save error report
// instead of the file
if (connection.getResponseCode() != HttpURLConnection.HTTP_OK) {
return "Server returned HTTP " + connection.getResponseCode()
+ " " + connection.getResponseMessage();
}
// this will be useful to display download percentage
// might be -1: server did not report the length
int fileLength = connection.getContentLength();
// download the file
input = connection.getInputStream();
output = new FileOutputStream("/sdcard/file_name.extension");
byte data[] = new byte[4096];
long total = 0;
int count;
while ((count = input.read(data)) != -1) {
// allow canceling with back button
if (isCancelled()) {
input.close();
return null;
}
total += count;
}
} catch (Exception e) {
return e.toString();
} finally {
try {
if (output != null)
output.close();
if (input != null)
input.close();
} catch (IOException ignored) {
}
if (connection != null)
connection.disconnect();
}
return null;
}
#Override
protected void onPostExecute(String result) {
if (result != null)
Toast.makeText(context,"Download error: "+result, Toast.LENGTH_LONG).show();
else
Toast.makeText(context,"File downloaded", Toast.LENGTH_SHORT).show();
}
i follow more explain in this site for download mp3 or picture from URL , I follow more method and try to write my method but when i run application it stop.
I make method to query download when click
also put permission for INTERNET & WRITE_EXTERNAL_STORAGE
put the problem is still
this method is download
public static void downloadMain(){
File fileToSave = null;
String scrPath ="http://***";
BufferedInputStream bis;
BufferedOutputStream bos;
fileToSave = new File(Environment.getExternalStorageDirectory().getPath() +"/"+ "A"+"/");
if (!fileToSave.exists())
fileToSave.mkdirs();
fileToSave = new File(Environment.getExternalStorageDirectory().getPath() +"/"+ "A" +"/" + "h"+"/");
if (!fileToSave.exists())
fileToSave.mkdirs();
File file = new File (fileToSave,"***.mp3");
try{
URL url = new URL(scrPath+"***.mp3");
URLConnection ucon = url.openConnection();
ucon.connect();
bis=new BufferedInputStream(ucon.getInputStream());
bos = new BufferedOutputStream(new FileOutputStream(file));
bis=new BufferedInputStream(url.openStream());
byte[] data = new byte[1024];
int a =0;
while(true){
int k = bis.read(data);
if(k==-1){
bis.close();
bos.flush();
bos.close();
break;
}
bos.write(data, 0, k);
a+=k;
}
}catch(IOException e){}
}
I have three main perplexity about your program:
Do you run the following code in an asynctask? (this must run asincronusly otherwise it will block)
Why it loop infinitly?
You couldn't open an url or a file named with a '*' inside of it
Edit:
You must run the download method asincronusly otherwise it wouldn't work, interaction with filesystem and network couldn't be done in the main thread
Edit2:
AsyncTask should be something like this
private class DownloadTask extends AsyncTask<String, Integer, String> {
private Context context;
public DownloadTask(Context context) {
this.context = context;
}
#Override
protected String doInBackground(String... sUrl) {
InputStream input = null;
OutputStream output = null;
HttpURLConnection connection = null;
try {
URL url = new URL(sUrl[0]);
connection = (HttpURLConnection) url.openConnection();
connection.connect();
// expect HTTP 200 OK, so we don't mistakenly save error report
// instead of the file
if (connection.getResponseCode() != HttpURLConnection.HTTP_OK) {
return "Server returned HTTP " + connection.getResponseCode()
+ " " + connection.getResponseMessage();
}
// download the file
input = connection.getInputStream();
output = new FileOutputStream("/sdcard/file_name.extension");//put here your path and your mkdirs
byte data[] = new byte[4096];
long total = 0;
int count;
while ((count = input.read(data)) != -1) {
total += count;
output.write(data, 0, count);
}
} catch (Exception e) {
return e.toString();
} finally {
try {
if (output != null)
output.close();
if (input != null)
input.close();
} catch (IOException ignored) {
}
if (connection != null)
connection.disconnect();
}
return null;
}
#Override
protected void onPostExecute(String result) {
if (result != null)
Toast.makeText(context,"Download error: "+result, Toast.LENGTH_LONG).show();
else
Toast.makeText(context,"File downloaded", Toast.LENGTH_SHORT).show();
}
}
And you shoould call it like this
DownloadTask downloadTask = new DownloadTask(YourActivity.this);
downloadTask.execute("the url to the file you want to download");
You could also have a look at this answer
am using sound cloud search api. when i hit the search url it give me search results. every audio has stream url but not download url because it depends on setting of the uploader. Every none downloadable file also has download count more than 1. for example, when you'll hit this url
http://api.soundcloud.com/tracks.json?client_id=4346c8125f4f5c40ad666bacd8e96498&q=tere%20bin&limit=1
It'll give the search result like that
[{"kind":"track","id":63225776,"created_at":"2012/10/13 01:52:38 +0000","user_id":26029726,"duration":206177,"commentable":true,"state":"finished","original_content_size":3298521,"last_modified":"2014/10/01 18:56:25 +0000","sharing":"public","tag_list":"","permalink":"tere-bin-uzair-jaswal-official","streamable":true,"embeddable_by":"all","downloadable":false,"purchase_url":null,"label_id":null,"purchase_title":null,"genre":"Musical","title":"Tere Bin - Uzair Jaswal [Official Music Audio]","description":"","label_name":"","release":"","track_type":"original","key_signature":"","isrc":"","video_url":null,"bpm":null,"release_year":null,"release_month":null,"release_day":null,"original_format":"mp3","license":"all-rights-reserved","uri":"https://api.soundcloud.com/tracks/63225776","user":{"id":26029726,"kind":"user","permalink":"uzair-jaswal-1","username":"Uzair Jaswal Music","last_modified":"2014/10/19 13:06:28 +0000","uri":"https://api.soundcloud.com/users/26029726","permalink_url":"http://soundcloud.com/uzair-jaswal-1","avatar_url":"https://i1.sndcdn.com/avatars-000110064166-2ts508-large.jpg"},"permalink_url":"http://soundcloud.com/uzair-jaswal-1/tere-bin-uzair-jaswal-official","artwork_url":"https://i1.sndcdn.com/artworks-000032079002-kup6vc-large.jpg","waveform_url":"https://w1.sndcdn.com/9bwAsZfGrxwN_m.png","stream_url":"https://api.soundcloud.com/tracks/63225776/stream","playback_count":359588,"download_count":100,"favoritings_count":7557,"comment_count":491,"attachments_uri":"https://api.soundcloud.com/tracks/63225776/attachments","policy":"ALLOW"}]
this is for only one audio and that audio is not downloadable but it has download count of 100. how is this possible ?
can anybody tell me how i can download that audio which is not downloadable?
any help would be much appreciated. Thanks :)
I fix it myself, i was using android and the stream url is also a download url. the stream url is also download url for downloading but it won't affect on download count. you can try like that
String file_url = "https://api.soundcloud.com/tracks/93216523/stream?client_id=4346c8125f4f5c40ad666bacd8e96498";
pass this url to asyntack and manage you download there, you can pass it like that
new DownloadFileFromURL().execute(file_url);
here is DownloadFileFromUR class using asyntask
class DownloadFileFromURL extends AsyncTask<String, Integer, String> {
#Override
protected void onPreExecute() {
super.onPreExecute();
}
#Override
protected String doInBackground(String... f_url) {
URL u = null;
InputStream is = null;
try {
u = new URL(f_url[0]);
is = u.openStream();
HttpURLConnection huc = (HttpURLConnection)u.openConnection();//to know the size of video
int size = huc.getContentLength();
if(huc != null){
String fileName = "FILE2.mp3";
String storagePath = Environment.getExternalStorageDirectory().toString();
File f = new File(storagePath,fileName);
FileOutputStream fos = new FileOutputStream(f);
byte[] buffer = new byte[1024];
long total = 0;
int len1 = 0;
if(is != null){
while ((len1 = is.read(buffer)) > 0) {
total+=len1;
publishProgress((int)((total*100)/size));
fos.write(buffer,0, len1);
}
}
if(fos != null){
fos.close();
}
}
}catch (MalformedURLException mue) {
mue.printStackTrace();
} catch (IOException ioe) {
ioe.printStackTrace();
} finally {
try {
if(is != null){
is.close();
}
}catch (IOException ioe) {
// just going to ignore this one
}
}
return "";
}
#Override
protected void onPostExecute(String file_url) {
}
}
String file_url = "https://api.soundcloud.com/tracks/93216523/stream?client_id=4346c8125f4f5c40ad666bacd8e96498";
DownLoad Class:
private class DownloadFile extends AsyncTask<String, Integer, String> {
#Override
protected String doInBackground(String... params) {
int count;
try {
URL url = new URL(file_url);
URLConnection conexion = url.openConnection();
conexion.connect();
// this will be useful so that you can show a tipical 0-100% progress bar
int lenghtOfFile = conexion.getContentLength();
// download the file
InputStream input = new BufferedInputStream(url.openStream());
OutputStream output = new FileOutputStream(getOutputMediaFile());
byte data[] = new byte[1024];
long total = 0;
while ((count = input.read(data)) != -1) {
total += count;
// publishing the progress....
publishProgress((int) (total * 100 / lenghtOfFile));
output.write(data, 0, count);
}
output.flush();
output.close();
input.close();
} catch (Exception e) {
}
return null;
}
#Override
protected void onProgressUpdate(Integer... values) {
super.onProgressUpdate(values);
}
#Override
protected void onPostExecute(String s) {
super.onPostExecute(s);
}
}