How to rename or move GCMIntentService - android

I would like to put the GCMIntentService in a directory other than my package root.
The GCM documentation states that
By default, it must be named .GCMIntentService, unless the
application uses a custom BroadcastReceiver that redefines its name.
My question is - how do I create this "custom BroadcastReceiver" thay talk about?

Try this -- Rename or change package of GCMIntentService class

The basic docs have you add the following to your manifest:
<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="my_app_package" />
</intent-filter>
</receiver>
This points to a GCM-supplied BroadcastReceiver that will route events to your .GCMIntentService. If you wish to have your service reside in some other package, you will need to supply your own BroadcastReceiver. This may be as simple as creating one that subclasses GCMBroadcastReceiver and overrides getGCMIntentServiceClassName() to return the fully-qualified class name of the service to use.

Related

How to address android lint complaint about exported Firebase Messaging service implementations?

Following the Google developer instructions on implementing Firebase in my app, I notice that android lint complains.
The idea is that we have to implement two services which inherit from Firebase services:
public class MyFirebaseInstanceIDService extends FirebaseInstanceIdService { ... }
public class MyFirebaseMessagingService extends FirebaseMessagingService { ... }
and then register those services in the manifest. But, it's not quite perfect. In particular, these two recommended AndroidManifest.xml service entries do not contain any special permissions:
<service android:name=".MyFirebaseMessagingService">
<intent-filter>
<action android:name="com.google.firebase.MESSAGING_EVENT"/>
</intent-filter>
</service>
<service android:name=".MyFirebaseInstanceIDService">
<intent-filter>
<action android:name="com.google.firebase.INSTANCE_ID_EVENT"/>
</intent-filter>
</service>
and so the linter says:
Exported services (services which either set exported=true or contain an intent-filter and do not specify exported=false) should define a permission that an entity must have in order to launch the service or bind to it. Without this, any application can use this service.
Should I just add this attribute to each service tag and be done with it
tools:ignore="ExportedService"
or is there a better approach in this situation? I mean, is it safe to expose these particular Firebase derived services like this?
You ask: ...is it safe to expose these particular Firebase derived services like this? It is if you trust the comments in the manifest files for these services.
In Android Studio, open your app's AndroidManifest.xml file. At the bottom of the window, select the tab for Merged Manifest. Scroll to find the entry for FirebaseMessagingService. Double-click on the line that contains the service name. The manifest file for the service should open and you will see this:
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.google.firebase.messaging">
<uses-sdk android:minSdkVersion="14"/>
<application>
<!-- FirebaseMessagingService performs security checks at runtime,
no need for explicit permissions despite exported="true" -->
<service android:name="com.google.firebase.messaging.FirebaseMessagingService" android:exported="true">
<intent-filter android:priority="-500">
<action android:name="com.google.firebase.MESSAGING_EVENT"/>
</intent-filter>
</service>
</application>
</manifest>
Note the comment: FirebaseMessagingService performs security checks at runtime, no need for explicit permissions despite exported="true"
You can do the same for FirebaseInstanceIdService and see the same comment.
If you trust the comments (I do), you can safely ignore the lint warnings or disable the checks.
<service android:name=".java.MyFirebaseMessagingService"
android:exported="false">
<intent-filter>
<action android:name="com.google.firebase.MESSAGING_EVENT" />
</intent-filter>
</service>
Based on the official code sample, it's safe to set exported=false

GCM receiver with Parse

Hi I know this question has been asked multiple times but my requirement is a little different so pls bear with me.
I use two different libraries in my android application. One is for parse push notification which has the following declarations:
<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.airloyal.ladooo" />
</intent-filter>
</receiver>
and the declaration for the other receiver is:
<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.airloyal.ladooo" />
</intent-filter>
</receiver>
I definitely need both the libraries in my app so removing one is not an option. I use both the receivers for different purposes. But when I declare both the receivers there is a conflict and I am not able to receive any push notifications.
Can someone pls point me in the right direction?
P.S Both the libraries are jar files and I do not have control over the receivers of both. So forwarding is not an option.
Any help would be appreciated. Thanks
If the broadcast receivers are conflict with each other, you may try to set the priority of your receiver in the AndroidManifest.xml in <intent-filter>
Use this attribute only if you really need to impose a specific order in which the broadcasts are received, or want to force Android to prefer one activity over others.
The value must be an integer, such as "100". Higher numbers have a higher priority. The default value is 0. The value must be greater than -1000 and less than 1000.
sample code:
<intent-filter android:icon="drawable resource"
android:label="string resource"
android:priority="integer" >
. . .
</intent-filter>
Also, another way to solve, please refer to here.

How can I get data or title from receiving notifications?

I create simple "ParseStarterProject" as default of parse.com project. It works. I send notification from one device to other device successfully via setchannel method.
But the problem is I do not use receiver class(I do not know how can I use that) so when a notification comes I need to get its message ? it is possible? or if I use set data can I get its data ?
I use this code to send message:
ParsePush push = new ParsePush();
String yourMessage = "Selam from LG G2";//I want to get this message from other device?
push.setChannel("device2");
push.setMessage(yourMessage);
//push.setData("exampledata"); if I use this can I get this data from other device?
push.sendInBackground();
my manifest file:
<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" />
<!--
IMPORTANT: Change "com.parse.starter" to match your app's package name.
-->
<category android:name="com.parse.starter" />
</intent-filter>
</receiver>
thanks in advance
Create a class that extends BroadcastReceiver, here we call it MyCustomReceiver. Declare the usage of this receiver in your manifest:
<receiver android:name="com.example.MyCustomReceiver" android:exported="false">
<intent-filter>
<action android:name="com.example.UPDATE_STATUS" />
</intent-filter>
</receiver>
I'm not sure what you mean by you have problems with "MyCustomReceiver class on the main activity", in your comment to #kingspeech's answer.
In the worst case, you can create your own Receiver which extends the ParseBroadcastReceiver (and reference the extended class in the manifest). Then it should work by default, but you'll be able to hook into onReceive(Context, Intent)
As Parse tutorial directs, you ca use JSONObject to set data and you can put whatever you want.
Then when you receive Push notification you can have a access to read the previously prepared JSONObject. Please look at the Android tutorial https://parse.com/docs/push_guide#options/Android.
Hope this helps,
Regards.

Can we Only work with one broadcast receiver?

Can We only work with one broadcast receiver ?
I have some broadcast receiver and they works well , :
Note: Only one BroadcastReceiver class can be specified per application. Should you need to incorporate two or more BroadcastReceivers from different SDKs, you will need to create your own BroadcastReceiver class that will receive all broadcasts and call the appropriate BroadcastReceivers for each type of Broadcast.
Yes, you may use a single BroadcastReceiver to catch all action strings. Make sure you do add all the action string in your IntentFilter used by that receiver to make it work.
An <application> can contain multiple <receiver> and each <receiver> can contain multiple <intent-filter>. E.g.:
<application>
<receiver android:name="ReceiverA">
<intent-filter>
<action android:name="android.intent.action.ACTION1"/>
</intent-filter>
</receiver>
<receiver android:name="ReceiverB">
<intent-filter>
<action android:name="android.intent.action.ACTION2" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.ACTION3" />
<data android:scheme="file" />
</intent-filter>
</receiver>
</application>
But you can only have one "com.google.android.apps.analytics.AnalyticsReceiver" - that is IMO what the documentation means.

Can't use #string notation to define <intent-filter> in AndroidManifest.xml

My BroadcastReceiver never gets called when I use "#string/action_name" to define the intent filter action. If I copy/paste the corresponding string from strings.xml into AndroidManifest.xml, then it works perfectly!
Non working example from AndroidManifest.xml:
<receiver
android:name=".ServerUpdateReceiver" >
<intent-filter>
<action android:name="#string/ACTION_INFORM_USER_SERVER_UPDATE" />
</intent-filter>
</receiver>
Working example from AndroidManifest.xml:
<receiver
android:name=".ServerUpdateReceiver" >
<intent-filter>
<action android:name="com.franklinharper.intent.action.ACTION_INFORM_USER_SERVER_UPDATE" />
</intent-filter>
</receiver>
Just for completeness, strings.xml contains the following line:
<string name="ACTION_INFORM_USER_SERVER_UPDATE">com.franklinharper.intent.action.ACTION_INFORM_USER_SERVER_UPDATE</string>
From the spec, there is no way to configure an action with a resource identifier. It has to be a simple string, perhaps to avoid requiring the Android Intent dispatch system to open your APK to figure out what the filter is for.

Categories

Resources