inloop / easygcm Goto Github PK
View Code? Open in Web Editor NEWAndroid Library for easy GCM integration in few lines of code.
License: Apache License 2.0
Android Library for easy GCM integration in few lines of code.
License: Apache License 2.0
Maybe it's just me, but I had to try all kinds of things to get this to work properly. First of all, the init command in the README file didn't even work. I already made one pull request that updated the init command.
Also, even before reaching this point I had to spend some time figuring out how to get it to build correctly. More specifically, I had to:
classpath 'com.google.gms:google-services:1.5.0-beta2'
to root gradle fileapply plugin: 'com.google.gms.google-services'
to module gradle file, and compile 'com.google.android.gms:play-services-gcm:8.3.0'
under dependencies.Are these simply not documented on README, or did I miss something?
Hello guys. GooglePlayServicesUtil is deprecated https://developers.google.com/android/reference/com/google/android/gms/common/GooglePlayServicesUtil
GCM registration listens to PACKAGE_REPLACED broadcast. Which is good, but sometimes version doesn't change - typically during development of the app, if you are installing the same version over and over. In that case it's not necessary to repeat registration.
Hi guys! First of all, thanks for your amazing library. It will save lot of my time.
I was wondering why not to have some way to recall this sendRegistrationIdToBackend method.
I mean.. I know that it's called in the first install of your app once you register by the first time with google, and I think (I'm not really sure, please clarify this) that it's called again once the app is updated.
But what happens if, for example, this first time that you call this method, my server fails?
I know that I can handle it easily, but I think it would be easier to be able to call this method again..
what do you think?
Thanks a lot again!
Lot of new features in GCM 3.0:
https://www.youtube.com/watch?v=gJatfdattno
But as I understand, changes to the library could be minimal - just replace registrationId with new Instance ID.
<permission
android:name="easygcm.permission.C2D_MESSAGE"
android:protectionLevel="signature" />
<uses-permission android:name="easygcm.permission.C2D_MESSAGE" /> <!-- This app has permission to register and receive data message. -->
Above is extracted from my AndroidManifest.xml, I guess the Manifest Merger cannot get the project's applicationid but using the library provided one.
Using a wrong applicationid would not affect Jelly Bean or above versions from my testing, but all of my ICS device are failed to receive any GCM message (but can get a registrationid)
Seems to be the same issue:
https://code.google.com/p/android/issues/detail?id=73128
https://groups.google.com/forum/#!topic/adt-dev/0qg87Zu9NuU
http://stackoverflow.com/questions/27988186/override-applicatoinid-inside-library-projects-manifest-with-gradle
Hello, would it be possible to pass Context in mentioned method? It can come handy in some situlations (especially when Application doesn't extend GcmListener).
Thank you
The sample project crashes after clicking the Send button - the onClick method is not defined. And it would be great if we could come up with a direct project dependency instead of a maven dependency on the parent project. It takes too much time to redeploy this into the local maven repo and then test again, and then revert the changes before comitting...
I'm trying to run my application in the Geenymotion emulator. I have installed the Google Play Services (part of Google Apps)
The problem is, when the app runs, the class GcmHelper.java trhow an exception:
java.lang.RuntimeException: An error occured while executing doInBackground()
at android.os.AsyncTask$3.done(AsyncTask.java:299)
at java.util.concurrent.FutureTask$Sync.innerSetException(FutureTask.java:273)
at java.util.concurrent.FutureTask.setException(FutureTask.java:124)
at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:307)
at java.util.concurrent.FutureTask.run(FutureTask.java:137)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1076)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:569)
at java.lang.Thread.run(Thread.java:856)
Caused by: java.lang.SecurityException: Not allowed to start service Intent { act=com.google.android.c2dm.intent.REGISTER pkg=com.google.android.gms (has extras) } without permission com.google.android.c2dm.permission.RECEIVE
at android.app.ContextImpl.startService(ContextImpl.java:1161)
at android.content.ContextWrapper.startService(ContextWrapper.java:383)
at com.google.android.gms.gcm.GoogleCloudMessaging.e()
at com.google.android.gms.gcm.GoogleCloudMessaging.register()
at eu.inloop.easygcm.GcmHelper$1.doInBackground(GcmHelper.java:189)
at eu.inloop.easygcm.GcmHelper$1.doInBackground(GcmHelper.java:180)
at android.os.AsyncTask$2.call(AsyncTask.java:287)
at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305)
at java.util.concurrent.FutureTask.run(FutureTask.java:137)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1076)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:569)
at java.lang.Thread.run(Thread.java:856)
This is a problem with Play Services or in the gcmeasy lib? Someone had this problem?
If an AsyncTask is in flight when the Activity is destroyed, it will keep the Activity instance alive an unnaturally long time. This could potentially cause OutOfMemoryErrors if the Activity is large enough.
You could make this seamless by adding an Activity lifecycle callback on the application, and when the given Activity is destroyed, you could kill the AsyncTask if it's still active.
The NetworkStateReceiver
performs GCM registration even though EasyGcm.init(Context)
was never called. I think that the library shouldn't do anything until its init
method was called.
In our app we perform the init
only in certain cases and we rely on the GcmListener
to be called after that. In case the registration was already done in the NetworkStateReceiver
the listener won't be called. I know that we can fix this by specifically checking for isRegistered(Context)
, but nevertheless, the first paragraph still stands.
Hi, I have am getting Post-registration message: Error :SERVICE_NOT_AVAILABLE continuously. I have followed instruction on the readme file.
The android Documentation says:
When the application receives a com.google.android.c2dm.intent.REGISTRATION intent with the error extra set as SERVICE_NOT_AVAILABLE, it should retry the failed operation (register or unregister).
I guess this is already implemented in the package. Any guess to why am i getting this error ?
Moreover, I checked that you didn't mention to add anything to Manifest (such as GCM C2Dm actions). Are they not required ?
When Android is upgraded, Google offers no guarantee the GCM token will keep working, and we saw some cases where GCM would stop working after an upgrade to Android 5.1.
EasyGCM should probably listen to system boot and renew the GCM token if needed:
<uses-permission
android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
...
<receiver android:name=".BootReceiver">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
Waiting a few seconds for the network to be available, or even better, some exponential backoff, could be a good idea.
I'm having trouble starting EasyGcm on sony devices, i have tested the same app on galaxy s6 and works fine, Xperia devices crash and this is the log.
08-24 15:08:18.363 10046-10322/roneskinder.x111 D/easygcm: Registration not found. 08-24 15:08:18.363 10046-10322/roneskinder.x111 W/dalvikvm: threadid=24: thread exiting with uncaught exception (group=0x4191d8b0) 08-24 15:08:18.363 10046-10322/roneskinder.x111 E/AndroidRuntime: FATAL EXCEPTION: IntentService[eu.inloop.easygcm.GcmRegistrationService] java.lang.NoClassDefFoundError: com.google.android.gms.iid.InstanceID at eu.inloop.easygcm.GcmRegistrationService.registerGcm(GcmRegistrationService.java:70) at eu.inloop.easygcm.GcmRegistrationService.onHandleIntent(GcmRegistrationService.java:56) at android.app.IntentService$ServiceHandler.handleMessage(IntentService.java:65) at android.os.Handler.dispatchMessage(Handler.java:99) at android.os.Looper.loop(Looper.java:137) at android.os.HandlerThread.run(HandlerThread.java:61) 08-24 15:08:18.373 10046-10046/roneskinder.x111 E/test: tab 2 oncreateview 08-24 15:08:18.393 10046-10046/roneskinder.x111 E/test: tab 2 container on activity created 08-24 15:08:18.393 10046-10046/roneskinder.x111 E/test: tab 2 init view
GCM registration ID is only valid for one version of the app. It's a good practice to listen to MY_PACKAGE_REPLACED
Broadcast receiver and re-register immediately after the update. Otherwise GCM messages will not come until user launches to app.
Adding sdk-manager-plugin will help developers avoid problems with missing sdks and api levels avoiding build problems (missing play services)
You can have maxSdkVersion
on the permission
Would be amazing to add this method. I need to resync my ids when the user is logged on the app or not (my case of use needs it).
Just remove the PROPERTY_REG_ID
on the SharedPreferences. At this time, I do it manuallity.
After integrating easygc in the app, manifest merger is adding new permissions to the app during the build phase:
android:uses-permission#android.permission.WRITE_EXTERNAL_STORAGE
IMPLIED from AndroidManifest.xml:2:1 reason: easygcm has a targetSdkVersion < 4
android:uses-permission#android.permission.READ_PHONE_STATE
IMPLIED from AndroidManifest.xml:2:1 reason: easygcm has a targetSdkVersion < 4
android:uses-permission#android.permission.READ_EXTERNAL_STORAGE
IMPLIED from AndroidManifest.xml:2:1 reason: easygcm requested WRITE_EXTERNAL_STORAGE
Because of
app can not request for get_accounts permission on api > 13. I tried to set app's manifest permissions to maxSdkVersion="22", but gradle fails to merge two manifests. It suggest a solution though:
Error:(20, 9) Attribute uses-permission#android.permission.GET_ACCOUNTS@maxSdkVersion value=(22) from AndroidManifest.xml:20:9
Error:(20, 9) Execution failed for task ':app:processDebugManifest'.
Manifest merger failed : Attribute uses-permission#android.permission.GET_ACCOUNTS@maxSdkVersion value=(22) from AndroidManifest.xml:20:9
is also present at eu.inloop:easygcm:1.4.0:15:9 value=(13)
Suggestion: add 'tools:replace="android:maxSdkVersion"' to element at AndroidManifest.xml:18:5 to override
IntentService would be nicer, less likely to be killed and it's a recommended pattern in GCM 3.0 registration.
We would like to migrate to latest GPS in Avast apps and we are not sure that it won't break EasyGCM.
Hi I am using latest stable Android Studio with 'com.android.tools.build:gradle:1.3.0' and 'eu.inloop:easygcm:1.5.0@aar'
However when I build the project and check the manifest file the permission row still show 'easygcm.permission.C2D_MESSAGE' instead of '{applicationId}.permission.C2D_MESSAGE'
As my other project use the same library so once I installed that application I cannot install current application.
I have checked the Release Log of this library, it should be fixed in latest version, but I still face the problem : (
Can anyone help me ? Thanks so much
Tested on Real Device/Genymotion with Google Play
Caused by java.lang.NoClassDefFoundError
eu.inloop.easygcm.GcmHelper$1.doInBackground (GcmHelper.java:221)
eu.inloop.easygcm.GcmHelper$1.doInBackground (GcmHelper.java:212)
This exeption appears after 2-3 secends on app runing. Logcat shows nothing. This log is from Fabric.io witch I have implemented into my app. Thanks in advance.
Hello,
Thank you for for this easy to use and helpful library!
My issue is that I am seeing this exception in my error logs for a small subset of my users (ongoing) and I can't figure out why. GCM messages are successfully received in the vast majority of cases so I suspect this must be some sort of esoteric configuration oddity that only hits a small subset of devices. The most common OS version this error is hit on is 4.4.4 (and a few 6.0+ devices).
I am using the latest version of the library.
java.lang.RuntimeException: Unable to start receiver com.google.android.gms.gcm.GcmReceiver: java.lang.SecurityException: Not allowed to start service Intent { act=com.google.android.c2dm.intent.RECEIVE flg=0x10 pkg=com.discord (has extras) } without permission not exported from uid 10008
at android.app.ActivityThread.handleReceiver(ActivityThread.java:2580)
at de.robv.android.xposed.XposedBridge.invokeOriginalMethodNative(XposedBridge.java:-2)
at de.robv.android.xposed.XposedBridge.handleHookedMethod(XposedBridge.java:631)
at android.app.ActivityThread.handleReceiver(ActivityThread.java:-2)
at android.app.ActivityThread.access$1700(ActivityThread.java:151)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1397)
at android.os.Handler.dispatchMessage(Handler.java:110)
at android.os.Looper.loop(Looper.java:193)
at android.app.ActivityThread.main(ActivityThread.java:5292)
at java.lang.reflect.Method.invokeNative(Method.java:-2)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:824)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:640)
at de.robv.android.xposed.XposedBridge.main(XposedBridge.java:132)
at dalvik.system.NativeStart.main(NativeStart.java:-2)
Caused by: java.lang.SecurityException: Not allowed to start service Intent { act=com.google.android.c2dm.intent.RECEIVE flg=0x10 pkg=com.discord (has extras) } without permission not exported from uid 10008
at android.app.ContextImpl.startServiceCommon(ContextImpl.java:1599)
at android.app.ContextImpl.startService(ContextImpl.java:1576)
at android.content.ContextWrapper.startService(ContextWrapper.java:494)
at android.content.ContextWrapper.startService(ContextWrapper.java:494)
at android.support.v4.content.WakefulBroadcastReceiver.startWakefulService(WakefulBroadcastReceiver.java:89)
at com.google.android.gms.gcm.GcmReceiver.zzi(Unknown:-1)
at com.google.android.gms.gcm.GcmReceiver.onReceive(Unknown:-1)
at android.app.ActivityThread.handleReceiver(ActivityThread.java:2573)
at de.robv.android.xposed.XposedBridge.invokeOriginalMethodNative(XposedBridge.java:-2)
at de.robv.android.xposed.XposedBridge.handleHookedMethod(XposedBridge.java:631)
at android.app.ActivityThread.handleReceiver(ActivityThread.java:-2)
at android.app.ActivityThread.access$1700(ActivityThread.java:151)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1397)
at android.os.Handler.dispatchMessage(Handler.java:110)
at android.os.Looper.loop(Looper.java:193)
at android.app.ActivityThread.main(ActivityThread.java:5292)
at java.lang.reflect.Method.invokeNative(Method.java:-2)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:824)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:640)
at de.robv.android.xposed.XposedBridge.main(XposedBridge.java:132)
at dalvik.system.NativeStart.main(NativeStart.java:-2)
Any suggestions would be very helpful.
I did find this answer which suggests using the application package for the permission.RECEIVE
tag (dubious) http://stackoverflow.com/questions/10315455/not-allowed-to-start-service-intent-x-without-permission-y but otherwise the final merged manifest appears to be correct.
This happens when application extends MultiDexApplication
public class App extends MultiDexApplication implements GcmListener{
.....
}
Caused by: java.lang.IllegalStateException: Please implement GcmListener in your Application or use method setGcmListener()
at eu.inloop.easygcm.GcmHelper.getGcmListener(GcmHelper.java:270)
I've been trying everything hours: it looks like that this library causes this error.
The Sender_ID is the right one, this works fines also:
am broadcast -a com.google.android.c2dm.intent.RECEIVE -n com.younes0.bnm/eu.inloop.easygcm.GcmBroadcastReceiver --es "type" "foo"
Did anybody else had the same problem?
New Google Play services were released with some important stuff for us developers. Can you please update your gradle dependencies and release and library update?
The completeWakefulIntent is called right after onMessage. This will work for simple implementations. But there is a high chance that some users will use asynchronous tasks inside onMessage (for example to call HTTP requests). In this case they should be releasing the wake lock themselves after they have completed all the asynchronous work inside onMessage. Otherwise Android might go into sleep during the async work in onMessage.
I propose sending another parameter to onMessage that would allow to release the lock. A simple object like WakeLock with one single method release(). Internally it would store the original Intent and call release on it. (I think it's better to not send the whole intent directly to onMessage - it's not needed and might confuse the developer on what to do with this).
The downside - it will be the responsibility of the developer to call WakeLock.release in onMessage. There has to be some big warning in the documentation (even though it's a bit self-explanatory, because they are getting a "WakeLock" argument into onMessage).
If you launch the app offline, the init(Activity) is performed, but the GCM doesn't work until next time onCreate of the first activity.
The library should register broadcast receiver for connection change and register once the device is online.
https://developers.google.com/cloud-messaging/faq
Is GCM going to be deprecated?
--->
We will continue to support the current version of GCM Android and iOS SDKs because we know a lot of developers are using GCM SDKs today to handle notifications, and client app upgrade takes time.
But all new client-side features will be added to FCM SDKs only moving forward. You are strongly encouraged to upgrade to FCM SDKs.
We need to provide error handling if the registration fails. Right we don't do anything besides logging the registration result message.
When registration or unregistration fails, the app should retry the failed operation.
In the simplest case, if your app attempts to register and GCM is not a fundamental part of the app, the app could simply ignore the error and try to register again the next time it starts. Otherwise, it should retry the previous operation using exponential back-off. In exponential back-off, each time there is a failure, it should wait twice the previous amount of time before trying again.
http://developer.android.com/google/gcm/gcm.html
Currently only restarting the Activity will try retry the GCM registration.
One way would be to add a onGcmRegistrationFailed(String errorMessage)
to the GcmListener
interface. The developer could then implement the retry logic (exponential backoff) and call the initialization again. Although right now this would not work without further modifications because the init()
requires an Activity context (to display the Play Services error dialog).
Some people are getting errors after uploading to APK like this:
http://stackoverflow.com/questions/31596794/google-play-apk-upload-failure-with-uses-permission-maxsdkversion
We are setting the maxSdkVersion 13 but the lowest possible value is 19, so we just need to change this.
Originally this project was based on GCM sample from Google. There is now updated sample at https://developers.google.com/cloud-messaging/android/start with git repo https://github.com/googlesamples/google-services.git
It is using classes like GcmListenerService that we do not. Would that help us to remove parts of the code and keep everything cleaner?
I don't know it is because of the SDK updated or what I get this error once the app is first launch
BroadcastReceiver trying to return result during a non-ordered broadcast
java.lang.RuntimeException: BroadcastReceiver trying to return result during a non-ordered broadcast
And it is wired that I get a empty GCM broadcast on the app first launch
Seems the source is this line in the GcmBroadcastReceiver
setResultCode(Activity.RESULT_OK);
would you please have a look on that ? thanks.
Bug was filed on https://code.google.com/p/android/issues/detail?id=156015 and recently got fixed. Probably should appear in dev builds of Android tools soon.
Let's have a look at how the new sample works.
I want to call the GcmHelper from a background task but I can't due to it needed an activity. Is there a specific reason why an activity object is needed and a regular context wont suffice?
Working fine on my 5.0+ Moto E, but never seems to get called on my other test device running 4.2.2 despite the logs showing it found an ID
New registration ID=[APA91bFeBLYTLlzCmQQxaPk1xw1Ab5P9m...]
04-09 16:24:07.579 2546-2559/com.flatchat D/easygcm﹕ Saving regId on app version 1
After running gradlew clean, the following exception occurs:
Execution failed for task ':easygcm-tasks:clean'.
Unable to delete file: C:\dev\easygcm\easygcm-tasks\build\libs\easygcm-tasks.jar
A temporary workaround is to comment out include 'easygcm-tasks'
from settings.gradle
If yes - how to handle this with the lib?
Can you please change the way this library uses service intent to make it work correctly on Android O?
AppController: java.lang.IllegalStateException: Not allowed to start service Intent { cmp=eu.inloop.easygcm.GcmRegistrationService (has extras) }: app is in background uid UidRecord{a3f0de1 u0a122 RCVR idle procs:1 seq(0,0,0)}
android.app.ActivityThread.handleBindApplication (ActivityThread.java:6037)
android.app.ActivityThread.-wrap1 ()
android.app.ActivityThread$H.handleMessage (ActivityThread.java:1756)
android.os.Handler.dispatchMessage (Handler.java:105)
android.os.Looper.loop (Looper.java:164)
android.app.ActivityThread.main (ActivityThread.java:6809)
java.lang.reflect.Method.invoke (Method.java)
com.android.internal.os.Zygote$MethodAndArgsCaller.run (Zygote.java:240)
com.android.internal.os.ZygoteInit.main (ZygoteInit.java:767)
GCM 8.1.0 introduced a breaking change and all libraries must update. Details:
https://www.reddit.com/r/androiddev/comments/3mehbb/breaking_changes_in_google_play_services_81/
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.