This must be something really stupid, trying to solve this issue for a couple of days now and it's really not working. I searched everywhere and there probably is someone with the same problem, but I can't seem to find it.
I'm working on an Android app and this app pulls some xml from a website. Since this website is down a lot, I decided to save it and run it locally. Now what I did:
I downloaded the kWs app for hosting the downloaded xml file.
I put the file in the right directory and could access it through the mobile browser, but not with my app (same code as I used with pulling it from some other website, not hosted by me, only difference was the URL obviously).
So I tried to host it on my PC and access it with my app from there. Again the same results, the mobile browsers had no problem finding it, but the app kept saying 404 Not Found: "The requested URL /test.xml¶ma=Someone¶mb= was not found on this server."
Note: Don't mind the 2 parameters I am sending, I needed that to get the right stuff from the website that wasn't hosted by me.
My code:
public String getStuff(String name){
String URL = "http://10.0.0.8/test.xml";
ArrayList<NameValuePair> params = new ArrayList<NameValuePair>(2);
params.add(new BasicNameValuePair("parama", name));
params.add(new BasicNameValuePair("paramb", ""));
APIRequest request = new APIRequest(URL, params);
try {
RequestXML rxml = new RequestXML();
AsyncTask<APIRequest, Void, String> a = rxml.execute(request);
...
} catch(Exception e) {
e.printStackTrace();
}
return null;
}
That should be working correctly. Now the RequestXML class part:
class RequestXML extends AsyncTask<APIRequest, Void, String>{
#Override
protected String doInBackground(APIRequest... uri) {
HttpClient httpclient = new DefaultHttpClient();
String completeUrl = uri[0].url;
// ... Add parameters to URL ...
HttpGet request = null;
try {
request = new HttpGet(new URI(completeUrl));
} catch (URISyntaxException e1) {
e1.printStackTrace();
}
HttpResponse response;
String responseString = "";
try {
response = httpclient.execute(request);
StatusLine statusLine = response.getStatusLine();
if(statusLine.getStatusCode() == HttpStatus.SC_OK){
// .. It crashes here, because statusLine.getStatusCode()
// returns a 404 instead of a 200.
The xml is just plain xml, nothing special about it. I changed the contents of the .htaccess file into "ALLOW FROM ALL" (works, cause the browser on my mobile device can access it and shows the correct xml).
I am running Android 4.0.4 and I am using the default browser AND chrome on my mobile device.
I am using MoWeS to host the website on my PC.
Any help would be appreciated and if you need to know anything before you can find an answer to this problem, I'll be more than happy to give you that info.
Thank you for you time!
Cheers.
I think you just miss the question mark after your filename
/test.xml?¶ma=Someone¶mb=
Related
This is going to be a bit long but hopefully others will also benefit from this thread.
I am planning to make a private application for quite a number of people. It is NOT going to be on the google play. Thus, I am now facing a few problems: How do I download the new version and how do I re-install it?
I have read some brilliant websites about installing and uninstalling applications with another app like:
http://android.amberfog.com/?p=98
and some about downloading app from online:
Download a file with Android, and showing the progress in a ProgressDialog
and even this:
Auto-Update for (private) Android apps
But I can't figure out how to do what I want to. I want to create an app that can auto-update. My plan, from researching over and over, is to have 2 applications. The main one needs to be updated, while the second one is always there. Each time the main one is on, the second app is called and perform checks and if necessary, uninstall the main app. Then, it goes on to download the new version of the main app to the phone, and install it.
Here are some codes of the downloading process that I'm stuck in:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
StringBuilder builder = new StringBuilder();
HttpClient client = new DefaultHttpClient();
HttpGet httpGet = new HttpGet(
"http://dl.dropboxusercontent.com/u/98196898/data.json");
try{
HttpResponse response = client.execute(httpGet);
StatusLine statusLine = response.getStatusLine();
int statusCode = statusLine.getStatusCode();
if(statusCode == 200) {
HttpEntity entity = response.getEntity();
InputStream content = entity.getContent();
BufferedReader reader = new BufferedReader(new
InputStreamReader (content));
String line;
while((line = reader.readLine()) != null) {
builder.append(line);
}
}
}catch (Exception e)
{
e.printStackTrace();
}
TextView tv = (TextView)findViewById(R.id.showresponse);
tv.setText(builder.toString());
try{
String answer = "";
JSONArray jsonArray = new JSONArray(builder.toString());
for(int i = 0; i < jsonArray.length(); i++) {
JSONObject jsonObject = jsonArray.getJSONObject(i);
answer += jsonObject.getString("VersionNumber");
}
tv.setText(answer);
Which, doesn't work. I do not know why. My .json is made with a notepad with the following:
{
"VersionNumber": "2"
"VersionCode": "2.0"
}
And my plan is to compare the version number with the old one--> obviously if the one online has a bigger number than it needs to be updated.
And, of course, it doesn't work. I've also tried to use defaulthttpclient and httpget and stuff but it doesn't work. Maybe dropbox has this problem?
Next, I realized that I am wasting my time so I moved on to installing the apk ASSUMING THAT one day I will figure out how to download things from the net. I tried, and it doesn't work either. Here are the codes and problems:
String fileName = Environment.getExternalStorageDirectory()
+ "/Android/CheckWebForUpdate.apk";
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(Uri.fromFile(new File(fileName)), "application/vnd.android.package-archive");
startActivity(intent);
I copy most of them here online, but it doesn't work. It prompted: "There is a problem parsing the package". I saw two ways of solving this but neither worked. I looked back it up and my codes should work. Someone mentioned that I should not have the same name, so I tried another program's name, and of course, it doesn't work. Then, I looked up again and this time I figured out that I "might" need permission android.permission.INSTALL_PACKAGES but then I figured out that I need to root my phone (and because the app is not just for me... I need to root LOTS of phones, which just does not make sense)-- It is only for system apps.
I am stuck here in two ways. Thank you for reading. Please reply if you know how to solve these problems.
I keep getting the error above (title) when I try to make a HTTP-request to a server with a special character (the character 'å'). I have tried to call:
_login = URLEncoder.encode(_login, "utf-8");
But I still get exception. If I try to change the URL it works fine. Seems that it happends for whatever URL I try if it has special characters. Like for example http://www.ål.no.
Anyone know about a work-around? One way could of course be to use the IP-address. But I would rather avoid that.
Thanks for any help!
Some of the source code:
private String _login = "http://www.ål.no";
HttpClient httpclient = new DefaultHttpClient();
try {
_login = URLEncoder.encode(_login, "utf-8");
} catch (UnsupportedEncodingException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
HttpPost httppost = new HttpPost(_login);
List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>();
//nameValuePairs.add(new BasicNameValuePair("Mail", this.Email));
//nameValuePairs.add(new BasicNameValuePair("Password", this.Password));
try
{
httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
BasicHttpResponse response = null;
try
{
response = (BasicHttpResponse) httpclient.execute(httppost);
}
catch (ClientProtocolException e)
{
System.out.println("BasicHttpResponse");
e.printStackTrace();
}
}
EDIT: Found a work around. Used Firebug to dig a little deeper. According to Firebug the server has another name when communicating (as far as I can see). This name does not contain any special characters and I successfully managed to communicate with the server using my application. Thanks for all help! :)
I think I understand what you're asking for. Here is a link to a list of special characters that the URL will identify.
http://www.degraeve.com/reference/urlencoding.php
If thats not what you need let me know.
to save you time, the character you're searching for is %E5
Okay, so I was trying to send Http Post Requests to this one site, and I sniffed the sent request with wireshark thus getting the text data from the post request of this site. I used this in a stock Java application, and it worked perfectly fine. I could use the post method regularly with no problem whatsoever, and it would return the appropriate website. Then I tried doing this with Android. Instead of returning the actual html data after executing the post request, it returns the regular page html data untouched. It DOES send a post request (sniff with wireshark again), it just doesn't seem to get the appropriate response. I took the exact same method used from another one of my projects, which worked perfectly fine in that project, and pasted it into my new project. I added the INTERNET user permission in Android, so there's nothing wrong with that. The only visible difference is that I used NameValuePairs in the other one (the one that worked) and in this one I'm directly putting the string into a StringEntity without encoding (using UTF-8 encoding screws up the String though). I used this exact same line of text in regular Java like I said, and it worked fine with no encoding. So what could be the problem? This is the code:
public static String sendNamePostRequest(String urlString) {
HttpClient client = new DefaultHttpClient();
HttpPost post = new HttpPost(urlString);
StringBuffer sb = new StringBuffer();
try {
post.setEntity(new StringEntity(
"__EVENTTARGET=&__EVENTARGUMENT=&__VIEWSTATE=%2FwEPDwULLTE3NDM5MzMwMzRkZA%3D%3D&__EVENTVALIDATION=%2FwEWBAL%2B%2B4CfBgK52%2BLYCQK1gpH7BAL0w%2FPHAQ%3D%3D&_nameTextBox=John&_zoekButton=Zoek&numberOfLettersField=3"));
HttpResponse response = client.execute(post);
HttpEntity entity = response.getEntity();
BufferedReader br = new BufferedReader(new InputStreamReader(
entity.getContent()));
String in = "";
while ((in = br.readLine()) != null) {
sb.append(in + "\n");
}
br.close();
} catch (Exception e) {
e.printStackTrace();
}
return sb.toString();
}
Can you see what's wrong here?
I am using the Jackson JSON parser as I heard it was a lot more efficient than the default Android parser. I learned how to use it off this tutorial here
http://www.mkyong.com/java/jackson-streaming-api-to-read-and-write-json/
which is great tutorial if anyone wants to learn how to use Jackson json parser.
However, I am having an issue in that I can parse data fine in Java from a URL, however when I use Jackson with Android, I get null values or the screen just shows up black for some reason.
In order to retrieve the data from the website I am using this code from here
http://www.javacodegeeks.com/2011/01/android-json-parsing-gson-tutorial.html
private InputStream retrieveStream(String url) {
DefaultHttpClient client = new DefaultHttpClient();
HttpGet getRequest = new HttpGet(url);
try {
HttpResponse getResponse = client.execute(getRequest);
final int statusCode = getResponse.getStatusLine().getStatusCode();
if (statusCode != HttpStatus.SC_OK) {
Log.w(getClass().getSimpleName(),
"Error " + statusCode + " for URL " + url);
return null;
}
HttpEntity getResponseEntity = getResponse.getEntity();
return getResponseEntity.getContent();
}
catch (IOException e) {
getRequest.abort();
Log.w(getClass().getSimpleName(), "Error for URL " + url, e);
}
return null;
}
Then in my parse data method
InputStream source = retrieveStream(url);
try {
JsonFactory jfactory = new JsonFactory();
JsonParser jParser = jfactory.createJsonParser(source);
Then I parse data as was shown in the tutorial I linked above
while (jParser.nextToken() != JsonToken.END_OBJECT) {
String fieldname = jParser.getCurrentName();
if ("Name".equals(fieldname)) {
jParser.nextToken();
this.setName(jParser.getText());
}
if ("Number".equals(fieldname)) {
jParser.nextToken();
this.setNumber(jParser.getText());
}
}
The url I am using is a dummy site set up which just has a JSON file on it which I am using to practice Jackson JSON parsing.
Now I know my parse data code is fine, as I in normal Java class, I can parse the data from the website using the code I created, and it works fine.
However if I try to use the code in Android with the code I have just shown, I just get a black screen for some odd reason. I have internet permissions enabled in manifest
Is there something wrong with the http code I have used? If so could someone show me how it should be done? And also why I am getting a black screen, I don't understand why it would show that.
Thanks in advance
Not sure if this is the problem, but your looping construct is unsafe: depending on kind of data you get, it is quite possible that you do not get END_OBJECT as the next token. And at the end of content, nextToken() will return null to indicate end-of-input. So perhaps you get into infinite loop with certain input?
I found the issue, the link was local host which could not be accessed from Emulator. Settings were changed, and can now access link, works perfectly now :D
I am making an app for Android. I like to make the rest calls as quick as possible. When I get my results as XML it takes 5 seconds (!) to get a simple xml like this:
<souvenirs>
<souvenir>
<id>1</id>
<name>Example 1</name>
<rating>3.4</rating>
<photourl>/images/example.jpg</photourl>
<price>3.50</price>
</souvenir>
<souvenir>
<id>2</id>
<name>Example 2</name>
<rating>2.4</rating>
<photourl>/images/example.jpg</photourl>
<price>8.50</price>
</souvenir>
</souvenirs>
So I tried it with JSON. But that takes also about 5 seconds to retrieve.
I load the XML in android with the following code:
URL url = new URL("http://example.nu?method=getAllSouvenirs");
URLConnection conn = url.openConnection();
long t=System.currentTimeMillis();
InputStream ins = conn.getInputStream();
Log.d("info", String.valueOf((System.currentTimeMillis()-t)));
The log says it takes about 5000 ms to get the inputstream.. Is there any way to speed this up? does anybody knows which technique the Android Market uses? This loads way faster than my app..
Thanks in advance! :)
When you try to get the data "manually" - via browser or via other means (wget, curl) how long does it take there.
On Android you also should take the mobile network into consideration that is usually significantly slower than for a desktop computer. Also latencies are bigger.
To me this sounds a lot like issues in the backend (e.g. trying to resolve the IP of the client and thus taking lots of time).
use Apache HttpClient instead of URLConnection:
Apache http client or URLConnection
EDIT(2012-02-07): no longer true on newer android platform please read: http://android-developers.blogspot.com/2011/09/androids-http-clients.html
Maybe that is how it is implemented and you can't do nothing. That is my guess.
My opinion is to do all connection based stuff on your own thread (to put in in background) and in foreground (main UI thread) entertain user. :)
I have played a little bit around this and it works fast enough for me... Here is my code:
private static HttpResponse doPost(String url, JSONStringer json) {
try {
HttpPost request = new HttpPost(url);
StringEntity entity;
entity = new StringEntity(json.toString());
entity.setContentType("application/json;charset=UTF-8");
entity.setContentEncoding(new BasicHeader(HTTP.CONTENT_TYPE, "application/json;charset=UTF-8"));
request.setEntity(entity);
try {
DefaultHttpClient httpClient = new DefaultHttpClient();
HttpResponse response = httpClient.execute(request);
return response;
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
return null;
}
And somewhere else I call that method like:
HttpResponse httpResponse = doPost(url, json);
BufferedReader reader = new BufferedReader(new InputStreamReader(httpResponse.getEntity().getContent(), "UTF-8"));
It works fine for me...