Failing to send POST from android to php - php

I'm new to android and I tried to make a simple login test with android http post and php, though I'm unable to send posts with the following code:
package com.yagami.boook.classify;
import android.app.ProgressDialog;
import android.os.AsyncTask;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.HttpURLConnection;
import java.net.URL;
/**
* Created by allen on 2017/1/1.
*/
public class GetUserInfo extends AsyncTask<String, Integer, String> {
// ProgressDialog dialog;
#Override
protected void onPreExecute() {
super.onPreExecute();
// dialog = ProgressDialog.show(MainActivity.class, "Retrieving User Data", "Please wait...", true);
}
#Override
protected void onPostExecute(String aString) {
super.onPostExecute(aString);
// dialog.dismiss();
}
#Override
protected String doInBackground(String... strings) {
HttpURLConnection connection;
OutputStreamWriter request = null;
URL url = null;
Log.d("A","A");
try {
url = new URL("http://localhost/login.php");
connection = (HttpURLConnection) url.openConnection();
connection.setDoOutput(true);
connection.setRequestMethod("POST");
Log.d("B","B");
request = new OutputStreamWriter(connection.getOutputStream());
Log.d("C","C");
request.write(strings[0]);
request.flush();
request.close();
InputStreamReader isr = new InputStreamReader(connection.getInputStream());
BufferedReader reader = new BufferedReader(isr);
String response = reader.readLine();
isr.close();
reader.close();
return response;
} catch (IOException e) {
// Error
}
return null;
}
}
Here is the php file, I tried to print a txt file so I would know if I received anything:
<?php
$email = $_POST['username'];
$password = $_POST['password'];
// echo $username."<br>";
// echo $password."<br>";
$connect = mysql_connect("localhost" , "root" , "112233");
mysql_select_db("classify", $connect);
$data = mysql_query("select * from users where email = '$email'");
$row = mysql_fetch_row($data);
// echo $row[2];
if($row[2] == $password) echo "pass";
else echo "nopass";
$fp = fopen('xxx.txt', 'w');
fwrite($fp , "abc");
fclose($fp);
?>
Here's the log, I added some Log.d into the code so that it would be more easy to understand what's happening. (As you can see the Log.d("C", "C") isn't showing up)
01/01 17:22:50: Launching app
$ adb push C:\Users\allen\Desktop\MyApplication\app\build\outputs\apk\app-debug.apk /data/local/tmp/com.example.allen.myapplication
$ adb shell pm install -r "/data/local/tmp/com.example.allen.myapplication"
Success
$ adb shell am start -n "com.example.allen.myapplication/com.example.allen.myapplication.MainActivity" -a android.intent.action.MAIN -c android.intent.category.LAUNCHER
Client not ready yet..Waiting for process to come online
Connected to process 3148 on device Nexus_5X_API_25 [emulator-5554]
W/System: ClassLoader referenced unknown path: /data/app/com.example.allen.myapplication-2/lib/x86
I/InstantRun: Instant Run Runtime started. Android package is com.example.allen.myapplication, real application class is null.
W/System: ClassLoader referenced unknown path: /data/app/com.example.allen.myapplication-2/lib/x86
W/art: Before Android 4.1, method android.graphics.PorterDuffColorFilter android.support.graphics.drawable.VectorDrawableCompat.updateTintFilter(android.graphics.PorterDuffColorFilter, android.content.res.ColorStateList, android.graphics.PorterDuff$Mode) would have incorrectly overridden the package-private method in android.graphics.drawable.Drawable
I/OpenGLRenderer: Initialized EGL, version 1.4
D/OpenGLRenderer: Swap behavior 1
E/EGL_emulation: tid 3195: eglSurfaceAttrib(1174): error 0x3009 (EGL_BAD_MATCH)
W/OpenGLRenderer: Failed to set EGL_SWAP_BEHAVIOR on surface 0x99477440, error=EGL_BAD_MATCH
W/IInputConnectionWrapper: finishComposingText on inactive InputConnection
D/NetworkSecurityConfig: No Network Security Config specified, using platform default
01/01 17:24:54: Launching app
W/System: ClassLoader referenced unknown path: /data/data/com.example.allen.myapplication/lib
E/EGL_emulation: tid 3195: eglSurfaceAttrib(1174): error 0x3009 (EGL_BAD_MATCH)
W/OpenGLRenderer: Failed to set EGL_SWAP_BEHAVIOR on surface 0x9947d420, error=EGL_BAD_MATCH
E/EGL_emulation: tid 3195: eglSurfaceAttrib(1174): error 0x3009 (EGL_BAD_MATCH)
W/OpenGLRenderer: Failed to set EGL_SWAP_BEHAVIOR on surface 0x98d37ba0, error=EGL_BAD_MATCH
Hot swapped changes, activity restarted
W/IInputConnectionWrapper: finishComposingText on inactive InputConnection
D/A: A
D/B: B
D/A: A
D/B: B
Have already searched the whole google for debugging but didn't find anything useful, hope it isn't a stupid mistake. Also please notify me if more information is needed.
Thanks in advance!

You are trying to access http://localhost/ from your device or emulator, but your actual web server runs somewhere else. So, for your device this web server is not a localhost.
To make this work, you need to make sure that the device is connected to the same network as your web server, and that the web server is accessible from your device (probable firewall issues, etc.). You then need to find out the IP address of your host inside the network, e.g. 192.168.1.42, and use that IP address in your android code:
// use your valid IP address instead
url = new URL("http://192.168.1.42/login.php");
With this connection, the device will look for a provided IP in your network, and access it, if it is available. Also, note that your IP will probably change, so you'll need to figure out how to make it static.
More on accessing localhost from an Android device here.

Related

HTTP JSON API request responds "-1"

I'm trying to make a REST API that an Arduino with an ESP8266 module can GET, but when I try to send a request to my server the HTTP Code that I get is -1, which I have not been able to find any documentation on anywhere (it's not in the list of HTTP status codes here).
My test-API that I get the -1 response from is here, while a this API works fine. My API is simple:
PHP API:
header('Content-Type: application/json; charset=utf-8');
header('Access-Control-Allow-Origin: *');
$array = array(
"status" => true
);
echo json_encode($array);
The Arduino code is just one of the ESP8266 examples, and looks like this:
#include <ESP8266WiFi.h>
#include <ESP8266HTTPClient.h>
const char* ssid = "Next-Guest";
const char* password = "";
void setup () {
Serial.begin(115200);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(1000);
Serial.print("Connecting..");
}
}
void loop() {
if (WiFi.status() == WL_CONNECTED) {
HTTPClient http;
//http.begin("http://jsonplaceholder.typicode.com/users/1"); <- this works
http.begin("https://makerspace.albe.pw/api/getDoorStatus.php"); // <- this doesn't
int httpCode = http.GET();
Serial.println(httpCode);
if (httpCode > 0) {
String payload = http.getString();
Serial.println(payload);
}
http.end();
}
delay(30000);
}
I can do a GET request locally from any computer to my API using jQuery AJAX, so it must be somewhat open?
Is my host the problem, or are my files missing some headers?
When accessing a domain protected with a SSL certificate (https), you need to specify the SSL thumbprint as a second parameter in the http.begin function:
String thumbprint = "the_thumbprint";
http.begin("https://api.site/api/get_details.json", thumbprint);

Unable to fetch sessionId for Magento API using SOAP webservice in Android

I am developing an Android mobile app for Magento website, I have created user and set role in admin panel of Magento, but I am unable to fetch the sessionId from it. I am using soap web service and my code is for connecting to the web service is:
private static final String NAMESPACE = "urn:Magento";
private static final String URL = "http://localhost.../index.php/api/index/index/?wsdl";
private static final String MAGENTO_METHOD_NAME = "login";
try {
SoapSerializationEnvelope env = new SoapSerializationEnvelope(
SoapEnvelope.VER11);
env.dotNet = false;
env.xsd = SoapSerializationEnvelope.XSD;
env.enc = SoapSerializationEnvelope.ENC;
SoapObject request = new SoapObject(NAMESPACE, MAGENTO_METHOD_NAME);
request.addProperty("username", "web_service_all");
request.addProperty("apiKey", "WebServiceUser";
env.setOutputSoapObject(request);
HttpTransportSE androidHttpTransport = new HttpTransportSE(URL);
androidHttpTransport.call("", env);
Object result = env.getResponse();
value=String.valueOf(so);
Log.d("sessionId", result.toString());
} catch (Exception e) {
e.printStackTrace();

Performing requests to ETSY store allowing access automatically PHP OAUTH

I am using a library to connect to my ETSY store and pull data from receipts to bring them into my personal website (database).
After making the request using OAuth, I get to the ETSY site to "Allow Access"
https://www.etsy.com/images/apps/documentation/oauth_authorize.png
Then, I need to manually click on Allow Access and my request will be completed and will display the data requested.
I would like to avoid the process of manually clicking on "Allow Access", since I want my personal site to automatically display information pulled from ETSY orders.
Here is my current code for page etsyRequest.php:
$credentials = new Credentials(
$servicesCredentials['etsy']['key'],
$servicesCredentials['etsy']['secret'],
$currentUri->getAbsoluteUri()
);
// Instantiate the Etsy service using the credentials, http client and storage mechanism for the token
/** #var $etsyService Etsy */
$etsyService = $serviceFactory->createService('Etsy', $credentials, $storage);
if (!empty($_GET['oauth_token'])) {
$token = $storage->retrieveAccessToken('Etsy');
// This was a callback request from Etsy, get the token
$etsyService->requestAccessToken(
$_GET['oauth_token'],
$_GET['oauth_verifier'],
$token->getRequestTokenSecret()
);
// Send a request now that we have access token
$result2 = json_decode($etsyService->request('/receipts/111111'));
//echo 'result: <pre>' . print_r($result, true) . '</pre>';
echo $result2->results[0]->seller_user_id;
How could I automate the Allow Access part and get the returned value for my request by just running this page?
You can resolved this problem by simply save the returned "access token" and "token secret".
Steps to do it:
After making the request using OAuth, you get to the ETSY site to
"Allow Access". after allowing it will show a oauth_verifier pin.
After you enter this pin in your code it will set "access token" and
"token secret" to your request.you just need to save them in
variables or database.
next time when to create any request to etsy you just have to set
these access token" and "token secret" with your oauth_consumer_key
and oauth_consumer_secret. you don't need oauth_verifier pin at that time.
it will work util you revoke permission from your etsy account.
I did this in my java code because i mm facing same problem and its working.(sorry i m not good enough in php) here is my sample code may this helps-
public void accessEtsyAccount(String consumer_key, String consumer_secret, String requestToken, String tokenSecret, String shopName) throws Throwable{
OAuthConsumer consumer = new DefaultOAuthConsumer(
consumer_key, consumer_secret
);
if(StringUtils.isBlank(requestToken) || StringUtils.isBlank(tokenSecret) ){
OAuthProvider provider = new DefaultOAuthProvider(
"https://openapi.etsy.com/v2/oauth/request_token",
"https://openapi.etsy.com/v2/oauth/access_token",
"https://www.etsy.com/oauth/signin");
System.out.println("Fetching request token from Etsy...");
// we do not support callbacks, thus pass OOB
String authUrl = provider.retrieveRequestToken(consumer, OAuth.OUT_OF_BAND);
System.out.println("Request token: " + consumer.getToken());
System.out.println("Token secret: " + consumer.getTokenSecret());
System.out.println("Now visit:\n" + authUrl
+ "\n... and grant this app authorization");
if(Desktop.isDesktopSupported()){
Desktop desktop = Desktop.getDesktop();
try {
desktop.browse(new URI(authUrl));
} catch (IOException | URISyntaxException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}else{
Runtime runtime = Runtime.getRuntime();
try {
runtime.exec("xdg-open " + authUrl);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
System.out.println("Enter the PIN code and hit ENTER when you're done:");
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String pin = br.readLine();
System.out.println("Fetching access token from Etsy...");
provider.retrieveAccessToken(consumer, pin);
} else {
consumer.setTokenWithSecret(requestToken, tokenSecret);
}
System.out.println("Access token: " + consumer.getToken());
System.out.println("Token secret: " + consumer.getTokenSecret());
URL url = new URL("https://openapi.etsy.com/v2/private/shops/"+shopName+"/transactions");
HttpURLConnection request = (HttpURLConnection) url.openConnection();
consumer.sign(request);
System.out.println("Sending request to Etsy...");
request.connect();
System.out.println("Response: " + request.getResponseCode() + " "
+ request.getResponseMessage());
System.out.println("Payload:");
InputStream stream = request.getInputStream();
String stringbuff = "";
byte[] buffer = new byte[4096];
while (stream.read(buffer) > 0) {
for (byte b: buffer) {
stringbuff += (char)b;
}
}
System.out.print(stringbuff);
You need to save the access token when you have requested the Etsy store for the first time and then the same access token can be used for later calls. This would prevent you from clicking ALLOW ACCESS again and again when requesting Etsy store through API.

Confusions about new GoogleCloudMessaging API (not the old one)

i have followed the tutorial for GCM available at the official site:
http://developer.android.com/google/gcm/gs.html
and i have successfully implemented it on my app.. but as i am new on android i have few confusions about GCM i would really appriciate if someone could clear these points.
i wrote a PHP script(found from google) and hardcoded my regisration ID (just for testing) when i run the script i recieve a notification on my device.. but i dont wanna receive a notification rather i want to silently recieve the data and handle it on my device. is it possible?? here is the PHP code:
$regID=$_REQUEST['regID'];
$registatoin_ids=array($regID);
$msg=array("message"=>'HI Wasif');
$url='https://android.googleapis.com/gcm/send';
$fields=array
(
'registration_ids'=>$registatoin_ids,
'data'=>$msg
);
$headers=array
(
'Authorization: key=MY-REG-KEY',
'Content-Type: application/json'
);
$ch=curl_init();
curl_setopt($ch,CURLOPT_URL,$url);
curl_setopt($ch,CURLOPT_POST,true);
curl_setopt($ch,CURLOPT_HTTPHEADER,$headers);
curl_setopt($ch,CURLOPT_RETURNTRANSFER,true);
curl_setopt($ch,CURLOPT_SSL_VERIFYPEER,false);
curl_setopt($ch,CURLOPT_POSTFIELDS,json_encode($fields));
$result=curl_exec($ch);
curl_close($ch);
echo $result;
Second point is i want to customize the notification i receive on my device i receive a notification like this...(see picture below) but i want to replace the heading text "GCM Notification" with my app's name and the message should me displayed properly(not like the key,value text) and also change the image of notification... can anybody plz provide a tutorial how to do it in new GoogleCloudMessaging API?? (please dont provide old methods if it is not same for new GoogleCouldMessaging API)
BROADCAST RECEIVER CODE:
public class GcmBroadcastReceiver extends WakefulBroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
// Explicitly specify that GcmIntentService will handle the intent.
ComponentName comp = new ComponentName(context.getPackageName(),
GcmIntentService.class.getName());
// Start the service, keeping the device awake while it is launching.
startWakefulService(context, (intent.setComponent(comp)));
setResultCode(Activity.RESULT_OK);
}
}
Hope this link helps : GCM
1) If you don't want to receive notification on device then remove the code of Notification from GCMIntentService class under generateNotification() method.
2) You can provide your app name, app icon by implementing following code in generateNotification() method :
private static void generateNotification(Context context, String message) {
int icon = R.drawable.ic_launcher;
long when = System.currentTimeMillis();
NotificationManager notificationManager = (NotificationManager)
context.getSystemService(Context.NOTIFICATION_SERVICE);
Notification notification = new Notification(icon, message, when);
String title = context.getString(R.string.app_name);
Intent notificationIntent = new Intent(context, MainActivity.class);
// set intent so it does not start a new activity
notificationIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP |
Intent.FLAG_ACTIVITY_SINGLE_TOP);
PendingIntent intent =
PendingIntent.getActivity(context, 0, notificationIntent, 0);
notification.setLatestEventInfo(context, title, message, intent);
notification.flags |= Notification.FLAG_AUTO_CANCEL;
// Play default notification sound
notification.defaults |= Notification.DEFAULT_SOUND;
// Vibrate if vibrate is enabled
notification.defaults |= Notification.DEFAULT_VIBRATE;
notificationManager.notify(0, notification);
}
Hope this helps.

Google cloud messaging GCM - Push Notification not being sent (Server Side)

I am able to get the device id and save it to my database, and when something happens, I try to send the push notification but it does not get delivered to the phone. Here is what I do in my PHP:
$url = 'https://android.googleapis.com/gcm/send';
$device_ids = array( $device_id );
$headers = array('Authorization: key=' . 'my_api_key',
'Content-Type: application/json');
$t_data = array();
$t_data['message'] = 'Someone commented on your business.';
$t_json = array( 'registration_ids' => $device_ids , 'data' => $t_data );
$ch = curl_init();
curl_setopt($ch, CURLOPT_HTTPHEADER, array( 'Authorization: key=my_id', 'Content-Type: application/json' ) );
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode( $t_json ) );
curl_setopt($ch, CURLOPT_URL, $url);
$result = curl_exec($ch);
if ($result === FALSE)
{
die('Curl failed: ' . curl_error($ch));
}
curl_close($ch);
and here is the result I get from the curl_exec call:
{"multicast_id":8714083978034301091,"success":1,"failure":0,"canonical_ids":0,"r‌​esults":[{"message_id":"0:1350807053347963%9aab4bd8f9fd7ecd"}]}
One thing I am wondering is whether I have to do something extra in the app like write my own Reciever class?
Thanks!
EDIT:
Here is my GCMIntentService class:
package com.problemio;
import static com.google.android.gcm.GCMConstants.ERROR_SERVICE_NOT_AVAILABLE;
import static com.google.android.gcm.GCMConstants.EXTRA_ERROR;
import static com.google.android.gcm.GCMConstants.EXTRA_REGISTRATION_ID;
import static com.google.android.gcm.GCMConstants.EXTRA_SPECIAL_MESSAGE;
import static com.google.android.gcm.GCMConstants.EXTRA_TOTAL_DELETED;
import static com.google.android.gcm.GCMConstants.EXTRA_UNREGISTERED;
import static com.google.android.gcm.GCMConstants.INTENT_FROM_GCM_LIBRARY_RETRY;
import static com.google.android.gcm.GCMConstants.INTENT_FROM_GCM_MESSAGE;
import static com.google.android.gcm.GCMConstants.INTENT_FROM_GCM_REGISTRATION_CALLBACK;
import static com.google.android.gcm.GCMConstants.VALUE_DELETED_MESSAGES;
import java.util.Random;
import java.util.concurrent.TimeUnit;
import com.google.android.gcm.GCMBaseIntentService;
import android.app.AlarmManager;
import android.app.IntentService;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.os.PowerManager;
import android.os.SystemClock;
import android.util.Log;
import android.widget.Toast;
import utils.GCMConstants;
public class GCMIntentService extends GCMBaseIntentService
{
public GCMIntentService()
{
super(ProblemioActivity.SENDER_ID);
}
#Override
protected void onRegistered(Context ctxt, String regId) {
Log.d(getClass().getSimpleName(), "onRegistered: " + regId);
Toast.makeText(this, regId, Toast.LENGTH_LONG).show();
}
#Override
protected void onUnregistered(Context ctxt, String regId) {
Log.d(getClass().getSimpleName(), "onUnregistered: " + regId);
}
#Override
protected void onMessage(Context ctxt, Intent message) {
Bundle extras=message.getExtras();
for (String key : extras.keySet()) {
Log.d(getClass().getSimpleName(),
String.format("onMessage: %s=%s", key,
extras.getString(key)));
}
}
#Override
protected void onError(Context ctxt, String errorMsg) {
Log.d(getClass().getSimpleName(), "onError: " + errorMsg);
}
#Override
protected boolean onRecoverableError(Context ctxt, String errorMsg) {
Log.d(getClass().getSimpleName(), "onRecoverableError: " + errorMsg);
return(true);
}
}
UPDATE:
Looking at LogCat, it turned out that the message is getting to the device. But the device is not displaying the push notification for some reason.
From the response it seems that the message is delivered. On Android you should have a GCMIntentService class that extends GCMBaseIntentService, to receive the message on the device. You should check the gcm-demo-client that comes in the SDK samples for a good approach on how to implement this on the app. There you only need set the SENDER_ID (your google proyect number) in the CommonUtilities class to receive messages from your server.
More info here.
To generate the notification on the GCMIntentService you can use:
//Issues a notification to inform the user that server has sent a message.
private static void generateNotification(Context context, String message, String title,) {
int icon = R.drawable.logo;
NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
Intent notificationIntent = new Intent(context, AnActivity.class);
// set intent so it does not start a new activity
notificationIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
PendingIntent intent = PendingIntent.getActivity(context, 0, notificationIntent, 0);
Uri defaultSound = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
Notification notification = new NotificationCompat.Builder(context)
.setContentTitle(title)
.setContentText(message)
.setContentIntent(intent)
.setSmallIcon(icon)
.setLights(Color.YELLOW, 1, 2)
.setAutoCancel(true)
.setSound(defaultSound)
.build();
notificationManager.notify(0, notification);
}
Have you also registered the receiver on the manifest? Under the application tag?
<!--
BroadcastReceiver that will receive intents from GCM
services and handle them to the custom IntentService.
The com.google.android.c2dm.permission.SEND permission is necessary
so only GCM services can send data messages for the app.
-->
<receiver
android:name="com.google.android.gcm.GCMBroadcastReceiver"
android:permission="com.google.android.c2dm.permission.SEND" >
<intent-filter>
<!-- Receives the actual messages. -->
<action android:name="com.google.android.c2dm.intent.RECEIVE" />
<!-- Receives the registration id. -->
<action android:name="com.google.android.c2dm.intent.REGISTRATION" />
<category android:name="com.google.android.gcm.demo.app" />
</intent-filter>
</receiver>
<!--
Application-specific subclass of GCMBaseIntentService that will
handle received messages.
By default, it must be named .GCMIntentService, unless the
application uses a custom BroadcastReceiver that redefines its name.
-->
<service android:name=".GCMIntentService" />
You only need a collapseKey if you are planning to have your messages overwrite the previous message of that type. So if you are sending a message that the app needs to sync you can give it a collapse key so it will only send 1 sync message. The official docs describe how to use it.
While sending notification from GCM Server, which url to be used?
https://android.googleapis.com/gcm/send or
https://gcm-http.googleapis.com/gcm/send

Categories