Push notifications with GCM, Freshplanet ANE, Flash Professional CS6 and VB.NET - android

I have created a Flash CS6 AIR for Android application with the Freshplanet ANE for push notifications. Everything seems to be working, but I am still not receiving the notifications on my device.
Here is my Flash CS6 code:
import com.freshplanet.nativeExtensions.PushNotification;
import com.freshplanet.nativeExtensions.PushNotificationEvent;
txtMsg.text = 'starting..';
var push:PushNotification = PushNotification.getInstance();
if (push.isPushNotificationSupported) {
push.registerForPushNotification("XXXXXXXXXXXXX"); //Google project ID
}
push.addEventListener(PushNotificationEvent.PERMISSION_GIVEN_WITH_TOKEN_EVENT, onRegistered);
push.addEventListener(PushNotificationEvent.PERMISSION_REFUSED_EVENT, onRefused);
function onRegistered(event:PushNotificationEvent):void
{
txtMsg.appendText("Registered with registration id:" + event.token);
}
function onRefused(event:PushNotificationEvent):void
{
txtMsg.appendText("Refused:" + event.errorMessage);
}
This code seems to work, because when i launch my App on my device, my txtMsg field displays the event.token. A long string containing what Im guessing to be the unique device id.
My Android manifest looks like this:
`
<android>
<manifestAdditions>
<![CDATA[<manifest>
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.WAKE_LOCK"/>
<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="com.google.android.c2dm.permission.RECEIVE" />
<uses-permission android:name="air.it.test.PushTest2.permission.C2D_MESSAGE" />
<permission android:name="air.it.test.PushTest2.permission.C2D_MESSAGE" android:protectionLevel="signature" />
<application>
<activity android:name="air.it.test.PushTest2"></activity>
<receiver android:name="com.freshplanet.nativeExtensions.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="air.it.test.PushTest2" />
<intent-filter>
</intent-filter>
<action android:name="com.google.android.c2dm.intent.REGISTRATION" />
<category android:name="air.it.test.PushTest2" />
</intent-filter>
</receiver>
<service android:name="com.freshplanet.nativeExtensions.LocalNotificationService"/>
<receiver android:name="com.freshplanet.nativeExtensions.LocalBroadcastReceiver" android:process=":remote"></receiver>
</application>
</manifest>]]>
</manifestAdditions>
</android>
<extensions>
<extensionID>com.freshplanet.AirPushNotification</extensionID>
</extensions>
`
This is my VB.NET server application which sends the message to the device with the token received above.
Dim regId As String = "XXXXXXXX-XXXXXXXXXXXXXXXXXXXXXXXXXX" device token id
Dim MessageText As String = "Hope this works"
Dim applicationID As String = "APP ID" 'received from Google API console as the Key for server applications
Dim result As String = ""
Dim SENDER_ID As String = "XXXXXXXXXXXXX" 'same ID used in my actionscript file above - Google project ID
Dim httpWebRequest As WebRequest = WebRequest.Create("https://android.googleapis.com/gcm/send")
httpWebRequest.ContentType = "application/json"
httpWebRequest.Method = "POST"
httpWebRequest.Headers.Add(String.Format("Authorization: key={0}", applicationID))
httpWebRequest.Headers.Add(String.Format("Sender: key={0}", SENDER_ID))
Dim streamWriter As StreamWriter = New StreamWriter(httpWebRequest.GetRequestStream())
Dim json As String = "{""registration_ids"": [""" & regId & """], ""data"": {""message"": """ & MessageText & """}}"
Response.Write(json)
streamWriter.Write(json)
streamWriter.Flush()
streamWriter.Close()
Dim httpResponse As WebResponse = httpWebRequest.GetResponse()
Dim streamReader As StreamReader = New StreamReader(httpResponse.GetResponseStream())
result = streamReader.ReadToEnd()
Response.Write(result)
When i run this function, it get a success message. So everything seems to work correctly, but my device doesn't receive anything. What am i doing wrong? Thanks

Fresh Planet have many branches, try this which is more recent:
https://github.com/freshplanet/ANE-Push-Notification/tree/feature/famepop-withOptions
And you need change the JASON to send these values:
contentTitle <---- this is the title
contentText <---- this is the message
tickerText <---- this is showed in the task bar

This?
push.addEventListener(PushNotificationEvent.COMING_FROM_NOTIFICATION_EVENT, onPushMessage);

Related

Amazon IAP Delegate not executed in Xamarin (Listener doesn't work?)

I'm trying to implement Amazon IAP in a xamarin project following the documentation here.
So here's how my manifest looks like:
<manifest xmlns:android="http://schemas.android.com/apk/res/android" android:versionCode="87" android:versionName="8.7" package="XXXXXXXXXXXX">
<uses-sdk android:minSdkVersion="21" android:targetSdkVersion="31" />
<application android:icon="#mipmap/ic_launcher" android:label="XXXXXXXXXXXX">
<meta-data android:name="com.google.android.gms.ads.APPLICATION_ID" android:value="XXXXXXXXXXXX" />
<receiver android:name="com.amazon.device.iap.ResponseReceiver" android:permission="com.amazon.inapp.purchasing.Permission.NOTIFY" >
<intent-filter>
<action android:name="com.amazon.inapp.purchasing.NOTIFY" />
</intent-filter>
</receiver>
</application>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
And here's my code which is in the Android Project of my solution:
public async Task<bool> MyMethod()
{
try
{
var iapService = AmazonIapV2Impl.Instance;
var tcs = new TaskCompletionSource<bool>();
var skus = new SkusInput { Skus = new List<string>() { "XXXXXXXXX" } };
var requestId = iapService.GetProductData(skus).RequestId;
GetProductDataResponseDelegator delegator = null;
delegator = new GetProductDataResponseDelegator(async response =>
{
await Task.Run(() =>
{
DoSomething();
tcs.SetResult(result);
});
});
iapService.AddGetProductDataResponseListener(delegator.responseDelegate);
await tcs.Task;
}
catch(Exception ex)
{
}
return true;
}
This doesn't throw exceptions but the method DoSomething(); is never called and the last line return true; is never reached. Also the line tcs.Task is stuck on WaitingActivation status. It's like the listener/reciever wasn't working. So my code endlessly wait for the answer.
Any idea how to fix this?
I'm using Xamarin Form version: 5.0.0
Running on Mac, through Visual Studio and debugging on a simulator or a real device (Xiaomi mi9)
Thanks
So first of all the code await Task.Run(() => wasn't necessary to make it work. Secondly, the problem was that my app wasn't submitted yet on the Amazon AppStore and so to test a non-submit app you need to download on your testing phone the app:Amazon App Tester.
In case you have issue to download the Amazon App Tester read this:
In the past, I've tried to download the Amazon App Tester but for some reason my phone didn't want it. I finally "bought" it (it's $0.00 anyway) from my computer on amazon website. Once bought, I was able to find the app in the tab "my app" in the Amazon AppStore on my phone.

Android-9 CallLog: CACHED_NAME and CACHED_PHOTO_URI always return NULL from CallLog

I had an app where I fetched Call Log and Contact List and showed them in a RecyclerView. Everything was going fine up to android-8. Suddenly I found that Names are not showing on an Android-9 Device. Then a debug shows that CACHED_NAME and CACHED_PHOTO_URI are always returning null on andorid-9.
I get NUMBER, DURATION and every other thing very well, only the CACHED_NAME and CACHED_PHOTO_URI are missing.
I have checked the changelog of android-9, handled the calllog permission properly, I'm attaching my permissions from manifest with this question. My app is properly taking runtime permissions too. I also checked it on device's Settings. In addition, my app is also set to Default Phone app.
<uses-permission android:name="android.permission.RECEIVE_SMS" />
<uses-permission android:name="android.permission.READ_CONTACTS" />
<uses-permission android:name="android.permission.WRITE_CONTACTS" />
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.READ_PHONE_NUMBERS" />
<uses-permission android:name="android.permission.ANSWER_PHONE_CALLS" />
<uses-permission android:name="android.permission.CALL_PHONE" />
<uses-permission android:name="android.permission.READ_CALL_LOG" />
<uses-permission android:name="android.permission.WRITE_CALL_LOG" />
<uses-permission android:name="android.permission.PROCESS_OUTGOING_CALLS" />
String number = cursor.getString(cursor.getColumnIndex(CallLog.Calls.NUMBER));
String name = cursor.getString(cursor.getColumnIndex(CallLog.Calls.CACHED_NAME));
Log.d("tag", "name: " + (name == null ? "null": name));
String date = cursor.getString(cursor.getColumnIndex(CallLog.Calls.DATE));
String duration = cursor.getString(cursor.getColumnIndex(CallLog.Calls.DURATION));
String photoUri = cursor.getString(cursor.getColumnIndex(CallLog.Calls.CACHED_PHOTO_URI));
Log.d("tag", "photoUri: " + (photoUri == null ? "null": photoUri));
String subscription_id = cursor.getString(cursor.getColumnIndex(CallLog.Calls.PHONE_ACCOUNT_ID));
String subscription_component_name = cursor.getString(cursor.getColumnIndex(CallLog.Calls.PHONE_ACCOUNT_COMPONENT_NAME));
Its working fine on android 8 and below, can anyone tell me where is the problem with android-9?
Please check that if needs RuntimePermission for CALL_LOG GROUP. Because they made some changes on Android-9
first, get contacts from Contacts.Contract and then get name, photo by phone number, or contact Id from the database.

CreateTransportFailure with PortSip

I am trying to create a basic calling app on Android with PortSip but get an error from the setUser method (error -60098: CreateTransportFailure). I think I've followed all the steps as their sample app, and I've used the same credentials that work with the sample app. I've tried using a different local port (as suggested in another post), but haven't had any success. These are my steps:
context = this.getApplicationContext();
callingSDK = new PortSipSdk();
callingSDK.setOnPortSIPEvent(this);
callingSDK.CreateCallManager(context);
int initStatus = callingSDK.initialize(PortSipEnumDefine.ENUM_TRANSPORT_UDP,
"0.0.0.0", 5771, PortSipEnumDefine.ENUM_LOG_LEVEL_DEBUG, LogPath, 200,
"PortSIP VoIP Calling App", 0, 0, "", "", false);
// initialize returns ECoreErrorNone
callingSDK.setSrtpPolicy(PortSipEnumDefine.ENUM_SRTPPOLICY_NONE);
int licenseStatus = callingSDK.setLicenseKey("PORTSIP_TEST_LICENSE");
// setLicenseKey return ECoreTrialVersionLicenseKey, as expected
int userStatus = callingSDK.setUser(accountName, displayName, authName, password,
domain, server, 5060, "", 0, null, 5060);
Apparently, another factor in this error condition is assuring the app that the appropriate permissions. Adding these to the manifest gets past the issue with setUser.
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />

How to get NFC working on Android using Qt 5.6

I'm trying to read NFC tags on my Android phone using the NFC module of Qt.
According to this page, Qt will support NFC on Android starting from version 5.6. This version hasn't been released yet, so I built it from source, following the instructions on this page, and installed it in Qt creator.
First step is to get the tag/card detection working and I'm stuck there. My test application instantiates a QNearFieldManager, checks if NFC is available and connects slots to the signals targetDetected and targetLost.
The QNearFieldManager::isAvailable method reports that NFC is available (with Qt 5.5 it did not), but the signals targetDetected/targetLost are never fired.
Below is the code of my test application:
#include <QLabel>
#include <QVBoxLayout>
#include <QNearFieldManager>
#include <QNearFieldTarget>
#include <QDebug>
#include "window.h"
Window::Window(QWidget *parent)
: QWidget(parent)
{
nfcLabel_ = new QLabel(this);
QVBoxLayout *mainLayout = new QVBoxLayout;
mainLayout->addWidget(nfcLabel_, 1);
setLayout(mainLayout);
setSizePolicy(QSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed));
setWindowTitle(tr("NFC Test"));
nfc_ = new QNearFieldManager(this);
if (nfc_->isAvailable()) {
nfcLabel_->setText("NFC available");
} else {
nfcLabel_->setText("NFC not available");
qWarning() << "NFC not available";
}
nfc_->setTargetAccessModes(QNearFieldManager::NdefReadTargetAccess); // doesn't help
nfc_->registerNdefMessageHandler(this, SLOT(handleNdefMessage(QNdefMessage,QNearFieldTarget*))); // doesn't help
connect(nfc_, SIGNAL(targetDetected(QNearFieldTarget*)), this, SLOT(targetDetected(QNearFieldTarget*)));
connect(nfc_, SIGNAL(targetLost(QNearFieldTarget*)), this, SLOT(targetLost(QNearFieldTarget*)));
if (!nfc_->startTargetDetection()) {
qWarning() << "NFC target detection could not be started";
}
}
Window::~Window()
{
nfc_->stopTargetDetection();
}
void Window::targetDetected(QNearFieldTarget * /*target*/)
{
nfcLabel_->setText("Target detected");
}
void Window::targetLost(QNearFieldTarget *target)
{
nfcLabel_->setText("Target lost");
target->deleteLater();
}
void Window::handleNdefMessage(const QNdefMessage &/*message*/, QNearFieldTarget */*target*/)
{
qDebug() << "Ndef Message";
}
I must be missing something...
UPDATE 1
It appears that the AndroidManifest.xml file needs to be modified. I tried different things, but none seem to produce the desired effect. I can only get the targetDetected and targetLost events to fire when the manifest defines an intent-filter like this:
<intent-filter>
<action android:name="android.nfc.action.TAG_DISCOVERED"/>
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
However, this also causes the app to be started each time a target is scanned, even if the app is already running. What I need is to start the app and then wait for a target to be scanned. How can I accomplish this?
UPDATE 2
Below is the full AndroidManifest.xml file that I tried.
<?xml version="1.0"?>
<manifest package="org.qtproject.example" xmlns:android="http://schemas.android.com/apk/res/android" android:versionName="1.0" android:versionCode="1" android:installLocation="auto">
<application android:hardwareAccelerated="true" android:name="org.qtproject.qt5.android.bindings.QtApplication" android:label="-- %%INSERT_APP_NAME%% --" android:theme="#android:style/Theme.Holo">
<activity android:configChanges="orientation|uiMode|screenLayout|screenSize|smallestScreenSize|layoutDirection|locale|fontScale|keyboard|keyboardHidden|navigation" android:name="org.qtproject.qt5.android.bindings.QtActivity" android:label="-- %%INSERT_APP_NAME%% --" android:screenOrientation="unspecified" android:launchMode="singleTop">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
<!-- Without this, the targetDetected/targetLost signals aren't fired -->
<intent-filter>
<action android:name="android.nfc.action.TAG_DISCOVERED"/>
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
<meta-data android:name="android.app.lib_name" android:value="-- %%INSERT_APP_LIB_NAME%% --"/>
<meta-data android:name="android.app.qt_sources_resource_id" android:resource="#array/qt_sources"/>
<meta-data android:name="android.app.repository" android:value="default"/>
<meta-data android:name="android.app.qt_libs_resource_id" android:resource="#array/qt_libs"/>
<meta-data android:name="android.app.bundled_libs_resource_id" android:resource="#array/bundled_libs"/>
<!-- Deploy Qt libs as part of package -->
<meta-data android:name="android.app.bundle_local_qt_libs" android:value="-- %%BUNDLE_LOCAL_QT_LIBS%% --"/>
<meta-data android:name="android.app.bundled_in_lib_resource_id" android:resource="#array/bundled_in_lib"/>
<meta-data android:name="android.app.bundled_in_assets_resource_id" android:resource="#array/bundled_in_assets"/>
<!-- Run with local libs -->
<meta-data android:name="android.app.use_local_qt_libs" android:value="-- %%USE_LOCAL_QT_LIBS%% --"/>
<meta-data android:name="android.app.libs_prefix" android:value="/data/local/tmp/qt/"/>
<meta-data android:name="android.app.load_local_libs" android:value="-- %%INSERT_LOCAL_LIBS%% --"/>
<meta-data android:name="android.app.load_local_jars" android:value="-- %%INSERT_LOCAL_JARS%% --"/>
<meta-data android:name="android.app.static_init_classes" android:value="-- %%INSERT_INIT_CLASSES%% --"/>
<!-- Messages maps -->
<meta-data android:value="#string/ministro_not_found_msg" android:name="android.app.ministro_not_found_msg"/>
<meta-data android:value="#string/ministro_needed_msg" android:name="android.app.ministro_needed_msg"/>
<meta-data android:value="#string/fatal_error_msg" android:name="android.app.fatal_error_msg"/>
<!-- Messages maps -->
<!-- Splash screen -->
<!--
<meta-data android:name="android.app.splash_screen_drawable" android:resource="#drawable/logo"/>
-->
<!-- Splash screen -->
<!-- Background running -->
<!-- Warning: changing this value to true may cause unexpected crashes if the
application still try to draw after
"applicationStateChanged(Qt::ApplicationSuspended)"
signal is sent! -->
<meta-data android:name="android.app.background_running" android:value="false"/>
<!-- Background running -->
</activity>
</application>
<uses-sdk android:minSdkVersion="10" android:targetSdkVersion="14"/>
<supports-screens android:largeScreens="true" android:normalScreens="true" android:anyDensity="true" android:smallScreens="true"/>
<uses-feature android:name="android.hardware.nfc" android:required="true"/>
<uses-permission android:name="android.permission.NFC"/>
</manifest>
If you are using NFC tag of certain manufacturer the same should be present in the mobile NFC also then only it will pair correctly as of now NFC do not support globally. For eg. if the NFC Present inside the Sony device will max support its manufacture only and in most cases it fails to connect to others devices like nexus. So try to find your Manufacturer and connect it . Hope it helps you..
I don't believe you want those intent filters in your manifest. Adding those, tells the operating system to start your app when a tag is detected (which is why it is doing so). It does look like you're registering correctly in your code for NFC events, so perhaps the issue is the brand of NFC chip in your phone, in conjunction with the tag you're using to test with. If your phone is equipped with a Broadcom NFC chip, and you're trying to use NXP's Mifare Classic tag, you'll run into issues. Using a Desfire, or NTAG tag might help.
I have solved this one.
The reason is that in QtNfc.java where qt handles NFC intents it handles only NDEF tags by filtering ACTION_NDEF_DISCOVERED actions (and ACTION_TECH_DISCOVERED for NDEF tags that will report as tech) without simple ACTION_TAG_DISCOVERED (despite the fact it handles it in getStartIntent fuction).
But I supposed you just want to scan a simple tag to read uid, as I do. So you need to add ACTION_TAG_DISCOVERED to filter list in QtNfc.java start() function:
IntentFilter[] filters = new IntentFilter[3];
filters[0] = new IntentFilter();
filters[0].addAction(NfcAdapter.ACTION_TAG_DISCOVERED);
filters[0].addCategory(Intent.CATEGORY_DEFAULT);
...
I think it would be more correct to modify filter to ACTION_TAG_DISCOVERED in setContext too.
The fastest way is to open in qt creator qtconnectivity .pro for corresponding branch, correct QtNfc.java, build it and replace libQt5Nfc.so in android_armv7\lib qt folder (QtNfc.jar and QtNfc-bundled.jar in android_armv7\jar folder will be updated during build).
That is. No need to modify manifest in working application.
By the way this one:
<uses-permission android:name="android.permission.NFC"/>
qt add automatically when you add module nfc to .pro
This one
<uses-feature android:name="android.hardware.nfc" android:required="true"/>
is not necessary I suppose. It works without it.
But you can add this intent-filter if you want to tell android to start your app when a tag is detected as Anansi mentioned upper. But I really recommend to add
android:alwaysRetainTaskState="true" android:launchMode="singleInstance"
in application activity (like here).
I test all this with android 4.4.4 tablet and ndefeditor example. It fires targetDetected/targetLost perfectly. There can be another default application for tags in system (for example NFC Reader) and it opens up on every tag detecting, but not the time ndefeditor is waiting tag (button retrieve). And of course qt example says "NDEF read error" for non-NDEF tags, but it detects them and reads uid. Precisely what I needed.
I add the suggestion to Qt Jira and submit the patch.
The only thing I didn't understand - why ndefeditor had worked on another tablet with android 4.2. Maybe it is a hardware aspect and android on another tablet was always intent ACTION_NDEF_DISCOVERED?
Hello below is the answer, let me know if you are looking for this only. :)
Firstly write this in onCreate()
//Code in onCreate
mNfcAdapter = NfcAdapter.getDefaultAdapter(this);
mPendingIntent = PendingIntent.getActivity(this, 0,
new Intent(this, getClass()).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP), 0);
// set an intent filter for all MIME data
IntentFilter ndefIntent = new IntentFilter(NfcAdapter.ACTION_NDEF_DISCOVERED);
try {
ndefIntent.addDataType("*/*");
mIntentFilters = new IntentFilter[] { ndefIntent };
} catch (Exception e) {
Log.fnLogToFile(strFunctionName + "-" + e.getMessage(), ErrorType.ERROR);
Log.createCrashReport();
}
mNFCTechLists = new String[][] { new String[] { NfcF.class.getName() } };
Write this onNewIntent outside onCreate()
#Override
public void onNewIntent(Intent intent) {
StackTraceElement[] arrFunctionName = Thread.currentThread().getStackTrace() ;
String strFunctionName = arrFunctionName[arrFunctionName.length-1].getMethodName();
Log.fnLogToFile(strFunctionName + "Entered", ErrorType.INFO);
tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
String strTagData = "";
// parse through all NDEF messages and their records and pick text type only
Parcelable[] data = intent.getParcelableArrayExtra(NfcAdapter.EXTRA_NDEF_MESSAGES);
if (data != null) {
try {
for (int i = 0; i < data.length; i++) {
NdefRecord [] recs = ((NdefMessage)data[i]).getRecords();
for (int j = 0; j < recs.length; j++) {
if (recs[j].getTnf() == NdefRecord.TNF_WELL_KNOWN &&
Arrays.equals(recs[j].getType(), NdefRecord.RTD_TEXT)) {
byte[] payload = recs[j].getPayload();
String textEncoding = ((payload[0] & 0200) == 0) ? "UTF-8" : "UTF-16";
int langCodeLen = payload[0] & 0077;
//tag data is saved in strTagData
strTagData += ("\n" +
new String(payload, langCodeLen + 1,
payload.length - langCodeLen - 1, textEncoding));
}
}
}
} catch (Exception e) {
Log.fnLogToFile(strFunctionName + "-" + e.getMessage(), ErrorType.ERROR);
Log.createCrashReport();
Log.e("TagDispatch", e.toString());
}
}
}
You will get NFC data in strTagData variable
Permission in Manifest

Push notification reaching ios (apns) but not android (gcm) device

So I have a simple Ruby app that uses Rpush to send push notifications to my iphone and my android phone. Right now all it does is sends it to the iphone. I am not sure whether the problem is with my script (i.e. incorrect values for the registration_id, app_name, or auth_key), or whether the problem is how I have my Android app configured.
The relevant part of that code is here (values changed for security - but format/length of keys left untouched to make sure they "look right" to people with experience)
API SETUP/RATIONALE (Sending the notification)
# GCM
app = Rpush::Gcm::App.new
app.name = "MyApp"
app.auth_key = "POfaSyfghilK3l-ueSvRLmbawcRThCWkwmcYGeM"
app.connections = 1
app.save
n = Rpush::Gcm::Notification.new
n.app = Rpush::Gcm::App.find_by_name("MyApp")
n.registration_ids = ["derGV80JK-s:APA91bHgerskBnrhHndes947nMKxI116tC3-k-tGd-hT5NzVc8QAWEkvCrMwrvs78RUL8-vvhp2ultoevqzZnn8gsr9t6WDXDYpGfCliqaJzj0XByBgbi0bm-rYufjcxfCc_5lEL381F"]
n.data = { message: "testing!" }
n.save!
Rpush.push
I determined that the name of my app was "MyApp" by looking at my google developer console here and noticing that the "Project Name" of the desired project is "MyApp".
I determined the Auth Key on the same site, by navigating to API & Auth -> Credentials -> API Key and copy/pasting the API key from there.
I determined my device's registration id using this code in the main activity of my Android App:
public static String getDeviceID(Context context) {
final TelephonyManager tm = (TelephonyManager) context
.getSystemService(Context.TELEPHONY_SERVICE);
final String tmDevice, tmSerial, tmPhone, androidId;
tmDevice = "" + tm.getDeviceId();
tmSerial = "";// + tm.getSimSerialNumber();
androidId = ""
+ android.provider.Settings.Secure.getString(
context.getContentResolver(),
android.provider.Settings.Secure.ANDROID_ID);
UUID deviceUuid = new UUID(androidId.hashCode(),
((long) tmDevice.hashCode() << 32) | tmSerial.hashCode());
String deviceId = deviceUuid.toString();
return deviceId;
}
When logged, getDeviceID shows me the registration id that I specified in the above ruby code.
APP SETUP/RATIONALE (Receiving the notification)
First, I set up my Android Manifest to have all the necessary permissions
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
<uses-permission android:name="com.johncorser.myapp.permission.RECEIVE" />
<permission android:protectionLevel="signature"
android:name="com.johncorser.myapp.permission.C2D_MESSAGE" />
<uses-permission android:name="com.johncorser.myapp.permission.C2D_MESSAGE" />
Then, I set up a listener service to react to push notifications:
<service
android:name="com.johncorser.myapp.services.GcmListenerService"
android:exported="false" >
<intent-filter>
<action android:name="com.google.android.c2dm.intent.RECEIVE" />
</intent-filter>
</service>
That class is very simple and looks like this:
public class GcmListenerService extends com.google.android.gms.gcm.GcmListenerService {
public void onMessageReceived(String from, Bundle data) {
String message = data.getString("message");
Log.d("push", "From: " + from);
Log.d("push", "Message: " + message);
}
}
I would expect these messages to log out after sending the push notifications. But instead nothing happens (no exceptions thrown on the server or app).
Any one see what I'm doing wrong here?
Why are you using the UUID you generated from the Android Device ID as a registration ID for Google Cloud Messaging?
That's NOT how you get a registration id.
To get a registration ID you have to register with GCM on the device and receive back a registration ID/token, as described in Cloud Messaging for Android Quickstart:
InstanceID instanceID = InstanceID.getInstance(this);
String token = instanceID.getToken(getString(R.string.gcm_defaultSenderId),
GoogleCloudMessaging.INSTANCE_ID_SCOPE, null);
In order for the above code to work you need to have a google-services.json configuration file (which is parsed by the com.google.gms.google-services gradle plugin, that you also need) in your app/ directory and you need the gcm_defaultSenderId which is the Project ID (Number) you get from the Google Developers Console.
You can easily generate that file and receive the above details by clicking the button "Get a configuration file" and following the steps mentioned there.
The code to get the registration ID needs to be in an IntentService as described here, and you need to define the service in the AndroidManifest.xml file as outlined here
For GCM to be able to communicate with your app, you also need to define in the manifest file a com.google.android.gms.gcm.GcmReceiver which has an intent filter with an action name "com.google.android.c2dm.intent.RECEIVE" and a category name with your package name. Look here for an example.
Try running the sample here by Google themselves.
https://developers.google.com/cloud-messaging/android/start
https://github.com/googlesamples/google-services/tree/master/android/gcm
I feel like something might just be missing in your manifest file.
Hope that helps.
In case anyone else runs in to this, the problem was that I did not whitelist my IP address on developers.google.com. I now have it set so all IPs are whitelisted, and it works like a charm.

Categories

Resources