Android Inputstream.read problem on Gingerbread (while downloading) - android

I didn't find any question like this here.
Yesterday I finally got Gingerbread 2.3.4 on my Nexus One. When I opened my application (basically loads an XML Feed into a ListView) again, it got stuck while downloading.
It seems that InputStream stream; -> stream.read(buffer); doesn't return -1 any more, when it's finished.
The Code ist nearly the same from here Download Progress
Here's my code:
public InputStream getInputStreamFromURL(String urlString, DownloadProgressCallback callback)
throws IOException, IllegalArgumentException
{
InputStream in = null;
conn = (HttpURLConnection) new URL(urlString).openConnection();
fileSize = conn.getContentLength();
out = new ByteArrayOutputStream((int) fileSize);
conn.connect();
stream = conn.getInputStream();
// loop with step 1kb
while (status == DOWNLOADING) {
byte buffer[];
if (fileSize - downloaded > MAX_BUFFER_SIZE) {
buffer = new byte[MAX_BUFFER_SIZE];
} else {
buffer = new byte[(int) (fileSize - downloaded)];
}
int read = stream.read(buffer);
if (read == -1) {
break;
}
// writing to buffer
out.write(buffer, 0, read);
downloaded += read;
// update progress bar
callback.progressUpdate((int) ((downloaded / fileSize) * 100));
}// end of while
if (status == DOWNLOADING) {
status = COMPLETE;
}
in= (InputStream) new ByteArrayInputStream(out.toByteArray());
// end of class DownloadImageTask()
return in;
}
The problem basically is that when the download finishes, stream.read(buffer) returns 0 instead of -1. When I change
if (read == -1) {
break;
}
to 0 or
if (fileSize == downloaded) {
break;
}
I get ParseExceptions (ExpatParser) on my MainActivity.
On 2.2 it runs really perfect.
I cleared the app cache and tried a few other things already, but I'm really stuck now.
I hope that someone can help me. :)
UPDATE:
That's awesome, you're the man, Guillaume. :)
Thank you very much, that saved my evening! :)
Your Code for my needs here:
public InputStream getStreamFromURL(String urlString, DownloadProgressCallback callback){
// initialize some timeouts
HttpParams httpParameters = new BasicHttpParams();
HttpConnectionParams.setConnectionTimeout(httpParameters,3000);
// create the connection
URL url;
try {
url = new URL(urlString);
URLConnection connection = url.openConnection();
HttpURLConnection httpConnection = (HttpURLConnection) connection;
// connection accepted
if(httpConnection.getResponseCode() == HttpURLConnection.HTTP_OK) {
int size = connection.getContentLength();
int index = 0;
int current = 0;
InputStream input = connection.getInputStream();
BufferedInputStream buffer = new BufferedInputStream(input);
byte[] bBuffer = new byte[1024];
out = new ByteArrayOutputStream((int) size);
while((current = buffer.read(bBuffer)) != -1) {
out.write(bBuffer, 0, current);
index += current;
callback.progressUpdate((index/size)*100);
}
out.close();
}
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return (InputStream) new ByteArrayInputStream(out.toByteArray());
}

This code work on my 2.3.4 Nexus One :
try {
// initialize some timeouts
HttpParams httpParameters = new BasicHttpParams();
HttpConnectionParams.setConnectionTimeout(httpParameters, 3000);
// create the connection
URL url = new URL(toDownload);
URLConnection connection = url.openConnection();
HttpURLConnection httpConnection = (HttpURLConnection) connection;
// connection accepted
if (httpConnection.getResponseCode() == HttpURLConnection.HTTP_OK) {
try {
file = new File(destination);
// delete the file if exists
file.delete();
} catch (Exception e) {
// nothing
}
int size = connection.getContentLength();
int index = 0;
int current = 0;
try {
file = new File(destination);
file.delete();
FileOutputStream output = new FileOutputStream(file);
InputStream input = connection.getInputStream();
BufferedInputStream buffer = new BufferedInputStream(input);
byte[] bBuffer = new byte[10240];
while ((current = buffer.read(bBuffer)) != -1) {
if (isCancelled()) {
file.delete();
break;
}
try {
output.write(bBuffer, 0, current);
} catch (IOException e) {
e.printStackTrace();
}
index += current;
publishProgress(index / (size / 100));
}
output.close();
} catch (SecurityException se) {
se.printStackTrace();
return 1;
} catch (FileNotFoundException e) {
e.printStackTrace();
return 1;
} catch (Exception e) {
e.printStackTrace();
return 2;
}
return 0;
}
// connection refused
return 2;
} catch (IOException e) {
return 2;
}

Related

Video recording from a textureview running mediaplayer

I am creating an android application which is running a mediaplayer on a textureview, and streaming video from the internet. Now, I want to record the same streaming video to a .mp4 file(or in any format) to SD card. how can I do it?
I cannot use a surfaceview instead of textureview. please help me.
I got a solution. If the server supports downloading use the following code.
private final int TIMEOUT_CONNECTION = 5000; //5sec
private final int TIMEOUT_SOCKET = 30000; //30sec
private final int BUFFER_SIZE = 1024 * 5; // 5MB
try {
URL url = new URL("http://....");
//Open a connection to that URL.
URLConnection ucon = url.openConnection();
ucon.setReadTimeout(TIMEOUT_CONNECTION);
ucon.setConnectTimeout(TIMEOUT_SOCKET);
// Define InputStreams to read from the URLConnection.
// uses 5KB download buffer
InputStream is = ucon.getInputStream();
BufferedInputStream in = new BufferedInputStream(is, BUFFER_SIZE);
FileOutputStream out = new FileOutputStream(file);
byte[] buff = new byte[BUFFER_SIZE];
int len = 0;
while ((len = in.read(buff)) != -1)
{
out.write(buff,0,len);
}
} catch (IOException ioe) {
// Handle the error
} finally {
if(in != null) {
try {
in.close();
} catch (Exception e) {
// Nothing you can do
}
}
if(out != null) {
try {
out.flush();
out.close();
} catch (Exception e) {
// Nothing you can do
}
}
}
it will help.thanks

HTTP-Download loads tons of questionmarks

I created a Async-Download-Class to download JSON-Code from an interface-website. It does actually work, but sometimes it breaks and in the download log I can see question marks that should be a string. I had this problem before and solved it by just increasing the buffer size but this affects the speed of the app.
As you can imagine the JSON-Reader searches for a timestamp but he cannot find one. So the error I get is a formatexception but I think this is not relevant. (Sometimes undetermined object, too)
10-17 18:38:11.443: D/debug(13532): {"ident":"50572","ts":"24.05.2011 07:40","content":"<inmydays> Bin ich der einzige der dachte, beim Film 1+1=10 geht es um Nerds und nicht darum, dass 2 Schauspieler die 10 Hauptrollen spielen?","rating":"2044"},
10-17 18:38:11.443: D/debug(13532): {"ident":"28685","ts":"20.12.2009 08:40","content":"<Frau> ich wohne jetzt hier fast 10 monate und habe heute endlich mal meinen nachbarn von nebenan kennengelernt[newline]<Alex> Glückwunsch [newline]<Frau> in der videothek... Hat sich 7 pornos ausgeliehen[newline]<Alex> lol","rating":"4787"},
10-17 18:38:11.443: D/debug(13532): {"ident":"12820�������������������������������������������������������������������������������������������������������������������������������������������������������������
*I deleted most of the questionmarks to keep it clear.
#Override
protected String doInBackground(String... params) {
String urlStr = params[0];
InputStream is = null;
try {
URL url = new URL(urlStr);
HttpURLConnection connection = (HttpURLConnection) url
.openConnection();
connection.setReadTimeout(100 * 1000);
connection.setConnectTimeout(100 * 1000);
connection.setRequestMethod("GET");
connection.setDoInput(true);
connection.connect();
int response = connection.getResponseCode();
Log.d("debug", "The response is: " + response);
is = connection.getInputStream();
// read string
// buffersize:
// ~max 1024 - 5
//
SharedPreferences sharedPref = PreferenceManager
.getDefaultSharedPreferences(activity);
String displayed_items = sharedPref.getString(
"pref_key_numberofitems", "10");
int items = Integer.parseInt(displayed_items);
if (items > 10) {
final int bufferSize = 40960 * 2;
byte[] buffer = new byte[40960 * 2];
ByteArrayOutputStream os = new ByteArrayOutputStream();
while (true) {
int count = is.read(buffer, 0, bufferSize);
if (count == -1) {
break;
}
os.write(buffer);
}
os.close();
result = new String(os.toByteArray(), "iso-8859-1");
Log.d("debug", result);
} else {
final int bufferSize = 2048 * 7;
byte[] buffer = new byte[2048 * 7];
ByteArrayOutputStream os = new ByteArrayOutputStream();
while (true) {
int count = is.read(buffer, 0, bufferSize);
if (count == -1) {
break;
}
os.write(buffer);
}
os.close();
result = new String(os.toByteArray(), "iso-8859-1");
Log.d("debug", result);
}
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return result;
Edit: Is there another method to download data from an interface webiste? Maybe this would help me.
This solved my problem:
String result = "";
#Override
protected String doInBackground(String... params) {
String urlStr = params[0];
URL url;
InputStream is = null;
BufferedReader br;
String line;
try {
url = new URL(urlStr);
is = url.openStream(); // throws an IOException
br = new BufferedReader(new InputStreamReader(is, "iso-8859-1"));
while ((line = br.readLine()) != null) {
result += line;
}
} catch (MalformedURLException mue) {
mue.printStackTrace();
} catch (IOException ioe) {
ioe.printStackTrace();
} finally {
try {
if (is != null) is.close();
} catch (IOException ioe) {
// nothing to see here
}
}
Log.d("Downloaded", result);
return result;
}
My thoughts why this finally worked:
With this way of downloading data you don't need to define a buffer which can be full.
Hope it helps others too :)
Have a nice day!
what happens if you use another encoding like UTF-8 instead of ISO-8859-1?

How can I download Image File from an URL to ByteArray?

following is my code:
private byte[] downloadImage(String image_url) {
byte[] image_blob = null;
URL _image_url = null;
HttpURLConnection conn = null;
InputStream inputStream = null;
try {
_image_url = new URL(image_url);
} catch (MalformedURLException e) {
e.printStackTrace();
}
try {
conn = (HttpURLConnection) _image_url.openConnection();
} catch (IOException e) {
e.printStackTrace();
}
conn.setDoInput(true);
try {
conn.connect();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
conn.setUseCaches(false);
try {
inputStream = conn.getInputStream();
inputStream.read(image_blob);
} catch (IOException ex) {
ex.printStackTrace();
} finally {
try {
inputStream.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
conn.disconnect();
}
return image_blob;
}
What I am trying to do is to get the byte array of an Image. Use it in a parcel to transfer it to another activity.
Using this code a NullPointerException is reported. Can any one say what is wrong?
You might want to try it like this:
DefaultHttpClient client = new DefaultHttpClient();
HttpGet request = new HttpGet(imageUrl);
HttpResponse response = client.execute(request);
HttpEntity entity = response.getEntity();
int imageLength = (int)(entity.getContentLength());
InputStream is = entity.getContent();
byte[] imageBlob = new byte[imageLength];
int bytesRead = 0;
while (bytesRead < imageLength) {
int n = is.read(imageBlob, bytesRead, imageLength - bytesRead);
if (n <= 0)
; // do some error handling
bytesRead += n;
}
And by the way: The NullPointerException is caused because image_blob is null. You need to allocate the array first before you can read data into it.
Rather then sending image, you can send path of image which is download in cache. You can just use this methods to proive image path and download image into local path.
private String createLocal(String surl) {
URL url;
try {
url = new URL(surl);
String tempname=String.valueOf(surl.hashCode());
File root=getCacheDir();
File localfile=new File(root.getAbsolutePath()+"/"+tempname);
localfile.deleteOnExit();
if(!localfile.exists()){
InputStream is=url.openStream();
OutputStream os = new FileOutputStream(localfile);
CopyStream(is, os);
os.close();
}
return localfile.getAbsolutePath();
} catch (Exception e){
return null;
}
}
public static void CopyStream(InputStream is, OutputStream os) {
final int buffer_size=1024;
try {
byte[] bytes = new byte[buffer_size];
for(;;) {
int count=is.read(bytes, 0, buffer_size);
if(count == -1)
break;
os.write(bytes, 0, count);
}
}
catch(Exception ex){}
}
Your byte[] image_blob is null,you must new enough space like that before you use it:
image_blob = new byte[enough];
inputStream.read(image_blob);
public static byte[] getByteArray(String url) throws IOException {
InputStream inputStream = (InputStream) new URL(url).getContent();
return IOUtils.toByteArray(inputStream);
}

Downloading a file from HTTP connection which redirect to HTTPS connection

I am using Dropbox in my project to get tiny url from dropbox which is like http://www.db.tt/xyzabc.
When I try to download the file in HTC My touch my code works fine, but if I try in Motorola Atrix it throws exception unknown host db.tt.
Actually first I have url like http://www.db.tt/xyzabc which is HTTP url I open it than I get exception and in exception I get actual url to file which contain file and is HTTPS url in exception. I start downloading file here is my code which work for me:
public static void fileUrl(String fAddress, String localFileName,
String destinationDir) {
OutputStream outStream = null;
URLConnection uCon = null;
InputStream is = null;
try {
URL url;
byte[] buf;
int ByteRead, ByteWritten = 0;
url = new URL(fAddress);
outStream = new BufferedOutputStream(new FileOutputStream(
destinationDir + localFileName));
try {
// Here i have "http://www.db.tt/xyzabc"
// after i hit url i get exception and in exception that
// FileNotFoundException at https://www.dropbox.com/abcxyz
// i get actual actual url i parse that exception and
//retrive https://www.dropbox.com/xyzabc(actual url)
// but in motorolla atrix instead of that url i get
// unknownhost exception "db.tt"
uCon = url.openConnection();
// uCon.connect();
is = uCon.getInputStream();
} catch (Exception e) {
url = new URL(e.getMessage().substring(
e.getMessage().indexOf("https"),
e.getMessage().length()));
outStream = new BufferedOutputStream(new FileOutputStream(
destinationDir + localFileName));
uCon = url.openConnection();
is = uCon.getInputStream();
}
buf = new byte[size];
while ((ByteRead = is.read(buf)) != -1) {
outStream.write(buf, 0, ByteRead);
ByteWritten += ByteRead;
}
System.out.println("Downloaded Successfully.");
System.out.println("File name:\"" + localFileName
+ "\"\nNo ofbytes :" + ByteWritten);
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
is.close();
outStream.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
ok after few attempt i made it solve my self and here is the solution will be helpfull if someone got same problem it requires some error handling and modification according to need
After seeing class heirarchy of Connection i found that HttpsURLConnection is child of HttpURLConnection and HttpURLConnection is child of UrlConnection so i i used HTTPConnection instead of UrlConnection and as HttpsUrlConnection is concrete for HttpsUrlConnection it solved my problem
i continue iterating till i get Https url after redirect
public static void fileUrl(String fAddress, String localFileName,
String destinationDir) {
OutputStream outStream = null;
URLConnection uCon = null;
HttpURLConnection mHttpCon;
InputStream is = null;
try {
URL url;
byte[] buf;
int ByteRead, ByteWritten = 0;
url = new URL(fAddress);
outStream = new BufferedOutputStream(new FileOutputStream(
destinationDir + localFileName));
try {
mHttpCon = (HttpURLConnection) url.openConnection();
while (!url.toString().startsWith("https")) {
mHttpCon.getResponseCode();
url = mHttpCon.getURL();
mHttpCon = (HttpURLConnection) url.openConnection();
}
is = mHttpCon.getInputStream();
} catch (Exception e) {
e.printStackTrace();
// url = new URL(e.getMessage().substring(
// e.getMessage().indexOf("https"),
// e.getMessage().length()));
// outStream = new BufferedOutputStream(new FileOutputStream(
// destinationDir + localFileName));
//
// uCon = url.openConnection();
// is = uCon.getInputStream();
}
buf = new byte[size];
while ((ByteRead = is.read(buf)) != -1) {
outStream.write(buf, 0, ByteRead);
ByteWritten += ByteRead;
}
System.out.println("Downloaded Successfully.");
System.out.println("File name:\"" + localFileName
+ "\"\nNo ofbytes :" + ByteWritten);
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
is.close();
outStream.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
public static void fileDownload(String fAddress, String destinationDir) {
int slashIndex = fAddress.lastIndexOf('/');
int periodIndex = fAddress.lastIndexOf('.');
String fileName = fAddress.substring(slashIndex + 1);
if (periodIndex >= 1 && slashIndex >= 0
&& slashIndex < fAddress.length() - 1) {
fileUrl(fAddress, fileName, destinationDir);
} else {
System.err.println("path or file name.");
}
}
This answer works - to an extent. I have a similar solution here
There is still a problem with Dropbox short hyperlinks on Atrix. They redirect from http to https but NOT to the required file, instead I get a whole lot of html from inside Dropbox.

How to receive data from the server?

I am trying to fetchg data from server like MP3 files, video files, etc. in my application. The application should show the list of video files received from the server.
How can I do this?
/** this function will download content from the internet */
static int writeData(String fileurl, boolean append, String path,
String filename, Activity mContext) throws CustomException {
URL myfileurl = null;
ByteArrayBuffer baf = null;
HttpURLConnection conn = null;
String mimeType="";
final int length;
try {
myfileurl = new URL(fileurl);
} catch (MalformedURLException e) {
e.printStackTrace();
}
try {
conn = (HttpURLConnection) myfileurl
.openConnection();
conn.setDoInput(true);
conn.connect();
conn.setConnectTimeout(100000);
length = conn.getContentLength();
mimeType=conn.getContentType().toString();
System.out.println("Extension..."+mimeType);
if(mimeType.equalsIgnoreCase("application/vnd.adobe.adept+xml") || mimeType.equalsIgnoreCase("text/html; charset=utf-8"))
return 0;
if (length > 0) {
InputStream is = conn.getInputStream();
BufferedInputStream bis = new BufferedInputStream(is);
baf = new ByteArrayBuffer(1000);
int current = 0;
while ((current = bis.read()) != -1) {
try {
baf.append((byte) current);
mBufferError=false;
} catch (Exception e){
// TODO: handle exception
mBufferError=true;
e.printStackTrace();
throw new CustomException("### memory problem ", "Buffer Error");
}
}
}
} catch (IOException e) {
mBufferError=true;
e.printStackTrace();
}
try{
if(conn.getResponseCode()==200 && mBufferError==false)
{
path = path + "/" + filename;
boolean appendData = append;
FileOutputStream foutstream;
File file = new File(path);
boolean exist = false;
try {
if (appendData)
exist = file.exists();
else
exist = file.createNewFile();
} catch (IOException e) {
try {
return 1;
} catch (Exception err) {
Log.e("SAX", err.toString());
}
}
if (!appendData && !exist) {
} else if (appendData && !exist) {
} else {
try {
foutstream = new FileOutputStream(file, appendData);
foutstream.write(baf.toByteArray());
foutstream.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
}catch (Exception e) {
// TODO: handle exception
throw new CustomException("### I/O problem ", "I/O Error");
}
return 1;
}
once download complete search the file with extension(.3gp) for video
hope it helps
Check this link,
https://stackoverflow.com/search?q=how+to+download+mp3+%2Cvideos+from+server+in+android
Try this code
url = "your url name+filename.jpg,mp3,etc..."
FileName = "/sdcard/savefilename" // save in your sdcard
try{
java.io.BufferedInputStream in = new java.io.BufferedInputStream(new java.net.URL(url).openStream());
java.io.FileOutputStream fos = new java.io.FileOutputStream(FileName);
java.io.BufferedOutputStream bout = new BufferedOutputStream(fos,1024);
byte[] data = new byte[1024];
int x=0;
while((x=in.read(data,0,1024))>=0){
bout.write(data,0,x);
}
fos.flush();
bout.flush();
fos.close();
bout.close();
in.close();
}
catch (Exception ex)
{
}
and after you want to use MediaPlayer
and create object of mediaplayer in your activity
and play.
mp.reset();
mp.start();

Categories

Resources