I have 2 Android apps on two different devices. App 1 is stationary and app 2 is mobile. I would like the app 1 to find the closest app 2 device and communicate like snapchat but I would like to update app 1 with app 2's current location. I am storing app 1's location in the server and retrieve app 2's location and calculate the distance between them and send the location of app 1 to app 2 over GCM. But this proved to be more complicated than I originally thought. I also tried to store the mobile app's location in the database and get the updated location once the stationary requests to communicate but that meant updating the database too much. Can someone give me a hint on how to accomplish this with efficiency? Following are code snippets to calculate distance between them and send location.
function distance_slc($lat1, $lon1, $lat2, $lon2) {
global $earth_radius;
global $delta_lat;
global $delta_lon;
$distance = sin(deg2rad($lat1)) * sin(deg2rad($lat2)) + cos(deg2rad($lat1)) * cos(deg2rad($lat2)) * cos(deg2rad($delta_lon));
$distance = acos($distance);
$distance = rad2deg($distance);
$distance = $distance * 60 * 1.1515;
$distance = round($distance, 4);
return $distance;
}
function compute($id, $lat, $lon) {
$p = getPLocation();
$d = array($id, $lat, $lon);
foreach ($d as $index => $value) {
$d_pass_distance = distance_slc($p['latitude'], $p['longitude'], $d['1'], $d['2']);
$closest_d = 0;
if ($closest_d = min($d_pass_distance)) {
sendPLocation($d['0'], $p['latitude'], $p['longitude']);
}
}
}
function sendUserLocation($id, $lat, $lon) {
//request url
//$url = 'https://android.googleapis.com/gcm/send';
$url = 'gcm-preprod.googleapis.com:5236'; //this url is only for testing not production
//your api key
$apiKey = 'myserverapikeyhere';
$fields = array('id' => $id, 'latitude' => $lat, 'longitude' => $lon);
//http header
$headers = array('Authorization: key=' . $apiKey,
'Content-Type: application/json');
//curl connection
$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;
}
What comes to mind is when the app 1 client wants to communicate it sends a message to your app server. The app server then sends a GCM push message to all of the appropriate mobile devices, the app 2 client on each device receives the message, determines its current location, and uses an upstream message to send its location to the app server. The app server determines the closest device (probably waiting a few seconds to get all of the various responses), and then sends a push message to the closest app 2 client (and optionally the app 1 client) with the appropriate information.
EDIT: Include some example code for upstream and downstream messages. By and large I am excluding general messaging stuff. You can replace the "contents" and "username" fields with your own stuff, and will need to have different types of upstream messages
Downstream message (app server side - this is in Java)
public void actionPerformed(ActionEvent e) {
// who are we sending it to?
String toAddr = "zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz";
// create the message
Map<String, Object> message = new HashMap<String, Object>();
message.put("to", toAddr);
message.put("message_id", myNextMessageId());
HashMap<String, String> dataPayload = new HashMap<>();
dataPayload.put( "contents", dataInfo.getText() );
message.put("data", dataPayload);
// actually send the message
try {
Packet request = new GcmPacketExtension(JSONValue.toJSONString(message)).toPacket();
connection.sendPacket(request);
} catch ( NotConnectedException enc ) {
// quietly ignore the error
}
}
Downstream message (Android client)
public class MyGcmListenerService extends GcmListenerService {
public MyGcmListenerService() { }
public void onMessageReceived (String from, Bundle data) {
// get info ("data" stuff)
String contents = data.getString( "contents" );
... process contents
}
}
Upstream messages (Android client)
GoogleCloudMessaging gcm;
String SENDER_ID = "999999999999";
// send the registration to the back-end app server
private void sendUpstreamMessage( user ) {
// use upstream message to register with the app server
// app server uses the 'from' field of the message
String msg = "";
try {
Bundle data = new Bundle();
String user = getGoogleAccount();
// username is the user email
data.putString( "username", user );
// and note this is a registration request
data.putString("my_action", "edu.eku.styere.gcmpushclient.REGISTER");
String id = myNewMessageId();
// send the registration message
gcm.send(SENDER_ID + "#gcm.googleapis.com", id, data);
} catch (IOException ex) {
// for now ignore error
}
return;
}
Upstream message (app server - again in Java)
// assume we already know this is an upstream message and not an ACK or something else
protected void handleUpstreamMessage(Map<String, Object> jsonObject) {
// PackageName of the application that sent this message.
String category = (String) jsonObject.get("category");
String from = (String) jsonObject.get("from");
#SuppressWarnings("unchecked")
Map<String, String> payload = (Map<String, String>) jsonObject.get("data");
// what action do they want?
String my_action = (String) payload.get( "my_action" );
if ( my_action.equals( "edu.eku.styere.gcmpushclient.REGISTER" ) ) {
// registration request
String username = (String) payload.get( "username" );
registerUser( username, from );
return;
}
}
Related
I can succesfully recive notifications from Firebase console, but when I call the PHP function to do it, doesn't recive anything. As I saw on internet, this is more less how I can send these notifications. And what I don't understand what is different when I switch to Firebase console (because it works from there). I don't think the problem is from my app, because I send a request to their server and then they should send to my device. It is very possible to make a mistake, please don't be too rude. I am still a beginner. Thank you for your wise answers!
PHP function
function push_notification_android($device_id,$message){
//API URL of FCM
$url = 'https://fcm.googleapis.com/fcm/send';
$api_key = 'MY_KEY';
$fields = array (
'to' => $device_id,
'data' => array(
"message" => $message,
"id" => '1',
),
);
//header includes Content type and api key
$headers = array(
'Content-Type:application/json',
'Authorization: key='.$api_key
);
$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;
return $result;
}
{"multicast_id":7370520341381062896,"success":1,"failure":0,"canonical_ids":0,"results":[{"message_id":"0:1611404485967655%6b34551f6b34551f"}]}
By documentation you can send two types of messages to clients:
Notification messages - handled by the FCM SDK automatically.
Data messages - handled by the client app.
If you want to send data message implement your FirebaseMessagingService like this (this is only example what to do, you can use it but improve it with your needs and also test all possible solution to understand how that works)
public class MyFirebaseMessagingService extends FirebaseMessagingService {
#Override
public void onMessageReceived(RemoteMessage remoteMessage) {
if (remoteMessage.getData().size() > 0) {
handleDataMessage(remoteMessage.getData());
}else if (remoteMessage.getNotification() != null) {
//remove this line if you dont need or improve...
sendNotification(100, remoteMessage.getNotification().getBody());
}
}
private void handleDataMessage(Map<String, String> data) {
if(data.containsKey("id") && data.containsKey("message")){
String message = data.get("message");
int id;
try {
id = Integer.parseInt(data.get("id"));
}catch (Exception e){
e.printStackTrace();
id = 1; // default id or something else for wrong id from server
}
sendNotification(id, message);
}
}
private void sendNotification(int id, String messageBody) {
Intent intent = new Intent(this, MainActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0 , intent, PendingIntent.FLAG_ONE_SHOT);
String channelId = "appChannelId"; //getString(R.string.default_notification_channel_id);
Uri defaultSoundUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
NotificationCompat.Builder notificationBuilder =
new NotificationCompat.Builder(this, channelId)
.setSmallIcon(R.drawable.icon) //TODO set your icon
.setLargeIcon(BitmapFactory.decodeResource(getResources(), R.drawable.iconpro_round)) //TODO set your icon
.setContentTitle("MyApp")
.setContentText(messageBody)
.setAutoCancel(true)
.setSound(defaultSoundUri)
.setContentIntent(pendingIntent);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) notificationBuilder.setPriority(NotificationManager.IMPORTANCE_HIGH);
NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
NotificationChannel channel = new NotificationChannel(channelId, "MyApp", NotificationManager.IMPORTANCE_DEFAULT);
if (notificationManager != null) {
notificationManager.createNotificationChannel(channel);
}
}
if (notificationManager != null) {
notificationManager.notify(id, notificationBuilder.build());
}
}
}
#adnandann's answer explains the reason indeed: you're sending a data message, while the Firebase console always sends a notification message (which is automatically displayed by the operation system).
So you have two options:
Display the data message yourself, which #adnandann's answer shows how to do.
Send a notification message from your PHP code, which you can do with:
$fields = array (
'to' => $device_id,
'notification' => array(
"title" => "New message from app",
"body" => $message
),
);
I'm trying to write an application to receive notifications via Firebase Cloud Messaging. It initially worked when I tried to send the message via the Firebase console, but then the moment I tried doing the same using PHP webservice, in response, it showed success, but I neither received the message nor am I able to get any more notifications via Firebase console. How can I fix this?
My code in the server side:
<?php
function send_notification ($tokens, $message)
{
$url = 'https://fcm.googleapis.com/fcm/send';
$fields = array(
'registration_ids' => $tokens,
'data' => $message
);
$headers = array(
'Authorization:key = AIzaSyDjrLKZGs4OcIgBPxpFnTzGeZHur4v9V8U',
'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_VERIFYHOST, 0);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($fields));
$result = curl_exec($ch);
if ($result === FALSE) {
die('Curl failed: ' . curl_error($ch));
}
curl_close($ch);
return $result;
}
$conn = mysqli_connect("localhost:3306", "minaaaa", "tt#2018", "dbSurvey");
$sql = "Select Token From users";
$result = mysqli_query($conn,$sql);
$tokens = array();
if(mysqli_num_rows($result) > 0 ){
while ($row = mysqli_fetch_assoc($result)) {
$tokens[] = $row["Token"];
}
}
mysqli_close($conn);
$message = array("message" => " FCM PUSH NOTIFICATION TEST MESSAGE");
$message_status = send_notification($tokens, $message);
echo $message_status;
?>
Code in Swift:
UIApplicationMain class AppDelegate: UIResponder, UIApplicationDelegate, MessagingDelegate, UNUserNotificationCenterDelegate {
var window: UIWindow?
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
// Override point for customization after application launch.
Util.copyFile(fileName: "db.zanjanwireFinal01.db")
//let alert = UIAlertController(title: title, message: message , preferredStyle: .alert)
UNUserNotificationCenter.current().requestAuthorization(options: [.alert,.sound,.badge]){(isGranted, err)
in
if err != nil {
}
else
{
UNUserNotificationCenter.current().delegate = self
Messaging.messaging().delegate = self
if let token = InstanceID.instanceID().token() {
print("DCS: " + token)
self.RegisterUsers(testStr: token)
}
DispatchQueue.main.async {
UIApplication.shared.registerForRemoteNotifications()
}
}
}
FirebaseApp.configure()
return true
}
func ConnectToFCM() {
Messaging.messaging().shouldEstablishDirectChannel = true
if let token = InstanceID.instanceID().token() {
print("DCS: " + token)
RegisterUsers(testStr: token)
}
}
func RegisterUsers(testStr:String){
let request = NSMutableURLRequest(url: NSURL(string:
request.httpMethod = "POST"
var dataString = "Token=\(testStr)"
print (dataString)
request.httpBody = dataString.data(using: String.Encoding.utf8)
let task = URLSession.shared.dataTask(with: request as URLRequest){
data, response, error in
if error != nil {
print("fffffffffatemeeeeeee")
print("error=\(error)")
return
}
print("response = \(response)")
let responseString = NSString(data: data!, encoding: String.Encoding.utf8.rawValue)
print("responseString = \(responseString)")
}
task.resume()
}
func applicationWillResignActive(_ application: UIApplication) {
// Sent when the application is about to move from active to
// inactive state. This can occur for certain types of
// temporary interruptions (such as an incoming phone call
// or SMS message) or when the user quits the application
// and it begins the transition to the background state.
// Use this method to pause ongoing tasks, disable timers,
// and invalidate graphics rendering callbacks. Games
// should use this method to pause the game.
}
func applicationDidEnterBackground(_ application: UIApplication) {
// Use this method to release shared resources, save user
// data, invalidate timers, and store enough application
// state information to restore your application to its
// current state in case it is terminated later.
// If your application supports background execution, this
// method is called instead of applicationWillTerminate:
// when the user quits.
//FirstMenueViewController().update()
Messaging.messaging().shouldEstablishDirectChannel = false
}
func applicationWillEnterForeground(_ application: UIApplication) {
FirstMenueViewController().update()
// Called as part of the transition from the background
// to the active state; here you can undo many of the
// changes made on entering the background.
ConnectToFCM()
}
func applicationDidBecomeActive(_ application: UIApplication) {
// Restart any tasks that were paused (or not yet started)
// while the application was inactive. If the application
// was previously in the background, optionally refresh
// the user interface.
}
func applicationWillTerminate(_ application: UIApplication) {
// Called when the application is about to terminate.
// Save data if appropriate. See also
// applicationDidEnterBackground:.
}
func messaging(_ messaging: Messaging, didRefreshRegistrationToken fcmToken: String) {
ConnectToFCM()
}
func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: #escaping (UNNotificationPresentationOptions) -> Void) {
UIApplication.shared.applicationIconBadgeNumber += 1
NotificationCenter.default.post(name: NSNotification.Name(rawValue: "com.DouglasDevlops.BadgeWasUpdated"), object: nil)
}
Structure your notification payload like this,
When I submit data through php file it is giving notification to registered phone but there is an empty message only no message content.Mostly tried all tutorial available online but not getting it.Please help.
Server Side Code:php file
<?php
$con = mysql_connect("localhost", "umane", "pass");
if(!$con){
die('MySQL connection failed');
}
$db = mysql_select_db("dbname");
if(!$db){
die('Database selection failed');
}
$registatoin_ids = array();
$sql = "SELECT * FROM tblname";
$result = mysql_query($sql, $con);
while($row = mysql_fetch_assoc($result)){
array_push($registatoin_ids, $row['registration_id']);
}
// Set POST variables
$url = 'https://android.googleapis.com/gcm/send';
$message = array("Notice" => $_POST['message']);
$fields = array(
'registration_ids' => $registatoin_ids,
'data' => $message,
);
$headers = array(
'Authorization: key= MY API KEY',
'Content-Type: application/json'
);
// Open connection
$ch = curl_init();
// Set the url, number of POST vars, POST data
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
// Disabling SSL Certificate support temporarly
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($fields));
// Execute post
$result = curl_exec($ch);
if ($result === FALSE) {
die('Curl failed: ' . curl_error($ch));
}
// Close connection
curl_close($ch);
echo $result;
?>
Android Code:
public class GcmSender {
public static final String API_KEY = "My API KEY";
public static void main(String[] args) {
if (args.length < 1 || args.length > 2 || args[0] == null) {
System.err.println("usage: ./gradlew run -Pmsg=\"MESSAGE\" [-Pto=\"DEVICE_TOKEN\"]");
System.err.println("");
System.err.println("Specify a test message to broadcast via GCM. If a device's GCM registration token is\n" +
"specified, the message will only be sent to that device. Otherwise, the message \n" +
"will be sent to all devices subscribed to the \"global\" topic.");
System.err.println("");
System.err.println("Example (Broadcast):\n" +
"On Windows: .\\gradlew.bat run -Pmsg=\"<Your_Message>\"\n" +
"On Linux/Mac: ./gradlew run -Pmsg=\"<Your_Message>\"");
System.err.println("");
System.err.println("Example (Unicast):\n" +
"On Windows: .\\gradlew.bat run -Pmsg=\"<Your_Message>\" -Pto=\"<Your_Token>\"\n" +
"On Linux/Mac: ./gradlew run -Pmsg=\"<Your_Message>\" -Pto=\"<Your_Token>\"");
System.exit(1);
}
try {
// Prepare JSON containing the GCM message content. What to send and where to send.
JSONObject jGcmData = new JSONObject();
JSONObject jData = new JSONObject();
jData.put("data", args[0].trim());
// Where to send GCM message.
if (args.length > 1 && args[1] != null) {
jGcmData.put("registration_ids", args[1].trim());
} else {
jGcmData.put("registration_ids", "/topics/global");
}
// What to send in GCM message.
jGcmData.put("data", jData);
// Create connection to send GCM Message request.
URL url = new URL("https://android.googleapis.com/gcm/send");
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestProperty("Authorization", "key=" + API_KEY);
conn.setRequestProperty("Content-Type", "application/json");
conn.setRequestMethod("POST");
conn.setDoOutput(true);
// Send GCM message content.
OutputStream outputStream = conn.getOutputStream();
outputStream.write(jGcmData.toString().getBytes());
// Read GCM response.
InputStream inputStream = conn.getInputStream();
String resp = IOUtils.toString(inputStream);
System.out.println(resp);
System.out.println("Check your device/emulator for notification or logcat for " +
"confirmation of the receipt of the GCM message.");
} catch (IOException e) {
System.out.println("Unable to send GCM message.");
System.out.println("Please ensure that API_KEY has been replaced by the server " +
"API key, and that the device's registration token is correct (if specified).");
e.printStackTrace();
}
}
}
Receiver Code
/**
* Copyright 2015 Google Inc. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package gcm.play.android.samples.com.gcmquickstart;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.media.RingtoneManager;
import android.net.Uri;
import android.os.Bundle;
import android.support.v4.app.NotificationCompat;
import android.util.Log;
import com.google.android.gms.gcm.GcmListenerService;
public class MyGcmListenerService extends GcmListenerService {
private static final String TAG = "MyGcmListenerService";
/**
* Called when message is received.
*
* #param from SenderID of the sender.
* #param data Data bundle containing message data as key/value pairs.
* For Set of keys use data.keySet().
*/
// [START receive_message]
#Override
public void onMessageReceived(String from, Bundle data) {
String message = data.getString("data");
Log.d(TAG, "From: " + from);
Log.d(TAG, "Message: " + message);
if (from.startsWith("/topics/")) {
// message received from some topic.
} else {
// normal downstream message.
}
// [START_EXCLUDE]
/**
* Production applications would usually process the message here.
* Eg: - Syncing with server.
* - Store message in local database.
* - Update UI.
*/
/**
* In some cases it may be useful to show a notification indicating to the user
* that a message was received.
*/
sendNotification(message);
// [END_EXCLUDE]
}
// [END receive_message]
/**
* Create and show a simple notification containing the received GCM message.
*
* #param message GCM message received.
*/
private void sendNotification(String message) {
Intent intent = new Intent(this, MainActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0 /* Request code */, intent,
PendingIntent.FLAG_ONE_SHOT);
Uri defaultSoundUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this)
.setSmallIcon(R.drawable.ic_stat_ic_notification)
.setContentTitle("E Protocol")
.setContentText(message)
.setAutoCancel(true)
.setSound(defaultSoundUri)
.setContentIntent(pendingIntent);
NotificationManager notificationManager =
(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(0 /* ID of notification */, notificationBuilder.build());
}
}
You are certain that it's retrieving the POST variable in your PHP code?
Try to replace this:
$message = array("Notice" => $_POST['message']);
with:
$message = array("Notice" => "testing");
Also in your receiver you are saying
String message = data.getString("data");
But you defined your data as "Notice" in the php code, so to retrieve the data you must say:
String message = data.getString("Notice");
I am working for a few days on an app which is based on real time communication between devices. In the past I was using GCM for notifications via POST methods using the OkHttp library. So far, so good.
But when it comes to real time communication I face a lot of issues around connection timeouts or even mesages which are never delivered.
My implementation is simple. First the user from his phone sends a request via POST and my online server to another phone (driver) which than confirms the request and replies back to the sender via another POST method and via the online server.
But only about 80% of the replies get back to the user, or they arrive after several minutes.
Can the problem be in my implementation?? Or should I switch to GCM Cloud Connection Server (XMPP)??
I am in serious need of some suggestions, please light me up.
Regards.
Php implementation:
<?php
include_once '../includes/db_connect.php';
// Query database for driver's regId
if(!empty($_POST["str"])) {
$sql = "SELECT * FROM DRIVERS WHERE NAME = '$_POST[driver]' " ;
$result = mysqli_query($mysqli, $sql);
$row = mysqli_fetch_assoc($result);
$gcmRegID = $row["REGID"];
$clientId = $_POST["clientId"];
$street = $_POST["str"];
$number = $_POST["nr"];
$bloc = $_POST["bl"];
$scara = $_POST["sc"];
if (isset($gcmRegID)) {
$gcmRegIds = array($gcmRegID);
$message = array("jstr" => $street, "jnr" => $number, "jbl" => $bloc, "jsc" => $scara, "jId" => $clientId);
$pushStatus = sendPushNotificationToGCM($gcmRegIds, $message);
}
}
// Reply to the client if available or not
if(!empty($_POST["response"])) {
$gcmRegID = $_POST["clientId"];
$response = $_POST["response"];
$gcmRegIds = array($gcmRegID);
$message = array("jresp" => $response);
$pushStatus = sendPushNotificationToGCM($gcmRegIds, $message);
}
//generic php function to send GCM push notification
function sendPushNotificationToGCM($registatoin_ids, $message) {
//Google cloud messaging GCM-API url
$url = 'https://android.googleapis.com/gcm/send';
$fields = array(
'registration_ids' => $registatoin_ids,
'data' => $message
);
// Google Cloud Messaging GCM API Key
define("GOOGLE_API_KEY", "**************");
$headers = array(
'Authorization: key=' . GOOGLE_API_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_VERIFYHOST, 0);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($fields));
$result = curl_exec($ch);
if ($result === FALSE) {
die('Curl failed: ' . curl_error($ch));
}
curl_close($ch);
return $result;
}
?>
Order Activity - for sending request to the driver
public void callDriver (View view){
MySendTask send = new MySendTask();
send.execute();
Toast.makeText(getApplicationContext(), "Button Pressed :)",
Toast.LENGTH_SHORT).show();
}
private class MySendTask extends AsyncTask<String, String, String> {
#Override
protected void onPreExecute() {
progressb.setVisibility(View.VISIBLE);
}
#Override
protected String doInBackground(String... arg0) {
// TODO Auto-generated method stub
String str = streetName.getText().toString();
String nr = streetNr.getText().toString();
String bl = bloc.getText().toString();
String sc = scara.getText().toString();
SharedPreferences prefs = getSharedPreferences("Notification", MODE_PRIVATE);
String registrationId = prefs.getString(PROPERTY_REG_ID, "");
try {
OkHttpClient client = new OkHttpClient();
client.setConnectTimeout(10000, TimeUnit.MILLISECONDS);
RequestBody formBody = new FormEncodingBuilder()
.add("clientId", registrationId)
.add("driver", "Peter Bleul")
.add("str", str)
.add("nr", nr)
.add("bl", bl)
.add("sc", sc)
.build();
Request request = new Request.Builder()
.url("http://edmon.net/andr/index.php")
.post(formBody)
.build();
Response response = client.newCall(request).execute();
if (!response.isSuccessful()) throw new IOException("Unexpected code " + response);
System.out.println(response.body().string());
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(String result) {
Toast.makeText(getApplicationContext(), "Order successfully sent!",
Toast.LENGTH_SHORT).show();
progressb.setVisibility(View.INVISIBLE);
}
}
}
GCM does not guarantee message delivery. GCM also throttles message delivery which can often result in significant delays. For more details on this topic see: http://developer.android.com/google/gcm/adv.html (goto the "Lifetime of a Message" section").
I have experienced issues similar to yours in the app I work on.
Thus it does not seem that GCM is a good candidate for real-time communication.
I have found an excellent example, with great sample applications explaining the process wonderfully, thanks to: Antoine Cambell
I reccomend it for everyone seaking answers for a simmilar application.
I am trying to implement Google Cloud Messaging in my app. Still i can't figure out why i don't get the correct message to my phone. My server sends a message, GCM servers respond to to that and send a message back to my phone.This message looks like this
{\"multicast_id\":8186678237008516542,\"success\":1,\"failure\":0,\"canonical_ids\":0,\"results\":[{\"message_id\":\"0:1356727074650189%12aaaeccf9fd7ecd\"}]}"
I think that means that i get a message, the problem is my app only shows null value. I am using the Browser Api key right now and get these results, but I have tried to use server key(which theoretically is more suitable to my needs), but i get Error 401.
For receiving the message, i use a broadcast receiver
public void onReceive(Context context, Intent intent){
String newMessage = intent.getExtras().getString(EXTRA_MESSAGE);}
EXTRA_MESSAGE = message
This is the code i use in my server.
$fields = array(
'registration_ids' => $registatoin_ids,
'data' => $message,
);
$headers = array(
'Authorization: key=' . GOOGLE_API_KEY,
'Content-Type: application/json'
);
// Open connection
$ch = curl_init();
// Set the url, number of POST vars, POST data
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
// Disabling SSL Certificate support temporarly
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($fields));
Does anybody know what the problem might be??
I think your response string name mismatch, So please check your response string name. I have used it as "price" in my server side code and in my android side code.you can see it in below images.
File at server side : send_message.php
File at application side : GCMNotificationIntentService
public static final int NOTIFICATION_ID = 1;
private NotificationManager mNotificationManager;
NotificationCompat.Builder builder;
public GCMNotificationIntentService() {
super("GcmIntentService");
}
public static final String TAG = "GCMNotificationIntentService";
#Override
protected void onHandleIntent(Intent intent) {
Bundle extras = intent.getExtras();
GoogleCloudMessaging gcm = GoogleCloudMessaging.getInstance(this);
String messageType = gcm.getMessageType(intent);
if (!extras.isEmpty()) {
if (GoogleCloudMessaging.MESSAGE_TYPE_SEND_ERROR
.equals(messageType)) {
sendNotification("Send error: " + extras.toString());
} else if (GoogleCloudMessaging.MESSAGE_TYPE_DELETED
.equals(messageType)) {
sendNotification("Deleted messages on server: "
+ extras.toString());
} else if (GoogleCloudMessaging.MESSAGE_TYPE_MESSAGE
.equals(messageType)) {
for (int i = 0; i < 3; i++) {
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
}
}
sendNotification("Message Received from Google GCM Server: "
+ extras.get("price"));
}
}
GcmBroadcastReceiver.completeWakefulIntent(intent);
}
private void sendNotification(String msg) {
//Log.d(TAG, "Preparing to send notification...: " + msg);
mNotificationManager = (NotificationManager) this
.getSystemService(Context.NOTIFICATION_SERVICE);
PendingIntent contentIntent = PendingIntent.getActivity(this, 0,
new Intent(this, MainActivity.class), 0);
NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(
this).setSmallIcon(R.drawable.gcm_cloud)
.setContentTitle("GCM Notification")
.setStyle(new NotificationCompat.BigTextStyle().bigText(msg))
.setContentText(msg);
mBuilder.setContentIntent(contentIntent);
mNotificationManager.notify(NOTIFICATION_ID, mBuilder.build());
//Log.d(TAG, "Notification sent successfully.");
}
adjust your code from
'data' => $message,
to be something like this:
'&data.message=' => $message,
and your onMessage() method in GCMIntentService should be something like below:
protected void onMessage(Context ctx, Intent intent) {
// TODO Auto-generated method stub
String message =intent.getStringExtra("message");;
}