When executing an HttpUriRequest using the AndroidHttpClient, it will throw an java.lang.IllegalArgumentException: Host name may not be null when the url is faulty.
In my application, the user can input his own url. When for example http://195.168.0.q is entered, the IllegalArgument is thrown, and the app crashes.
How can I prevent this (preferably, without catching exceptions)?
Catch the exception with a 'try-catch(-finally)' block.
try {
// your code
} catch(IllegalArgumentException) {
// Faulty url
}
You should make sure the user has supplied a valid URL before trying to use it as one:
URL url;
try {
url = new URL("http://195.168.0.q");
} catch (MalformedURLException e) {
// tell user the URL they entered is invalid
}
Related
I'm getting an issue where ContentResolver.getType is not ready when the app starts.
However, putting a delay of 1s, will make it ready.
Code:
String mimeType = contentResolver.getType(uri); // returns null
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
String mimeType2 = contentResolver.getType(uri); // returns correct mime type
Note this only happens on app startup.
Any help is highly appreciated.
Thanks.
I'm trying to connect my Android application to my company local network (Windows) using smb protocol. The problem is I'm kinda newbie on this matter and something is missing me.
The goal is download the file AREQA.txt from the network to the device. However I don't even can verify if the code can trace the file location because the application crashes when I compile it to the device (it loads fine but crashes when I call the DownLoadF001 procedure). Here's the code:
public void DownLoadF001(View v) {
jcifs.Config.registerSmbURLHandler();
String user;
String password;
String filename;
File localFile;
SmbFile path = null;
try {
NtlmPasswordAuthentication auth = new NtlmPasswordAuthentication(null,"######", "********");
path = new SmbFile("smb:\\192.168.1.11/.../AREQA.txt", auth);
try {
if(path.exists()){
Toast.makeText(getApplicationContext(), "Sucesso!", Toast.LENGTH_LONG).show();
}
} catch (Exception e1) {
Toast.makeText(getApplicationContext(), e1.toString(), Toast.LENGTH_LONG).show();
}
} catch (MalformedURLException e2) {
Toast.makeText(getApplicationContext(), e2.toString(), Toast.LENGTH_LONG).show();
}
}
I already tried to remove the inside try from the main one (with all its associated code), and the application stops crashing. However, without it, I can't see if the connection is working.
EDIT: I managed to catch the error (Exception e1):
java.lang.NullPointerException: Attempt to invoke virtual method int java.lang.String.length()' on a null object reference. Any ideas to solve it?
Also, as pointed by #greenapps, I'm calling this procedure from a .xml button by onClick method.
I have a webview that loads a google doc with a flyer (pdf, from the web) in it. Some of the flyers are live on my website but others aren't, but I have them coded in the app so when they become available the user will see them.
The google doc in the webview works great with flyers that are available but ones that aren't available yet I get a error-type message in the google doc. I would like to intercept the 404 response code error from the URL that has the flyer (pdf). How do I do this?
Current code:
/*opens in app using google docs*/
mWebView.getSettings().setJavaScriptEnabled(true);
mWebView.getSettings().setPluginState(PluginState.ON);
mWebView.loadUrl("https://docs.google.com/viewer?url="+round_num_url);
//round_num_url is the url for my flyer
Message in google doc in webview for flyers unavailable - "Sorry, we were unable to find the document at the original source. Verify that the document still exists. You can also try to download the original document by clicker here"
EDIT: doesn't work yet (crashes) after taking suggestions from #x-code
try {
URL url = new URL(round_num_url);
HttpURLConnection huc = (HttpURLConnection) url.openConnection();
huc.setRequestMethod("HEAD");
huc.connect();
if (huc.getResponseCode() != 404) {
// the pdf is available, continue with your code that loads the web view
// ...
} else {
// the pdf is not available, you may need to notify the user
// ...
}
huc.disconnect();
} catch (MalformedURLException e) {
e.printStackTrace();
} catch(IOException e) {
e.printStackTrace();
}
Although Google docs will receive a 404 when it tries to access your broken URL, it is not going to return a 404 to the web view, because the Google docs URL is valid.
You should first test your own URL (the URL of your PDF) by trying to load it with for example the AndroidHttpClient and an HttpHead request. If this returns a 404 don't bother trying to load gdocs.
Here is some example code. I used HttpUrlConnection because that is the method recommended by Android docs for new code:
HttpUrlConnection huc = new HttpUrlConnection(round_num_url);
huc.setRequestMethod("HEAD");
huc.connect();
if (huc.getResponseCode() != 404) {
// the pdf is available, continue with your code that loads the web view
// ...
} else {
// the pdf is not available, you may need to notify the user
// ...
}
huc.disconnect();
I have not compiled this code, and you may have to wrap it in a try / catch block before it will compile.
Update: I had to modify the code to make it work, as suggested above:
try {
URL url = new URL(strUrl);
HttpURLConnection huc = (HttpURLConnection) url.openConnection();
try {
if (huc.getResponseCode() != 404) {
// url is available
} else {
// url is not available
}
} finally {
huc.disconnect();
}
} catch (MalformedURLException e) {
;
} catch (IOException e) {
;
}
I am trying to perform a simple get request using Apache HTTPClient however it seems as if all the code after the HTTPResponse response = client.execute(get); is being skipped. I am not able to access the contents of the response object,they are all null. However when I use debug mode and I explore the object I see all the data. This function is wrapped in an async task so I am wondering the task itself is not waiting on it to be executed or something I am not sure.
Something similar happened here:
Android code after httpclient.execute(httpget) doesn't get run in try (using AsyncTask)
Here is the code.
#Override
public T execute()
{
utils = new GeneralUtils();
if(getURL() == null)
{
throw new NullPointerException("No path specified");
}
HttpClient client = new DefaultHttpClient();
HttpGet get = new HttpGet(getURL());
Log.e(TAG,"client created");
if(getHeaders()!=null)
{
Log.e(TAG,"client created");
for(Map.Entry<String,String> header:getHeaders().entrySet())
{
get.addHeader(header.getKey(),header.getValue());
}
}
try
{
HttpResponse response = client.execute(get);
Log.e(TAG,"executed");
if(response==null)
Log.v(TAG,"its null as heell");
Log.v(TAG,response.getStatusLine().getReasonPhrase());
Log.v(TAG,String.valueOf(response.getStatusLine().getStatusCode()));
Log.e(TAG,getURL());
Log.v(TAG,"everything else is dead");
for(Header header:response.getAllHeaders())
{
Log.v(TAG,header.getName()+" "+header.getValue());
}
if(response.getStatusLine().getStatusCode() == 200)
{
if(response.getEntity().getContent()!=null)
{
try
{
if(utils.isExternalStorageWritable())
{
String path = getContext().getFilesDir().getAbsolutePath()+"/"+getFileCategory()+"/" +getAlarmId()+getFileExtension();
media = new File(path);
/**
* if the directory has not being created this function does the creation.
*/
media.mkdirs();
FileOutputStream fileOutputStream = new FileOutputStream(media);
IOUtils.copy(response.getEntity().getContent(),fileOutputStream);
fileOutputStream.close();
Log.e(TAG,media.getAbsolutePath());
return (T)media;
}
return null;
}
catch (ClientProtocolException e)
{
Log.v(TAG,e.getMessage());
}
catch (IOException e)
{
Log.v(TAG,e.getMessage());
}
}
}
}
catch (IOException e)
{
Log.e(TAG, e.getCause().getMessage());
e.printStackTrace();
}
return null;
}
The code is not throwing any exceptions so I am not sure about what's happening.
All the code after the response object does not work. It just returns null, As in as soon as I try to obtain a value from response like so response.getStatusCode(), it seems as if the code goes dead and just returns null.
Why don't you use a library that will handle all these restful connections?
I would recommend a couple:
https://github.com/darko1002001/android-rest-client (this is mine i have to mention it first :). I have built this library for the projects i build. For your case you would supply a parser which will give you an InputStream which you will just save as a file (as you do it now with IO utils). It handles the Asynchronous part of the whole thing and generally gives you a nice way to organize code.
http://square.github.io/retrofit/ - is another one that i have been playing around with. i think it is pretty well made and should be able to do whatever you want with it.
http://java.dzone.com/articles/android-%E2%80%93-volley-library - Volley is a project that came out straight from Google and it was demoed at the last Google IO conference. It handles all the async operations for you as well and enables you to do all these things. One thing that i am not really sure about is whether or not it will enable you to parse the responses in the background thread.
I would strongly suggest for you to use one of these as they might save you a lot of time.
If you do want to continue with your code then i would suggest to first investigate if some of the "if" blocks you have are skipped, use the debugger or add log messages to see if it enters the blocks. Go step by step and see what goes wrong.
I am doing something similar in my project, check out this file:
https://github.com/darko1002001/android-rest-client/blob/master/android-rest-lib/src/main/java/com/dg/libs/rest/client/BaseRestClient.java
I am constantly getting error reports (from users) such as:
Caused by: Status Code: 400, AWS Service: AmazonSimpleDB, AWS Request ID: c5cb109d-bbff-fcea-bc0d-0cb60ff8f6af, AWS Error Code: RequestExpired, AWS Error Message: Request has expired. Timestamp date is 2012-06-06T13:19:59.415Z. Current date is 2012-06-06T14:20:03Z
Apparently this is because the user has the wrong timezone or something set? Regardless, I would like to catch this particular error and post a message to the user asking them to check their timezone settings however I can't find a way to do it. If I catch AmazonServiceException, the error shows up as null.
How can I catch errors based on Status Code or even Error Code? The current code that I tried looks like this:
try {
dostuff()
} catch (IOException e) {
updateAWS("DownloadErrors");
return "filenotfound";
} catch (AmazonServiceException e) {
return "downloadfail";
}
However AmazonServiceException e is always null so I can't pull any information from it.
other code:
private void doStuff() throws IOException, AmazonServiceException{
//code here
}
Apparently this is what I needed. SDb tracks "RequestExpired" and S3 uses "RequestTimeTooSkewed"
Also, this appears to be occurring because the system time is >15 minutes different than the AWS server. I put a note to the user to check their time and use "Automatic" date/time if possible. Tested it myself and reproduced the error as well as the solution.
try {
result = doOperations();
} catch (AmazonServiceException e) {
if (e.getErrorCode().equals("RequestExpired") || e.getErrorCode().equals("RequestTimeTooSkewed")) {
result = "timestamp";
}
}
return result;
}