Mail Account For C2DM Registration - android

I am using C2DM for "Push Notification" on Android. Every thing is okay.
My question is; can I get "if device has more than synchronized gmail accounts, which one is used for C2DM"?

Refer this link for C2DM and sample at this LINK. Now you device think where it is related to device.
In the below code the email id use is not device specific. C2DM uses email id just for interaction between server and C2DM not depending on device.
// Call when your application start
public void StartRegistrationNotification()
{
Intent registrationIntent = new Intent("com.google.android.c2dm.intent.REGISTER");
registrationIntent.putExtra("app", PendingIntent.getBroadcast(this, 0, new Intent(), 0));
registrationIntent.putExtra("sender", "....#gmail.com");
this.startService(registrationIntent);
}
// change in Manifest File
<receiver android:name="com.ReceiverC2DM"
android:permission="com.google.android.c2dm.permission.SEND">
<!-- Receive the actual message -->
<intent-filter>
<action android:name="com.google.android.c2dm.intent.RECEIVE" />
<category android:name="yourpackagename" />
</intent-filter>
<!-- Receive the registration id -->
<intent-filter>
<action android:name="com.google.android.c2dm.intent.REGISTRATION" />
<category android:name="yourpackagename" />
</intent-filter>
</receiver>
<permission android:name="yourpackagename.permission.C2D_MESSAGE"
android:protectionLevel="signature" />
<uses-permission android:name="yourpackagename.permission.C2D_MESSAGE" />
<!-- This app has permission to register and receive message -->
<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />

Related

Firebase Notification broke server notifications

I have made the switch from GCM to FCM in my android app. But I have not touched the server portion of the code since supposedly I don’t have to. But now, when server sends a notification, my device is no longer seeing it. So did I misunderstand the following?
https://developers.google.com/cloud-messaging/android/android-migrate-fcm#update_server_endpoints
Updating these endpoints is not strictly required, as Google will
continue to support the existing GCM endpoints.
MANIFEST
<!-- for notifications -->
<!--<uses-permission android:name="android.permission.WAKE_LOCK"/>-->
<!--<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE"/>-->
<!--<uses-permission android:name="com.business.myapp.android.permission.C2D_MESSAGE"/>-->
…
<application …>
…
<!-- START GCM SECTION -->
<!--<receiver-->
<!--android:name="com.google.android.gms.gcm.GcmReceiver"-->
<!--android:exported="true"-->
<!--android:permission="com.google.android.c2dm.permission.SEND">-->
<!--<intent-filter>-->
<!--<action android:name="com.google.android.c2dm.intent.RECEIVE"/>-->
<!--<category android:name="com.business.myapp"/>-->
<!--</intent-filter>-->
<!--</receiver>-->
<service
android:name=".data.service.notification.BusinessGcmListenerService"
android:exported="false">
<intent-filter>
<action android:name="com.google.firebase.MESSAGING_EVENT"/>
</intent-filter>
</service>
<service
android:name=".data.service.notification.BusinessInstanceIDListenerService">
<intent-filter>
<action android:name="com.google.firebase.INSTANCE_ID_EVENT"/>
</intent-filter>
</service>
<service
android:name=".data.service.notification.RegistrationIntentService"
android:exported="false">
<intent-filter>
<action android:name="com.google.android.c2dm.intent.RECEIVE"/>
</intent-filter>
</service>
<!-- END GCM SECTION -->
Note that when I send notification from the Firebase Console it comes through: if the app is in the foreground, it goes through onMessageReceived; otherwise, I just get a notification in status bar. Basically I follow the instructions on the link provided.
Here is onTokenRefresh
#Override
public void onTokenRefresh() {
Intent intent = new Intent(this, RegistrationIntentService.class);
startService(intent);//intent service to send token to my server
}
Do you change your json-service.json of on root /app of on application ?

Android Urban Airship 6.0.1, not able to intercept push notification actions

I am extending BaseIntentReceiver into a new class PushIntentReceiver, intended to take different actions from the key/value pairs within push notification objects.
Although my push notifications display correctly, PushIntentReceiver never gets called. Therefore clicking a notification seems to do nothing. Every method has a log tag inside of it, such as
#Override
protected void onBackgroundPushReceived(Context context, PushMessage message) {
Log.i(TAG, "Received background push message: " + message);
}
but none of this appears in LogCat. Whether it is the registration method, or the notification clicked method or anything. Similarly my breakpoints do not get hit in these functions.
Why is this? I’ve included the relevant parts of my AndroidManifest. The previous version of UrbanAirship that was in this app was the version where Amazon UA was split from Android UA when you guys first created the Amazon UA. So I don’t know if that was Android UA 5.0 or 4.x , but my Push Notification interception via BroadcastReceivers did work in that old version of the library. Now everything has been restructured to the UA 5.1.x+ ways and I can’t get it to work.
Insight appreciated
This is the relevant portion of my AndroidManifest.xml
<!-- REQUIRED for Urban Airship -->
<service
android:name="com.urbanairship.push.PushService"
android:label="Push Notification Service" />
<!-- Required for analytics -->
<service
android:name="com.urbanairship.analytics.EventService"
android:label="Event Service" />
<!-- Required for Actions -->
<service android:name="com.urbanairship.actions.ActionService" />
<!-- Required for Rich Push -->
<service android:name="com.urbanairship.richpush.RichPushUpdateService" />
<!-- OPTIONAL for Urban Airship Location (for segments support) -->
<service
android:name="com.urbanairship.location.LocationService"
android:label="Segments Service" />
<!-- This is required for persisting preferences related to push and location -->
<!-- MODIFICATION REQUIRED - Replace PACKAGE_NAME with your package name -->
<provider
android:name="com.urbanairship.UrbanAirshipProvider"
android:authorities="com.myapp.app.urbanairship.provider"
android:exported="true"
android:multiprocess="true"
android:permission="com.myapp.app.permission.UA_DATA" />
<!-- OPTIONAL, if you want to receive push, push opened and registration completed intents -->
<!-- Replace the receiver below with your package and class name -->
<receiver
android:name="com.myapp.app.controllers.push.PushIntentReceiver"
android:exported="false">
<intent-filter>
<action android:name="com.urbanairship.push.CHANNEL_UPDATED" />
<action android:name="com.urbanairship.push.OPENED" />
<action android:name="com.urbanairship.push.RECEIVED" />
<action android:name="com.urbanairship.push.DISMISSED" />
<category android:name="com.myapp.app" />
</intent-filter>
</receiver>
<receiver android:name="com.urbanairship.CoreReceiver"
android:exported="false">
<intent-filter android:priority="-999">
<action android:name="com.urbanairship.push.OPENED" />
<!-- MODIFICATION REQUIRED - Use your package name as the category -->
<category android:name="com.myapp.app" />
</intent-filter>
</receiver>
<!-- REQUIRED for PlayServiceUtils.handleAnyPlayServicesError to handle Google Play Services recoverable errors. -->
<activity
android:name="com.urbanairship.google.PlayServicesErrorActivity"
android:theme="#android:style/Theme.Translucent.NoTitleBar" />
<!-- REQUIRED for GCM -->
<receiver
android:name="com.urbanairship.push.GCMPushReceiver"
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" />
<!-- MODIFICATION REQUIRED - Use your package name as the category -->
<category android:name="com.myapp.app" />
</intent-filter>
</receiver>
<!-- end Urban Airship tags -->
Problems like these usually happen when the intent receiver extends the base intent receiver but overrides onReceive without calling through to super, the package name is messed up for the category, or the app does not declare and use the "PACKAGE_NAME.UA_DATA" permission. The SDK now automatically launches the application's launcher activity by default, but if that part is not working then you most likely need to declare the permission.
In the manifest section of the AndroidManifest.xml add:
<permission android:name="com.myapp.app.permission.UA_DATA" android:protectionLevel="signature" />
<uses-permission android:name="com.myapp.app.permission.UA_DATA" />

Android: How to use Parse as an alternative GCM push notification provider?

SEE EDIT#2 at the end of the question (Google updated the way push is implemented so it became easier to handle gcm and parse together)
I already use GCM inside a application and I would like to add parse as an alternative. This is what I have now (all the permissions are correctly declared):
<service
android:name="com.mypackagename.GCMIntentService"
android:enabled="true" />
<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.mypackagename.GCMIntentService" />
</intent-filter>
</receiver>
The 'GCMIntentService' (inherits from 'GCMBaseIntentService') class handles the server registration and receiving of messages - it works fine and all the push messages are received. The server sometimes sends custom data so I handle the messages myself and create the notifications programmatically (the intent used when the notification is clicked has some important extras sent from the server).
I would like to somehow make parse behave in the same way in order to be able to send channel pushes from the parse website and create my own notifications, but everything I tried failed (following the android push tutorial isn't really working for my problem). Is there anyone who tried a similar thing? I'm kind of out of ideas after spending a lot of time tweaking the push guides/tutorials - sometimes I don't receive any notifications; sometimes both parse and my receiver are called and I get double notifications. I also tried to register using parse REST apis and handle everything myself but found out it isn't possible on Android.
So, how could I handle both parse pushes and the traditional gcm pushes (using my server) in such a way that I have access to both notifications and I can build them from scratch (create my own pending notifications with the required extras)?
EDIT#1:
The first thing I tried was to use the parse service and have a single broadcast receiver to handle the GCM messages:
AndroidMaifest.xml:
<service
android:name="com.mypackagename.GCMIntentService"
android:enabled="true" />
<service android:name="com.parse.PushService"
android:enabled="true"/>
<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.mypackagename.GCMIntentService" />
</intent-filter>
</receiver>
And the parse library requires the following initializations:
Parse.initialize(context, appId, apiKey);
PushService.setDefaultPushCallback(context, MainActivity.class);
// I'm subscribing to channel push because I send channel pushes from the
// parse console
PushService.subscribe(context, MDConstants.PARSE_PUSH_CHANNEL, MainActivity.class);
ParseInstallation.getCurrentInstallation().saveInBackground();
The problem is that I receive the notifications from my other provider but I don't receive anything from parse (all the permissions are declared) and I get the following error from the parse library (when receiving the error the parse registration is not properly done - I can't see my device in the parse console):
E/com.parse.ManifestInfo(11677): Cannot use GCM for push because the app manifest is missing some required declarations. Please make sure that these permissions are declared as children of the root <manifest> element:
E/com.parse.ManifestInfo(11677):
E/com.parse.ManifestInfo(11677): <uses-permission android:name="android.permission.INTERNET" />
E/com.parse.ManifestInfo(11677): <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
E/com.parse.ManifestInfo(11677): <uses-permission android:name="android.permission.VIBRATE" />
E/com.parse.ManifestInfo(11677): <uses-permission android:name="android.permission.WAKE_LOCK" />
E/com.parse.ManifestInfo(11677): <uses-permission android:name="android.permission.GET_ACCOUNTS" />
E/com.parse.ManifestInfo(11677): <uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />
E/com.parse.ManifestInfo(11677): <permission android:name="com.mypackagename.permission.C2D_MESSAGE" android:protectionLevel="signature" />
E/com.parse.ManifestInfo(11677): <uses-permission android:name="com.mypackagename.permission.C2D_MESSAGE" />
E/com.parse.ManifestInfo(11677):
E/com.parse.ManifestInfo(11677): Also, please make sure that these services and broadcast receivers are declared as children of the <application> element:
E/com.parse.ManifestInfo(11677):
E/com.parse.ManifestInfo(11677): <service android:name="com.parse.PushService" />
E/com.parse.ManifestInfo(11677): <receiver android:name="com.parse.GcmBroadcastReceiver" android:permission="com.google.android.c2dm.permission.SEND">
E/com.parse.ManifestInfo(11677): <intent-filter>
E/com.parse.ManifestInfo(11677): <action android:name="com.google.android.c2dm.intent.RECEIVE" />
E/com.parse.ManifestInfo(11677): <action android:name="com.google.android.c2dm.intent.REGISTRATION" />
E/com.parse.ManifestInfo(11677): <category android:name="com.mypackagename" />
E/com.parse.ManifestInfo(11677): </intent-filter>
E/com.parse.ManifestInfo(11677): </receiver>
E/com.parse.PushService(11677): Tried to use push, but this app is not configured for push due to: Push is not configured for this app because the app manifest is missing required declarations. Please add the following declarations to your app manifest to support either GCM or PPNS for push (or both). To enable GCM support, please make sure that these permissions are declared as children of the root <manifest> element:
E/com.parse.PushService(11677):
E/com.parse.PushService(11677): <uses-permission android:name="android.permission.INTERNET" />
E/com.parse.PushService(11677): <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
E/com.parse.PushService(11677): <uses-permission android:name="android.permission.VIBRATE" />
E/com.parse.PushService(11677): <uses-permission android:name="android.permission.WAKE_LOCK" />
E/com.parse.PushService(11677): <uses-permission android:name="android.permission.GET_ACCOUNTS" />
E/com.parse.PushService(11677): <uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />
E/com.parse.PushService(11677): <permission android:name="com.mypackagename.permission.C2D_MESSAGE" android:protectionLevel="signature" />
E/com.parse.PushService(11677): <uses-permission android:name="com.mypackagename.permission.C2D_MESSAGE" />
E/com.parse.PushService(11677):
E/com.parse.PushService(11677): Also, please make sure that these services and broadcast receivers are declared as children of the <application> element:
E/com.parse.PushService(11677):
E/com.parse.PushService(11677): <service android:name="com.parse.PushService" />
E/com.parse.PushService(11677): <receiver android:name="com.parse.GcmBroadcastReceiver" android:permission="com.google.android.c2dm.permission.SEND">
E/com.parse.PushService(11677): <intent-filter>
E/com.parse.PushService(11677): <action android:name="com.google.android.c2dm.intent.RECEIVE" />
E/com.parse.PushService(11677): <action android:name="com.google.android.c2dm.intent.REGISTRATION" />
E/com.parse.PushService(11677): <category android:name="com.mypackagename" />
E/com.parse.PushService(11677): </intent-filter>
E/com.parse.PushService(11677): </receiver>
E/com.parse.PushService(11677): To enable PPNS support, please make sure that these permissions are declared as children of the root <manifest> element:
E/com.parse.PushService(11677):
E/com.parse.PushService(11677): <uses-permission android:name="android.permission.INTERNET" />
E/com.parse.PushService(11677): <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
E/com.parse.PushService(11677): <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
E/com.parse.PushService(11677): <uses-permission android:name="android.permission.VIBRATE" />
E/com.parse.PushService(11677): <uses-permission android:name="android.permission.WAKE_LOCK" />
E/com.parse.PushService(11677):
E/com.parse.PushService(11677): Also, please make sure that these services and broadcast receivers are declared as children of the <application> element:
E/com.parse.PushService(11677):
E/com.parse.PushService(11677): <service android:name="com.parse.PushService" />
E/com.parse.PushService(11677): <receiver android:name="com.parse.ParseBroadcastReceiver">
E/com.parse.PushService(11677): <intent-filter>
E/com.parse.PushService(11677): <action android:name="android.intent.action.BOOT_COMPLETED" />
E/com.parse.PushService(11677): <action android:name="android.intent.action.USER_PRESENT" />
E/com.parse.PushService(11677): </intent-filter>
E/com.parse.PushService(11677): </receiver>
EDIT#2:
I updated the way gcm push was handled based on the google push notification developer guide. While implementing the class that extends 'GcmListenerService', you can now easily check if the 'from' arguments is the same as your google project id used to register for push.
public class MyGcmListenerService extends GcmListenerService {
#Override
public void onMessageReceived(String from, Bundle data) {
// only handle gcm messages that come from the same project id used to register
if (from.equals("Your google project id)) {
// handle the gcm push
}
}
}
Also, parse updated their libraries (I'm using '1.9.4' right now) and you can subclass the 'ParsePushBroadcastReceiver' to handle the notifications as you'd like. See the guide here for a basic implementation.
Parse initialization in the 'onCreate' method of your 'Application' class:
Parse.initialize(this, "your parse app id", "your parse client key");
// subscribing to a channel
ParsePush.subscribeInBackground("your channel name", new SaveCallback() {
#Override
public void done(ParseException e) {
if (e == null) {
Log.d("com.parse.push", "successfully subscribed to the broadcast channel.");
} else {
Log.e("com.parse.push", "failed to subscribe for push");
}
}
});
The broadcast receiver implementation:
public class MyParsePushBroadcastReceiver extends ParsePushBroadcastReceiver {
#Override
protected void onPushReceive(Context context, Intent intent) {
// handle the parse push notification
}
}
The manifest declaration for both parse and gcm:
...
<!-- GCM listener service -->
<service
android:name=".MyGcmListenerService"
android:exported="false" >
<intent-filter>
<action android:name="com.google.android.c2dm.intent.RECEIVE" />
</intent-filter>
</service>
...
<!-- Parse broadcast receiver -->
<receiver android:name=".MyParsePushBroadcastReceiver" 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>
...
I only added the service and the receiver, but you need to make sure you follow the GCM guide and the Parse push guides to have a full implementation (for example, google also added a way to handle the token refresh - a sample containing full code samples can be found here).
If I understand correctly, you want your code to handle all the incoming GCM messages, regardless of their source (which can be either your server or Parse website), which means you don't want the Parse code in your app do handle them.
You can achieve this by declaring only a single broadcast receiver handling com.google.android.c2dm.intent.RECEIVE action in your manifest. That would be your GCMBroadcastReceiver class, which would handle all the arriving GCM messages.
The behavior you are currently experiencing can happen when you declare two broadcast receivers that handle the same action.

Push notification does not happening when app is not running - android

I am using Urban Airship for Push notification. Its works like a charm but just found that its did not sending push notification when application is not running.
How to handle this? I am sure its a common scenario and there will be a solution.
I checked many posts in stack overflow but most of them are for iOS. I want for Android
AirshipConfigOptions options = AirshipConfigOptions.loadDefaultOptions(this);
UAirship.takeOff(this, options);
Logger.logLevel = Log.VERBOSE;
PushManager.shared().setIntentReceiver(IntentReceiver.class);
PushManager.enablePush();
I have below code in Manifest Fie
<!-- REQUIRED for Urban Airship GCM-->
<receiver android:name="com.urbanairship.CoreReceiver" />
<receiver android:name="com.urbanairship.push.GCMPushReceiver" 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" />
<!-- MODIFICATION REQUIRED - Use your package name as the category -->
<category android:name="com.itest.guide.urbanairship" />
</intent-filter>
</receiver>
<service android:name="com.urbanairship.push.PushService" android:label="Push Notification Service"/>
<service android:name="com.urbanairship.push.PushWorkerService" android:label="Push Notification Worker Service"/>
<service android:name="com.urbanairship.analytics.EventService" android:label="Event Service"/>
<!-- This is required for persisting preferences related to push and location -->
<provider android:name="com.urbanairship.UrbanAirshipProvider"
android:authorities="com.itest.mauritiustourguide.urbanairship.provider"
android:exported="false"
android:multiprocess="true" />
<!-- END OF REQUIRED ITEMS -->
<!-- OPTIONAL, if you want to receive push, push opened and registration completed intents -->
<!-- Replace the receiver below with your package and class name -->
<receiver android:name="com.itest.guide.urbanairship.IntentReceiver" />
The reason may be because of the Broadcast receiver in manifest file. Are you sure you put it? The broadcast receiver wakes the application up, and notifies when there is a push.
It doesn't look like the line the category in the BroadcastReceiver intent filter matches your app package
<category android:name="com.itest.guide.urbanairship" />

Android C2DM Wont register

I have used This guide. But if i add it to another project, i dont receive anything:
I have made changes to the manifest so it matches the guide(I think):
Question: But now i dont get any response to my registration attempt.
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="de.vogella.android.c2dm" android:versionCode="1"
android:versionName="1.0">
<permission android:name="de.vogella.android.c2dm.permission.C2D_MESSAGE"
android:protectionLevel="signature" />
<uses-permission android:name="de.vogella.android.c2dm.permission.C2D_MESSAGE" />
<!-- Permissions -->
<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<application android:icon="#drawable/ic_launcher" android:label="#string/app_name">
<activity android:name="RegisterActivity" android:label="#string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<service android:name="de.vogella.android.c2dm.C2DMReceiver" />
<!-- Only C2DM servers can send messages for the app. If permission is
not set - any other app can generate it -->
<receiver android:name="com.google.android.c2dm.C2DMBroadcastReceiver"
android:permission="com.google.android.c2dm.permission.SEND">
<!-- Receive the actual message -->
<intent-filter>
<action android:name="com.google.android.c2dm.intent.RECEIVE" />
<category android:name="de.vogella.android.c2dm" />
</intent-filter>
<!-- Receive the registration id -->
<intent-filter>
<action android:name="com.google.android.c2dm.intent.REGISTRATION" />
<category android:name="de.vogella.android.c2dm" />
</intent-filter>
</receiver>
<activity android:name="ResultActivity"></activity>
</application>
</manifest>
How to start registering (Have checked that it reaches into the if condition)(is called from C2DM2Activity):
public void checkRegistered() {
String registered = C2DMessaging
.getRegistrationId(getApplicationContext());
if (registered.equals("")) {
Log.i(TAG, "starting registration of C2DM");
C2DMessaging.register(this, C2DMID);
}
}
Filestructure:
What if you add a '.' to your service name, I think that's the way it should be.
Try this <service android:name=".c2dm.C2DMReceiver" />
In the code part. C2DMBaseReceiver, there is a place where it defines the C2DMReceiver to be in the application package default folder.
Thanks to all others for trying to help.
Try to change
android:name="com.google.android.c2dm.C2DMBroadcastReceiver"
To
android:name="dk.lector.cms.c2dm.YourReceiverClassName"
You said in a comment above that C2DMBroadcastReceiver is your receiver. Then what is with the C2DMReceiver that I see in your de.vogella.android.c2dm package?
And you question is about how to start registering. In the tutorial under section 2.2. Getting the registration ID for the mobile app there is a register method that needs to be called. When the registrationId comes back from the Google server it is caught in your receiver's onReceive. In his tutorial, the receiver for registering is C2DMRegistrationReceiver. If you say that C2DMBroadcastReceiver is your receiver and you are sure about that, just call register and the onReceive should receive the message.
Also, you should try posting the entire Manifest.xml. Make sure you are using the permission for INTERNET and a custom permission like:
<permission
android:name="de.vogella.android.c2dm.simpleclient.permission.C2D_MESSAGE"
android:protectionLevel="signature" />
<uses-permission
android:name="de.vogella.android.c2dm.simpleclient.permission.C2D_MESSAGE" />
The package name u got registered with C2DM is it same as other project you transfered because for C2DM it identify an app with its Package name

Categories

Resources