I found this source code on the net and have modified it a little. But I get an error saying: java.io.FileNotFoundException /data/datafile.zip.
What should I do to get it running? Do I have to create the file first?
Thanks, Sigurd
private Thread checkUpdate = new Thread() {
public void run() {
try {
long startTime = System.currentTimeMillis();
Log.d("Zip Download", "Start download");
File file = new File(Environment.getDataDirectory(), "datafil.zip");
Log.d("Zip Download", file.getAbsolutePath());
URL updateURL = new URL("http://dummy.no/bilder/bilder/XML_Item_Expo_01.zip");
URLConnection conn = updateURL.openConnection();
InputStream is = conn.getInputStream();
BufferedInputStream bis = new BufferedInputStream(is);
ByteArrayBuffer baf = new ByteArrayBuffer(50);
int current = 0;
while((current = bis.read()) != -1){
baf.append((byte)current);
}
/* Convert the Bytes read to a String. */
FileOutputStream fos = new FileOutputStream(file);
fos.write(baf.toByteArray());
fos.close();
Log.d("Zip Download", "download ready in" + ((System.currentTimeMillis() - startTime) / 1000) + " sec");
} catch (Exception e) {
Log.d("Zip Download", "Error: " + e);
}
}
};
Seems like permission error. You maybe writing to the wrong place. Check that answer at link below,
Data directory has no read/write permission in Android
Environment.getDataDirectory() does not return a path where you can place files. You should use one of these methods instead:
Environment.getExternalStorageDirectory() gives you a path to external storage (SD card).
getFilesDir() from an Activity or other Context. Gives a path to app's internal file storage
You can also call openFileOutput() with a string file name (no path, just the file), which will open the FileOutputStream and create the file all in one shot for your use.
Hope that Helps!
Related
I have one requirement in my Android application. I need to download and save file in specific folder of SD card programmatically. I have developed source code, which is
String DownloadUrl = "http://myexample.com/android/";
String fileName = "myclock_db.db";
DownloadDatabase(DownloadUrl,fileName);
// and the method is
public void DownloadDatabase(String DownloadUrl, String fileName) {
try {
File root = android.os.Environment.getExternalStorageDirectory();
File dir = new File(root.getAbsolutePath() + "/myclock/databases");
if(dir.exists() == false){
dir.mkdirs();
}
URL url = new URL("http://myexample.com/android/");
File file = new File(dir,fileName);
long startTime = System.currentTimeMillis();
Log.d("DownloadManager" , "download url:" +url);
Log.d("DownloadManager" , "download file name:" + fileName);
URLConnection uconn = url.openConnection();
uconn.setReadTimeout(TIMEOUT_CONNECTION);
uconn.setConnectTimeout(TIMEOUT_SOCKET);
InputStream is = uconn.getInputStream();
BufferedInputStream bufferinstream = new BufferedInputStream(is);
ByteArrayBuffer baf = new ByteArrayBuffer(5000);
int current = 0;
while((current = bufferinstream.read()) != -1){
baf.append((byte) current);
}
FileOutputStream fos = new FileOutputStream( file);
fos.write(baf.toByteArray());
fos.flush();
fos.close();
Log.d("DownloadManager" , "download ready in" + ((System.currentTimeMillis() - startTime)/1000) + "sec");
int dotindex = fileName.lastIndexOf('.');
if(dotindex>=0){
fileName = fileName.substring(0,dotindex);
}
catch(IOException e) {
Log.d("DownloadManager" , "Error:" + e);
}
}
Now the issue is only empty file with filename myclock_db.db is saving in the path. but I need to download and save content of file in the specific folder. Tried several ways to get the file download, but I can't.
Your download URL is not a link to any file. It's a directory. Make sure its a file and exists. Also check your logcat window for error logs. One more suggestion, its always better to do a printStackTrace() in catch blocks instead of Logs. Its gives a more detailed view of the error.
Change this line:
URL url = new URL("http://myexample.com/android/");
to:
URL url = new URL("http://myexample.com/android/yourfilename.txt"); //some file url
Next, in catch block, add this line:
e.printStackTrace();
Also in the directory path, it should be something like this:
File dir = new File(root.getAbsolutePath() + "/mnt/sdcard/myclock/databases");
instead of
File dir = new File(root.getAbsolutePath() + "/myclock/databases");
Next, make sure you have acquired permission for writing to external storage in Android manifest.
I am using following code to download and read a PDF file from internal storage on device.
I am able to download the files successfully to the directory:
data/data/packagename/app_books/file.pdf
But I am unable to read the file using a PDF reader application like Adobe Reader.
Code to download file
//Creating an internal dir;
File mydir = getApplicationContext().getDir("books", Context.MODE_WORLD_READABLE);
try {
File file = new File(mydir, outputFileName);
URL downloadUrl = new URL(url);
URLConnection ucon = downloadUrl.openConnection();
ucon.connect();
InputStream is = ucon.getInputStream();
FileOutputStream fos = new FileOutputStream(file);
byte data[] = new byte[1024];
int current = 0;
while ((current = is.read(data)) != -1) {
fos.write(data, 0, current);
}
is.close();
fos.flush();
fos.close();
isFileDownloaded=true;
} catch (IOException e) {
e.printStackTrace();
isFileDownloaded = false;
System.out.println(outputFileName + " not downloaded");
}
if (isFileDownloaded)
System.out.println(outputFileName + " downloaded");
return isFileDownloaded;
Code to read the file
PackageManager packageManager = getPackageManager();
Intent testIntent = new Intent(Intent.ACTION_VIEW);
testIntent.setType("application/pdf");
List list = packageManager.queryIntentActivities(testIntent,
PackageManager.MATCH_DEFAULT_ONLY);
try {
Intent intent = new Intent();
intent.setAction(Intent.ACTION_VIEW);
File fileToRead = new File(
"/data/data/com.example.filedownloader/app_books/Book.pdf");
Uri uri = Uri.fromFile(fileToRead.getAbsoluteFile());
intent.setDataAndType(uri, "application/pdf");
startActivity(intent);
} catch (Exception ex) {
Log.i(getClass().toString(), ex.toString());
Toast.makeText(MainActivity.this,
"Cannot open your selected file, try again later",
Toast.LENGTH_SHORT).show();
}
All works fine but the reader app says "File Path is not valid".
Your path is only valid for your app. Place the file in a place where other apps can 'see' it. Use GetExternalFilesDir() or getExternalStorageDirectory().
Note about files which are created inside the directory created by Context.getDir(String name, int mode) that they will only be accessible by your own application; you can only set the mode of the entire directory, not of individual files.
So you can use Context.openFileOutput(String name, int mode). I'm re-using your code for an example:
try {
// Now we use Context.MODE_WORLD_READABLE for this file
FileOutputStream fos = openFileOutput(outputFileName,
Context.MODE_WORLD_READABLE);
// Download data and store it to `fos`
// ...
You might want to take a look at this guide: Using the Internal Storage.
If you would like to keep the file app specific, you can use PdfRenderer available for Lollipop and above builds. There are great tutorials on google and youtube that work well. The method you are using is a secure way to store a PDF file that is only readable from inside the app ONLY. No outside application like Adobe PDF Reader will be able to even see the file.It took me a lot of seaching but I found a solution to my specific usage by using this site and especially youtube.
How to download PDF file from asset folder to storage by making folder
make sure you have storage permission are given like marshmallow device support etc then follow these steps
private void CopyReadAssets()
{
AssetManager assetManager = getContext().getAssets();
FileInputStream in = null;
FileOutputStream out = null;
File sdcard = Environment.getExternalStorageDirectory();
File dir = new File(Environment.getExternalStorageDirectory()+File.separator+ "A_level");
File dir2;
if (dir.exists() && dir.isDirectory()){
Log.e("tag out", ""+ dir);
}else {
dir.mkdir();
Log.e("tag out", "not exist");
}
File file = new File(dir, mTitle+".pdf");
try
{
Log.e("tag out", ""+ file);
out = new FileOutputStream(file);
in = new FileInputStream (new File(mPath));
Log.e("tag In", ""+ in);
copyFile(in, out);
in.close();
in = null;
out.flush();
out.close();
out = null;
} catch (Exception e)
{
Log.e("tag out", ""+ out);
Log.e("tag In", ""+ in);
Log.e("tag", e.getMessage());
Log.e("tag", ""+file);
Log.i("tag",""+sdcard.getAbsolutePath() + "A_level");
}
}
private void copyFile(InputStream in, OutputStream out) throws IOException
{
byte[] buffer = new byte[1024];
int read;
while ((read = in.read(buffer)) != -1)
{
out.write(buffer, 0, read);
}
}
how can i download audio file from server by url and save it to sdcard.
i am using the code below:
public void uploadPithyFromServer(String imageURL, String fileName) {
try {
URL url = new URL(GlobalConfig.AppUrl + imageURL);
File file = new File(fileName);
Log.d("ImageManager", "download begining");
Log.d("ImageManager", "download url:" + url);
Log.d("ImageManager", "downloaded file name:" + fileName);
/* Open a connection to that URL. */
URLConnection con = url.openConnection();
InputStream is = con.getInputStream();
BufferedInputStream bis = new BufferedInputStream(is, 1024 * 50);
FileOutputStream fos = new FileOutputStream("/sdcard/" + file);
byte[] buffer = new byte[1024 * 50];
int current = 0;
while ((current = bis.read(buffer)) != -1) {
fos.write(buffer, 0, current);
}
fos.flush();
fos.close();
bis.close();
} catch (IOException e) {
Log.d("ImageManager", "Error: " + e);
}
}
the above code is not downloading audio file.
if use any permission in menifest file plz tell me.. (i have used internet permission)
please help
thanks..
you must also add
android.permission.WRITE_EXTERNAL_STORAGE
permission if you wish to write data to sd card.
also post your logcat output , if you are getting any IOExceptions.
Your example does not specify a request method and some mimetypes and stuff.
Here you will find a list of mimetypes http://www.webmaster-toolkit.com/mime-types.shtml
Find the mimetypes relevant to you and add it to the mimetypes specified below in the code.
Oh and btw, the below is normal Java code. You'll have to replace the bit that stores the file on the sdcard. dont have an emulator or phone to test that part at the moment
Also see the docs for storage permissions on sd here: http://developer.android.com/reference/android/Manifest.permission_group.html#STORAGE
public static void downloadFile(String hostUrl, String filename)
{
try {
File file = new File(filename);
URL server = new URL(hostUrl + file.getName());
HttpURLConnection connection = (HttpURLConnection)server.openConnection();
connection.setRequestMethod("GET");
connection.setDoInput(true);
connection.setDoOutput(true);
connection.setUseCaches(false);
connection.addRequestProperty("Accept","image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/msword, application/vnd.ms-excel, application/vnd.ms-powerpoint, application/x-shockwave-flash, */*");
connection.addRequestProperty("Accept-Language", "en-us,zh-cn;q=0.5");
connection.addRequestProperty("Accept-Encoding", "gzip, deflate");
connection.connect();
InputStream is = connection.getInputStream();
OutputStream os = new FileOutputStream("c:/temp/" + file.getName());
byte[] buffer = new byte[1024];
int byteReaded = is.read(buffer);
while(byteReaded != -1)
{
os.write(buffer,0,byteReaded);
byteReaded = is.read(buffer);
}
os.close();
} catch (IOException e) {
e.printStackTrace();
}
Then call,
downloadFile("http://localhost/images/bullets/", "bullet_green.gif" );
EDIT:
Bad coder me.
Wrap that input InputStream in a BufferedInputStream. No need to specify buffersizes ect.
Defaults are good.
Does anyone know how to save a file from a webserver(local host) to the sdcard through wifi?
I am doing xml parsing to my application and for that I have to download an xml file from localhost to the sdcard and then tag the parsing. I am stuck with downloading an xml file to the sd card. Please guide me on how to do this..
You can use this method to download a file from the internet to your SD card:
public void DownloadFromUrl(String DownloadUrl, String fileName) {
try {
File root = android.os.Environment.getExternalStorageDirectory();
File dir = new File (root.getAbsolutePath() + "/xmls");
if(dir.exists()==false) {
dir.mkdirs();
}
URL url = new URL(DownloadUrl); //you can write here any link
File file = new File(dir, fileName);
long startTime = System.currentTimeMillis();
Log.d("DownloadManager", "download begining");
Log.d("DownloadManager", "download url:" + url);
Log.d("DownloadManager", "downloaded file name:" + fileName);
/* Open a connection to that URL. */
URLConnection ucon = url.openConnection();
/*
* Define InputStreams to read from the URLConnection.
*/
InputStream is = ucon.getInputStream();
BufferedInputStream bis = new BufferedInputStream(is);
/*
* Read bytes to the Buffer until there is nothing more to read(-1).
*/
ByteArrayBuffer baf = new ByteArrayBuffer(5000);
int current = 0;
while ((current = bis.read()) != -1) {
baf.append((byte) current);
}
/* Convert the Bytes read to a String. */
FileOutputStream fos = new FileOutputStream(file);
fos.write(baf.toByteArray());
fos.flush();
fos.close();
Log.d("DownloadManager", "download ready in" + ((System.currentTimeMillis() - startTime) / 1000) + " sec");
} catch (IOException e) {
Log.d("DownloadManager", "Error: " + e);
}
}
You need to add the following permissions to your AndroidManifest.xml:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"></uses-permission>
<uses-permission android:name="android.permission.INTERNET"></uses-permission>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"></uses-permission>
<uses-permission android:name="android.permission.READ_PHONE_STATE"></uses-permission>
The Sourav's answer is OK, but for large file sizes you should implement it on a new thread; because while downloading, the main thread is busy for downloading the file. If the waiting time be more that expected the system will generate "Not responding" error.
In order to do that you can use "TaskAsync" or "IntentService"
I prefer to build soap server and make a call from app to server and by that receiving XML. Or maybe you could just make an URL which generates XML and that just parse URL directly.
Try to read more on this LINK
Hopefully I have answer the question. Otherwise would be pleased to help, but I need more detailed functionality description.
I am working on an application that plays a video file on a loop. Up until now I was just mounting the device and copying the video file onto the SD card and then using the file path to start it up on my VideoView. I am trying to implement a way that I can remotely update what video it plays so I have moved to storing my video online. Inside the app I check for a local copy and download if it doesn't exist, or if there is a newer one. I have tested it on two different video files both .mp4s. After downloading one of them plays the first time but upon trying to start again for the loop it tells me video cannot be played. The other won't even play the first time, it just gives me the dialog that says the video cannot be played. Both of these files work correctly with my app if I copy them onto the SD card via the USB cable. They work if I exit my app and manually download them with something else(dropbox) but not if I download them from within my app. Here is the code I am using to download the file:
public static void DownloadFromUrl(String fileName) { //this is the downloader method
try {
URL url = new URL("http://dl.dropbox.com/u/myfile.mp4");
File file = new File(PATH + fileName);
long startTime = System.currentTimeMillis();
Log.d(myTag, "download begining");
Log.d(myTag, "download url:" + url);
Log.d(myTag, "downloaded file name:" + fileName);
/* Open a connection to that URL. */
URLConnection ucon = url.openConnection();
Log.i(myTag, "Opened Connection");
/*
* Define InputStreams to read from the URLConnection.
*/
InputStream is = ucon.getInputStream();
BufferedInputStream bis = new BufferedInputStream(is);
Log.i(myTag, "Got InputStream and BufferedInputStream");
FileOutputStream fos = new FileOutputStream(file);
BufferedOutputStream bos = new BufferedOutputStream(fos);
Log.i(myTag, "Got FileOutputStream and BufferedOutputStream");
/*
* Read bytes to the Buffer until there is nothing more to read(-1).
*/
int current = 0;
Log.i(myTag, "About to write");
while ((current = bis.read()) != -1) {
bos.write(current);
}
fos.close();
Log.d(myTag, "download ready in"
+ ((System.currentTimeMillis() - startTime))
+ " sec");
} catch (IOException e) {
Log.d(myTag, "Error: " + e);
}
}
I know the dropbox url in this snippet is not correct I changed it only for this post, in my app the url is pointing to a file correctly. And the variable PATH thats used when creating the File is set in my code outside of this snippet.
Is there something about this code snippet that could be corrupting my mp4 files?
That method was corrupting the file somehow, I am still not quite sure how but I changed part of it and now it is fixed.
I am now using this:
byte data[] = new byte[1024];
long total = 0;
int count;
while ((count = bis.read(data)) != -1) {
total += count;
fos.write(data, 0, count);
}
fos.flush();
fos.close();
instead of the old while loop and it works correctly.