im currently trying to implement the Steam Web API using the given code in the following repository -> https://github.com/Overv/SteamWebAPI/blob/master/SteamAPISession.cs into my Android app and im getting different exceptions dependend on using the given wep api ip ( 63.228.223.110 ) or the adress ( https://api.steampowered.com/ ) itself.
my code actually looks like this in the given method when building up a connection to the web api:
private String steamRequest( String get, String post ) {
final int MAX_RETRIES = 3;
int numberOfTries = 0;
HttpsURLConnection request = null;
while(numberOfTries < MAX_RETRIES) {
if (numberOfTries != 0) {
Log.d(TAG, "Retry -> " + numberOfTries);
}
try {
request = (HttpsURLConnection) new URL("https://api.steampowered.com/" + get).openConnection(); //or 63.228.223.110/ ???
SSLSocketFactory socketFactory = (SSLSocketFactory) SSLSocketFactory.getDefault();
String host = "api.steampowered.com";
int port = 443;
int header = 0;
socketFactory.createSocket(new Socket(host, port), host, port, false);
request.setHostnameVerifier(new HostnameVerifier() {
#Override
public boolean verify(String s, SSLSession sslSession) {
return true;
}
});
request.setSSLSocketFactory(socketFactory);
request.setDoOutput(false);
// request.setRequestProperty("Host", "api.steampowered.com:443");
// request.setRequestProperty("Protocol-Version", "httpVersion");
request.setRequestProperty("Accept", "*/*");
request.setRequestProperty("Accept-Encoding", "gzip, deflate");
request.setRequestProperty("Accept-Language", "en-us");
request.setRequestProperty("User-Agent", "Steam 1291812 / iPhone");
request.setRequestProperty("Connection", "close");
if (post != null) {
byte[] postBytes;
try {
request.setRequestMethod("POST");
postBytes = post.getBytes("US-ASCII");
// request.setRequestProperty("Content-Length", Integer.toString(postBytes.length));
request.setFixedLengthStreamingMode(postBytes.length);
request.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
PrintWriter out = new PrintWriter(request.getOutputStream());
out.print(post);
out.close();
// DataOutputStream requestStream = new DataOutputStream(request.getOutputStream());
//// OutputStreamWriter stream = new OutputStreamWriter(request.getOutputStream());
//// stream.write(postBytes, 0, postBytes.length);
// requestStream.write(postBytes, 0, postBytes.length);
// requestStream.close();
message++;
} catch (ProtocolException e) {
e.printStackTrace();
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
try {
int statusCode = request.getResponseCode();
InputStream is;
Log.d(TAG, "The response code of the status code is" + statusCode);
if (statusCode != 200) {
is = request.getErrorStream();
Log.d(TAG, String.valueOf(is));
}
// String src = null;
// OutputStreamWriter out = new OutputStreamWriter(request.getOutputStream());
// out.write(src);
// out.close();
Scanner inStream = new Scanner(request.getInputStream());
String response = "";
while (inStream.hasNextLine()) {
response += (inStream.nextLine());
}
// String src;
// BufferedReader in = new BufferedReader(new InputStreamReader(request.getInputStream()));
// StringBuilder builder = new StringBuilder();
// while ((src = in.readLine()) != null) {
// builder.append(src);
// }
// String jsonData = builder.toString();
Log.d(TAG, response); //jsonData
// in.close();
return response; //jsonData
} catch (MalformedURLException ex) {
Toast.makeText(getActivity(), ex.toString(), Toast.LENGTH_LONG).show();
ex.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (request != null) {
request.disconnect();
}
}
numberOfTries++;
}
Log.d(TAG, "Max retries reached. Giving up on connecting to Steam Web API...");
return null;
}
following exception occurs when using https://api.steampowered.com/ as url:
W/System.err﹕ java.io.FileNotFoundException: https://api.steampowered.com/ISteamOAuth2/GetTokenWithCredentials/v0001
D/OptionsFragment﹕ Failed to log in!
i've really tried and researched on those issues, but i just can't get a solution. If someone got a good hint on helping to solve these exceptions please let me know!
EDIT:
I've researched some more!
Looking up on https://partner.steamgames.com/documentation/webapi#creating the direct ip adress shouldn't be used and therefore only the DNS name itself (for further clarification look on the given link). Hence, looking up on the API interface list itself -> http://api.steampowered.com/ISteamWebAPIUtil/GetSupportedAPIList/v0001/?format=json there doesn't seem to be a given Interface with a method called ISteamOAuth2/GetTokenWithCredentials.(Or not anymore!) Only ISteamUserAuth and ISteamUserOAuth which seem to handle Authentication stuff.
I will update this post again if i should get a working connection and handling with the steam web api.
Cheers!
Related
I'm using Asynctask to pass the parameters of API. The Asynctask executing but the String Response in Asynctask PostExecute giving me a null for a device with SDK 23 and below. But when the device is equal or higher to SDK24(Nougat), it works perfectly and the data are being sent to the API however when the SDK is 23 and lower data are not being sent to API. Does anyone encounter this problem? Please enlighten me what I miss in my code or I do wrong code. Massive thank you.
private class sendToServerOfficial extends AsyncTask<String,Void,String> {
int statusCodeone;
String convert_txt_et_username = et_username.getText().toString();
String convert_txt_content = et_content.getText().toString();
#Override
protected String doInBackground(String... strings) {
try {
urlURL = new URL("http://www.testingsite.com/api/sendServer?/ip="+getIPAddress+"&phone_num="+getMobilePhoneNumber+"&user_text="+convert_txt_et_username+"&content_text="+convert_txt_content);
HttpURLConnection httpURLConnection = (HttpURLConnection) urlURL.openConnection();
httpURLConnection.setRequestMethod("POST");
httpURLConnection.setRequestProperty("Content-Type","UTF-8");
httpURLConnection.connect();
statusCodeone = httpURLConnection.getResponseCode();
if (statusCodeone == 200) {
InputStream it = new BufferedInputStream(httpURLConnection.getInputStream());
InputStreamReader read = new InputStreamReader(it);
BufferedReader buff = new BufferedReader(read);
StringBuilder dta = new StringBuilder();
String chunks;
while ((chunks = buff.readLine()) != null) {
dta.append(chunks);
}
buff.close();
read.close();
return dta.toString();
}
}
catch (ProtocolException e) { e.printStackTrace(); }
catch (MalformedURLException e) { e.printStackTrace(); }
catch (IOException e) { e.printStackTrace(); }
return null;
}
#Override
protected void onPostExecute(String response) {
Toast.makeText(MainActivity.this, response + "Form is submitted already" + urlURL, Toast.LENGTH_LONG).show();
txt_inputURL.setEnabled(true);
btnClick.setClickable(true);
txt_inputURL.getText().clear();
}
}
The docs say AsyncTask is designed to handle short operations(few seconds maximum) and states that Java classes like FutureTask are better for operations that last long. So I tried to send my location updates to the server using FutureTask but I am getting NetworkOnMainThreadException. I don't want to use AsyncTask because I wanted to keep the http connection open until the updates are cancelled. Here is my code:
SendLocation updates = new SendLocation(idt, String.valueOf(location.getLatitude()), String.valueOf(location.getLongitude()));
FutureTask ft = new FutureTask<String>(updates);
boolean b = ft.cancel(false);
ft.run();
class SendLocation implements Callable<String> {
String t, la, lo;
public SendLocation(String a, String b, String c){
this.t = a;
this.la = b;
this.lo = c;
}
public String call() {
sendUpdates(token, la, lo);
return "Task Done";
}
public void sendUpdates(String a, String b, String c){
HttpURLConnection urlConn = null;
try {
try {
URL url;
//HttpURLConnection urlConn;
url = new URL(remote + "driver.php");
urlConn = (HttpURLConnection) url.openConnection();
System.setProperty("http.keepAlive", "true");
//urlConn.setDoInput(true); //this is for get request
urlConn.setDoOutput(true);
urlConn.setUseCaches(false);
urlConn.setRequestProperty("Content-Type", "application/json");
urlConn.setRequestProperty("Accept", "application/json");
urlConn.setRequestMethod("POST");
urlConn.connect();
try {
//Create JSONObject here
JSONObject json = new JSONObject();
json.put("drt", a);
json.put("drlat", b);
json.put("drlon", c);
String postData = json.toString();
// Send POST output.
OutputStreamWriter os = new OutputStreamWriter(urlConn.getOutputStream(), "UTF-8");
os.write(postData);
Log.i("NOTIFICATION", "Data Sent");
os.flush();
os.close();
BufferedReader reader = new BufferedReader(new InputStreamReader(urlConn.getInputStream()));
String msg = "";
String line = "";
while ((line = reader.readLine()) != null) {
msg += line;
}
Log.i("msg=", "" + msg);
} catch (JSONException jsonex) {
jsonex.printStackTrace();
Log.e("jsnExce", jsonex.toString());
}
} catch (MalformedURLException muex) {
// TODO Auto-generated catch block
muex.printStackTrace();
} catch (IOException ioex) {
ioex.printStackTrace();
try { //if there is IOException clean the connection and clear it for reuse(works if the stream is not too long)
int respCode = urlConn.getResponseCode();
InputStream es = urlConn.getErrorStream();
byte[] buffer = null;
int ret = 0;
// read the response body
while ((ret = es.read(buffer)) > 0) {
Log.e("streamingError", String.valueOf(respCode) + String.valueOf(ret));
}
// close the errorstream
es.close();
} catch(IOException ex) {
// deal with the exception
ex.printStackTrace();
}
}
} catch (Exception e) {
e.printStackTrace();
Log.e("ERROR", "There is error in this code " + String.valueOf(e));
}
}
}
Doesn't it get executed in a worker thread? If the answer is no why does the docs say that it is an alternative to AsyncTask?
Your code must not be in the void run() method. This is where the asynchronous code is ran.
I am writing android code to change the field in a Nest thermostat using the newly released API. Authentication and getting the field values is working just perfect, however I am haing problem with changing the field values. Based on the the API for changing the field values you need to use HTTP put, but once I am doing this, nothing happens in the device (the value (e.g. the value of target_temperature_f doesn't change!))
Here is my android code:
String url = "https://developer-api.nest.com/devices/thermostats/"
+ this.device_id + "?auth=" + this.access_token;
try{
HttpClient httpclient = new DefaultHttpClient();
/** set the proxy , not always needed */
HttpHost proxy = new HttpHost(proxy_ip,proxy_port);
httpclient.getParams().setParameter(ConnRoutePNames.DEFAULT_PROXY,proxy);
// Set the new value
HttpPut httpPut = new HttpPut(url);
httpPut.setHeader("Content-Type", "application/json");
JSONObject jsonObj = new JSONObject("{\"target_temperature_f\":'60'}");
HttpEntity put_entity = new StringEntity(jsonObj.toString());
httpPut.setEntity(put_entity);
HttpResponse put_response = httpclient.execute(httpPut);
I can set the field in the device via "curl" command in linux though!! So the device is working fine.
Any help is highly appreciated!
I'm unsure of how to do it using the DefaultHttpClient and according to the documentation it has been deprecated in favor of HttpURLConnection.
Here's some code that uses HttpURLConnection that I've tested with Hue lights.
This will open a URL connection and perform a POST query with the given body. The readFromHttpConnection method expects a JSON response. It looks like Nest uses JSON so this may work for your needs.
private String synchronousPostMethod(String destination, String body)
{
Log.i(TAG, "Attempting HTTP POST method. Address=" + destination + "; Body=" + body);
String responseReturn;
try
{
HttpURLConnection httpConnection = openConnection(destination);
httpConnection.setDoOutput(true);
httpConnection.setRequestMethod("POST");
writeToHttpConnection(httpConnection, body);
responseReturn = readFromHttpConnection(httpConnection);
}
catch(Exception e)
{
responseReturn = RESPONSE_FAIL_MESSAGE + "; exception = " + e;
}
Log.i(TAG, "Result of HTTP POST method: " + responseReturn);
return responseReturn;
}
These are the helper methods.
private HttpURLConnection openConnection(String destination)
{
HttpURLConnection httpConnection = null;
try
{
URL connectionUrl = new URL(destination);
httpConnection = (HttpURLConnection) connectionUrl.openConnection();
}
catch(MalformedURLException malformedUrlException)
{
Log.w(TAG, "Failed to generate URL from malformed destination: " + destination);
Log.w(TAG, "MalformedURLException = " + malformedUrlException);
}
catch(IOException ioException)
{
Log.w(TAG, "Could not open HTTP connection. IOException = " + ioException);
}
return httpConnection;
}
private boolean writeToHttpConnection(HttpURLConnection httpConnection, String data)
{
// No data can be written if there is no connection or data
if(httpConnection == null || data == null)
{
return false;
}
try
{
OutputStreamWriter outputStream = new OutputStreamWriter(httpConnection.getOutputStream());
outputStream.write(data);
outputStream.close();
}
catch(IOException ioException)
{
Log.w(TAG, "Failed to get output stream from HttpUrlConnection. IOException = " + ioException);
return false;
}
return true;
}
private String readFromHttpConnection(HttpURLConnection httpConnection)
{
String responseReturn = "";
if(httpConnection != null)
{
try
{
InputStream response = httpConnection.getInputStream();
int size;
do
{
byte[] buffer = new byte[mResponseBufferSize];
size = response.read(buffer, 0, mResponseBufferSize);
// Convert the response to a string then add it to the end of the buffer
responseReturn += new String(buffer, 0, size);
}while(size < mResponseBufferSize || size <= 0);
// Cleanup
response.close();
}
catch (IOException ioException)
{
Log.w(TAG, "Failed to get input stream from HttpUrlConnection. IOException = " + ioException);
}
}
return responseReturn;
}
I have a problem. I met only once. My code algoritm is designed requesting only one time.
But a request was received twice by server. I must produce a solution.
I think, this problem likes this url But I cant find anything(bug or question) about httpurlconnection?
Device's Android Version is 4.0.3 and Connection Method is GET.
try {
String encoding = session.getPlatform().getEncodingIse();
if (TradeUtil.isApachiClientActive()) {
HttpResponse hr = XHttpClientFactory.getConnectionResponse(session.getPlatform(), TradeServiceType.ISE, command);
if (!session.getPlatform().isUseStaticEncodingForIse()) {
encoding = XHttpClientFactory.getEncoding(hr, encoding);
}
strRtn = TradeUtil.getResponse(hr.getEntity().getContent(), encoding);
} else {
con = TradeUtil.createConnection(session.getPlatform(), TradeServiceType.ISE, command);
if (!session.getPlatform().isUseStaticEncodingForIse()) {
encoding = TradeUtil.getEncoding(con, session.getPlatform().getEncodingIse());
}
strRtn = TradeUtil.getResponse(con.getInputStream(), encoding);
}
} catch (Exception e) {
TradeUtil.toConsole(e);
response.getResponseResult().setResponseCode(ResponseResult.CONNECTION_ERROR);
response.getResponseResult().setDescription(e.getMessage());
try {
if (con != null)
con.disconnect();
} catch (Exception ex) {
}
return response;
}
public static HttpURLConnection createConnection(Platform platform,
TradeServiceType serviceType, String command) throws Exception {
command = command + "&MTXTimeAnd=" + Calendar.getInstance().getTimeInMillis(); // Cachlemeyi
// Engellemek
// için
TradeUtil.initSSLContext(); // Zoom ve ustundeki makinalar için SSL
// handshake için trust manager set etmek
// gerekiyor.
System.setProperty("http.keepAlive", "false");// Yatirim finansman +
// Android 2.2 Bug için
// gerekli
System.setProperty("https.keepAlive", "false"); // Yatirim finansman +
// Android 2.2 Bug için
// gerekli
HttpURLConnection con;
String methodType;
String encoding;
String strAdd = null;
if (serviceType.equals(TradeServiceType.ISE)) {
strAdd = platform.getIseServiceAdress();
methodType = platform.getIseConnectionMethodType();
encoding = platform.getEncodingIse();
} else if (serviceType.equals(TradeServiceType.TURKDEX)) {
strAdd = platform.getTurkdexServiceAdress();
methodType = platform.getTurkdexConnectionMethodType();
encoding = platform.getEncodingTurkdex();
} else {
throw new IllegalArgumentException("hatali service tipi");
}
if (methodType.equalsIgnoreCase("GET")) {
strAdd = strAdd + "?" + command;
}
URL adress = new URL(strAdd);
if (adress.getProtocol().equalsIgnoreCase("https")) {
con = (HttpsURLConnection) adress.openConnection();
((HttpsURLConnection) con).setHostnameVerifier(new HostnameVerifier() {
public boolean verify(String hostname, SSLSession session) {
return true;
}
});
} else {
con = (HttpURLConnection) adress.openConnection();
}
con.setUseCaches(false);
con.setReadTimeout(platform.getConnectionTimeout());
con.setConnectTimeout(platform.getConnectionTimeout());
if (methodType.equalsIgnoreCase("POST")) {
con.setDoOutput(true);
con.setDoInput(true);
con.setRequestMethod("POST");
OutputStreamWriter osw = null;
try {
osw = new OutputStreamWriter(con.getOutputStream(), encoding);
osw.write(command);
osw.flush();
osw.close();
osw = null;
} catch (Exception ex) {
TradeUtil.toConsole(ex);
try {
if (osw != null)
osw.close();
} catch (Exception ex2) {
TradeUtil.toConsole(ex);
}
throw ex;
}
} else {
}
return con;
}
I was previously using HttpClient and BasicNameValuePairs, for some reason i have to shift to HttpUrlConnection.
Hence this code, to make a HttpPost request with certain parameters:
public class MConnections {
static String BaseURL = "http://www.xxxxxxxxx.com";
static String charset = "UTF-8";
private static String result;
private static StringBuilder sb;
private static List<String> cookies = new ArrayList<String>();
public static String PostData(String url, String sa[][]) {
HttpURLConnection connection = null;
try {
connection = (HttpURLConnection) new URL(BaseURL + url)
.openConnection();
} catch (MalformedURLException e1) {
} catch (IOException e1) {
}
cookies = connection.getHeaderFields().get("Set-Cookie");
try{
connection.setDoOutput(true); // Triggers POST.
connection.setRequestProperty("Accept-Charset", charset);
connection.setRequestProperty("Content-Type",
"application/x-www-form-urlencoded;charset=" + charset);
}catch (Exception e) {
//Here i get Exception that "java.lang.IllegalStateException: Already connected"
}
OutputStream output = null;
String query = "";
int n = sa.length;
for (int i = 0; i < n; i++) {
try {
query = query + sa[i][0] + "="
+ URLEncoder.encode(sa[i][1], "UTF-8");
} catch (UnsupportedEncodingException e) {
}
}
try {
output = connection.getOutputStream();
output.write(query.getBytes(charset));
} catch (Exception e) {
//Here i get Exception that "android: java.net.protocolException: Does not support output"
} finally {
if (output != null)
try {
output.close();
} catch (IOException e) {
}
}
InputStream response = null;
try {
response = connection.getInputStream();
} catch (IOException e) {
//Here i get Exception that "java.io.IOException: BufferedInputStream is closed"
} finally {
//But i am closing it here
connection.disconnect();
}
try {
BufferedReader reader = new BufferedReader(new InputStreamReader(
response, "iso-8859-1"), 8);
sb = new StringBuilder();
sb.append(reader.readLine());
String line = "0";
while ((line = reader.readLine()) != null) {
sb.append("\n" + line);
}
response.close();
result = sb.toString();
} catch (Exception e) {
}
return result;
}
}
But i get such Exceptions as commented in the code.
Actually i am calling MConnections.PostData() twice from my Activity using a AsyncTask. This might cause the Exception: Already Connected but i am using connection.disconnect. But why am i still getting that Exception?
Am i using it the wrong way?
Thank You
For the protocol exception, try adding the following before you call getOutputStream():
connection.setDoOutput(true);
Discovered this answer thanks to Brian Roach's answer here: https://stackoverflow.com/a/14026377/387781
Side note: I was having this issue on my HTC Thunderbolt running Gingerbread, but not on my Nexus 4 running Jelly Bean.