I have researching for hour and hour and found many similar question but have no a working solution for my question.
I'm understand if I close the app by force close that is normal that I not receive data from gcm. But I was unable to receive the notification with gcm until I start the app. So the application is running either foreground or background then I only be able to receive the data from gcm but when I close the app by sliding away it (which is not done by force close) the notification didn't show up which mean gcm wasn't receive any data at all. . So it mean I need to stay active but if I do so then there is no point for using gcm anymore which design for pushing notification.
Here is my manifest
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.khooteckwei.google" >
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<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="com.google.android.c2dm.permission.RECEIVE" />
<permission android:name="com.example.gcmtesting.google.permission.C2D_MESSAGE"
android:protectionLevel="signature" />
<uses-permission android:name="com.example.gcmtesting.google.permission.C2D_MESSAGE" />
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<activity
android:name=".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.gcmtesting.google" />
</intent-filter>
</receiver>
<service android:name=".GcmIntentService" />
</application>
</manifest>
here is the wakefulBroadcastReceiver
public class GcmBroadcastReceiver extends WakefulBroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
// Explicitly specify that GcmIntentService will handle the intent.
ComponentName comp = new ComponentName(context.getPackageName(),
GcmIntentService.class.getName());
// Start the service, keeping the device awake while it is launching.
startWakefulService(context, (intent.setComponent(comp)));
setResultCode(Activity.RESULT_OK);
}
}
The notification working fine when the app is active so I didn't include the function that use to display notification.Is there any problem with this 2 pages?
I think your problem is in your GcmBroadcastReceiver receiver, you can look at this link , I think it's will help you with GCM http://www.intertech.com/Blog/push-notifications-tutorial-for-android-using-google-cloud-messaging-gcm/
I think notifications doesn't work because your receiver doesn't check do your app running or not , if it is you need to handle notification or if not show android notification
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 have a service that I would like to start on BOOT COMPLETE
when it is started , I have a toast message displayed.
my problem is that when the device boots up , the toast is displayed and is stuck on screen, and the service is not starting correctly.
however if I am trying to start my service through an activity , the service is starting well and the toast disappears after a few seconds correctly.
my manifest:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.tfl.extprotocolservice"
android:versionCode="7"
android:versionName="1.6" >
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="21" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WRITE_SETTINGS"/>
<application
android:allowBackup="true"
android:icon="#drawable/launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<receiver android:name="com.tfl.extprotocolservice.ExtProtocolBroadcastReceiver"
android:enabled="true" >
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
<service android:name=".ExtProtocolService" >
<intent-filter>
<action android:name="com.tfl.extprotocolservice.ISetIpPort" />
</intent-filter>
<intent-filter>
<action android:name="com.tfl.extprotocolservice.IExtMessage" />
</intent-filter>
</service>
<!--
<activity
android:name=".MainActivity"
android:label="#string/app_name"
android:screenOrientation="landscape" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
-->
</application>
</manifest>
my broadcast receiver:
public class ExtProtocolBroadcastReceiver extends BroadcastReceiver {
/* broadcast receiver to start on BOOT COMPLETE*/
#Override
public void onReceive(Context context, Intent intent) {
Intent StartServiceIntent=new Intent(context,ExtProtocolService.class);
context.startService(StartServiceIntent);
}
}
btw, the activity in the manifest is commented because I don't really need it , it was just to test starting the service from an activity.
If your application has no activities, your BroadcastReceiver will never get called.
When you install an application, it is installed in the "stopped state". applications in "stopped state" do not get broadcast Intents delivered to them.
In order to get your application out of "stopped state", the user must manually launch your application (at least once). In order to do this, you must offer him an Activity that he can use to start your application.
Once your application is no longer in "stopped state", Android will deliver broadcast Intents to it. That is, until the user "force stops" your application.
If the user "force stops" your application, it will go back to "stopped state" and will no longer get the broadcast Intents. Until the user manually starts your application again.
I tried with am broadcast -a android.intent.action.BOOT_COMPLETED then it restart the device.
You can try <action android:name="android.intent.action.USER_PRESENT"/>
After more research, I think it was the fastboot mode which will not broadcast BOOT_COMPLETE.
Your service is filtering actions, but your intent doesn't provide any.
Fix with this:
StartServiceIntent.setAction("com.tfl.extprotocolservice.IExtMessage");
I'm trying to use Google Cloud Messaging in one my android applications, everything was going fine but once I changed the package structure of my project I couldn't receive notifications , here is my new Manifest file
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.gcm"
android:versionCode="1"
android:versionName="1.0" >
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<permission
android:name="com.example.gcm.permission.C2D_MESSAGE"
android:protectionLevel="signature" />
<uses-permission android:name="com.example.gcm.permission.C2D_MESSAGE" />
<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.VIBRATE" />
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="16" />
<application
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<activity
android:name="com.example.gcm.actvities.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>
<receiver
android:name="com.example.gcm.utils.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.gcm" />
</intent-filter>
</receiver>
<service android:name="com.example.gcm.services.GCMNotificationIntentService" />
</application>
You haven't included the code of com.example.gcm.utils.GcmBroadcastReceiver, but since your trouble started after changing packages, it is very likely that the code of the broadcast receiver that starts the intent service uses context.getPackageName() as the package of the intent service, which is incorrect after your change. You should specify the correct package of the intent service class.
Assuming you used the standard code from the GCM demo in your receiver, it probably look like this :
#Override
public void onReceive(Context context, Intent intent) {
// Explicitly specify that GcmIntentService will handle the intent.
ComponentName comp = new ComponentName(context.getPackageName(),
GcmIntentService.class.getName());
// Start the service, keeping the device awake while it is launching.
startWakefulService(context, (intent.setComponent(comp)));
setResultCode(Activity.RESULT_OK);
}
In that case, change it to this :
#Override
public void onReceive(Context context, Intent intent) {
// Explicitly specify that GcmIntentService will handle the intent.
ComponentName comp = new ComponentName(GcmIntentService.class.getPackage().getName(),
GcmIntentService.class.getName());
// Start the service, keeping the device awake while it is launching.
startWakefulService(context, (intent.setComponent(comp)));
setResultCode(Activity.RESULT_OK);
}
I am trying to register my app on GCM but I don't know why my app is never registered. GCMRegistrar.register(this, SENDER_ID); is called but onRegistered() from my GCMIntentService is never called. I don't know WHY.
This is my Logcat
01-17 11:03:00.015: D/GCMRegistrar(3509): resetting backoff for com.abc.xyz.ui.activity
01-17 11:03:03.210: V/GCMRegistrar(3509): Registering app com.abc.xyz.ui.activity of senders 964256581311
01-17 11:03:06.070: V/GCMBroadcastReceiver(3509): onReceive: com.google.android.c2dm.intent.REGISTRATION
01-17 11:03:06.070: V/GCMBroadcastReceiver(3509): GCM IntentService class: com.abc.xyz.ui.activity.GCMIntentService
01-17 11:03:06.070: V/GCMBaseIntentService(3509): Acquiring wakelock
and this is my complete manifest
<?xml version="1.0" encoding="utf-8"?>
<manifest package="com.abc.xyz.ui.activity"
android:versionCode="1"
android:versionName="1.5.6" xmlns:android="http://schemas.android.com/apk/res/android">
<uses-sdk
android:minSdkVersion="11" android:targetSdkVersion="16"/>
<uses-feature
android:name="android.hardware.usb.host"/>
<!-- This app has permission to register and receive data message. -->
<uses-permission
android:name="com.google.android.c2dm.permission.RECEIVE" />
<uses-permission
android:name="android.permission.INTERNET" />
<uses-permission
android:name="android.permission.READ_PHONE_STATE" />
<uses-permission
android:name="android.permission.GET_TASKS" />
<uses-permission
android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission
android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission
android:name="android.permission.ACCESS_WIFI_STATE"/>
<uses-permission
android:name="android.permission.CALL_PHONE" />
<uses-permission
android:name="android.permission.BLUETOOTH" />
<!-- 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.
NOTE: the permission *must* be called PACKAGE.permission.C2D_MESSAGE,
where PACKAGE is the application's package name.
-->
<uses-permission
android:name="com.abc.xyz.ui.activity.permission.C2D_MESSAGE" />
<permission
android:name="com.abc.xyz.ui.activity.permission.C2D_MESSAGE"
android:protectionLevel="signature" />
<application
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#android:style/Theme.Holo.Light"
android:name="com.abc.xyz.MyApplication"
android:allowBackup="false">
<activity
android:name=".StartupActivity"
android:noHistory="true"
android:label="#string/title_startup_screen"
android:configChanges="orientation">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name=".LoginActivity"
android:windowSoftInputMode="stateAlwaysVisible|adjustResize"
android:label="#string/title_login_screen"
android:configChanges="orientation">
</activity>
//my other activity defination
<!--
BroadcastReceiver that will receive intents from GCM
services and handle them to the custom IntentService.
The com.google.android.c2dm.permission.SEND permission is necessary
so only GCM services can send data messages for the app.
-->
<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.abc.xyz.ui.activity" />
</intent-filter>
</receiver>
<!--
Application-specific subclass of GCMBaseIntentService that will
handle received messages.
By default, it must be named .GCMIntentService, unless the
application uses a custom BroadcastReceiver that redefines its name.
-->
<service android:name="com.abc.xyz.ui.activity.GCMIntentService" />
</application>
</manifest>
I don't know what is wrong and why onRegistered() is never called. Any help will be appreciated.
I figured out in another post what is the problem. My GCMIntentService Class was defined in my manifest as
<service android:name="MY_PACKAGE.gcm.GCMIntentService" />
because I didn't want to put this class at the root package, instead I put at MY_PACKAGE.gcm". This seems to cause a problem and as the documentation says,
Add the following intent service
<service android:name=".GCMIntentService" />
So when I moved to the root package it worked! There is another way to put the GCMIntentServiceSubclass wherever you want and name it differently. You should subclass GCMBroadcastReceiver and do the changes in manifest and in the subclass as shown in this other post.
I answer because pasting code is barely readable in comments:
I am missing some logs from your logcat that suggest your service is even called. I have this in my Logcat when registering:
GCMBroadcastReceiver V onReceive: com.google.android.c2dm.intent.REGISTRATION
GCMBroadcastReceiver V GCM IntentService class: com.package.android.app.GCMIntentService
GCMBaseIntentService V Acquiring wakelock
GCMBaseIntentService V Intent service name: GCMIntentService-DynamicSenderIds-1
Especially the last line is missing or you have forgotten to paste it. Could you make sure that you posted the complete LogCat? Filter for GCM to make sure you didn't missed something.
Update
As the OP mentioned in the comments, he used the service to do more. This somehow interfered with the GCM functionality and after separating this into two services it worked. Lessons learned: Don't use the GCMIntentService for anything else than GCM.
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