I'm trying to set up push notifications in an app for the first time. I think the server side is OK (the message send to google comes back with status code 200, and I see a success result in the response body).
But the device never does anything :(
Manifest is set as follows:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="my.package" >
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />
<permission android:name="my.package.permission.C2D_MESSAGE"
android:protectionLevel="signature" />
<uses-permission android:name="my.package.permission.C2D_MESSAGE" />
<application
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/appName"
android:theme="#style/AppTheme" >
<activity
android:name="my.package.activity.MainActivity"
android:label="#string/title_activity_main" >
<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.gms.gcm.GcmReceiver"
android:enabled="true"
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="my.package" />
<action android:name="com.google.android.c2dm.intent.REGISTRATION" />
</intent-filter>
</receiver>
<service
android:name=my.package.NotificationListenerService"
android:exported="false" >
<intent-filter>
<action android:name="com.google.android.c2dm.intent.RECEIVE" />
</intent-filter>
</service>
</application>
</manifest>
And the NotificationListenerService is like this:
public class NotificationListenerService extends GcmListenerService {
#Override
public void onMessageReceived(String from, Bundle data) {
String message = data.getString("message");
Log.d("MyApp", "message);
Notification.ShowNotification("test", getApplicationContext());
}
}
I think that's all I need according to https://developers.google.com/cloud-messaging/android/client (asides from the stuff to handle reset tokens which I've not added yet. My token registration seems to work as I can see the token in the dev console data store.)
I've tried looking at logcat but nothing obvious seems to appear. Do I need to "start" the service in some way? The documentation suggests not... I'm obviously missing something fundamental though!
When you send a message, your server normally gets a message_id as a response. Using the diagnostics tool with the message_id could be useful to make sure that GCM correctly relayed the message.
Is Google Play Services up-to-date on your device ?
Related
I have an application that correctly receives notifications, even when the application has been killed by swiping. However, after a longer period of inactivity (e.g. application not used for ~2 weeks) the notifications stop getting delivered. The behavior is consistent with applications that have been force stopped (http://developer.android.com/about/versions/android-3.1.html#launchcontrols). However, I am confident that the application has not been force stopped.
To elaborate, the device receives the GCM message and the intent is triggered, but the application is not available to process it. See log excerpt below for details on what happens when notification is sent.
03-30 19:43:24.596: I/GCM(4931): GCM message com.company.application 0:1459359805552536%60ff11d7f9fd7ecd
03-30 19:43:24.606: W/GCM-DMM(4931): broadcast intent callback: result=CANCELLED forIntent { act=com.google.android.c2dm.intent.RECEIVE pkg=com.company.application (has extras) }
Does android sometimes force idle applications into a stopped state? Is there reason for this to occur other than a stopped state?
If it matters, notifications are implemented using Urban Airship, but I had similiar problems before migrating from Parse.
Code excerpts below.
Manifest
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.company.application"
android:versionCode="27"
android:versionName="1.31">
<uses-sdk
android:minSdkVersion="11"
android:targetSdkVersion="21" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />
<permission
android:name="com.company.application.permission.C2D_MESSAGE"
android:protectionLevel="signature" />
<uses-permission android:name="com.company.application.permission.C2D_MESSAGE" />
<uses-permission
android:name="android.permission.WRITE_EXTERNAL_STORAGE"
android:maxSdkVersion="18" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission
android:name="android.permission.READ_EXTERNAL_STORAGE"
android:maxSdkVersion="18" />
<application
android:name=".MyApplication"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name">
<activity
android:name=".Main"
android:label="#string/app_name"
android:screenOrientation="portrait"
android:theme="#android:style/Theme.NoTitleBar.Fullscreen">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
...
<activity android:name=".ParseDeepLinkActivity">
<intent-filter>
<action android:name="android.intent.action.VIEW"/>
<!-- Handles any vnd.company.application://deeplink URI's -->
<data android:scheme="vnd.company.application" android:host="deeplink" />
<category android:name="android.intent.category.DEFAULT"/>
<category android:name="android.intent.category.BROWSABLE"/>
</intent-filter>
</activity>
</application>
</manifest>
Application
public class MyApplication extends Application {
#Override
public void onCreate() {
super.onCreate();
UAirship.takeOff(this, new UAirship.OnReadyCallback() {
#Override
public void onAirshipReady(UAirship airship) {
// Enable user notifications
airship.getPushManager().setUserNotificationsEnabled(true);
}
});
}
}
Are you implementing a WakeLock object? Do you set a keepalive value for your GCM messages? I suggest you start by checking both points or post some more code / details so we can understand the whole scope :)
I couldn't find a page or question where it can tell me how to make a notification without the app running in background or it being opened.
It would be great if anyone could help. (I'm using Android)
First step is to create a Parse account and get your Application Id and Client Key.
After that you have to create your own custom Application class by creating a class that extends Application and then override onCreate (just like you would any activity) and place that line in.
public class MyApplication extends Application {
public void onCreate() {
Parse.initialize(this, PARSE_APPLICATION_ID, PARSE_CLIENT_KEY);
ParseInstallation.getCurrentInstallation().saveInBackground();
}
}
You also have to tell the manifest that you are using a custom application class. You can do this by, in your AndroidManifest.xml file, you will have to set the name element to the location of you new Application class:
<application
android:name="com.packageName.example.MyApplication"
android:label="#string/app_name"
android:logo="#drawable/ic_launcher_no_text" >
In the Manifest file
Declare the following permissions:
<permission android:name="com.packagename.permission.C2D_MESSAGE" android:protectionLevel="signature" />
<uses-permission android:name="com.packagename.permission.C2D_MESSAGE" />
<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" />
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.INTERNET"/>
Also declare a service and receiver in the manifest:
<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.packagename.android" />
</intent-filter>
</receiver>
Change com.packagename to your package name too!
Finally go to your parse account and try sending a push notification from there.
I am happily receiving notifications when app is in background and foreground but when app is killed, I am not receiving notifications in some phones (like Xiaomi model phones eg mi3, etc.)
GCM message 0:1434141725194227%03b66390f9fd7ecd
broadcast intent callback: result=CANCELLED forIntent { act=com.google.android.c2dm.intent.RECEIVE pkg= (has extras) }
Although I am getting notifications in other phones like nexus, samsung, others.
Did anyone also had similar problem?
Can someone explain me where I am wrong.
Here is my Manifest file
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="<package_name>">
<permission android:name="<package_name>.permission.C2D_MESSAGE" android:protectionLevel="signature"/>
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="<package_name>.permission.C2D_MESSAGE" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
<uses-permission android:name="android.permission.CALL_PHONE" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.GET_TASKS" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.FLASHLIGHT" />
<action android:name="android.net.wifi.WIFI_STATE_CHANGED"/>
<action android:name="android.net.wifi.STATE_CHANGE"/>
<application
android:name="<package_name>.ApplicationSingleton"
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme">
<activity
android:name="<package_name>.ui.activity.ReferralActivity"
android:label="#string/app_name"
android:screenOrientation="portrait"
android:windowSoftInputMode="adjustResize">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<receiver
android:name="<package_name>.gcm.GcmBroadcastReceiver"
android:permission="com.google.android.c2dm.permission.SEND" >
<intent-filter>
<action android:name="com.google.android.c2dm.intent.RECEIVE" />
<category android:name="<package_name>" />
</intent-filter>
<intent-filter>
<action android:name="com.google.android.c2dm.intent.REGISTRATION"/>
<category android:name="<package_name>"/>
</intent-filter>
</receiver>
<service android:name="<package_name>.gcm.GcmIntentService" />
</activity>
<meta-data
android:name="com.google.android.gms.version"
android:value="#integer/google_play_services_version" />
</application>
Autostart probably the best MIUI feature that doesn’t come enabled by default, but should.
What does autostart do? It basically starts the apps you select when the phone starts, so you never miss any notifications or updates.
To enable autostart for your apps, follow the steps below:
Tap on the Security app from the app screen.
You will not find this if you enter from the Settings menu, you have to tap directly on the app icon.
Open Security App:
Once in the Security app, tap on Permissions.
Tap on Autostart
Toggle the apps you want to enable Autostart for
Reboot your phone.
Now you are all set up with autostart!
I have been eating my brains for hours and cannot find an answer.
My problem is that I am trying to send push notifications to my android device from the Parse.com console on the web and when I send a message there is no problem but if I try to send JSON then I will never see the notification on my device.
I am trying to send a JSON message as simple as this-> {"x":"1"}
my relevant manifest code
<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.ACCESS_COARSE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />
<permission android:protectionLevel="signature"
android:name="my.app.package.permission.C2D_MESSAGE" />
<uses-permission android:name="my.app.package.permission.C2D_MESSAGE" />
<!-- Parse push notification receiver -->
<service android:name="com.parse.PushService" />
<receiver android:name="com.parse.ParseBroadcastReceiver">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
<action android:name="android.intent.action.USER_PRESENT" />
</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="my.app.package" />
</intent-filter>
</receiver>
<receiver android:name="my.app.package.parse.NotificationReceiver" 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>
my.app.package.parse.NotificationReceiver exists normally and handles the application opening successfully for the message notifications
and my Application's onCreate() runs the following
Parse.enableLocalDatastore(this);
Parse.initialize(this, "..........", ".............");
ParseACL defaultACL = new ParseACL();
defaultACL.setPublicReadAccess(true);
ParseACL.setDefaultACL(defaultACL, true);
ParsePush.subscribeInBackground("everything", 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", e);
}
}
});
I have run out of ideas so Please help!
My next idea solved my problem.
It seems that a JSON message should include a tag "alert" with the value of the text that is needed to be shown as a notification.
If "alert" tag is not specified then the notification is not shown. So my {"x":"1"} would not show up but
{ "x": "1", "alert": "show me to the user" }
is showing up normally.
Unfortunately I did not find this anywhere in parse user guide, so PLEASE Parsers add this to the guides to let other developers not waste time.
Thanks
Try to specify that the POST you are sending is of type application/json
By default, the POST has a media type of application/x-www-form-urlencoded. This will obviously not be recognized as JSON by the machine.
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