Looking at all possible solution for C2dm Android Push Notification on various communities ,i would like to contribute best approach which i have been successfully able to implement .
1. I have used Titanium 1.7.5 and 1.8.0.1 earlier ,which don't work and give various errors,which are due to deprecated methods and absence of libraries used in C2dm,i would suggest either to add those libraries in you project by creating a lib folder ,else directly use 1.8.2(best SDK version) and create an empty lib folder.So execute command below in ur MAC Terminal,an alias will be created for ur SDK. alias titanium="Library/Application\ Support/Titanium/mobilesdk/osx/1.8.2/titanium.py". You can check if it is created by using following Command, cd Titanium This will give you Appcelerator Titanium Copyright (c) 2010-2011 by Appcelerator, Inc.
commands:
create - create a project run - run an existing project emulator - start the emulator (android) docgen - generate html docs for a module (android) fastdev - management for the Android fastdev server help - get help
2.Now create a module from your project,by using common below, (Your_root)$ titanium create --platform=android --type=module --name=c2dmmod --id=com.Yourcompany.c2dmmod --android=Documents/android-sdk-mac_x86.
3.Once your module is created in your root directory,u need to change build.properties based on path your machine uses,my machine uses following
titanium.platform=/Users/Yourpath/Library/Application Support/Titanium/mobilesdk/osx/1.8.2/android android.platform=/Users/Yourpath/Documents/android-sdk-mac_x86/platforms/android-8 google.apis=/Users/Yourpath/Documents/android-sdk-mac_x86/add-ons/addon-google_apis-google_inc_-8 android.ndk=/Users/Yourpath/Documents/android-ndk-r7b
Make sure to have ndk,addon-google_apis-google_inc_-8 on ur machine and give respective paths.
4.Download https://github.com/Kuraturpa/titanium-c2dm ,we just need src folder from here replace Source folder of your module with src folder of newly downloaded project from link above.
5.Now we are set with Module which has your build properties(as per your machine),src replaced,wince they have find law and google code which help us execute c2dm.
6.We have to build ant for newly created module,add an empty folder called lib in your module if it doesn't exists.
7.Now before running ant command get into your module directory ,in our case we have created a c2dm module called c2dmmod, so my terminal would look something like (Your_root)-Mac-mini-6:c2dmmod Yourroot$ ant
just get into module's directory and run ant.
8.Once you run ant if every thing is perfect you will get a message saying Build Successful message .Now you will find a new folder called dist(Distribution) has been created in to your module project,with a jar and a zip file of your project(This zip is what we are going to use in our Titanium Project).
9.Now get back into your project where you want to use C2dm and do following
a. Add zip of your Module project to this Titanium Project at Root level,at the same level as tiapp.xml. In our case for module create zip file will be com.findlaw.c2dmmod-android-0.1.zip.
b. In your tiapp.xml add,following
<android xmlns:android="http://schemas.android.com/apk/res/android">
<manifest>
<permission
android:name="Your_Appid.permission.C2D_MESSAGE" android:protectionLevel="signature"/>
<uses-permission android:name="com.yourcompany.newbuildc2dm.permission.C2D_MESSAGE"/>
<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE"/>
<uses-permission android:name="android.permission.WAKE_LOCK"/>
<uses-permission android:name="android.permission.VIBRATE"/>
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.GET_ACCOUNTS"/>
<uses-permission android:name="android.permission.USE_CREDENTIALS"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<application>
<service android:name="com.findlaw.c2dm.C2DMReceiver"/>
<receiver
android:name="com.google.android.c2dm.C2DMBroadcastReceiver" android:permission="com.google.android.c2dm.permission.SEND">
<intent-filter>
<action android:name="com.google.android.c2dm.intent.RECEIVE"/>
<category android:name="Your_Appid"/>
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED"/>
<category android:name="android.intent.category.HOME"/>
</intent-filter>
<intent-filter>
<action android:name="com.google.android.c2dm.intent.REGISTRATION"/>
<category android:name="Your_Appid"/>
</intent-filter>
</receiver>
</application>
</manifest>
</android>
<modules>
<module platform="android" version="0.1">Your Module id</module>
</modules>
com.findlaw.c2dmmod in module being your module name.
c. Register for c2dm at http://code.google.com/android/c2dm/signup.html.
D. From downloaded example of https://github.com/Kuraturpa/titanium-c2dm,you can use same app.js file in your Titanium project,replace var senderId = 'Your registered Gmail id'; var c2dm = require('Your module name);
e. Change Class name and package name based on your project settings className: 'Your_Appid.YourActivity_name' (Your Activity name can be found at YourProject/Build/Android/Gen/Your module/Activity.java(Activity name would be based on your project id,just pick name of file with name as activity,don't copy .java just name is enough). packageName: 'Your App_id'(Can be seem in tiapp.xml).
10.Once you run this project as per steps above you will receive a Device id from Google,which we will use in our Server Call.This need to be passed to server 11.Once your done this ,we need to execute php service from Server end,following is code which you will need to execute,
<?php /* * * $username - your gmail email address you white listed with the c2dm service * $password - password for above gmail account. */
function googleAuthenticate($username, $password, $source="Company-AppName-Version", $service="ac2dm") {
@session_start();
if( isset($_SESSION['google_auth_id']) && $_SESSION['google_auth_id'] != null)
return $_SESSION['google_auth_id'];
// get an authorization token
$ch = curl_init();
if(!$ch){
return '';
}
curl_setopt($ch, CURLOPT_URL, "https://www.google.com/accounts/ClientLogin");
$post_fields = "accountType=" . urlencode('HOSTED_OR_GOOGLE')
. "&Email=" . urlencode($username)
. "&Passwd=" . urlencode($password)
. "&source=" . urlencode($source)
. "&service=" . urlencode($service);
curl_setopt($ch, CURLOPT_HEADER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $post_fields);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_FRESH_CONNECT, true);
curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_ANY);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
// for debugging the request
//curl_setopt($ch, CURLINFO_HEADER_OUT, true); // for debugging the request
$response = curl_exec($ch);
//echo $response;
//var_dump(curl_getinfo($ch)); //for debugging the request
//var_dump($response);
curl_close($ch);
if (strpos($response, '200 OK') === false) {
echo "200 Not Ok";
return '';
}
// find the auth code
preg_match("/(Auth=)([\w|-]+)/", $response, $matches);
if (!$matches[2]) {
echo "No Match";
return '';
}
$_SESSION['google_auth_id'] = $matches[2];
return $matches[2];
//return true;
}
/* * * $authCode - the authcode returned when you ran the googleAuthenticate function * $deviceRegistrationId - registrationID returned by the device receiving the message * $$msgType - can be anything i.e. 'chat message' * $messageText - text to be sent */
function sendMessageToPhone($authCode, $deviceRegistrationId, $msgType, $messageText) {
$headers = array('Authorization: GoogleLogin auth=' . $authCode);
$data = array(
'registration_id' => $deviceRegistrationId,
'collapse_key' => $msgType,
'data.message' => $messageText //TODO Add more params with just simple data instead
);
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "https://android.apis.google.com/c2dm/send");
if ($headers)
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
$response = curl_exec($ch);
curl_close($ch);
echo $response;
//var_dump($response);
}
$msgType = 'chat message111'; $message = 'Friend Request111!';
$regID='Your Device regestration ID';
$auth = googleAuthenticate("Your Registered Email Id","Yourmessage","Your Titanium project's App ID"); sendMessageToPhone($auth, $regID, $msgType, $message);
?>
12.Once you run this from server you will get Notification on your device ,which while have message as sent,this will redirect you to your app when clicked.
13.I have checked all possible solutions,and finally been able to get Notifications following steps above. I would suggest to use 1.8.2 SDK,1.8.0.1 has many bugs hence i would't advice you that.
14.Thanks all communities which have inspired me to write this and given me a strong urge to share what we receive.
Thanks for such a great guide; however when I run the first command (creating the project) I get the following:
ReplyDeletepc229139:~ administrator$ titanium create --platform=android --type=module --name=c2dmcumobile --id=edu.cedarville.cd2cumobile --android=/Users/administrator/android-sdks/
[ERROR] Couldn't find the Google APIs r8 add-on directory
Aborting
hey my friend i cant find this directory
ReplyDeleteLibrary/Application\ Support/Titanium/mobilesdk/osx/1.8.2/titanium.py
since i searched on titanium.py and i didn't find it :S
Note: i'm working on mac
It shoudl be there, inf act inside any of the sdks. You could repeat this procedure with the 2.0.1GA2 and obtain the same results. (I had to do this in order to use the module with the new Ti 2.0 SDK)
Delete@Abraham in case of "Couldn't find the Google APIs r8 add-on directory",u have to download that in ur android folders
ReplyDeleteActually; I had the Google API SDK already, however I had to rename the folder to whatever Titanium was looking for.
Delete@ramzi,dude its the lastest version of titanium u hav to download that API
ReplyDeleteI can build the module and require it, but I get this error: Object #C2dmmod has no method 'registerC2dm'.
ReplyDeleteI've looked at the C2dmModule.java file and registerC2dm is defined as public void registerC2dm(String senderId, HashMap options), so everything should work fine.
It looks like my module isn't aware of this source code. Do you have any idea what's going on?
That method should be in this project please check https://github.com/Kuraturpa/titanium-c2dm,download that
ReplyDeleteThis comment has been removed by the author.
ReplyDeleteOk, I got it to work by making sure my module name is exactly "com.findlaw.c2dm". The problem was I called my module something else.
ReplyDeleteSo now I'm getting permission problems:
Permission Denial: receiving Intent { act=com.google.android.c2dm.intent.REGISTRATION cat=[com.mytest.myproject] (has extras) } to com.mytest.myproject requires com.mytest.myproject.permission.C2D_MESSAGE due to sender com.google.android.gsf (uid 10023)
But I'm sure I'll figure that by Googling around. Thanks for a very detailed and helpful post! :)
Figured out the permission problem. If anyone is having the same issue, please note that in the manifest example above (tiapp.xml), this line:
ReplyDeletecom.sagarsoft.newbuildc2dm.permission.C2D_MESSAGE
should really be:
Your_Appid.permission.C2D_MESSAGE
Perhaps obvious, but I managed to overlook it nevertheless.
Great work by my buddy bushan :)
ReplyDeleteFirst of all thanks for this guide. I was able to implement a c2dm modul. The registration was successful and i could receive Push Notifications, but only when the app was running. When the app is closed, it not works.
ReplyDeleteOn both engines i can see in ddms that the module receives the messege.
On V8 the logcat stops with:
"Runtime disposed, cannot call function."
And on Rhino the module is able to start the Callback Funktion in the app and breaks on creating Intent with:
"Activity is null or already finishing, skipping dialog."
Have somebody an idea what's wrong?
@Alex I think you have to create a android service that will run even your app is closed. Write your Logic in that service so that the service takes care of your app's push notification when your app is closed.
ReplyDeleteThanks for your answer, but it not solves the problem. With background service it shows the same behavior.
Deletecan any one tell me how to pass my registration iD to the server. I know its a lame question- new to it
ReplyDeleteThere is an example in the Appcelerator Wiki:
Deletehttps://wiki.appcelerator.org/display/guides/Working+with+JSON+Data
Thanks for the post Bhushan...I have a problem when i am replacing src folder..it gives me error that no register method found.when i am creating module first time then it's working fine.
ReplyDeleteso if possible then can you please share the code ??
@Sarfaraz,Make sure you are using https://github.com/Kuraturpa/titanium-c2dm ,since this download gives you method called "c2dm.register",which is present in its app.js file,i think u r missing that js file
ReplyDeleteHi which path to give in the --android="" in the create command. Because my android SDK is in the path /users/myname/.eclipse and whatever path I gave in --android field it shaows like no android sdk-8 even though I am having it in the same path.
ReplyDeleteHi Niv,please chk point number 3 above
ReplyDeletethat point only I am not understanding. Can I create the module anywhere in the root directory?
ReplyDeleteIf so I tried to give the path /users/myuser
but it shows the same error as I mentioned above
my path in terminal is like this Niv-MacBook:~ awsuser006$ titanium create --platform=android --type=module --name=c2dmmod --id=com.Yourcompany.c2dmmod --android=Users/awsuser006
ReplyDeleteand its showing exception like no android sdk-8.
But I am having it in Niv-MacBook:~ awsuser006$ cd .eclipse/platforms/android-8. Please reply me where should I create it.
Looks like its unable to find ur Android,i would suggest you to download sdk at above mentioned path and try using it.Keep the existing eclipse related android same place,but download new at a common place say above mentioned path.
ReplyDeleteNice post with great details. I really appreciate your job. desktop notification software
ReplyDeleteThanks hope it helped you :)
ReplyDelete