In my application i am downloading images from the web and these images will be stored in the sdcard. Here i am using the url as file name. For this first i am checking the file name is exits in the sdcard. if it exists then get the image from the sdcard. otherwise i am getting from web.But i am geting the following exception how to handle it.
Exception
09-09 15:24:58.873: WARN/System.err(1117): java.io.IOException: Parent directory of file is not writable: /sdcard/http+++ecx.images-amazon.com+images+I+41KdssHpg1L._SL160_.jpg
09-09 15:24:58.904: WARN/System.err(1117): at java.io.File.createNewFile(File.java:1263)
09-09 15:24:58.924: WARN/System.err(1117): at com.ibkr.elgifto.GiftCategories$itemlistadapter$4$1.run(GiftCategories.java:947)
Code
private Drawable getDrawableFromUrl(String imageUrl) {
String filename = imageUrl;
filename = filename.replace("/", "+");
filename = filename.replace(":", "+");
filename = filename.replace("~", "s");
final File file = new File(Environment.getExternalStorageDirectory() + File.separator + filename);
boolean exists = file.exists();
if (!exists) {
try {
URL myFileUrl = new URL(imageUrl);
HttpURLConnection conn = (HttpURLConnection) myFileUrl.openConnection();
conn.setDoInput(true);
conn.connect();
InputStream is = conn.getInputStream();
final Bitmap result = BitmapFactory.decodeStream(is);
is.close();
new Thread() {
public void run() {
ByteArrayOutputStream bytes = new ByteArrayOutputStream();
if (result != null) {
result.compress(Bitmap.CompressFormat.JPEG, 40, bytes);
}
try {
if (file.createNewFile()) {
//
} else {
//
}
FileOutputStream fo;
fo = new FileOutputStream(file);
fo.write(bytes.toByteArray());
fo.flush();
fo.close();
// result.recycle();
} catch (IOException e) {
e.printStackTrace();
}
}
}.start();
BitmapDrawable returnResult = new BitmapDrawable(result);
return returnResult;
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return null;
} else {
return new BitmapDrawable(BitmapFactory.decodeFile(file.toString()));
}
}
just add permission to AndroidManifest.xml file and check, it may work.
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
You should always check whether SD storage is available before accessing it. If it's not, you can inform the user about failure instead of crashing application. Here's the function I'm using:
public static boolean storageAvailable()
{
String state = Environment.getExternalStorageState();
if (!Environment.MEDIA_MOUNTED.equals(state)) return false;
return true;
}
There's also possibility you forgot to add required permission into AndroidManifest.xml:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
Related
I am developing app like playstore in which user can download any app. i have many apps in my application that i got from my website through wp api v2. when we click on any of the available application detail opened and it have a download link. when we click on the link it goes to the browser but what i want is when we click on any of the apps downloading link downloading should start within my app with progress bar. i didn't found any appropriate solution yet on stack or anywhere.
Here is the screenshot attached for better understanding. arrow is pointing to the downloading link.
Try this code, you can put this on click of the link(textview)
private static void downloadFile(String url, File outputFile) {
try {
URL u = new URL(url);
URLConnection conn = u.openConnection();
int contentLength = conn.getContentLength();
DataInputStream stream = new DataInputStream(u.openStream());
byte[] buffer = new byte[contentLength];
stream.readFully(buffer);
stream.close();
DataOutputStream fos = new DataOutputStream(new FileOutputStream(outputFile));
fos.write(buffer);
fos.flush();
fos.close();
} catch(FileNotFoundException e) {
return; // swallow a 404
} catch (IOException e) {
return; // swallow a 404
}
}
you can use intent service to download the app.
Here is the code :
public class DownloadService extends IntentService {
File cacheDir;
public DownloadService() {
super("DownloadService");
}
#Override
public void onCreate() {
super.onCreate();
String tmpLocation =
Environment.getExternalStorageDirectory().getPath();
cacheDir = new File(tmpLocation);
if (!cacheDir.exists()) {
cacheDir.mkdirs();
}
}
#Override
protected void onHandleIntent(Intent intent) {
String remoteUrl = intent.getExtras().getString("url");
String location;
String filename =
remoteUrl.substring(
remoteUrl.lastIndexOf(File.separator) + 1);
File tmp = new File(cacheDir.getPath()
+ File.separator + filename);
if (tmp.exists()) {
location = tmp.getAbsolutePath();
stopSelf();
return;
}
try {
URL url = new URL(remoteUrl);
HttpURLConnection httpCon =
(HttpURLConnection) url.openConnection();
if (httpCon.getResponseCode() != 200)
throw new Exception("Failed to connect");
InputStream is = httpCon.getInputStream();
ByteArrayOutputStream out = new ByteArrayOutputStream();
byte[] buf = new byte[1024];
int n = 0;
while (-1 != (n = is.read(buf))) {
out.write(buf, 0, n);
}
out.close();
is.close();
byte[] response = out.toByteArray();
FileOutputStream fos = new FileOutputStream(tmp);
fos.write(response);
fos.flush();
fos.close();
is.close();
location = tmp.getAbsolutePath();
} catch (Exception e) {
Log.e("Service", "Failed!", e);
}
}
}
Run this service with url passed in the intent
I try to use FlushedInputStream : Android decoder->decode returned false for Bitmap download
but nothing change, because i use: BitmapFactory.decodeFile(path_of_my_downloaded_file), not use BitmapFactory.decodeStream
This is my code of download file:
public static boolean downloadFile(String url, String dir, String name){
Log.i("Start Downloading ", "=");
// Create download folder:
File f = new File(dir);
if(!f.exists()){
f.mkdirs();
}
try {
File fTo = new File(dir, name);
URL downloadUrl = new URL(url);
//create the new connection
HttpURLConnection urlConnection = (HttpURLConnection) downloadUrl.openConnection();
//set up some things on the connection
urlConnection.setRequestMethod("GET");
urlConnection.setDoOutput(true);
//and connect!
urlConnection.connect();
FlushedInputStream in = new FlushedInputStream(downloadUrl.openStream());
// in = new FlushedInputStream(in);
byte[] buffer= new byte[4096];
// Write file to toFolder
FileOutputStream os = new FileOutputStream(fTo);
try {
do{
int numread = in.read(buffer);
if (numread <= 0) {
break;
}
os.write(buffer, 0, numread);
}while(true);
} catch (ConnectTimeoutException e) {
e.printStackTrace();
return false;
}
if (os != null) {
os.close();
}
if (in != null) {
in.close();
}
} catch (IOException e) {
Log.e("Error reading file", e.toString());
return false;
}
return true;
}
And this is my code to set Bitmap to ImageView:
Bitmap bitmap = BitmapFactory.decodeFile(my_file);
mImageView.setImageBitmap(bitmap);
I always have "decoder->decode returned false"
Note: I have to download this image first.
This is the problems of image.
I used following code for downloading XML file from ftp to android phone memory using that i able to connect ftp but while retrieving XML to local memory it is giving following exception 07-19 15:01:03.721: DEBUG/SntpClient(61): request time failed: java.net.SocketException: Address family not supported by protocol
please help somebody thank you,
Java class
private void fnfileDownloadBuf()
{
FTPClient client = new FTPClient();
FileOutputStream fos = null;
try {
//client.connect("ftp://ftp.qualityinaction.net/QIA/Questions/Airlines/");
client.connect("ftp.qualityinaction.net");
client.login("qualityinaction.net","password");
client.setFileType(FTP.BINARY_FILE_TYPE);
//
// The remote filename to be downloaded.
//
// String filename = "/QIA/Questions/Airlines/index.xml";
String filename = getFilesDir().getAbsolutePath()+ File.separator + "/index.xml";
// String filename = "/QIA/Questions/Airlines/index.xml";
File file = new File(filename);
fos = new FileOutputStream(file);
//
// Download file from FTP server
//
//client.retrieveFile("/" + filename, fos);
client.retrieveFile("/QIA/Questions/Airlines/index.xml;type=i", fos);
// client.retrieveFile( getFilesDir().getAbsolutePath()+ File.separator + "/index.xml", fos);
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (fos != null) {
fos.close();
}
client.disconnect();
} catch (IOException e) {
e.printStackTrace();
}
}
}
manifest XML file
<uses-permission android:name="android.permission.INTERNET"></uses-permission>
Exception
exception 07-19 15:01:03.721: DEBUG/SntpClient(61): request time failed: java.net.SocketException: Address family not supported by protocol
for that you have to use passive mode corrected code as shown below..
** Java Code **
FTPClient ObjFtpCon = new FTPClient();
try
{
ObjFtpCon.connect(strIp);
if (ObjFtpCon.login(strFtpUser, strFtpPwd))
{
ObjFtpCon.enterLocalPassiveMode(); // important!
ObjFtpCon.cwd("/QIA/Questions/Hotel/");
String[] strArrQuesFiles=ObjFtpCon.listNames();
int intcnt=0;
boolean blnresult = false;
File objfile=new File(getFilesDir().getAbsolutePath()+ "/Questions");
if(!objfile.exists())objfile.mkdirs();
objfile=null;
for(intcnt=0;intcnt<strArrQuesFiles.length;intcnt++)
{
objfile=new File(getFilesDir().getAbsolutePath()+ File.separator + "/Questions/" + strArrQuesFiles[intcnt]);
objfile.createNewFile();
//ByteArrayInputStream in = new ByteArrayInputStream(data.getBytes());
FileOutputStream objFos=new FileOutputStream(objfile);
blnresult=ObjFtpCon.retrieveFile(strArrQuesFiles[intcnt] , objFos);
objFos.close();
}
// boolean result = con.storeFile("/QIA/Response/test/Responses.xml", in);
if (blnresult) dlgAlert.setMessage("Questions Are Successfully Downloaded").create().show();
}
}
catch (Exception e)
{
e.printStackTrace();
}
try
{
ObjFtpCon.logout();
ObjFtpCon.disconnect();
}
catch (IOException e)
{
e.printStackTrace();
}
}
I am new in Android.
I am downloading images from the internet in the ListView .I getting the url in the file object but when I send it into the Bitmap object the bitmap object is return null means image is not loaded into the bitmap object.please reply me. the code is here:
private Bitmap getBitmap(String url) {
String filename = String.valueOf(url.hashCode());
File f = new File(cacheDir, filename);
// here in f i getting image url
// here in bitmap the url is not loaded & get null
Bitmap bitmap = BitmapFactory.decodeFile(f.getPath());
if(bitmap != null) return bitmap;
// Nope, have to download it
try {
bitmap =
BitmapFactory.decodeStream(new URL(url).openConnection().getInputStream());
// save bitmap to cache for later
writeFile(bitmap, f);
return bitmap;
} catch (Exception ex) {
ex.printStackTrace();
return null;
}
}
private void writeFile(Bitmap bmp, File f) {
FileOutputStream out = null;
try {
out = new FileOutputStream(f);
bmp.compress(Bitmap.CompressFormat.PNG, 80, out);
} catch (Exception e) {
e.printStackTrace();
}
finally {
try { if (out != null ) out.close(); }
catch(Exception ex) {}
}
}
I do not think you are downloading properly the bitmap.
CODE
This is a function I created that will take a url from you and it will return a drawable!
It will save it to a file and get it if it exists
If not, it will download it and return the drawable.
You can easily edit it to save file to your folder instead.
/**
* Pass in an image url to get a drawable object
*
* #return a drawable object
*/
private static Drawable getDrawableFromUrl(final String url) {
String filename = url;
filename = filename.replace("/", "+");
filename = filename.replace(":", "+");
filename = filename.replace("~", "s");
final File file = new File(Environment.getExternalStorageDirectory()
+ File.separator + filename);
boolean exists = file.exists();
if (!exists) {
try {
URL myFileUrl = new URL(url);
HttpURLConnection conn = (HttpURLConnection) myFileUrl
.openConnection();
conn.setDoInput(true);
conn.connect();
InputStream is = conn.getInputStream();
final Bitmap result = BitmapFactory.decodeStream(is);
is.close();
new Thread() {
public void run() {
ByteArrayOutputStream bytes = new ByteArrayOutputStream();
result.compress(Bitmap.CompressFormat.JPEG, 40, bytes);
try {
if (file.createNewFile()){
//
}
else{
//
}
FileOutputStream fo;
fo = new FileOutputStream(file);
fo.write(bytes.toByteArray());
fo.flush();
fo.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}.start();
BitmapDrawable returnResult = new BitmapDrawable(result);
return returnResult;
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
else {
return new BitmapDrawable(BitmapFactory.decodeFile(file.toString()));
}
}
Only thing I can think of here is that you're missing INTERNET permission in your manifest.
Try adding <uses-permission android:name="android.permission.INTERNET" /> in your AndroidManifest.xml if it's not there yet
In my activity, I am downloading images from url. I want these images to be downloaded only for the first time. Later on when I visit this page, it should take the image from the sdcard. How can I do that? Can anyone help?
In manifest I have set permission:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
The method which I use for downloading is:
public static Bitmap downloadFileFromUrl(String fileUrl){
URL myFileUrl =null;
Bitmap imageBitmap = null;
try {
myFileUrl= new URL(fileUrl);
}
catch (MalformedURLException e) {
e.printStackTrace();
}
try {
HttpURLConnection connection= (HttpURLConnection)myFileUrl.openConnection();
connection.setDoInput(true);
connection.connect();
InputStream is = connection.getInputStream();
imageBitmap = BitmapFactory.decodeStream(is);
//Below two lines I just tried out for saving to sd card.
FileOutputStream out = new FileOutputStream(fileUrl);
imageBitmap.compress(Bitmap.CompressFormat.PNG, 90, out);
}
catch (IOException e) {
e.printStackTrace();
}catch (Exception e) {
e.printStackTrace();
}
return imageBitmap;
}
Try this method
public void DownloadImage(String imageUrl)
{
InputStream is = null;
if((imageUrl == null) || (imageUrl.length() == 0) || (imageUrl == " "))
{
System.out.println("No need to download images now");
}
else
{
System.gc();
String[] items;
String ImageName = null;
URL myFileUrl =null;
Bitmap bmImg = null;
String path = IMAGE_DOWNLOAD_PATH;
FileOutputStream outStream = null;
File file = new File(path);
if(!file.exists())
{
file.mkdirs();
}
File outputFile;
BufferedOutputStream bos;
try {
myFileUrl= new URL(imageUrl.trim());
HttpURLConnection conn= (HttpURLConnection)myFileUrl.openConnection();
conn.setRequestMethod("GET");
conn.setDoInput(true);
conn.setConnectTimeout(20000);
conn.connect();
is = conn.getInputStream();
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
ImageName = getImageName(imageUrl);
try {
outputFile = new File(file, ImageName);
if(outputFile.exists())
{
System.out.println("No need to download image it already exist");
outputFile.delete();
}
outputFile.createNewFile();
outStream = new FileOutputStream(outputFile);
//bos = new BufferedOutputStream(outStream);
BufferedInputStream bis = new BufferedInputStream(is);
ByteArrayBuffer baf = new ByteArrayBuffer(50);
int current = 0;
while ((current = bis.read()) != -1)
{
baf.append((byte) current);
}
outStream.write(baf.toByteArray());
outStream.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
and then to retrieve image from sdcard,
File extStore = Environment.getExternalStorageDirectory();
String file_path = "/(folder name)/"+"(image name)".trim()+".extension".trim();
String mypath = extStore + file_path;
Bitmap bmp=BitmapFactory.decodeFile(mypath);
ImageView image = (ImageView) v.findViewById(R.id.image);
image.setImageBitmap(bmp);
You should store somewhere what you've got in cache.
Or if your filename are unique you've to check than the file exist or not.
You have to write the data got from InputStream to specified SD card location ..