I am trying to test downloading and storing an image (any image) using Robolectric but I keep getting a 403. The URL is properly accessible and work with Android's VM, also works when I open in the browser.
Here is what I am trying to test.
try{
URLConnection urlConnection = new URL("http://<any image url>").openConnection();
InputStream inputStream = urlConnection.getInputStream();
// call a method to write to disk
} catch(Exception ex){
ex.printStackTrace();
}
My Roboelectric method fails when I try to get the inputStream. It always returns a 403. I looked at the FalseHTTP thing as well but it only seems to work with apache's connection.
Is this a Roboelectric problem or what am I doing incorrectly ? Robolectric is properly configured. RUnnables work. It fails over here.
Thanks!
Try Robolectric.getFakeHttpLayer().interceptHttpRequests(false) to allow the requests to actually go through instead of being intercepted.
Related
I'm about to code an Android app (using A.Studio 3.5.1) that should connect to a back-end using https. I'm quite new to the techniques so I looked at https://developer.android.com/training/articles/security-ssl.html#HttpsExample
I has four lines of code:
URL url = new URL("https://wikipedia.org");
URLConnection urlConnection = url.openConnection();
InputStream in = urlConnection.getInputStream();
copyInputStreamToOutputStream(in, System.out);
When I try it I get a red text;
new URL gives MalformedURLException
url.openConnection() gives IOException,
urlConnection.getInputStream() also
copyInputStreamToOutputStream is not found.
I have read about copyInputStreamToOutputStream, that it can be solved
copyInputStreamToOutputStream(in, System.out)
and
Easy way to write contents of a Java InputStream to an OutputStream
I tried the first way, using apache commons, with no success.
I'm mostly curious about the exceptions.
I will try another walk-through on
https://codelabs.developers.google.com/codelabs/android-network-security-config/
But it would be nice to learn about this...
I have faced similar situations many times. This occur because the webpage you are trying to reach doesn't return anything as a response after connection is established. So the parsing returns IOException as there is nothing to read in the response of URL after connection.
newURL is returning MalformedURLException because your url contains -- " -- which should be escaped as these are special characters.
Hope this helps.
here is url ...
https://api.thingspeak.com/update?api_key=R3LQP7IXIXEQ1OIV&field1=0
Actually..I don't want to get the content of url.
I just want to update the value of field1 to 1 and 0.
If I just type this url in any broswer,my thingspeak data will be update.All I need to do is to write code like typing in any broswer of this url.
In that way I think I can turn on and off my led through android application for my IOT project.I think all I need to do is to make connection between apk and thingspeak from this url.I am new to android studio.I have tried many ways.Help me please.
Thanks a lot.
You can simply use a HTTP GET method (that is what your browser does).
To answer your question:
try {
// create the HttpURLConnection
url = new URL(yourUrl);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
// just want to do an HTTP GET here like your browser would
connection.setRequestMethod("GET");
// give it 15 seconds to respond
connection.setReadTimeout(15*1000);
connection.connect();
} catch (Exception e) {
e.printStackTrace();
throw e;
} finally {
connection.disconnect();
}
There are better (cleaner) ways to do his, but this should answers your question.
PS: Be aware that in Android you will not be able to do this on the main thread! You should do this in a AsyncTask, AsyncTaskLoader, ...
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.
I'm trying to download an object from S3 using the AWS Android SDK 1.0.4 or 1.0.3.
This is my code:
AmazonS3Client client = getConnection(userCredentials);
S3Object obj = client.getObject(workspaceName, objectName);
ObjectMetadata meta = obj.getObjectMetadata();
long size = meta.getContentLength();
logger.info("S3 object length: "+size);
InputStream is = new BufferedInputStream(obj.getObjectContent());
byte[] fragmentBytes = IOUtils.toByteArray(is);
logger.info("Read bytes: "+ fragmentBytes.length);
This sometimes, rarely, works. Most of the time either an "java.net.SocketException: Socket is closed" is thrown or no error is reported but only part of the object is read.
Note, that the BufferedInputStream should not be necessary for IOUtils.toByteArray(...) and it makes no difference if it is there or not.
The problem does not seem to occur when stepping through the code line by line in a debugger.
This happens on my Android 2.3.3 device and 3.2 device. It happens over WiFi and 3G.
Any ideas?
ps> The objects are about 250k big
The issue is that the client is being Garbage Collected. To fix it, you need to keep an explicit reference to the S3Client.
The flow of the bug is as follows:
The program gets an S3 client
The program gets a S3 object from the client.
The program gets an inputStream from the s3Object, which gets it through the client.
Garbage collection runs, and since there is no reference to the client, it gets Garbage Collected, randomly closing your inputStream.
IMO, this is a very bad bug by Amazon. Why the S3 object input stream does not have a reference back to the client is a mystery to me.
Here's the thread on the AWS forums: https://forums.aws.amazon.com/thread.jspa?threadID=83326
You probably already solved this but I could not find the correct answer and ended up figuring it out by myself, so here goes the solution:
The getObjectContent methods documentation is very clear about closing the InputStream:
S3ObjectInputStream com.amazonaws.services.s3.model.S3Object.getObjectContent()
Gets an input stream containing the contents of this object. Callers should close this input stream as soon as possible, because the object contents aren't buffered in memory and stream directly from Amazon S3.
You are making the same mistake as I was of using the InputStream (S3Object) as if closure was transparent.
I am guessing you need to get an image from S3 to be used on Android, so here goes an example method that returns a Bitmap. It really applies to any kind of input.
private Bitmap getFromStore(String fileName) {
AmazonS3Client client = new AmazonS3Client(new BasicAWSCredentials(ACCESS_KEY, SECRET_KEY));
S3Object o = client.getObject(BUCKET, fileName);
InputStream is = o.getObjectContent();
Bitmap image = null;
try {
// Use the inputStream and close it after.
image = BitmapFactory.decodeStream(is);
} finally {
try {
is.close();
} catch (IOException e) {
Log.w(TAG, "Error trying to close image stream. ", e);
}
}
return image;
}
Just in case, dont forget to execute this on a different thread then the UI.
Good luck,
Well, it seems you are not alone. The accepted in the post answer talks of your problem.
How to write an S3 object to a file?
I would try looping the content like the answer in the question above. Buffered is good, but....
You could also try not using the IOUtil, after all there are other options in java.
no need to keep re-initializing s3.
In your onCreate, make the call to initialize s3Object and s3Client.
Then use the call in your asynctask. This way, your s3Client will keep the same data and never close the socket connection with s3 when doing the while read.
S3Client s3Client;
S3Object s3Object;
onCreate() {
s3Client = new AmazonS3Client(new BasicSessionCredentials(
Constants.ACCESS_KEY_ID, Constants.SECRET_KEY, Constants.TOKEN
));
object = new S3Object();
}
doinbackground() {
object = s3Client.getObject(new GetObjectRequest(Constants.getBucket(), id +".png"));
}
/****** add this in your onCreate ******/
AmazonS3Client client = getConnection(userCredentials);
I have the following code to read a website. The code is searches on google. I want to open automatically the first result and read it again. For the keywords i want the "I am feeling lucky is not working". Please somebody help me find a solution
I have the following code.
URL url = new URL("http://www.google.com/search?q=sample");
URLConnection urlConnection = url.openConnection();
InputStream in = new BufferedInputStream(urlConnection.getInputStream());
try {
readStream(in);
finally {
in.close();
}
}
The query sample is just a sample....
Its already discussed in SO QA :
How to search in google by using java code?
Your approach is also a solution. But it will be complex as it requires parsing of returned HTML.
I think there are some APIS for doing this.
http://code.google.com/p/google-api-java-client/
This is deprecated but might still work -->
http://code.google.com/apis/websearch/docs/