I have 2 phones:
lg g3 that i bought from China
and lg g3 that i bought from Israel
i build an android app that gets a response from web according to a keysearch(key search can be in any language:russian,hebrew, arabic, english etc.)
In english, both phones work great.
But when i use non-english langauge(all above, didn't try chinese) the Israel phone still works great but the China phone not.
When i debug the program in the China phone i saw that the keysearch (in non english langaage) when i get the reponse is in question marks. but in the Isreal phone it's works great, so i tried all kinds of encoding, but nothing seems to work.
here's the piece of the code that have the problem:
HttpURLConnection connection = null;
try {
//Create connection
URL url = new URL("https://www.example.com/results?search_query="+keyword);
connection = (HttpURLConnection)url.openConnection();
connection.setRequestProperty("User-Agent", "Mozilla/5.0");
connection.setRequestProperty("Accept-Charset", "UTF-8");
connection.setRequestProperty("content-type", "application/x-www-form-urlencoded; charset=utf-8");
BufferedReader in = new BufferedReader(
new InputStreamReader(connection.getInputStream(),"UTF-8"));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
response.append(inputLine);
response.append('\r');
}
m_htmlDoc = response.toString();
} catch (Exception e) {
e.printStackTrace();
m_htmlDoc = null;
} finally {
if(connection != null) {
connection.disconnect();
}
}
the question is: do i need to change something in the code so the China phone will accept other langauges (not just english)? if so, it would be great if someone can direct me to the answer. if not, so maybe i need to change settings on the phone? both phones has the same OS langauge (hebrew)
Thank you all.
so the utf-8 was correct and i didn't need tochange any local langauge on the phone all i needed is to encode the keysearch (URLEncoder.encode(keyword, "UTF-8")).
this is the complete answer:
HttpURLConnection connection = null;
try {
//Create connection
URL url = new URL("https://www.example.com/results?search_query=" + URLEncoder.encode(keyword, "UTF-8"));
connection = (HttpURLConnection)url.openConnection();
connection.setRequestProperty("User-Agent", "Mozilla/5.0");
connection.setRequestProperty("Accept-Charset", "UTF-8");
connection.setRequestProperty("content-type", "application/x-www-form-urlencoded; charset=utf-8");
BufferedReader in = new BufferedReader(
new InputStreamReader(connection.getInputStream(),"UTF-8"));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
response.append(inputLine);
response.append('\r');
}
m_htmlDoc = response.toString();
} catch (Exception e) {
e.printStackTrace();
m_htmlDoc = null;
} finally {
if(connection != null) {
connection.disconnect();
}
}
Thank you all for the help.
Related
I'm having trouble to connect to a webservice through HttpURLConnection when using 3g (any mobile network). I don't know exactly the problem because when it's on the wifi, it works perfectly. When I check for the errorStream, it says that the buffer length is unknown. Why does it happen only through 3g?
My code is:
if (method_type == 0) {
param = url[0].concat("?identificacao=" + postDataParam.get("identificacao") + "&senha=" + postDataParam.get("senha"));
System.out.println(param);
try{
URL link = new URL(param);
HttpURLConnection e = (HttpURLConnection)link.openConnection();
e.setReadTimeout(15000);
e.setConnectTimeout(15000);
e.setRequestMethod("GET");
e.setRequestProperty("User-Agent", "");
e.setRequestProperty("Authorization", "Basic " + base64CredenciaisCodificadas);
BufferedReader in = new BufferedReader(
new InputStreamReader(e.getInputStream()));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
response.append(inputLine);
}
in.close();
resposta = response.toString();
globalResposta = resposta;
senhaCorreta = Boolean.parseBoolean(separarDados(globalResposta, 0).replace("\"", ""));
} catch(Exception e){
}
}
Before you all ask, I tried changing the User-Agent to Mozilla, AppleWebKit and this stuff. I have also set the permission to access the internet at the manifest.
I have been running into a very strange problem. I am trying to implement log in service in my app. When I pass right email and password service returns response as expected(means no error comes) but when I delibrately pass wrong email or password geInputStream() method throws FileNotFoundException. I don't know what is the reason behind this.Further more, before calling getInputStream() method i checked status code as well(this is the case when I am passing wrong email and password intentionally).The status code was 500. I checked for 500 and that was internal server error. My question is why is that so? I mean when intentionally passing wrong email or password why internal server occurred? One more thing I would like to mention that I have checked the same service on post man it is working fine as expected. If i pass wrong email or password postman returns the expected error. Below is the code I am using
private String invokeWebservice() {
String data = null;
HttpURLConnection conn = null;
BufferedReader in = null;
try {
String webservice = Constants.BASE_URL + serviceName;
LogUtility.debugLog("webservice just called "+ webservice);
URL url = new URL(webservice);
conn = (HttpURLConnection) url.openConnection();
conn.setReadTimeout(10000);
conn.setConnectTimeout(15000);
conn.setUseCaches(false);
if (isPost) {
conn.setDoOutput(true);
conn.setRequestMethod("POST");
conn.setRequestProperty("Content-Type", "application/json");
conn.setRequestProperty("Accept", "application/json");
Writer writer = new BufferedWriter(new OutputStreamWriter(conn.getOutputStream(), "UTF-8"));
if (jsonObject != null)
writer.write(jsonObject.toString());
writer.close();
}
in = new BufferedReader(new InputStreamReader(conn.getInputStream()));
StringBuffer sb = new StringBuffer("");
String l = "";
String nl = System.getProperty("line.separator");
while ((l = in.readLine()) != null)
sb.append(l + nl);
in.close();
data = sb.toString();
return data;
} catch (Exception e) {
LogUtility.errorLog("exception while calling web service");
} finally {
try {
if (conn != null)
conn.disconnect();
if (in != null)
in.close();
} catch (Exception ex) {
// LogUtility.errorLogWithException(ex, ex.getMessage());
}
}
return data;
}
Any help?
After spending some time now I was able to solve my problem.Posting my answer for others. Passing wrong email and password to the service was right and server was consuming those parameters as well and because there was an error(because email and password) that is why it was returning 500 code. So, I checked for status code if it was 200 then I used getInputStream() method and else i called getErrorStream() method. By this way i got the stream that has property for error(this property contains error detail). Below is the code i used
if (conn.getResponseCode() != HttpURLConnection.HTTP_OK) {
in = new BufferedReader(new InputStreamReader(conn.getErrorStream()));
} else {
in = new BufferedReader(new InputStreamReader(conn.getInputStream()));
}
Hope it helps other as well.
I have a trouble with my HttpsConnection on android.
First of all, no it is not a duplicate. I try almost all the solutions on SO, like changing the keep-alive option or the timeout ( and some of them indeed optimized a part of my code a little bit ) but it is still 5 to 10 times ( probably more ) slower on android than on iOS.
Sending a request to my server takes several seconds on android while it's almost instant on iOS and from a browser. I am sure that the server is not in cause. But it seems that getting the inputstream is terribly slow!
This line:
in=conn.getInputStream();
is the most delaying one, taking several seconds by itself.
My aim is to get a JSON from my server. My code is supposed to be technically as optimized as possible ( and it can probably help some people with HttpsConnection on the same time ):
protected String getContentUrl(String apiURL)
{
StringBuilder builder = new StringBuilder();
String line=null;
String result="";
HttpsURLConnection conn= null;
InputStream in= null;
try {
URL url;
// get URL content
url = new URL(apiURL);
System.setProperty("http.keepAlive", "false");
trustAllHosts();
conn = (HttpsURLConnection) url.openConnection();
conn.setHostnameVerifier(DO_NOT_VERIFY);
conn.setRequestMethod("GET");
conn.setRequestProperty(MainActivity.API_TOKEN, MainActivity.ENCRYPTED_TOKEN);
conn.setRequestProperty("Connection", "close");
conn.setConnectTimeout(1000);
in=conn.getInputStream();
// open the stream and put it into BufferedReader
BufferedReader br = new BufferedReader(new InputStreamReader(in));
while ((line=br.readLine())!= null) {
builder.append(line);
}
result=builder.toString();
//System.out.print(result);
br.close();
} catch (MalformedURLException e) {
result=null;
} catch (IOException e) {
result=null;
} catch (Exception e) {
result=null;
}
finally {
try {
in.close();
}catch(Exception e){}
try {
conn.disconnect();
}catch(Exception e){}
return result;
}
}
However, it keeps taking several seconds.
So I would like to know: is there a way to improve the speed of this API call? The problem is not the server or the JSON parsing but for sure the function above. Thanks a lot.
Today I'm making my first attempt of sending a POST request with a JSON to save some data, and I'm not being able to do so.
My app works by signing in, and then save, modify and delete data. It's already done in iOS, but since I'm new to Android, I'm not sure how to do it.
Here's my POST function:
public String POST(String targetURL, String urlParameters, String user, String pwd) {
URL url;
String u = targetURL;
HttpURLConnection connection = null;
try {
// Create connection
// u=URLEncoder.encode(u, "UTF-8");
url = new URL(u);
connection = (HttpURLConnection) url.openConnection();
// cambiarlo luego al usuario q esta logeado
String login = user + ":" + pwd;
String encoding = new String(org.apache.commons.codec.binary.Base64.encodeBase64(org.apache.commons.codec.binary.StringUtils.getBytesUtf8(login)));
connection.setRequestMethod("POST");
connection.setRequestProperty("Authorization", "Basic " + encoding);
connection.setRequestProperty("Content-Type", "plain/text");// hace q sirva con el string de json
connection.setRequestProperty("Content-Length", "" + Integer.toString(urlParameters.getBytes().length));
connection.setRequestProperty("Content-Language", "en-US");
connection.setUseCaches(false);
connection.setDoInput(true);
connection.setDoOutput(true);
connection.setReadTimeout(120000);
// Send request
DataOutputStream wr = new DataOutputStream(connection.getOutputStream());
wr.writeBytes(urlParameters);
wr.flush();
wr.close();
// Get Response
InputStream is = connection.getInputStream();
BufferedReader rd = new BufferedReader(new InputStreamReader(is));
String line;
StringBuffer response = new StringBuffer();
this.setResponseCode(connection.getResponseCode());
while ((line = rd.readLine()) != null) {
response.append(line);
response.append('\r');
}
rd.close();
return response.toString();
} catch (Exception e) {
e.printStackTrace();
return null;
} finally {
if (connection != null) {
connection.disconnect();
}
}
}
The method above is executed with Asynctask, and even if I use it to Login using Spring security, it works, and even I can save for internal usage the username, password, and secret token.
I dunno if I need to put the token in a header or something, because I already did that, with no positive results.
I'm supposing that the only permission I need to execute this is the internet one, so in my manifest file I specified that permission.
I'm going crazy with this issue, please help!
Thanks in advance.
EDIT:
Sorry guys, I'm kinda new to this way of asking, and also, not an English native speaker :P
The output I receive after sending the request, is the HTML of the page that handles logging in into the web app... I need like a json response or something like that to make sure the request was saved correctly
Try handling your cookies
CookieManager cookieManager = new CookieManager();
CookieHandler.setDefault(cookieManager);
This should be a singleton.
I am testing a https post on android , I have 2 android devices, this code perfectly worked on my 2.3 device but will be blocked in my 4.1 device at "retcode=urlCon.getResponseCode();", also I have checked the packet in sniffer the post request has been sent and the server did reply the https response,but it still be blocked until timeout.
private String GetHttpPage(HttpsURLConnection urlsCon,String host,String url,String reference,boolean type,String curcookie,String postparam){
String query = postparam;
byte[] entitydata = query.getBytes();
String line="";
HttpURLConnection urlCon=urlsCon;
try{
String domain="";
String fullurl=host+url;
if(urlCon==null){
if(host.indexOf("https")!=-1){
urlCon =GetHttpsConnect(fullurl);
domain=host.substring(8);
}
else{
urlCon =GetHttpConnect(fullurl);
domain=host.substring(7);
}
}
urlCon.setConnectTimeout(30000);
urlCon.setReadTimeout(30000);
if(reference!=null)
urlCon.setRequestProperty("Referer", reference);
urlCon.setRequestProperty("Cache-Control", "no-cache");
urlCon.setRequestProperty("User-Agent", "Mozilla/4.0 (compatible; MSIE 5.5; Windows 98)");
urlCon.setRequestProperty("Accept-Encoding", "identity");
urlCon.setRequestProperty("Accept", "image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, */*");
urlCon.setRequestProperty("Accept-Language", "zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3");
urlCon.setRequestProperty("connection", "Keep-Alive");
urlCon.setRequestProperty("Host", domain);
//
if(curcookie.length()>0)
urlCon.setRequestProperty("Cookie", curcookie);
if(type){
urlCon.setDoOutput(true);
urlCon.setDoInput(true);
urlCon.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
urlCon.setRequestProperty("Content-Length",String.valueOf(entitydata.length));
urlCon.setRequestMethod("POST");
}
else{
urlCon.setDoOutput(false);
urlCon.setDoInput(true);
urlCon.setRequestMethod("GET");
}
urlCon.connect();
if(type){
OutputStream outStream = urlCon.getOutputStream();
outStream.write(entitydata, 0, entitydata.length);
// outStream.write(entitydata);
outStream.flush();
outStream.close();
}
retcode=urlCon.getResponseCode();
if(urlCon.getHeaderField("Location")!=null)
redirect=urlCon.getHeaderField("Location");
Map m=urlCon.getHeaderFields();
Set set=m.entrySet();
Iterator it=set.iterator();
while(it.hasNext())
{
Map.Entry me=(Map.Entry)it.next();
String skey=me.getKey()!=null?me.getKey().toString():"";
String svalue=me.getValue()!=null?me.getValue().toString():"";
if(skey.compareToIgnoreCase("Set-Cookie")==0){
String tempcookie=svalue;
tempcookie=tempcookie.substring(1, tempcookie.length()-1);
cookie+=ProcessCookie(tempcookie);
//cookie=cookie.substring(0, cookie.length()-2);
}
}
// if(urlCon.getHeaderField("Set-Cookie")!=null)
// cookie=urlCon.getHeaderField("Set-Cookie");
BufferedReader in = new BufferedReader(new InputStreamReader(urlCon.getInputStream()));
String subline="";
while ((subline = in.readLine()) != null) {
line+=subline;
}
in.close();
}
catch(IOException e){
String aaa=e.toString();
Log.e("xx", aaa);
}
catch(Exception e){
String aaa=e.toString();
Log.e("xx", aaa);
}
if(urlCon!=null)
urlCon.disconnect();
return line;
}
I suppose you have the Internet permission inside the manifest?I think that the problem is in the "User-Agent" inside one of the setRequestProperty or maybe in another one, but not in the rest of the code.
Try putting
System.setProperty("http.keepAlive", "false");
somewhere in your code.