Android C2DM and lib project - android

I'm currently working on a libproject (Android) that should be included inside a few other applications.
Everything is working fine now that I've been struggling a bit with Activities and Manifests, exept for the C2DM bit.
I can invoke my different classes fine, but I can't seem to catch the registration ID (or of course actual messages, but that must be the same problem...)
I think the problem is coming from the filtering in my manifest(s), so if anyone has any advice for me, that would be really helpful.
Here is a copy of receiver part of my manifest (from the apps, not the library, but it's actually just a copy), but it's pretty straighforward. I just want to know how I should adapt it in order to invoke the right class in the lib...
<!--
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="com.myapp.lib" />
</intent-filter>
<!-- Receive the registration id -->
<intent-filter>
<action android:name="com.google.android.c2dm.intent.REGISTRATION" />
<category android:name="com.myapp.lib" />
</intent-filter>
</receiver>
Where com.myapp.lib is my lib package name, and the receiver is in a package named the same (in the lib project, of course).
Thanks in advance for the help, and don't hesitate to ask for furthers details :)
Edit :
I tried with only the lib registered on google C2DM, and also with both app and lib. Same problem

There is a better way of using your C2DM from a library project by using the intent-filter.
The manifest file is the one from the app.
The package for the lib is com.mylib and the one for the app is com.myapp.
There is 2 things to change from the lib manifest.
The classpath used in permissions.
The intent-filter package.
Both should be you app package and not your lib package.
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.myapp"
android:versionCode="1"
android:versionName="1.0" >
<permission android:name="com.myapp.permission.C2D_MESSAGE" android:protectionLevel="signature" />
<uses-permission android:name="com.myapp.permission.C2D_MESSAGE" />
<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />
<application
android:icon="#drawable/icon"
android:label="#string/app_name" >
<uses-library android:name="com.google.android.maps" android:required="true"/>
<activity
android:name=".MyActivity"
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.mylib.C2DMRegistrationReceiver"
android:permission="com.google.android.c2dm.permission.SEND" >
<intent-filter>
<action android:name="com.google.android.c2dm.intent.REGISTRATION" >
</action>
<category android:name="com.myapp" />
</intent-filter>
</receiver>
<receiver
android:name="com.mylib.C2DMMessageReceiver"
android:permission="com.google.android.c2dm.permission.SEND" >
<intent-filter>
<action android:name="com.google.android.c2dm.intent.RECEIVE" >
</action>
<category android:name="com.myapp" />
</intent-filter>
</receiver>
</application>
</manifest>

Answer, is anyone stumble upon the same problem...
In the google.android.c2dm package, class C2DMBaseReceiver, method runIntentInService, change
String receiver = context.getPackageName() + ".C2DMReceiver"
with the fully qualified name.. and there you go :)

The manifest looks fine. In your package you should have a class called C2DMReceiver and it should extend C2DMBaseReceiver. This class and the overridden methods it contains are then called upon successful registration and when a message is received. I have written a very basic example of this that may be helpful for you to refer to here

Related

Can't find uses-permission into manifest file

I'm trying to upload a new version of an application into Google Developer Console.
At the end of the upload, the console show this error message:
"Your APK uses permissions that require the setting of privacy policies: (android.permission.CAMERA)"
So I think that I have this uses-permission into the manifest file and I need to add a google privacy policy.
That's ok, but this is my manifest file:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="simone.biliato.delonghitrevisotvb">
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:supportsRtl="true"
android:theme="#style/AppTheme">
<activity
android:name="simone.biliato.delonghitrevisotvb.MainActivity"
android:label="#string/app_name"
android:theme="#style/AppTheme.NoActionBar">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<service android:name="simone.biliato.delonghitrevisotvb.NotificationInstanceIdService">
<intent-filter>
<action android:name="com.google.firebase.INSTANCE_ID_EVENT" />
</intent-filter>
</service>
<service android:name="simone.biliato.delonghitrevisotvb.NotificationMessagingService">
<intent-filter>
<action android:name="com.google.firebase.MESSAGING_EVENT" />
</intent-filter>
</service>
</application>
Where are all the permissions? Why I don't see them? I'm sure that I added them earlier and now disappear. Is there a specific location? A list of all permission for the project?
User permissions are made up from the ones you have in your manifest and those that come from the library or dependencies you have in your project. The result will be a manifest merged by all of them. Check your dependencies.
You can use the apk analyzer : https://developer.android.com/studio/build/apk-analyzer.html
Our friends from CommonsWare give us a good solution to detect where the permissions come from:
https://commonsware.com/blog/2015/06/25/hey-where-did-these-permissions-come-from.html
To get a better sense of where those elements are
coming from, we can look at
app/build/outputs/logs/manifest-merger-debug-report.txt.

Specific device not receiving Google Cloud Messaging notifications

I have an application where I'm implementing Google Cloud Messaging notifications, but in a specific device the messages don't arrive. This device has the minimum requirements to use GCM (Android version 2.2, Play Store installed and an Google Account logged). In the log I see that the device is receiving the registration id and sending to the back-office where I have a list of devices registered.
My question is: Do I need to make extra configurations to make the device receive these notifications?
Here is the manifest
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="br.com.testegcm"
android:versionCode="1"
android:versionName="1" >
<uses-sdk
android:minSdkVersion="7"
android:targetSdkVersion="18" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />
<permission android:name="com.example.gcm.permission.C2D_MESSAGE"
android:protectionLevel="signature" />
<uses-permission android:name="com.example.gcm.permission.C2D_MESSAGE" />
<application
android:name="TesteGCM"
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<receiver
android:name="br.com.testegcm.GcmBroadcastReceiver"
android:exported="true"
android:enabled="true"
android:permission="com.google.android.c2dm.permission.SEND" >
<intent-filter>
<action android:name="com.google.android.c2dm.intent.RECEIVE" />
<category android:name="br.com.testegcm" />
</intent-filter>
</receiver>
<service android:name="br.com.testegcm.GcmIntentService" />
<activity
android:name="br.com.testegcm.Home"
android:screenOrientation="portrait"
android:label="#string/app_name"
android:theme="#style/notitle" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
Change this :
<permission android:name="com.example.gcm.permission.C2D_MESSAGE"
android:protectionLevel="signature" />
<uses-permission android:name="com.example.gcm.permission.C2D_MESSAGE" />
to :
<permission android:name="br.com.testegcm.permission.C2D_MESSAGE"
android:protectionLevel="signature" />
<uses-permission android:name="br.com.testegcm.permission.C2D_MESSAGE" />
Add the same issue and i eventually i realized that i need to change in the manifest, the broadcast receiver package name from com.example.gcm to my package name :
<!-- Push notifcations-->
<receiver
android:name=".BroadcastRecivers.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.gcm"/>
</intent-filter>
</receiver>
To
<!-- Push notifcations-->
<receiver
android:name=".BroadcastRecivers.GcmBroadcastReceiver"
android:permission="com.google.android.c2dm.permission.SEND">
<intent-filter>
<action android:name="com.google.android.c2dm.intent.RECEIVE"/>
<category android:name="MY PACKAGE NAME"/>
</intent-filter>
</receiver>
No apart from Android version 2.2, Play Store app installed and an Google Account logged in no other configuration is needed, Now there are only two cases left
1) Either there is some ambiguity in your code.
2) or may be it is a device specific issue.
I had the very same problem.My code would work on nexus4(Kitkat) but would fail to get me a notification from the appln server(via gcm server).For versions less that 4.0.4 you should make sure that you have your google account setup on your device for gcm to work. I had google account on my phone but the mistake I made was that my Account and Sync settings in my galaxy ace was 'Off'.When I turned it ON and ran my code, i received the notification.
Please check the following solution. if still didn't work, let me know.
Add RECEIVE and REGISTRATION Intent in two different intent filters
<receiver
android:name=“<.GCM BroadcastReceiver Name>“ // Name of your BroadcastReceiver, define in code.
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=“<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=“<.GCM IntentService Name>" /> // Name of your IntentService, define in code.
<meta-data
android:name="com.google.android.gms.version"
android:value="#integer/google_play_services_version" />
Add RECEIVE and REGISTRATION Intent in two different intent filters as shown as above otherwise it won’t work for some devices(Ex. HTC).

What kind of case can I omit?

The following code works well, I often find some sample code to omit, so I change my code as
<service android:name=".MyInternetServer"></service>
but I get an error "The service can't be found".
I guess the package="com.example.enabledisablebroadcastreceiver" and
<service android:name="com.code4reference.enabledisablebroadcastreceiver.MyInternetServer"></service>,
maybe it should be use full name, right?
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.enabledisablebroadcastreceiver"
android:versionCode="1"
android:versionName="1.0" >
<application
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<activity
android:name="com.code4reference.enabledisablebroadcastreceiver.EnableDisableBroadcastReceiver"
android:label="#string/title_activity_enable_disable_boradcast_receiver" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<!-- Broadcast receiver -->
<receiver android:name="com.code4reference.enabledisablebroadcastreceiver.AlarmManagerBroadcastReceiver" >
<intent-filter>
<action android:name="android.provider.Telephony.SMS_RECEIVED" />
</intent-filter>
</receiver>
<service android:name="com.code4reference.enabledisablebroadcastreceiver.MyInternetServer"></service>
</application>
</manifest>
The shorthand "dot" notation in the Manifest file works as described in the documentation:
However, as a shorthand, if the first character of the string is a
period, the string is appended to the application's package name (as
specified by the <manifest> element's package attribute).
So in your case, using:
.MyInternetServer
...is shorthand for:
com.example.enabledisablebroadcastreceiver.MyInternetServer
as that's what's in your <manifest>'s package attribute.
I'm guessing you probably want to update your manifest's package attribute to match the package you're actually using for your project.
Yes give your service a full path, where its actually located with full package name and then check, it will work.

Android Play Store Campaign tracking pre-requisites

I'm attempting to use a campaign to promote my application. I've found these instructions and am attempting to do step one:
https://developers.google.com/analytics/devguides/collection/android/v2/campaigns#google-play-campaigns
However, my IDE (IntelliJ) is telling me it cannot resolve "com.google.analytics.tracking.android.CampaignTrackingService" in the Manifest file.
Is this a Bug in the IDE? Or is there a library I'm meant to be including with my application? And are there any other steps they have missed out? E.g. do I need to be adding internet permissions to my application?
When I run the application it seems to work fine, and here is my Android Manifest file:
<uses-sdk android:minSdkVersion="7" android:targetSdkVersion="17" />
<application
android:icon="#drawable/ic_launcher_toddlerswords"
android:label="#string/app_name"
android:hardwareAccelerated="true">
<activity android:name="maddy.toddlercolors.ToddlerWords"
android:screenOrientation="landscape"
android:theme="#android:style/Theme.NoTitleBar">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name="maddy.toddlercolors.menu.QuickPrefsActivity" android:label="#string/app_name"/>
<!-- Used for install referral measurement-->
<service android:name="com.google.analytics.tracking.android.CampaignTrackingService"/>
<receiver android:name="com.google.analytics.tracking.android.CampaignTrackingReceiver" android:exported="true">
<intent-filter>
<action android:name="com.android.vending.INSTALL_REFERRER" />
</intent-filter>
</receiver>
</application>
After some further reading it looks like campaign tracking requires a google analytics jar, and will require internet permissions.
https://developers.google.com/analytics/devguides/collection/android/v2/

Android - Declare widget in manifest

I have 1 android app project and 1 widget project, they all work fine. Now, i want to include widget project to android app project in order to when user install application, the widget will be installed too. I did like below but it did not work. Any helps?
Thanks you!
In manifest file:
<application>
............ (this is of android app project. below is of widget).......
<receiver android:name=".widget.PlayerWidgetActivity" >
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
</intent-filter>
<meta-data android:name="android.appwidget.provider"
android:resource="#xml/playerwidgetprovider" />
</receiver>
<service android:name=".widget.PlayerWidgetActivity$UpdateService" />
<service android:name=".widget.PlayerWidgetActivity$ServiceBindUnbindService" />
</application>
EDIT: My application is quite big (.APK ~ 10MB), of course it has many activity, many services, many broadcast receivers, ..... so it takes times to build.
I create a new very small application with just an activity and put the code for widget like i put on the big app above. It works! OMG! Why it worked on that small app but not my big app :(
<application
android:icon="#drawable/ic_launcher"
android:label="#string/app_name" >
<activity
android:label="#string/app_name"
android:name=".activity.ApplicationWithWidgetActivity" >
<intent-filter >
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<receiver android:name=".widget.PlayerWidgetActivity"
android:icon="#drawable/ic_launcher"
android:label="#string/appwidget_name">
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
</intent-filter>
<meta-data android:name="android.appwidget.provider"
android:resource="#xml/playerwidgetprovider" />
</receiver>
<service android:name=".widget.PlayerWidgetActivity$UpdateService" />
<service android:name=".widget.PlayerWidgetActivity$ServiceBindUnbindService" />
</application>
I've had same problem!
The solution is - INSTALLING APPLICATION INTO PHONE.
Just move application to phone and you will see your widget.
Hope it helps you!
Info from here: http://www.hrupin.com/2012/07/how-to-fix-android-homescreen-widget-installation-widget-as-part-of-android-application

Categories

Resources