I guess this quesiton has been answered already, buy it doesn't seem to work, and it is very furstrating...
I am just trying to get the size of a remote file in Android.
So far, I have tried the following two approaches, without success:
1)
try
{
file = new File("http://50.19.156.118/feed2/storage/download/a_17/Madagascar.3gp");
a=(int) myFileBeingUploaded.length();
}
catch (Exception j)
{
}
2)
try
{
url = new URL("http://50.19.156.118/feed2/storage/download/a_17/Madagascar.3gp);
urlConnection = (HttpURLConnection) url.openConnection();
a=urlConnection.getContentLength();
}
catch (Exception e)
{
}
getContentLength() returns always 77 !!, while File.length() returns 0
Any ideas?
Many thanks
HTTP is not a filesystem -- it is a protocol for communicating hyperlinked resources. With standard HTTP, the only way to determine the size of a resource is to download that resource. The way to solve your problem, assuming that you want the size before you want the resource, is to implement another resource which tells you the size. True, the Content-Size field of a response tells you the size of the data contained in the response, but only after you request the resource.
e.g. given your web server with image portrait.jpg, you could set up a php script meta.php to which you pass the name of the resource of interest... meta.php?f=portrait.jpg. Then meta.php would ask its filesystem for the size of f and return that number via HTTP.
Related
Is there any way to get the image dimensions or size without actually downloading it from the server.
Like if a image is hosted on https://500px.com/
or https://imgur.com/ and i want to do some calculations but i also want to save the bandwidth. If the image size is quite large and the user bandwidth is not so good i want to queue the image for later.
Assuming that API doesn't provide such information.
In the didRecieveResponse delegate method for the NSURLConnection you will recieve a response that contains such info. if and only if those has been set on server:
The following gets you the disk size of the image:
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
{
NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *) response;
int state = [httpResponse statusCode];
if (state >= 400 && state <600)
{
// something wrong happen
}
NSLog(#"Download Response : %#", [response description]); // this shows all the info. available by server.
int file_size = [response expectedContentLength];
}
You can check for the size and then cancel the connection if you want to.
For image dimensions. check this question. the answer claims that
it can be done with the suggested fastimage category.
The only logical way to get this done is by downloading the first part of the image that contains the image header. which contains such an info as the image type(png, jpg ...) and the image dimensions. I believe that this library do so.
I don't know if it's possible or not. But here is my tip. you could check the size of the file. see here: How to know the size of a file before downloading it?
and if the size is larger than x you queue the image for later ;-)
Code from linked answer:
URL url = new URL("http://server.com/file.mp3");
URLConnection urlConnection = url.openConnection();
urlConnection.connect();
int file_size = urlConnection.getContentLength();
It's not possible to calculate image size without downloading.
I'm Unable to download file from FTP server using URLConnection having spaces in pat
String s = "ftp://username:password#ftpclient:21/AAB BBC/hhhh 0001.jpg";
URL u = new URL(s);
URLConnection uc = u.openConnection();
BufferedOutputStream bos = new BufferedOutputStream(uc.getOutputStream());
Dont want FTP client solution.
Using URLencoder getting 550 error file not found.
Thanks,
Gaurav
Are you using Apache commons Library ? If so , use this code
try {
FileOutputStream desFileStream = new FileOutputStream(desFilePath);;
status = FTP_object.retrieveFile(srcFilePath, desFileStream);
desFileStream.close();
return status;
} catch (Exception e) {
Log.d(TAG, "download failed");
}
You shouldn't have spaces in your URL itself per RFC1738 section 2.2 Run it through the URL Encode method to encode it:
String s = "ftp://username:password#ftpclient:21/AAB BBC/hhhh 0001.jpg";
String encodedUrl = URLEncoder.encode(s,"UTF-8");
I realize you said you were already doing the encoding, but that returned a 550 error. I didn't see the encoding so am just mentioning it should be needed.
I would really try this from a browser and see if you can get to it. I would also dump out the URL it is using and try that from a browser (or wget, curl, whatever you have handy). The 550 is listed as being a "permission" problem, not file not found, so I'm a little surprised at that, but that may be the short code and come up as an error to prevent people from poking around testing user/password combinations. Hard to say.
The other question I have for you is that you mention you don't want a client solution, but you seem to be writing a client not a server. You're going to port 21, which is the default FTP port for a server.
I would try various combinations of the encoding and see if maybe you're not encoding everything...you should encode the url path. Does the password have any funky characters in it?
Testing from the browser directly will give you a lot of insight.
Im developing an app which is a product catalogue. Users can search for and view products (books). It's all read only and just so allow user's to view products. When the user clicks on a product, the next screen displays
- book title
- book author
- picture of front cover.
It's the picture part that I've a question about. I know one way to present drawables is to have them in the "drawable" direction in my android project and access them (in my xml file) as android:src="#drawable/name".
Only problem is that new products will be added so I can't store drawables in the APK file when I release it. I'll need to read them at runtime. I'm wondering what the best way to approach this is.
I'm thinking of upon (very first) launch of the app executing an AsyncTask which would call
openConnection of HttpURLConnection and would grab down all drawable (from a particular remote directory on a website) and would then store them in the sqllite db (as a blob). Each product in the db could easily be associated with it's specific drawable.
Not sure if there's a better approach to this ? or should I save them to the internal storage of the device (I know the size is an issue with this option). Trying to grab the drawable on demand can take 2-4secs (i.e. to get from remote server). Is there a way to download drawables in an efficent way ?
Update: The only problem with the above approach is the time it takes to grab the remote drawable and render it on the device (between 2-7 seconds). So I can't go with that approach for performance reasons. When the user launches the app for the very first time, it (using an ASynch task) grabs all products (in a csv remotely) and stores it's contents in an SQLLite db. So they've a small acceptable wait on very first launch of the app but none after that. I'd like to do something similiar (i.e. get the drawables too) but not sure should should I store them in internal storage or persist them as BLOB into the db. There max size of 2-3kb each in size but there could be 300 products in total
Any help would be great. I'm developing on Android 4.0.3.
Thanks - Ro
The method you described is the best way to perform such a task. Grab them directly from online so that any time you change the picture it is changed on your phone. Also an easier way, you can directly display images to user no need for storing them into database but before you have to check internet connection.
Function for retrieving images:
public static Bitmap getBitmapFile(String str)
{
Bitmap bmImg=null;
URL myFileUrl;
try {
myFileUrl = new URL(str);
HttpURLConnection conn= (HttpURLConnection)myFileUrl.openConnection();
conn.setDoInput(true);
conn.connect();
InputStream is = conn.getInputStream();
bmImg = BitmapFactory.decodeStream(is);
} catch (Exception e) {
e.printStackTrace();
}
return bmImg;
}
For checking Internet connection:
// declaring variable for holding Internet connection state
boolean connected = false;
// checking connectivity to the Internet through mobile network or WIFI
ConnectivityManager connectivityManager = (ConnectivityManager)getSystemService(Context.CONNECTIVITY_SERVICE);
if(connectivityManager.getNetworkInfo(ConnectivityManager.TYPE_MOBILE).getState() == NetworkInfo.State.CONNECTED ||
connectivityManager.getNetworkInfo(ConnectivityManager.TYPE_WIFI).getState() == NetworkInfo.State.CONNECTED) {
// Internet connection
connected = true;
}
else
// no Internet connection
connected = false;
Example:
// grab image to display
try {
// Bitmap bmp1;
// String url1;
// ImageView img1;
// in case there is Internet connection display image from online url
if(connected == true)
{
bmp1=MainActivity.getBitmapFile(url1);
img1.setImageBitmap(bmp1);
}
else
{
img1.setImageResource(R.drawable.not_connected);
}
} catch(Exception e) {
e.printStackTrace();
}
I would like to use Android's system cache when downloading images as per these previous instructions: android system cache. I was able to get the following code working but the log statements are telling me that the images are never being read from the cache.
try {
//url = new URL("http://some.url.com/retrieve_image.php?user=" + username);
URL url = new URL("http://some.url.com/prof_pics/b4fe7bdfa174ff372c9f26ce6f78f19c.png");
URLConnection connection = url.openConnection();
connection.setUseCaches(true);
Object response = connection.getContent();
if (response instanceof Bitmap) {
Log.i("CHAT", "this is a bitmap");
current_image.setImageBitmap((Bitmap) response);
}
else {
Log.i("CHAT", "this is not a bitmap");
Log.i("CHAT", response.toString());
InputStream is = connection.getInputStream();
BufferedInputStream bis = new BufferedInputStream(is);
current_image.setImageBitmap(BitmapFactory.decodeStream(bis));
}
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
I have tried two different types of requests, one is to go through a PHP script that returns the image and another that is directly accessing the image file. I refresh the same image multiple times in a row and it never seems to get cached. For the direct image access, I get:
05-31 23:45:12.177 I/CHAT ( 2995): this is not a bitmap
05-31 23:45:12.177 I/CHAT ( 2995): org.apache.harmony.luni.internal.net.www.protocol.http.FixedLengthInputStream#40c1c660`
For the indirect image access, I consistently get:
05-31 23:45:14.550 I/CHAT ( 2995): this is not a bitmap
05-31 23:45:14.550 I/CHAT ( 2995): org.apache.harmony.luni.internal.net.www.protocol.http.ChunkedInputStream#40c02448
I found a better way to do it. If anyone else is having trouble after following the link android system cache, use this Google developer's blog post instead. The source code in that blog post is designed for a ListView but I am using it for all image retrievals. It downloads the image in an AsyncTask, puts a temporary image while downloading, and has an image cache. This last part is listed as a "Future Item" in the blog post, but if you download the source code, the cache is implemented. I had to modify the code slightly because the AndroidHttpClient isn't supported in 2.1. I switched it to a URL connection. So far, this looks to be a great image downloader class. Let's just hope it doesn't impact our already struggling memory management issues.
I have a text file on my server. I want to open the text file from my Android App and then display the text in a TextView. I cannot find any examples of how to do a basic connection to a server and feed the data into a String.
Any help you can provide would be appreciated.
Try the following:
try {
// Create a URL for the desired page
URL url = new URL("mysite.com/thefile.txt");
// Read all the text returned by the server
BufferedReader in = new BufferedReader(new InputStreamReader(url.openStream()));
String str;
while ((str = in.readLine()) != null) {
// str is one line of text; readLine() strips the newline character(s)
}
in.close();
} catch (MalformedURLException e) {
} catch (IOException e) {
}
(taken from Exampledepot: Getting text from URL)
Should work well on Android.
While URL.openStream will work, you would be better off using the Apache HttpClient library that comes with Android for HTTP. Among other reasons, you can use content encoding (gzip) with it, and that will make text file transfers much smaller (better battery life, less net usage) and faster.
There are various ways to use HttpClient, and several helpers exist to wrap things and make it easier. See this post for more details on that: Android project using httpclient --> http.client (apache), post/get method (and note the HttpHelper I included there does use gzip, though not all do).
Also, regardless of what method you use to retrieve the data over HTTP, you'll want to use AysncTask (or Handler) to make sure not to block the UI thread while making the network call.
And note that you should pretty much NEVER just use URL.openStream (without setting some configuration, like timeouts), though many examples show that, because it will block indefinitely if you the server is unavailable (by default, it has no timeout): URL.openStream() Might Leave You Hanging.
Don't forget to add internet permissions to the manifest when taking net resources: (add in manifest).