Background service on Ionic 2 geofence won't trigger - java

I'm working on an Ionic app that requires geofence to run in the background. I'm using the cordova-plugin-geofence plugin. I understand that JavaScript does not run in the background and that the plugin developer provided native code to listen to geofence transitions.
I followed the instructions but it doesn't seem to work. Transition does not trigger when the app is closed.
Here is my package name: io.ionic.pla.
I placed this code below in my Android Manifest
<receiver android:name="io.ionic.pla.TransitionReceiver">
<intent-filter>
<action android:name="com.cowbell.cordova.geofence.TRANSITION" />
</intent-filter>
</receiver>
Here is my TransitionReceiver.java
package io.ionic.pla;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.util.Log;
import com.cowbell.cordova.geofence.Gson;
import com.cowbell.cordova.geofence.GeoNotification;
public class TransitionReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
String error = intent.getStringExtra("error");
if (error != null) {
//handle error
Log.println(Log.ERROR, "YourAppTAG", error);
} else {
String geofencesJson = intent.getStringExtra("transitionData");
Log.println(Log.INFO, "xxxYourAppTAG", geofencesJson);
GeoNotification[] geoNotifications = Gson.get().fromJson(geofencesJson, GeoNotification[].class);
//handle geoNotifications objects
}
}
}
Please help guys, I really need this to work.

Related

Nativescript, Can't extend NotificationListenerService using typescript-angular2?

I'm trying to listen to all the notifications that the mobile receive, I'm working with nativescript & angular2,
First solution I've tried : -
after installing the tns-platform-declarations package and referencing it
android.service['notification']['NotificationListenerService'].extend({
onNotificationPosted: (sbn) => {
console.log("got it");
console.log(sbn.getNotification().tickerText);
},
onCreate: () => {
console.log("Created");
}
});
put unfortunately nothing happens on notification posted.
second try:-
I've made a java file and place it in
platforms/android/src/main/java/com/tns/MoNotificationListener.java
package com.tns;
import android.service.notification.NotificationListenerService;
import android.service.notification.StatusBarNotification;
import android.util.Log;
import android.app.Notification;
import java.util.List;
import java.util.Set;
import java.util.Arrays;
import java.util.ArrayList;
import android.widget.RemoteViews;
import java.lang.reflect.Field;
import android.os.Parcelable;
import android.os.Parcel;
import android.text.TextUtils;
import java.text.SimpleDateFormat;
import java.util.Date;
import android.app.PendingIntent;
public class MoNotificationListener extends NotificationListenerService {
static PendingIntent pickCallIntent ;
static PendingIntent rejectCallIntent ;
static PendingIntent hangCallIntent ;
#Override
public void onCreate() {
Log.d("ReactNative", "Created");
super.onCreate();
}
#Override
public void onListenerConnected() {
Log.d("ReactNative", "Got onListenerConnected");
}
#Override
public void onNotificationPosted(StatusBarNotification sbn) {
Log.d("Native", "Got Notification");
if(sbn.getNotification().tickerText !=null) {
Log.d("Native",sbn.getNotification().tickerText.toString());
Log.d("Native",sbn.getPackageName());
}
}
}
tested with
adb logcat *:S Native:V
and got the logs on notifications posted successfully
add to the android manifest in
app/App_Resources/Android/AndroidManifest.xml
<service
android:name="com.tns.WheemoNotificationListener"
android:permission="android.permission.BIND_NOTIFICATION_LISTENER_SERVICE"
>
<intent-filter>
<action android:name="android.service.notification.NotificationListenerService" />
</intent-filter>
</service>
then I was trying to extend that class from the typescript to get notified on notification posted.
android.service['notification']['NotificationListenerService'].extend("com.tns.notification.MoNotificationListener", {
onNotificationPosted: (sbn) => {
console.log("got it");
console.log(sbn.getNotification().tickerText);
},
onCreate: () => {
console.log("Created");
}
});
but again nothing happens
After searching we found that NotificationListenerService wasn't available through the default definition file
android.d.ts
so we used this
NativeScript/android-dts-generator
to generate a new one with the latest platform level we needed, and it worked.
thanks all

Android Studio: can't add class to <receiver> in AndroidManifest

I have done everything exactly as tutorial shows but I still get one error...I have created new activity SmsReceiver.java and there is everything OK but in the manifest when I try to add this
<receiver android:name=".SmsReceiver"> // <-- this is problem
<intent-filter android:priority="1000">
<action android:name="android.provider.Telephony.SMS_RECEIVED" />
</intent-filter>
</receiver>
It doesn't want to accept that class .SmsReceiver....
I have tried everything please help. When i hover mouse over it says " 'class' or 'interface' expected ".
Here is package view and manifest full code
This is SmsReceiver.java code
package com.dreamdev.matko.smsarduino;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.telephony.SmsMessage;
import android.widget.Toast;
public class SmsReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Bundle bundle = intent.getExtras();
if (bundle != null) {
Object[] pdus = (Object[]) bundle.get("pdu");
for (int i = 0; i < pdus.length; i++) {
SmsMessage sms = SmsMessage.createFromPdu((byte[]) pdus[i]);
String from = sms.getOriginatingAddress();
String msg = sms.getDisplayMessageBody();
Toast.makeText(context, "Prišla správa", Toast.LENGTH_LONG).show();
}
}
}
}
You say:
I have created new activity SmsReceiver.java
If you have created an Activity, then you cannot declare it in the manifest as a BroadcastReceiver. If you want to have a BroadcastReceiver then your class needs to extend BroadcastReceiver and then you add it to the manifest like this:
<receiver android:name=".SmsReceiver">
Please extend the class as a BroadcastReceiver in your .java file. Like below
public class SmsReceiver extends BroadcastReceiver {
......
}

Why isn't my BroadcastReceiver starting on the Android Emulator?

I'm new to Android development, and I'm trying to create a simple "proof of concept application" which will run as a background service. I'm trying to use IntentService with a BroadcastReceiver to kick off the process (during boot time for now, at some point I might switch it to Screen on / user present).
I created a new project within Android Studio with no activity. Then I added the following Java files and made the following changes to the AndroidManifest.xml.
AndroidManifest.xml
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.circlesquires.netcountable.netcountable">
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED">
</uses-permission>
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:supportsRtl="true"
android:theme="#style/AppTheme">
<service android:name=".SnapshotService" android:exported="true">
</service>
<receiver android:name=".ServiceStarter" >
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
</application>
</manifest>
ServiceStarter.java
package com.circlesquires.netcountable.netcountable;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.util.Log;
/**
* Created by camha on 6/18/2016.
*/
public class ServiceStarter extends BroadcastReceiver{
static final String ACTION = "android.intent.action.BOOT_COMPLETED";
#Override
public void onReceive(Context context, Intent intent) {
Log.i("output", "onReceive occured!");
if(intent.getAction().equals(ACTION)) {
Intent serviceIntent = new Intent(context, SnapshotService.class);
context.startService(serviceIntent);
}
}
}
SnapshotService.java
package com.circlesquires.netcountable.netcountable;
import android.app.IntentService;
import android.content.Intent;
import android.util.Log;
/**
* Created by camha on 6/18/2016.
*/
public class SnapshotService extends IntentService {
public SnapshotService() {
super("SnapshotService");
}
#Override
protected void onHandleIntent(Intent workIntent) {
while(true) {
Log.i("output", "I'm running!");
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
I deploy the application to an emulator being sure to click the "debug" button. However I don't ever see ANY of the logs outputted in logcat.
I'm sure I'm doing something wrong--help me figure out what :D. Thanks!
android.intent.action.BOOT_COMPLETED is send, as its name suggest, after, but only after a device boot time. Are you restarting your device?
Instead of restarting device to test out your application, you can send system broadcasts directly through adb:
./adb shell am broadcast -a android.intent.action.BOOT_COMPLETED -c android.intent.category.HOME -n <your.package.name>/.<YourReceiverClass>
You can find more info here.
if (intent.getAction().equals(Intent.ACTION_BOOT_COMPLETED)) {
Intent i = new Intent(context, SnapshotService.class);
context.startService(i);
}
compare direct with intent value instead of making string
and one thing more
On Android 3.1 and higher, the user must launch one of your activities before any manifest-registered BroadcastReceiver will work.
check this https://stackoverflow.com/a/17067671/3288890

Google Play / Google Analytics INSTALL_REFERRER for BroadcastReceiver in 2014

On StackOverflow, I noticed a number of people having trouble catching INSTALL_REFERRER over the years, and a number of bug reports on the Android forum (all closed due to "wrong forum" -- but, I'm not seeing any public issue tracker). I'm wondering if anyone has a way to get INSTALL_REFERRER to work in the current 2014 version of Google Play.
Edit: I did find an issue tracker and created an issue:
https://code.google.com/p/play-games-platform/issues/detail?id=202
Edit 2: (replace com.myapp with the app's name)
Here's what I did for a test of the response. This is the same as on Google's Analytics help docs. This works.
adb shell am broadcast -a com.android.vending.INSTALL_REFERRER -n com.myapp/com.flyingsoftgames.googleplayquery.QueryReceiver --es "referrer" "utm_source=testSource&utm_medium=testMedium&utm_term=testTerm&utm_content=testContent&utm_campaign=testCampaign"``
Here's what I did for a test of the response from Google's Play Store. This is also the same as Google's Analytics help docs, from the link generation utility. (Yes, the keys are different, but that's per the docs, and not what I'm testing -- I just want ANY response, and the docs indicate that referrer should work...) I installed from this rank and ran, listening for QueryReceiver with logcat (adb logcat -s QueryReceiver). This doesn't work.
https://play.google.com/store/apps/details?id=com.myapp&referrer=utm_source%3Dgoogle%26utm_medium%3Dcpc%26utm_term%3Dpodcast%252Bapps%26utm_content%3DdisplayAd1%26utm_campaign%3Dpodcast%252Bgeneralkeywords
Here is my (Cordova plugin) code, which works perfectly when triggering a manual broadcast:
AndroidManifest.xml:
<receiver android:exported="true" android:name="com.flyingsoftgames.googleplayquery.QueryReceiver">
<intent-filter>
<action android:name="com.android.vending.INSTALL_REFERRER" />
</intent-filter>
</receiver>
GooglePlayQuery.java:
package com.flyingsoftgames.googleplayquery;
import com.flyingsoftgames.googleplayquery.QueryReceiver;
import org.apache.cordova.CallbackContext;
import org.apache.cordova.CordovaInterface;
import org.apache.cordova.CordovaWebView;
import org.apache.cordova.CordovaPlugin;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.Context;
import android.app.Activity;
import android.content.ComponentName;
import android.content.pm.PackageManager;
import org.json.JSONArray;
import org.json.JSONException;
public class GooglePlayQuery extends CordovaPlugin {
public static CallbackContext queryCallback = null;
public static CordovaInterface cordova = null;
#Override public void initialize (CordovaInterface initCordova, CordovaWebView webView) {
// Create a static cordova reference so that QueryReceiver can access it.
cordova = initCordova;
// Enable the broadcast receiver in case it isn't enabled.
Activity activity = cordova.getActivity ();
ComponentName receiver = new ComponentName (activity, QueryReceiver.class);
PackageManager pm = activity.getPackageManager ();
pm.setComponentEnabledSetting (receiver, PackageManager.COMPONENT_ENABLED_STATE_ENABLED, PackageManager.DONT_KILL_APP);
super.initialize (cordova, webView);
}
public boolean execute (String action, JSONArray inputs, CallbackContext callbackContext) throws JSONException {
if ("getURI".equals(action)) {this.queryCallback = callbackContext;}
return true;
}
}
QueryReceiver.java:
package com.flyingsoftgames.googleplayquery;
import com.flyingsoftgames.googleplayquery.GooglePlayQuery;
import org.apache.cordova.PluginResult;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.app.Activity;
import android.content.ComponentName;
import android.content.pm.PackageManager;
import android.util.Log;
public class QueryReceiver extends BroadcastReceiver {
#Override public void onReceive (Context context, Intent intent) {
if (GooglePlayQuery.queryCallback != null) {
Log.d ("QueryReceiver", intent.toURI());
GooglePlayQuery.queryCallback.sendPluginResult (new PluginResult (PluginResult.Status.OK, intent.toURI()));
}
// Now disable the broadcast receiver since we don't need it anymore.
Activity activity = GooglePlayQuery.cordova.getActivity ();
ComponentName receiver = new ComponentName (activity, QueryReceiver.class);
PackageManager pm = activity.getPackageManager ();
pm.setComponentEnabledSetting (receiver, PackageManager.COMPONENT_ENABLED_STATE_DISABLED, PackageManager.DONT_KILL_APP);
}
}
I believe I finally found the reason that it does not work. There is a silent error where GooglePlayQuery.cordova is null. QueryReceiver.onReceive runs before GooglePlayQuery.initialize, but only in production mode. Insane.
I still need a few hours to test it (as my game is published) to verify, but here's my new code. It's also available at https://github.com/agamemnus/cordova-plugin-google-play-query-receiver.
AndroidManifest.xml:
<receiver android:exported="true" android:name="com.flyingsoftgames.googleplayquery.QueryReceiver">
<intent-filter>
<action android:name="com.android.vending.INSTALL_REFERRER" />
</intent-filter>
</receiver>
GooglePlayQuery.java:
package com.flyingsoftgames.googleplayquery;
import com.flyingsoftgames.googleplayquery.QueryReceiver;
import org.apache.cordova.CallbackContext;
import org.apache.cordova.CordovaInterface;
import org.apache.cordova.CordovaWebView;
import org.apache.cordova.CordovaPlugin;
import org.apache.cordova.PluginResult;
import android.content.Intent;
import android.app.Activity;
import android.content.ComponentName;
import android.content.pm.PackageManager;
import org.json.JSONArray;
import org.json.JSONException;
public class GooglePlayQuery extends CordovaPlugin {
public static CallbackContext queryCallback = null;
public static CordovaInterface cordova = null;
public static String referrer_uri = "";
public static Intent QueryReceiverCachedIntent = null;
#Override public void initialize (CordovaInterface initCordova, CordovaWebView webView) {
// Create a static cordova reference so that QueryReceiver can access it.
cordova = initCordova;
// Enable the broadcast receiver in case it isn't enabled.
Activity activity = cordova.getActivity ();
ComponentName receiver = new ComponentName (activity, QueryReceiver.class);
PackageManager pm = activity.getPackageManager ();
pm.setComponentEnabledSetting (receiver, PackageManager.COMPONENT_ENABLED_STATE_ENABLED, PackageManager.DONT_KILL_APP);
// If the QueryReceiver's onReceive already ran, run the cached data.
if (QueryReceiver.cachedIntent != null) {QueryReceiver.runCachedOnReceive (QueryReceiver.cachedIntent);}
super.initialize (cordova, webView);
}
public boolean execute (String action, JSONArray inputs, CallbackContext callbackContext) throws JSONException {
if ("getURI".equals(action)) {
if (referrer_uri != "") {
callbackContext.sendPluginResult (new PluginResult (PluginResult.Status.OK, referrer_uri));
referrer_uri = "";
return true;
}
this.queryCallback = callbackContext;
}
return true;
}
}
QueryReceiver.java:
package com.flyingsoftgames.googleplayquery;
import com.flyingsoftgames.googleplayquery.GooglePlayQuery;
import org.apache.cordova.PluginResult;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.app.Activity;
import android.content.ComponentName;
import android.content.pm.PackageManager;
import android.util.Log;
public class QueryReceiver extends BroadcastReceiver {
public static Intent cachedIntent = null;
#Override public void onReceive (Context context, Intent intent) {
// If the onReceive occurred before the GooglePlayQuery initialize function ran: cache the intent. Otherwise, run as intended.
if (GooglePlayQuery.cordova == null) {cachedIntent = intent;} else {runCachedOnReceive (intent);}
}
public static void runCachedOnReceive (Intent intent) {
if (cachedIntent != null) cachedIntent = null;
Log.e ("QueryReceiver", intent.toURI());
if (GooglePlayQuery.queryCallback != null) {
GooglePlayQuery.queryCallback.sendPluginResult (new PluginResult (PluginResult.Status.OK, intent.toURI()));
} else {
GooglePlayQuery.referrer_uri = intent.toURI();
}
// Now disable the broadcast receiver since we don't need it anymore.
Activity activity = GooglePlayQuery.cordova.getActivity ();
ComponentName receiver = new ComponentName (activity, QueryReceiver.class);
PackageManager pm = activity.getPackageManager ();
pm.setComponentEnabledSetting (receiver, PackageManager.COMPONENT_ENABLED_STATE_DISABLED, PackageManager.DONT_KILL_APP);
}
}

Service not starting when button is pressed?

I know this has been asked a million times before, but nothing is working for me. I have a service in a separate class that needs to be started when a button is pushed, after an application is launched from a LaunchIntent.
Long story short, here's my goal:
run commands>wait three seconds for commands to run>launch app>start service
The service is to monitor for the CONFIGURATION_CHANGED broadcast.
Manifest (the parts that matter):
</activity>
<receiver android:name="MyReceiver" >
<intent-filter>
<action android:name="android.intent.action.CONFIGURATION_CHANGED" >
</action>
</intent-filter>
</receiver>
<service android:enabled="true" android:name=".MyService" />
</application>
</manifest>
MyService.java:
import android.content.Context;
import android.content.Intent;
import android.os.IBinder;
import android.widget.Toast;
import android.app.Service;
public class MyService extends Service {
String[] commandsdefault = {"/x"};
public void onCreate() {
Toast.makeText(this, "x", Toast.LENGTH_SHORT);
}
public void onDestroy() {
Toast.makeText(this, "x", Toast.LENGTH_SHORT);
}
public void onReceive(Context context, Intent intent) {
MainActivity ogres = new MainActivity();
ogres.RunAsRoot(commandsdefault);
}
#Override
public void onStart(Intent intent, int startid) {
Toast.makeText(this, "x", Toast.LENGTH_SHORT);
}
#Override
public IBinder onBind(Intent intent) {
return null;
}
}
And then I simply have the following line in my MainActivity.java to call the service to start:
startService(new Intent(getApplicationContext(), MyService.class));
I am more confused than a mosquito in a mannequin shop. LogCat is returning absolutely nothing helpful other than u=0 not found.
Do I have something incorrect here? I'm not even seeing toasts from the service starting.
Make sure your service is declared in Android manifest
try to Override the onStartCommand() method of your service. hope this helps
Try specifying the full name of your service as the android:name attribute (e.g. android:name="com.example.MyService")
Ok, solved my own question.
MyService was running the whole time! I just didn't see the toast notifications to alert me when it started. Now I have a monitor in my main Activity that posts a toast when the service is started/killed, rather than using MyService itself to post toasts.

Categories

Resources