I'm trying to register my android app with GCM, I followed the instructions in this link in order to obtain an api key, I did what is written in numbers 1-7 but in step 8 I can't find
the Android Key section.
What should I do?
p.s.
When I try to register my device with gcm gcm.register(SENDER_ID) I get error saying service not available, are those to problems connected? or this error is something else? (I didn't write the server part of the application)
android manifest:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.appspot.smartgan"
android:versionCode="1"
android:versionName="1.0" >
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<permission
android:name="com.appspot.smartgan.permission.C2D_MESSAGE"
android:protectionLevel="signature" />
<uses-permission android:name="com.appspot.smartgan.permission.C2D_MESSAGE" />
<uses-sdk
android:minSdkVersion="16"
android:targetSdkVersion="19" />
<application
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/Theme.AppCompat.Light" >
<activity
android:name="com.appspot.smartgan.MainActivity"
android:label="#string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<receiver
android:name=".GcmBroadcastReceiver"
android:permission="com.google.android.c2dm.permission.SEND" >
<intent-filter>
<action android:name="com.google.android.c2dm.intent.RECEIVE" />
<category android:name="com.appspot.smartgan" />
</intent-filter>
</receiver>
<service android:name=".GcmIntentService" />
<meta-data
android:name="com.google.android.gms.version"
android:value="#integer/google_play_services_version" />
<activity
android:name="com.appspot.smartgan.LoginActivity"
android:label="#string/title_activity_login"
android:windowSoftInputMode="adjustResize|stateVisible" >
</activity>
<activity
android:name="com.appspot.smartgan.ChildActivity"
android:label="#string/title_activity_child" >
</activity>
</application>
</manifest>
registration code: (I used the code from an example Google published)
private void registerInBackground() {
new AsyncTask<Void, Void, String>() {
String str = "";
#Override
protected String doInBackground(Void... params) {
String message = "";
try {
if (gcm == null) {
gcm = GoogleCloudMessaging.getInstance(context);
}
regid = gcm.register(SENDER_ID);
message = "Device registered, registration ID=" + regid;
Log.d("SMARTGAN_PLAY", "register completed");
// send registration id to the server
sendRegistrationIdToServer();
// Persist the regID - no need to register again.
storeRegistrationId(context, regid);
} catch (IOException e) {
message = "Error:" + e.getMessage();
}
str = message;
return message;
}
#Override
protected void onPostExecute(String message) {
childrenTextView.setText(str);
}
}.execute(null, null, null);
}
You don't need an API Key in order to register to GCM. You only need a Sender ID (which is the Project ID of the Google API Project you created for your app). The API Key is only needed in the server side for sending GCM messages to your app.
The reason for getting service not available can be many things. You'll have to post your manifest and client registration code to get more help.
//Subtitute with your own project ID
String SENDER_ID = "46086692976";
See screenshot:
Related
I've configured Push notifications in Android for an app following all the instructions in:
https://github.com/ParsePlatform/Parse-Server/wiki/Push-Configuring-Clients
https://parseplatform.github.io/docs/android/guide/#push-notifications
But no matter what I do, the mobile phone I'm using can't seem to get any push notifications at all.
The same app is configured to receive the notifications on iOS and works perfectly.
These are the relevant bits in the Manifest:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.xxy.xxy">
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
<permission
android:name="com.xxy.xxy.permission.C2D_MESSAGE"
android:protectionLevel="signature" />
<uses-permission android:name="com.xxy.xxy.permission.C2D_MESSAGE" />
<application
android:name="com.xxy.xxy.MiXXYApplication"
android:allowBackup="true"
android:icon="#drawable/logoapp"
android:label="#string/app_name"
android:supportsRtl="true"
android:theme="#style/AppTheme">
<service android:name="com.parse.PushService" />
<receiver
android:name="com.parse.ParsePushBroadcastReceiver"
android:exported="false">
<intent-filter>
<action android:name="com.parse.push.intent.RECEIVE" />
<action android:name="com.parse.push.intent.DELETE" />
<action android:name="com.parse.push.intent.OPEN" />
</intent-filter>
</receiver>
<receiver
android:name="com.parse.GcmBroadcastReceiver"
android:permission="com.google.android.c2dm.permission.SEND">
<intent-filter>
<action android:name="com.google.android.c2dm.intent.RECEIVE" />
<action android:name="com.google.android.c2dm.intent.REGISTRATION" />
<category android:name="com.xxy.xxy" />
</intent-filter>
</receiver>
<meta-data
android:name="com.parse.push.gcm_sender_id"
android:value="id:123456789012" />
</application>
This is the Application class (with the AppID and Client Key replaced with the current value given by Back4App):
public class MiXXYApplication extends Application {
#Override
public void onCreate() {
super.onCreate();
Parse.setLogLevel(Parse.LOG_LEVEL_VERBOSE);
Parse.initialize(new Parse.Configuration.Builder(getApplicationContext())
.applicationId("back4App_AppID")
.clientKey("back4App_ClientKey")
.server("https://parseapi.back4app.com/")
.build()
);
}
}
These are the methods I call to register the installation (I can't do it on the Application class because I need the userId, after login)
public void enablePush(final String userId) {
ParseInstallation installation = ParseInstallation.getCurrentInstallation();
installation.put("GCMSenderId", "123456789012");
installation.put("userId", userId);
installation.saveInBackground(new SaveCallback() {
#Override
public void done(ParseException e) {
if (e == null) {
Log.i("push", "ok");
subscribe("");
subscribe(userId);
} else {
Log.i("push", "nok");
e.printStackTrace();
}
}
});
}
public void subscribe(String channel){
ParsePush.subscribeInBackground(channel, new SaveCallback() {
#Override
public void done(ParseException e) {
if (e == null) {
Log.i("Push", "subscribed");
} else {
Log.i("push", "nok");
e.printStackTrace();
}
}
});
}
This is the installation registry on the Parse DB:
ObjectID: l1tkO3YM2r
GCMSenderID: 123456789012
deviceToken: APA91bHeKnj...
localeIdentifier: en-US
badge: (undefined)
parseVersion: 1.13.1
ACL: Public Read + Write
appIdentifier: com.xxy.xxy
appName: appName
deviceType: android
channels: ["","CyTPw5xc4r"]
pushType: gcm
installationId: 8cf9c606-5a0e...
userId: CyTPw5xc4r
In the google developer console, the project number is 123456789012, I've created an API key and added the API key + the project number in the Back4App dashboard's Android Push Notification Settings.
The logcat in verbose mode is showing the following:
09-21 09:29:19.863 10721-10721/com.xxy.xxy V/com.parse.ManifestInfo: Using gcm for push.
09-21 09:29:19.884 10721-10885/com.xxy.xxy V/com.parse.CachedCurrentInstallationController: Successfully deserialized Installation object
09-21 09:29:19.899 10721-10886/com.xxy.xxy V/com.parse.GcmRegistrar: Sending GCM registration intent
09-21 09:29:29.782 10721-11340/com.xxy.xxy V/com.parse.GcmRegistrar: Received deviceToken <APA91bHeKnj...> from GCM.
For what I can tell, everything's good to go, but I'm not getting any notification in my phone.
Is there anything wrong with my setup?
Thanks!
Solved it!
The thing is that, instead of getting the Api key the way all the guides say, you should get it from https://developers.google.com/mobile/add.
It generated another API key and activated the service, and then, it worked.
We are putting together an Unity app that uses Amazon S3 and SNS SDKs. On their own they're working fine - with SNS only the app registers and receives notifications properly, with S3 we can download images and videos fine.
Combining the SDKs into one app is now causing problems and after hours I have found the line that's causing the crash:
GCM.cs
string regId = cls.CallStatic<string>("register",senderIds);
What's odd is that ADB logcat is giving no errors at this point but after putting a return before then after this call it is known this is where the app crashes. Strangely the push registration process continues in ADB while the "This app has crashed" message is being displayed up until it completes with success as if the app starts up properly...
The "register" function being called is in AWSUnityGCMWrapper.java
public static String register(final String senderIds) {
try {
if (senderIds == null) {
return "";
}
Activity activity = UnityPlayer.currentActivity;
GoogleCloudMessaging gcm = GoogleCloudMessaging.getInstance(activity);
String regId = gcm.register(senderIds);
storeRegistrationId(activity, regId);
return regId;
} catch (IOException e) {
Log.e(TAG, "failed to register the to gcm");
Log.e(TAG, "exception = " + e.getMessage());
}
return "";
}
Tried many configs for the AndroidManifest.xml with no luck, except that all seems to be working fine through logcat! The CallStatic returns properly and the process continues nonetheless until 'ok' is pressed on the crash popup...
Any idea why this call static function is causing this problem? Ask for more code samples if needed!
Edit: AndroidManifest.xml if it helps...
<?xml version="1.0" encoding="utf-8"?>
<manifest
xmlns:android="http://schemas.android.com/apk/res/android"
package="com.company.appname"
android:installLocation="preferExternal"
android:theme="#android:style/Theme.NoTitleBar"
android:versionCode="1"
android:versionName="1.0">
<uses-feature android:name="android.hardware.camera" />
<supports-screens
android:smallScreens="true"
android:normalScreens="true"
android:largeScreens="true"
android:xlargeScreens="true"
android:anyDensity="true"/>
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<!-- PUSH --><uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />
<!-- PUSH --><permission android:name="com.company.appname.permission.C2D_MESSAGE" android:protectionLevel="signature" />
<!-- PUSH --><uses-permission android:name="com.company.appname.permission.C2D_MESSAGE" />
<application
android:icon="#drawable/app_icon"
android:label="#string/app_name"
android:theme="#android:style/Theme.NoTitleBar.Fullscreen"
android:debuggable="false">
<activity android:name="com.unity3d.player.UnityPlayerNativeActivity"
android:label="#string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<meta-data android:name="unityplayer.UnityActivity" android:value="true" />
<meta-data android:name="unityplayer.ForwardNativeEventsToDalvik" android:value="false" />
</activity>
<activity android:name="com.unity3d.player.VideoPlayer"
android:label="#string/app_name"
android:screenOrientation="portrait"
android:configChanges="fontScale|keyboard|keyboardHidden|locale|mnc|mcc|navigation|orientation|screenLayout|screenSize|smallestScreenSize|uiMode|touchscreen">
</activity>
<!-- PUSH --><receiver
android:name="com.company.appname.GCMBroadcastReceiver"
android:permission="com.google.android.c2dm.permission.SEND" >
<intent-filter>
<action android:name="com.google.android.c2dm.intent.RECEIVE" />
<action android:name="com.google.android.c2dm.intent.REGISTRATION"/>
<category android:name="com.company.appname" />
</intent-filter>
</receiver>
<!-- PUSH --><service android:name="com.company.appname.GCMIntentService" />
<!--
To support devices using the TI S3D library for stereo mode we must
add the following library.
Devices that require this are: ODG X6
-->
<uses-library android:name="com.ti.s3d" android:required="false" />
<!--
To support the ODG R7 in stereo mode we must add the following library.
-->
<uses-library android:name="com.osterhoutgroup.api.ext" android:required="false" />
</application>
Edit - AWSUnityGCMWrapper.java Using AsyncTask
public static String register(final String senderIds) {
// Async Task
_regID = "0";
_done = false;
new RegTask().execute(senderIds);
while(!_done);
return _regID;
}
public static void storeRegistrationId(Context context, String regId) {
final SharedPreferences prefs = getGCMPreferences(context);
int appVersion = getAppVersion(context);
Log.i(TAG, "Saving regId on app version " + appVersion);
SharedPreferences.Editor editor = prefs.edit();
editor.putString(PROPERTY_REG_ID, regId);
editor.putInt(PROPERTY_APP_VERSION, appVersion);
editor.commit();
}
public static void setReg(String regID) {
_done = true;
_regID = regID;
}
public static String getReg() {
return _regID;
}
private static class RegTask extends AsyncTask<String, Void, String> {
String _regID;
public RegTask() {
super();
_regID = "0";
}
#Override
protected String doInBackground(String... params) {
Log.i(TAG, ">>> Registering With GCM Async Task... Sender: " + params[0]);
String senderIds = params[0];
try {
if (senderIds == null) {
//_regID = "0";
return "0";
}
Log.i(TAG, ">>> Trying Registration...");
Activity activity = UnityPlayer.currentActivity;
GoogleCloudMessaging gcm = GoogleCloudMessaging.getInstance(activity);
String regId = gcm.register(senderIds);
Log.i(TAG, ">>> New Registration ID: " + regId);
storeRegistrationId(activity, regId);
//_regID = regId;
return regId;
} catch (IOException e) {
Log.e(TAG, "failed to register the to gcm");
Log.e(TAG, "exception = " + e.getMessage());
}
//_regID = "0";
Log.i(TAG, ">>> Registering With GCM Async Task Done...");
return "0";
}
#Override
protected void onPostExecute(String result) {
setReg(result);
}
}
In Logcat
I/AWSUnityGCMWrapper(21896): >>> Registering With GCM Async Task... Sender: 750882817708
I/AWSUnityGCMWrapper(23338): >>> New Registration ID: APA91bHWev8CCsbso8JE5a28J...
I/AWSUnityGCMWrapper(21896): Saving regId on app version 1
The app still crashes immediately when the register button is pressed.
So, from our discussion in comments under your post, your code for registering for GCM should be run in UI thread. Namely, you should wrap your function in a runOnUiThread(), which you did by:
Creating a Runnable class
MyRunnable r = new MyRunnable(UnityPlayer.currentActivity, senderIds);
Running it like so:
UnityPlayer.currentActivity.runOnUiThread(r);
What it does is no longer crashing up, but coming up with a exception thrown (which is just called MAIN_THREAD in your logs).
What you should do is instead of just calling .register(...) in your runnable function call it on the background, for example in an AsyncTask:
private void registerBackground(final String senderId) {
new AsyncTask() {
#Override
protected String doInBackground(Void... params) {
String msg = "";
try {
GoogleCloudMessaging gcm = GoogleCloudMessaging.getInstance(UnityPlayer.currentActivity);
String regId = gcm.register(senderId);
storeRegistrationId(UnityPlayer.currentActivity, regId);
} catch (IOException ex) {
msg = "Error :" + ex.getMessage();
}
return msg;
}
#Override
protected void onPostExecute(String msg) {
// msg returned
}
}.execute(null, null, null);
This is because UI operations on android happen on the main thread, but networking has to be done in a background one.
Call this instead of your register function and let me know if that helped.
Edit:
Btw, you might want to listen for changes or wait for them in a proper way since I can see your static f-tion returns the string.
Edit2:
So after my advice you've moved it to a proper async task. But there is another problem of waiting for a result. To do that you can write something like this instead of a while:
Handler myHandler = new Handler() {
#Override
public void handleMessage(Message msg) {
switch (msg.what) {
case 0:
_done = true;
break;
default:
break;
}
}
};
also in your task's onPostExecute() call this
myHandler.sendEmptyMessage(0);
Then, instead of a while() in your function make a runnable or another simple waiter. But for now, you might want to test it with Thread.sleep(1000); inside a while to ease the load on UI.
So I decided to revert back to what I had originally and started stripping down the AndroidManifest.xml (lots of things in there from a colleague which seem to have been redundant). Using the following manifest seems to have solved the problem, there must have been something conflicting...
<?xml version="1.0" encoding="utf-8"?>
<manifest
xmlns:android="http://schemas.android.com/apk/res/android"
package="com.company.appname"
android:installLocation="preferExternal"
android:versionCode="1"
android:versionName="1.0">
<supports-screens
android:smallScreens="true"
android:normalScreens="true"
android:largeScreens="true"
android:xlargeScreens="true"
android:anyDensity="true"/>
<uses-sdk android:minSdkVersion="9" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<permission android:name="com.amazonaws.unity.permission.C2D_MESSAGE"
android:protectionLevel="signature" />
<uses-permission android:name="com.amazonaws.unity.permission.C2D_MESSAGE" />
<application
android:theme="#android:style/Theme.NoTitleBar"
android:icon="#drawable/app_icon"
android:label="#string/app_name"
android:debuggable="true">
<activity android:name="com.unity3d.player.UnityPlayerNativeActivity"
android:label="#string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
<category android:name="android.intent.category.LEANBACK_LAUNCHER" />
</intent-filter>
<meta-data android:name="unityplayer.UnityActivity" android:value="true" />
<meta-data android:name="unityplayer.ForwardNativeEventsToDalvik" android:value="false" />
</activity>
<receiver
android:name="com.company.appname.GCMBroadcastReceiver"
android:permission="com.google.android.c2dm.permission.SEND" >
<intent-filter>
<action android:name="com.google.android.c2dm.intent.RECEIVE" />
<action android:name="com.google.android.c2dm.intent.REGISTRATION"/>
<category android:name="com.company.appname" />
</intent-filter>
</receiver>
<service android:name="com.company.appname.GCMIntentService" />
I will do some tests today and try to find out exactly what part was causing the problem.
i am trying to add push notification to my app.. i have been following Ravi Tamada's blog for this http://www.androidhive.info/2012/10/android-push-notifications-using-google-cloud-messaging-gcm-php-and-mysql/
Incidentally i was able to get the individual project running with my sender id and registration id, all push notification worked perfectly.. the problem occurs when i try to implement this in my app.. when the project is being run, the app stops after CHECKING REGID = NULL
the app dose not crash.. it simply stops as intent does not occurs as the server dosn't respond
my bad.. i have multiple packages.. the services have the correct package name.. so does the category
so what s wrong with the app?? why is it not working?
this is my log cat for the app including pushnotifications
onReceive: com.google.android.c2dm.intent.REGISTRATION
GCM IntentService class: com.example.smss.GCMIntentService
V/GCMBaseIntentService(2959): Acquiring wakelock
This is my manifest. .
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.smss"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="18" />
<!-- GCM connects to Internet Services. -->
<uses-permission android:name="android.permission.INTERNET" />
<!-- GCM requires a Google account. -->
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
<!-- Keeps the processor from sleeping when a message is received. -->
<uses-permission android:name="android.permission.WAKE_LOCK" />
<!-- Creates a custom permission so only this app can receive its messages. -->
<permission
android:name="com.example.smss.permission.C2D_MESSAGE"
android:protectionLevel="signature" />
<uses-permission android:name="com.example.smss.permission.C2D_MESSAGE" />
<!-- This app has permission to register and receive data message. -->
<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />
<!-- Network State Permissions to detect Internet status -->
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<!-- Permission to vibrate -->
<uses-permission android:name="android.permission.VIBRATE" />
<application
android:allowBackup="true"
android:icon="#drawable/logo"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<activity
android:name="com.example.smss.MainActivity"
android:label="#string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<!-- Register Activity -->
<activity
android:name="com.quinoid.sms.pushnotifications.RegisterActivity"
android:label="#string/app_name" >
</activity>
<!-- Main Activity -->
<activity
android:name="com.quinoid.sms.pushnotifications.InitialActivity"
android:configChanges="orientation|keyboardHidden"
android:label="#string/app_name" >
</activity>
<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.example.smss" />
</intent-filter>
</receiver>
<service android:name="com.quinoid.sms.pushnotifications.GCMIntentService" />
</application>
This is my main class InitialActivity.class
public class InitialActivity extends Activity {
// label to display gcm messages
TextView lblMessage;
// Asyntask
AsyncTask<Void, Void, Void> mRegisterTask;
// Alert dialog manager
AlertDialogManager alert = new AlertDialogManager();
// Connection detector
ConnectionDetector cd;
public static String username;
public static String password;
public static String userid;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main1);
cd = new ConnectionDetector(getApplicationContext());
// Check if Internet present
if (!cd.isConnectingToInternet()) {
// Internet Connection is not present
alert.showAlertDialog(InitialActivity.this,
"Internet Connection Error",
"Please connect to working Internet connection", false);
// stop executing code by return
return;
}
// Getting name, email from intent
Intent i = getIntent();
username = i.getStringExtra("username");
password = i.getStringExtra("password");
userid = i.getStringExtra("userid");
// Make sure the device has the proper dependencies.
GCMRegistrar.checkDevice(this);
// Make sure the manifest was properly set - comment out this line
// while developing the app, then uncomment it when it's ready.
GCMRegistrar.checkManifest(this);
lblMessage = (TextView) findViewById(R.id.lblMessage);
registerReceiver(mHandleMessageReceiver, new IntentFilter(
DISPLAY_MESSAGE_ACTION));
// Get GCM registration id
final String regId = GCMRegistrar.getRegistrationId(this);
// Check if regid already presents
if (regId.equals("")) {
// Registration is not present, register now with GCM
GCMRegistrar.register(this, SENDER_ID);
lblMessage.append("inside first if condition where regid = null" + "\n\n");
} else {
// Device is already registered on GCM
if (GCMRegistrar.isRegisteredOnServer(this)) {
// Skips registration.
Toast.makeText(getApplicationContext(), "Already registered with GCM", Toast.LENGTH_LONG).show();
} else {
// Try to register again, but not in the UI thread.
// It's also necessary to cancel the thread onDestroy(),
// hence the use of AsyncTask instead of a raw thread.
lblMessage.append("inside 2nd if condition where regid != null and GCMRegistrar.isRegisteredOnServer(this) = false " + "\n");
final Context context = this;
mRegisterTask = new AsyncTask<Void, Void, Void>() {
#Override
protected Void doInBackground(Void... params) {
// Register on our server
// On server creates a new user
lblMessage.append("inside doinbackground" + "\n\n");
ServerUtilities.register(context, username, password, regId);
return null;
}
#Override
protected void onPostExecute(Void result) {
mRegisterTask = null;
}
};
mRegisterTask.execute(null, null, null);
}
}
}
/**
* Receiving push messages
* */
private final BroadcastReceiver mHandleMessageReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
lblMessage.append("inside BroadcastReceiver mHandleMessageReceiver " + "\n\n");
String newMessage = intent.getExtras().getString(EXTRA_MESSAGE);
// Waking up mobile if it is sleeping
WakeLocker.acquire(getApplicationContext());
/**
* Take appropriate action on this message
* depending upon your app requirement
* For now i am just displaying it on the screen
* */
// Showing received message
lblMessage.append(newMessage + "\n");
Toast.makeText(getApplicationContext(), "New Message: " + newMessage, Toast.LENGTH_LONG).show();
// Releasing wake lock
WakeLocker.release();
if(newMessage.equals("From Demo Server: successfully added device!"))
{
Intent myIntent = new Intent(InitialActivity.this,homepage.class);
myIntent.putExtra("userid", userid);
startActivity(myIntent);
}
}
};
#Override
protected void onDestroy() {
if (mRegisterTask != null) {
mRegisterTask.cancel(true);
}
try {
unregisterReceiver(mHandleMessageReceiver);
GCMRegistrar.onDestroy(this);
} catch (Exception e) {
Log.e("UnRegister Receiver Error", "> " + e.getMessage());
}
super.onDestroy();
}
}
my log cat!!!!
D/dalvikvm(2959): GC_FOR_ALLOC freed 62K, 18% free 8937K/10848K, paused 35ms, total 41ms
I/System.out(2959): the readerjava.io.BufferedReader#b24bf900
I/System.out(2959): value of login = {"Login":"Success","UserId":"3"}
I/ActivityManager(395): START u0 {cmp=com.example.smss/com.quinoid.sms.pushnotifications.InitialActivity (has extras)} from pid 2959
W/InputMethodManagerService(395): Window already focused, ignoring focus gain of: com.android.internal.view.IInputMethodClient$Stub$Proxy#b275fd28 attribute=null, token = android.os.BinderProxy#b22865e8
D/GCMRegistrar(2959): resetting backoff for com.example.smss
V/GCMRegistrar(2959): Registering app com.example.smss of senders 170214588075
I/Choreographer(2959): Skipped 115 frames! The application may be doing too much work on its main thread.
V/GCMBroadcastReceiver(2959): onReceive: com.google.android.c2dm.intent.REGISTRATION
V/GCMBroadcastReceiver(2959): GCM IntentService class: com.example.smss.GCMIntentService
V/GCMBaseIntentService(2959): Acquiring wakelock
W/ActivityManager(395): Unable to start service Intent { act=com.google.android.c2dm.intent.REGISTRATION flg=0x10 pkg=com.example.smss cmp=com.example.smss/.GCMIntentService (has extras) } U=0: not found
I/ActivityManager(395): Displayed com.example.smss/com.quinoid.sms.pushnotifications.InitialActivity: +3s309ms
seems that you have not implemented the GCMIntentService class correctly. do this in your AndroidManifest.xml:
<service android:name="com.example.smss.GCMIntentService" />
and also create the corresponding class in the correct package name. For the rest you can follow the tutorial..
hello there are so many code missing in Android menifest file see my below code and check your google-play service lib and metadata for that...
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.ex_gcmdemo"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="19" />
<permission android:name="com.example.ex_gcmdemo.permission.C2D_MESSAGE" android:protectionLevel="signature"></permission>
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.GET_ACCOUNTS"/>
<uses-permission android:name="android.permission.WAKE_LOCK"/>
<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />
<uses-permission android:name="com.example.ex_gcmdemo.permission.C2D_MESSAGE"/>
<application
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<activity
android:name="com.example.ex_gcmdemo.MainActivity"
android:label="#string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<receiver android:name="GcmBroadcastReceiver"
android:permission="com.google.android.c2dm.permission.SEND">
<intent-filter >
<action android:name="com.google.android.c2dm.intent.RECEIVE"/>
<category android:name="com.example.ex_gcmdemo"/>
</intent-filter>
</receiver>
<service android:name="GcmIntentService"></service>
<meta-data android:name="com.google.android.gms.version"
android:value="#integer/google_play_services_version" />
<activity android:name="HomePage"></activity>
</application>
</manifest>
I am not very experienced with Android development and I shall include gcm to an existing app.
So far, I can register all devices and I receive the registrationId. The problem is, that I never enter the onMessage() method on my Android 4.0 device. I also tried it with a Galaxy Note 2 (Android 4.1) and there I can receive the message.
I don't get any error message, I just never enter onMessage().
When I send the message, I always get an messageId, so gcm "accepted" the message. But it is never delivered to the device.
How can I find out what the problem is??? Thanks in advance
GCMIntentService.java
public class GCMIntentService extends GCMBaseIntentService {
public GCMIntentService() {
super("82........");
}
#Override
protected void onError(Context arg0, String error) {
System.out.println("Not able to register or unregister because: "
+ error);
}
#Override
protected void onMessage(Context context, Intent intent) {
String message = intent.getStringExtra("message");
System.out.println("GCM DELIVERED MESSAGE TO DEVICE:" + message);
}
#Override
protected void onRegistered(Context arg0, String regId) {
System.out.println("Device is registered with RegisterId: " + regId);
}
#Override
protected void onUnregistered(Context arg0, String regId) {
System.out.println("Device with RegisterId: " + regId
+ " has unregistered");
}
#Override
protected boolean onRecoverableError(Context context, String errorId) {
System.out.println("Entered onRecoverableError");
return super.onRecoverableError(context, errorId);
}
}
My Manifest.xml
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.activities"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="15" />
<uses-permission android:name="android.permission.READ_CONTACTS" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<permission
android:name="com.example.activities.permission.C2D_MESSAGE"
android:protectionLevel="signature" />
<uses-permission android:name="com.example.activities.permission.C2D_MESSAGE" />
<!-- App receives GCM messages. -->
<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />
<!-- GCM connects to Google Services. -->
<uses-permission android:name="android.permission.INTERNET" />
<!-- GCM requires a Google account. -->
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
<!-- Keeps the processor from sleeping when a message is received. -->
<uses-permission android:name="android.permission.WAKE_LOCK" />
<application
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<!-- Activity which is called first to decide which Activity comes next -->
<activity
android:name=".StartUp"
android:label="#string/title_activity_start_up" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name=".Login"
android:label="#string/title_activity_login" >
</activity>
<activity
android:name=".DisplayContent"
android:label="#string/title_activity_display_content" >
</activity>
<activity
android:name=".AllSigns"
android:label="#string/title_activity_all_signs" >
</activity>
<receiver
android:name="com.google.android.gcm.GCMBroadcastReceiver"
android:permission="com.google.android.c2dm.permission.SEND" >
<intent-filter>
<action android:name="com.google.android.c2dm.intent.RECEIVE" />
<action android:name="com.google.android.c2dm.intent.REGISTRATION" />
<category android:name="com.example.activities" />
</intent-filter>
</receiver>
<service android:name=".GCMIntentService" />
</application>
Code in onCreate() of my first activity (Startup.java)
GCMRegistrar.checkDevice(this);
GCMRegistrar.checkManifest(this);
final String regId = GCMRegistrar.getRegistrationId(this);
if (regId.equals("")) {
System.out.println("Id ist leer, Device wird neu registriert");
GCMRegistrar.register(this, "825134311331");
} else {
System.out.println("This device is already registered");
}
If you are trying this over WIFI, make sure that port 5228 isn't being blocked by the network. That's how I fixed the problem that I had after more days of trying to get it to work than I'd like to admit.
Make sure the GCMIntentService class is in the package specified in your manifest
I have a important delivery, i hope you can help me.
I have to use GCM.
I am using the file in the official guide in http://developer.android.com/guide/google/gcm/demo.html
I did "Setting Up the Server Using App Engine for Java" and it work.
My problem is the android application .Exactly I don't recive the id from GCM and so anytime my application try the registration.
Thanks a lot....
public class DemoActivity extends Activity {
TextView mDisplay;
AsyncTask<Void, Void, Void> mRegisterTask;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
checkNotNull(SERVER_URL, "SERVER_URL");
checkNotNull(SENDER_ID, "SENDER_ID");
// Make sure the device has the proper dependencies.
GCMRegistrar.checkDevice(this);
// Make sure the manifest was properly set - comment out this line
// while developing the app, then uncomment it when it's ready.
GCMRegistrar.checkManifest(this);
setContentView(R.layout.main);
mDisplay = (TextView) findViewById(R.id.display);
registerReceiver(mHandleMessageReceiver,
new IntentFilter(DISPLAY_MESSAGE_ACTION));
final String regId = GCMRegistrar.getRegistrationId(this);
if (regId.equals("")) {
// Automatically registers application on startup.
GCMRegistrar.register(this, SENDER_ID);
} else {
....
}
CommonUtilities
public final class CommonUtilities
{
static final String SERVER_URL = "http://127.0.0.1:8888/gcmdemo4/home";
static final String SENDER_ID = "843761346XXX";
...
}
GCMIntentService
public class GCMIntentService extends GCMBaseIntentService {
#SuppressWarnings("hiding")
private static final String TAG = "GCMIntentService";
public GCMIntentService() {
super(SENDER_ID);
}
#Override
public void onRegistered(Context context, String registrationId) {
Log.i(TAG, "Device registered: regId = " + registrationId);
displayMessage(context, getString(R.string.gcm_registered));
ServerUtilities.register(context, registrationId);
}
.....
MY manifest
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.registrazionegcm"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="16" />
<permission
android:name="com.example.registrazionegcm.permission.C2D_MESSAGE"
android:protectionLevel="signature" />
<uses-permission android:name="com.example.registrazionegcm.permission.C2D_MESSAGE" />
<!-- App receives GCM messages. -->
<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />
<!-- GCM connects to Google Services. -->
<uses-permission android:name="android.permission.INTERNET" />
<!-- GCM requires a Google account. -->
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
<!-- Keeps the processor from sleeping when a message is received. -->
<uses-permission android:name="android.permission.WAKE_LOCK" />
<application
android:icon="#drawable/ic_launcher"
android:label="#string/app_name" >
<activity
android:name="DemoActivity"
android:label="#string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<receiver
android:name="com.google.android.gcm.GCMBroadcastReceiver"
android:permission="com.google.android.c2dm.permission.SEND" >
<intent-filter>
<action android:name="com.google.android.c2dm.intent.RECEIVE" />
<action android:name="com.google.android.c2dm.intent.REGISTRATION" />
<category android:name="com.example.registrazionegcm" />
</intent-filter>
</receiver>
<service android:name=".GCMIntentService" />
</application>
could you supply your code of "registerReceiver".
I had the same problem, when my SENDER_ID was wrong.
Try to check it again, and check your package too: com.example.registrazionegcm.GCMIntentService
Put some breakpoint in onError and onRegistered
For me, this code works:
#Override
public void run() {
GCMRegistrar.checkDevice(mContext);
GCMRegistrar.checkManifest(mContext);
String deviceToken = GCMRegistrar.getRegistrationId(mContext);
if (deviceToken.equals("")) {
GCMRegistrar.register(mContext, "XXXXXXXXXXXXXXX");
deviceToken = GCMRegistrar.getRegistrationId(mContext);
if(!deviceToken.equals("")){
GCMRegistrar.setRegisteredOnServer(mContext, true);
// register deviceToken on CommNotes srv
RequestMaker req = new RequestMaker(Constant.REQ_REGISTER_GCM, mContext);
//if unsuccessful, try again 5 times
for(int i = 0; i<5; i++){
Log.d("ComNotes", "registration id"+deviceToken);
if(req.doRequest(deviceToken) == ReturnCode.CODE_OK){
break;
}
}
}
//TODO manage unsuccess: display error : "No PUSH available"
} else {
Log.v("CommunityNotes", "Already registered "+deviceToken);
}
}