I have an Android app that sends a http post to a remote server:
protected Void doInBackground(Void... params) {
// Get the message from the intent
Intent intent = getIntent();
String message = intent.getStringExtra(MapsActivity.EXTRA_MESSAGE);
double longitude = intent.getDoubleExtra(MapsActivity.EXTRA_LONGITUDE, 0.0);
double latitude = intent.getDoubleExtra(MapsActivity.EXTRA_LATITUDE, 0.0);
Log.d("doInBackground", message);
Log.d("doInBackground", String.valueOf(longitude));
Log.d("doInBackground", String.valueOf(latitude));
URL url = null;
HttpURLConnection client = null;
try {
// Establish http connection
url = new URL("http://******.com/");
client = (HttpURLConnection) url.openConnection();
client.setDoOutput(true);
client.setDoInput(true);
client.setRequestMethod("POST");
client.connect();
OutputStreamWriter writer = new OutputStreamWriter(client.getOutputStream());
String output;
output = URLEncoder.encode("message", "UTF-8")
+ "=" + URLEncoder.encode(message, "UTF-8");
output += "&" + URLEncoder.encode("longitude", "UTF-8") + "="
+ URLEncoder.encode(String.valueOf(longitude), "UTF-8");
output += "&" + URLEncoder.encode("latitude", "UTF-8") + "="
+ URLEncoder.encode(String.valueOf(latitude), "UTF-8");
Log.d("doInBackground(output)", output);
Log.d("doInBackground(code)", String.valueOf(client.getResponseCode())); // Return 200
writer.write(output);
writer.flush();
writer.close();
} catch (IOException e) {
e.printStackTrace();
} finally {
client.disconnect();
}
return null;
}
In the server, I have:
<?php
$m = urldecode($_POST['message']);
$long = urldecode($_POST['longitude']);
$lat = urldecode($_POST['latitude']);
print " ==== POST DATA =====
Message : $m
Longitude : $long
Latitude : $lat";
?>
client.getResponseCode() returns 200, I think that means my connection was successful? But the website still shows nothing. What might cause the problem?
I got
E/GMPM: getGoogleAppId failed with status: 10
E/GMPM: Uploading is not possible. App measurement disabled
might this be the problem?
What do you mean by the website doesn't show anything? You cannot see the print when you reload the web site because you are not saving it anywhere, you are simply printing out the values on that one single request. To debug you can write the post params to a file instead to see if they are coming through or better yet log the returned object on the android side.
Related
After a complete and utter failure to implement code with Retrofit, I have used Android's HttpURLConnection class to try and send an email through MailGun. However whatever I seem to do I get error 400 bad request back. I do not know what I am doing wrong - similar code seems to be working perfectly within iOS. The 4 lines commented out make no difference. Hardcoding the values for from and to did not fix it either. I have tried using application/json for Content-Type as well. Any pointers in the right direction would be appreciated!
URL u = new URL("https://api.mailgun.net/v3/companyname.com/messages");
HttpURLConnection restConnection = (HttpURLConnection) u.openConnection();
restConnection.setRequestMethod("POST");
String authHeader = "Basic " + Base64.encodeToString(apiKey.getBytes(), Base64.DEFAULT);
restConnection.setRequestProperty("Authorization", authHeader);
restConnection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
restConnection.setRequestProperty("from", "Company Name <noreply#companyname.com>");
restConnection.setRequestProperty("to", "myemailaddress#gmail.com");
restConnection.setRequestProperty("subject", "test");
restConnection.setRequestProperty("text", "test");
//restConnection.setUseCaches(false);
//restConnection.setAllowUserInteraction(false);
//restConnection.setConnectTimeout(10000);
//restConnection.setReadTimeout(10000);
restConnection.connect();
int status = restConnection.getResponseCode();
Try this:
String apiKey = "api:{key}"
String authHeader = "Basic " + Base64.encodeToString(apiKey.getBytes(), Base64.DEFAULT);
try {
String data = URLEncoder.encode("from", "UTF-8") + "=" + URLEncoder.encode("from#from.com", "UTF-8");
data += "&" + URLEncoder.encode("to", "UTF-8") + "=" + URLEncoder.encode("to#to.com", "UTF-8");
data += "&" + URLEncoder.encode("subject", "UTF-8") + "=" + URLEncoder.encode("subject", "UTF-8");
data += "&" + URLEncoder.encode("text", "UTF-8") + "=" + URLEncoder.encode("msg body", "UTF-8");
URL u = new URL("https://api.mailgun.net/{DOMAIN}/messages");
HttpURLConnection restConnection = (HttpURLConnection) u.openConnection();
restConnection.setRequestMethod("POST");
restConnection.setDoOutput(true);
restConnection.setRequestProperty("Authorization", authHeader);
OutputStreamWriter w = new OutputStreamWriter(restConnection.getOutputStream());
w.write(data);
w.flush();
w.close();
int status = restConnection.getResponseCode();
// switch statement to catch HTTP 200 and 201 errors
switch (status) {
case 200:
// live connection to your REST service is established here using getInputStream() method
BufferedReader br = new BufferedReader(new InputStreamReader(restConnection.getInputStream()));
// create a new string builder to store json data returned from the REST service
StringBuilder sb = new StringBuilder();
String line;
// loop through returned data line by line and append to stringbuilder 'sb' variable
while ((line = br.readLine()) != null) {
sb.append(line + "\n");
}
br.close();
// remember, you are storing the json as a stringy
try {
json = sb.toString();
} catch (Exception e) {
Log.e(TAG, "Error parsing data " + e.toString());
}
// return JSON String containing data to Tweet activity (or whatever your activity is called!)
break;
case 400:
Log.d(TAG, "Bad request");
break;
case 401:
Log.d(TAG, "Unauthorized");
break;
case 402:
Log.d(TAG, "Request Failed");
break;
case 404:
Log.d(TAG, "404");
break;
case 500:
case 502:
case 503:
case 504:
Log.d(TAG, "Mailgun fail");
break;
}
} catch (Exception e) {
e.printStackTrace();
}
If you want to use MailGun on Android just do few steps:
1) Check this library. And implement it.
2) This library is for Java, not for Android. So you need to add 'configurations' to your gradle file and it should look like this:
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
compile 'net.sargue:mailgun:1.3.2'
}
configurations {
compile.exclude group: 'javax.inject', module: 'javax.inject'
}
more information here
3) So now you can use this library: (don't forget to run it in background thread)
Configuration configuration = new Configuration()
.domain("somedomain.com")
.apiKey("key-xxxxxxxxxxxxxxxxxxxxxxxxx")
.from("Test account", "postmaster#somedomain.com");
Response response = Mail.using(configuration)
.to("marty#mcfly.com")
.subject("This message has an text attachment")
.text("Please find attached a file.")
.multipart()
.attachment(new File("/path/to/image.jpg"))
.build()
.send();
I have an Android app that communicates with an internal web server here.
So far I have a login activity and another activity that helps do repetitive work.
I can login fine and I can store the Session ID cookie into a string. I've verified that the string is passed correctly through intent to the next activity. I have also verified that the cookie is received in the next activity.
However when I try to give this cookie to the web server via a setRequestProperty, the server doesn't seem to use it. When my app reads the requested URL, it just gets a login page, meaning it was redirected and the cookie didn't work. I receive zero errors.
I've talked to the website creator, and he says that he does no custom handling of HTTP headers, and that all of his scripts utilize session variables, and that ASP manages the session on its own. He wasn't aware that the web site was setting a session ID and value via cookies, and we then figured out that ASP was doing it automatically. This site has been functional via a web browser for years, I'm just trying to port a specific feature from it to an app.
I don't know what I'm doing wrong. Here is the chunk of code that reads the URL and sets the cookie and other HTTP header fields:
private class GetURLContent extends AsyncTask<URL, Integer, String> {
#Override
protected void onPostExecute(String result) {
setData(result);
}
protected String doInBackground(URL... url) {
String pageText = "";
String charset = "UTF-8";
String SessionCookie = "No SessionCookie passed.";
Bundle extras = getIntent().getExtras();
if (extras != null) {
SessionCookie = extras.getString("SessionCookie");
}
try {
URL ThisURL = new URL(url[0].toString());
HttpURLConnection ThisConnection = (HttpURLConnection) ThisURL.openConnection();
ThisConnection.setRequestMethod("GET");
ThisConnection.setRequestProperty("Host","technology.fergflor.k12.mo.us");
ThisConnection.setRequestProperty("User-Agent", "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2228.0 Safari/537.36");
ThisConnection.setRequestProperty("Connection","keep-alive");
ThisConnection.setRequestProperty("Cookie",SessionCookie);
ThisConnection.connect();
// wrap the urlconnection in a bufferedreader
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(ThisConnection.getInputStream()));
String line;
//read from the urlconnection via the bufferedreader
while ((line = bufferedReader.readLine()) != null)
{
pageText = pageText + line + "\n";
}
bufferedReader.close();
pageText = SessionCookie + "\n" + pageText;
} catch (MalformedURLException e) {
pageText = "MalformedURLException Error Message=\"" + e.getMessage() + "\" " + pageText;
} catch (IOException e2) {
pageText = "IOException Error Message=\"" + e2.getMessage() + "\" " + pageText;
} catch (NullPointerException e3) {
pageText = "NullPointerException Error Message=\"" + e3.getMessage() + "\" " + pageText;
}
return pageText;
}
}
All of the set-request properties here are identical to the ones used in the previous activities login class. I am using HttpURLConnection in both activities.
The goal is to use this class to give a cookie to re-use the session established from the previous login activity, and to retrieve a web page. I'm not sure what's going wrong.
I had a very similar problem with code that worked fine with API < 23. With API 23 it was redirected to the login page. The solution was to add this code line:
ThisConnection.setInstanceFollowRedirects(false);
I have been trying to get the cURL command translated into java code so that I can create a new AppLink object: https://developers.facebook.com/docs/applinks/hosting-api
I downloaded cURL and then typed in the following in Windows which worked and returned a applink ID:
curl -k -g https://graph.facebook.com/app/app_link_hosts -F
access_token="INSERTED MY OWN APP_TOKEN" -F name="Android App Link
Object Example" -F
android='[{"url":"sharesample://story/1234","package":"com.facebook.samples.sharesample","app_name":"ShareSample",},]'
-F web='{"should_fallback" : false,}'
Would anyone know how to convert the curl code into Java so that I can use it on my server?
Also I would like to find out if there is a way to found to query for all the applinks that are created for a particularly package name so that I can see everything that was created?
Thanks!
I spent hours researching this and finally found this piece of code from 1997 that I thought might no longer work as methods get deprecated and modified it for facebook applinks: http://www.javaworld.com/article/2077532/learn-java/java-tip-34--posting-via-java.html
Then I used Spring to generate this endpoint and now its working and returns an app link id:
#RequestMapping(value="/applink", method=RequestMethod.GET)
public void applink() {
URL url;
URLConnection urlConn;
DataOutputStream printout;
DataInputStream input;
try {
url = new URL ("https://graph.facebook.com/app/app_link_hosts");
// URL connection channel.
urlConn = url.openConnection();
// Let the run-time system (RTS) know that we want input.
urlConn.setDoInput (true);
// Let the RTS know that we want to do output.
urlConn.setDoOutput (true);
// No caching, we want the real thing.
urlConn.setUseCaches (false);
// Specify the content type.
urlConn.setRequestProperty
("Content-Type", "application/x-www-form-urlencoded");
// Send POST output.
printout = new DataOutputStream (urlConn.getOutputStream ());
String content =
"access_token=" + URLEncoder.encode("INSERT APP ACCESS TOKEN", "UTF-8") +
"&name=" + URLEncoder.encode("Android App Link Object Example", "UTF-8") +
"&android=" + URLEncoder.encode("[{'url':'sharesample://story/1234', 'package':'com.facebook.samples.sharesample','app_name':'ShareSample'}]", "UTF-8") +
"&web=" + URLEncoder.encode("{'should_fallback' : false}", "UTF-8");
printout.writeBytes(content);
printout.flush ();
printout.close ();
// Get response data.
input = new DataInputStream (urlConn.getInputStream ());
BufferedReader d = new BufferedReader(new InputStreamReader(urlConn.getInputStream()));
String str;
while (null != ((str = d.readLine())))
{
System.out.println (str);
//textArea.appendText (str + "\n");
}
input.close ();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
I'm trying to make a simple chat server. It works fine on the iphone, but not all the chats are going through on the android.
My idear was to use the http protocol so I can use the standard sfkd on the iphone and android to talk to my server
I'm using the URLConnection connection class on the android.
When I was tacing the code on my server, I noticed that I was getting the length of the post data sent in the header. I'm not setting any length value on the URLConnection class. I figured since I was not setting the size in the header that is why its not working. I could not find any info about this.
code that reads in haeder on my server
I have my server code and android code below,
public int ReadHeader()
{
// read in one line
int PageId=0;
// try{
request = new StringBuffer(1000);
System.out.println("get connection reading in header \r");
//InputStream in = new BufferedInputStream( connection.getInputStream() );
StopFlag=false;
String out;
// the first line shouls have the page
out=ReadLine();
int p;
p=out.lastIndexOf("stop");
if (p!=-1)
PageId=1;
p=out.lastIndexOf("enter");
if (p!=-1)
PageId=2;
p=out.lastIndexOf("add");
if (p!=-1)
PageId=3;
p=out.lastIndexOf("exit");
if (p!=-1)
PageId=4;
p=out.lastIndexOf("update");
if (p!=-1)
PageId=5;
int MessageSize=0;
do{
out=ReadLine();
// check for content size
// GET SIZR OF DATA SENT
if (out.contains("Length"))
{
System.out.println("found length \r");
int pes=out.indexOf(' ');
String Length=out.substring(pes+1);
System.out.println("found size");
System.out.println(Length);
//MessageSize=(int)Length;
MessageSize= Integer.parseInt( Length) ;
//MessageSize=36;
}
} while(out!="finish header" && out!="");
System.out.println("finsih header \r");
ClientMessage=ReadSize(MessageSize);
/*
} catch(IOException ec)
{
System.out.println(ec.getMessage());
}
*/
return PageId;
}
// CODE ON ANDROID
String data = URLEncoder.encode("username", "UTF-8") + "=" + URLEncoder.encode( cGlobals.UserName, "UTF-8"); data += "&" + URLEncoder.encode("comment", "UTF-8") + "=" + URLEncoder.encode( s, "UTF-8");
cGlobals.Message=""; // THIS IS NOT TKING IN ANY INFO ABOUT THE LENGTH OF data URLConnection conn = url.openConnection();
// set timeouts to 5 seconds
// conn.setConnectTimeout(1000*5);
// conn.setReadTimeout(5*1000);
conn.setDoOutput(true);
OutputStreamWriter wr = new OutputStreamWriter(conn.getOutputStream());
wr.write(data);
wr.flush();
wr.close();
I am developing a final year project where I need to connect Android emulator with MySQL database in order to retrieve values. Java file:
public class connectivity extends Activity {
/** Called when the activity is first created. */
TextView txt;
public static final String KEY_121 = "http://10.0.2.2/mysqlcon.php";
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
LinearLayout rootLayout = new LinearLayout(getApplicationContext());
txt = new TextView(getApplicationContext());
rootLayout.addView(txt);
setContentView(rootLayout);
// Set the text and call the connect function.
txt.setText("Connecting...");
// call the method to run the data retreival
txt.setText(getServerData(KEY_121));
}
private String getServerData(String returnString) {
InputStream is = null;
String result = null;
// the year data to send
ArrayList<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>();
nameValuePairs.add(new BasicNameValuePair("year", "1970"));
// http post
try {
HttpClient httpclient = new DefaultHttpClient();
HttpPost httppost = new HttpPost(KEY_121);
httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
HttpResponse response = httpclient.execute(httppost);
HttpEntity entity = response.getEntity();
is = entity.getContent();
} catch (Exception e) {
Log.e("log_tag", "Error in http connection " + e.toString());
}
// convert response to string
try {
BufferedReader reader = new BufferedReader(new InputStreamReader(is, "iso-8859-1"), 8);
StringBuilder sb = new StringBuilder();
String line = "0";
while ((line = reader.readLine()) != null) {
sb.append(line + "\n");
}
is.close();
result = sb.toString();
} catch (Exception e) {
Log.e("log_tag", "Error converting result " + e.toString());
}
// parse json data
try {
JSONArray jArray = new JSONArray(result);
JSONObject json_data = null;
for (int i = 0; i < jArray.length(); i++) {
json_data = jArray.getJSONObject(i);
Log.i("log_tag", "id: " + json_data.getInt("id") + ", name: " + json_data.getString("name") + ", sex: " + json_data.getInt("sex") + ", birthyear: " + json_data.getInt("birthyear"));
// Get an output to the screen
returnString += "\n\t" + jArray.getJSONObject(i);
}
} catch (JSONException e) {
Log.e("log_tag", "Error parsing data " + e.toString());
}
return returnString;
}
}
I have also given an internet permission in my Android manifest file. But after running the application I get the following error in logcat:
ERROR PARSING DATA org.json.JSONException:A JSONArraytext must start with '[' at character 0
I think this goes to show that a null value is being returned. Please help me out as this is my final year project. I have spent hours trying to find the solutions but it has been of no use.
I am currently using Android 2.2. The wamp server is on the localhost so I am using the address 10.0.2.2 which is a special alias to localhost (127.0.0.1). Any help will be really appreciated.
Here is the PHP code:
<?php
mysql_connect("127.0.0.1","root","chetan");
mysql_select_db("db1");
$q=mysql_query("SELECT * FROM people WHERE birthyear>'".$_REQUEST['year']."'");
while($e=mysql_fetch_assoc($q))
$output[]=$e;
print(json_encode($output,JSON_FORCE_OBJECT));
mysql_close();
This is actually an issue I've run into before. The problem is your server isn't outputting valid JSON. It's missing some of the markup. I suggest you print the raw text of the response to Logcat and examine it. Perhaps even pass it into a JSON validator. That will also help you figure out if it is returning an empty value. If it's returning an empty value, then you'll need to debug your server...not your client...
Additionally, try visiting the php page from your browser and letting it simply display the JSON response. This will allow you to see what's being written by the server and help you determine where the problem really is. Just be aware, because the server is expecting a POST the easiest way to test this would probably to be to create a simple html form to POST the test data to that page. Without doing that, getting a browser to do a POST on it's own can be a pain.
do u need to use connection to php??? if not you can directly connect to mysql db to retrieve the result:
// Assume function to be :
public String customerData() {
String customerInfo = ""; //To store result
try {
Class.forName("com.mysql.jdbc.Driver");
Connection con =
DriverManager.getConnection(
"jdbc:mysql://10.0.2.2:3306/retailer","root","pswrd");
PreparedStatement statement = con.prepareStatement("SELECT * FROM customers");
ResultSet result = statement.executeQuery();
while(result.next()) {
customerInfo = customerInfo + result.getString("name") + "&" +
result.getString("C_ID") + "&" + result.getString("address") +
"&" + result.getString("email");
// Here "&"s are added to the return string. This is help to split the
// string in Android application
}
} catch(Exception exc) {
System.out.println(exc.getMessage());
}
return customerInfo;
}
But to your project library include Connector jar file for Mysql.