Looking at the code sample here - I find the following comment puzzling:
// ... We assume here that the
// app has implemented a method called createShortcutResultIntent() that
// returns a broadcast intent.
what does it mean the app has implemented ... where is this implementation done?
is it a broadcast receiver? registered to which intent filter?
is this an abstract method? of which class?
and then I see this code sample - which handles a completely different flow (I think) and I'm lost again
You can obtain feedback via catching the broadcast event which you setup while use requestPinShortcut function.
At first you need a usual broadcast receiver (in the code below it has name ShortcutReceiver). You can even use existing broadcast receiver and simple add new action which it should catch.
Lets the action will be "general.intent.action.SHORTCUT_ADDED" and it will be stored in ShortcutReceiver.kInstalledAction constant. In this case in the manifest you should have:
<receiver android:name=".ShortcutReceiver" >
<intent-filter>
<action android:name="general.intent.action.SHORTCUT_ADDED"/>
</intent-filter>
</receiver>
After this you can use following code in the activity for create a pinned shortcut (in other places change this on object of Context class):
ShortcutManager manager = this.getSystemService(ShortcutManager.class);
Intent targetIntent = new Intent(ShortcutReceiver.kInstalledAction);
targetIntent.setPackage(this.getPackageName());
PendingIntent intent = PendingIntent.getBroadcast(this, 0, targetIntent, 0);
manager.requestPinShortcut(info, intent.getIntentSender());
In this code info is correct object of ShortcutInfo class.
You can handle the event while catch the broadcast:
public class ShortcutReceiver extends BroadcastReceiver {
public static final String kInstalledAction = "general.intent.action.SHORTCUT_ADDED";
#Override
public void onReceive(Context context, Intent intent) {
if (kInstalledAction.equals(intent.getAction())) {
// Handle the event after the shortcut has been added
Toast.makeText(context, "The shortcut has been added", Toast.LENGTH_LONG).show();
}
}
}
Please take into account that from my experience the broadcast event happens after the shortcut has been added but sometimes there can be some delays (at about some minutes). But may be there is some dependency on the launcher.
Update
As described in other answers on Android 8 catching of implicit intent via broadcast in general doesn't work.
So I simple changed the intent to explicit via set package name of the current app. So only our broadcast receiver can catch the intent.
First things first. Implicit intents on Android 8.0 Oreo:
Because Android 8.0 (API level 26) introduces new limitations for broadcast receivers, you should remove any broadcast receivers that are registered for implicit broadcast intents. Leaving them in place does not break your app at build-time or runtime, but they have no effect when your app runs on Android 8.0.
Explicit broadcast intents—those that only your app can respond to—continue to work the same on Android 8.0.
There are exceptions to this new restriction. For a list of implicit broadcasts that still work in apps targeting Android 8.0, see Implicit Broadcast Exceptions.
https://developer.android.com/about/versions/oreo/android-8.0-changes
Note: there are some exceptions: https://developer.android.com/guide/components/broadcast-exceptions (very few)
Instead, we will use the so-called context-registered receiver, it will last as long as our app lives, or until we unregister it.
Also, ShortcutManager requires API 25 that's why we will use it's compat version in order not to duplicate the code for old and new versions. (ShortcutManagerCompat was added in version 26.1.0)
Code to create a pinned shortcut on the Home screen:
public static void addShortcut(Context context, String id) {
if(context == null || note == null)
return;
//there may be various Home screen apps, better check it
if (ShortcutManagerCompat.isRequestPinShortcutSupported(context)){
Intent shortcutIntent = new Intent(context, MainActivity.class);
shortcutIntent.setAction(Constants.ACTION_SHORTCUT); // !!! intent's action must be set on oreo
ShortcutInfoCompat shortcutInfo = new ShortcutInfoCompat.Builder(context, note.get_id().toString())
.setIntent(shortcutIntent)
.setShortLabel("MyShortcut") //recommend max 10 chars
.setLongLabel("Long shortcut name")//recommend max 25 chars
.setIcon(IconCompat.createWithResource(context, R.drawable.ic_shortcut))
.build();
//callback if user allowed to place the shortcut
Intent pinnedShortcutCallbackIntent = new Intent(ACTION_SHORTCUT_ADDED_CALLBACK);
PendingIntent successCallback = PendingIntent.getBroadcast(context, REQ_CODE_SHORTCUT_ADDED_CALLBACK,
pinnedShortcutCallbackIntent, 0);
ShortcutManagerCompat.requestPinShortcut(context, shortcutInfo, successCallback.getIntentSender());
}
And here is the code to receive the broadcast in your Activity, for example. Note that this "callback" will be called only if your app is running, receiver is registered and the user allowed the shortcut:
private ShortcutAddedReceiver shortcutAddedReceiver;
private void registerShortcutAddedReceiver(){
if(shortcutAddedReceiver == null){
shortcutAddedReceiver = new ShortcutAddedReceiver();
}
IntentFilter shortcutAddedFilter = new IntentFilter(ShortcutHelper.ACTION_SHORTCUT_ADDED_CALLBACK);
registerReceiver(shortcutAddedReceiver, shortcutAddedFilter);
}
private void unregisterShortcutAddedReceiver(){
if(shortcutAddedReceiver != null){
unregisterReceiver(shortcutAddedReceiver);
shortcutAddedReceiver = null;
}
}
#Override
public void onStart() {
super.onStart();
registerShortcutAddedReceiver();
}
#Override
public void onStop() {
super.onStop();
unregisterShortcutAddedReceiver();
}
private class ShortcutAddedReceiver extends BroadcastReceiver{
#Override
public void onReceive(Context context, Intent intent) {
Snackbar.make(view, "Shortcut added", Snackbar.LENGTH_LONG).show();
}
}
Hope this helps!
Related
In my application I have registered a broadcast receiver for an implicit broadcast by another application protected with permission :
<receiver
android:name=".receiver.MyReceiver"
android:exported="true"
android:permission="owner.custom.permission">
<intent-filter>
<action android:name="owner.custom.broadcast"/>
</intent-filter>
</receiver>
In MyReceiver#onReceive() I am invoking a JobIntentService MyService using enqueueWork():
public class MyReceiver extends BroadcastReceiver {
#Override
public void onReceive(final Context context, final Intent intent) {
Log.i(TAG, "Received the broadcast");
MyService.enqueueWork(context, getServiceIntent(context));
}
private Intent getServiceIntent(final Context context) {
final Intent intent = new Intent(context, MyService.class);
intent.putExtra("someKey", true);
return intent;
}
}
I have the following method in MyService :
public static void enqueueWork(final Context context, final Intent work) {
enqueueWork(context, MyService.class, 111, work);
}
Now whenever owner.custom.broadcast is broadcast, MyReceiver is not triggered and I can see the following logs :
07-23 03:56:29.755 3335 3361 W BroadcastQueue: Background execution not allowed: receiving Intent { act=owner.custom.broadcast flg=0x10 } to com.amazon.myApp/.receiver.MyReceiver
Now the thing is I am listening to another such 3rd party implicit broadcast with a different broadcast receiver and invoking MyService over there and it works fine. I am also listening for BOOT_COMPLETED broadcast in a yet another broadcast receiver and invoking MyService over there and it works fine there too.
What are the possible causes for this error which would help me identify if I'm missing something.
UPDATE :
I am now just trying to get the broadcast receiver to trigger but I am still getting the same error. I am trying with nothing but a log line in the receiver :
public class MyReceiver extends BroadcastReceiver {
#Override
public void onReceive(final Context context, final Intent intent) {
Log.i(TAG, "Received the broadcast");
}
}
Android O limits the implicit broadcast, you can't execute a background service in the receiver.
However, it only limits the static receivers, you can register your receiver in the code to trigger your service.
Of course, in some case, you don't want to do it "programmatically", then you should check the error case, from this link http://androidxref.com/8.1.0_r33/xref/frameworks/base/services/core/java/com/android/server/am/BroadcastQueue.java#1275 (Line:1275), I find the error (not sure if this is the same as your system version).
We can see there are few conditions to access to this code block, we analyze them one by one, all we want to do is make the condition equals false:
(r.intent.getFlags()&Intent.FLAG_RECEIVER_EXCLUDE_BACKGROUND) != 0
It means if we don't want the background to receive the intent the condition will be true, and usually, we don't add this flag because we want the background to receive the broadcast, go ahead.
r.intent.getComponent() == null
It should not be null in any of our case, go ahead.
r.intent.getPackage() == null
Same above, go ahead.
r.intent.getFlags()&Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND) == 0
It means we cannot have a flag called Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND, I think we can try this, but you will see this in the Intent class:
/**
* If set, the broadcast will always go to manifest receivers in background (cached
* or not running) apps, regardless of whether that would be done by default. By
* default they will only receive broadcasts if the broadcast has specified an
* explicit component or package name.
*
* NOTE: dumpstate uses this flag numerically, so when its value is changed
* the broadcast code there must also be changed to match.
*
* #hide
*/
public static final int FLAG_RECEIVER_INCLUDE_BACKGROUND = 0x01000000;
It's hidden, but you can just hardcode the integer in your project, now add this flag to your intent to try if your code is work.
intent.addFlags(0x01000000)
Good luck :)
Note: this solution will NOT resolve to receive the system implicit broadcast to run background tasks.
This is an old question, but I found a solution which worked for me.
As mentioned here
Context-registered receivers receive broadcasts as long as their
registering context is valid. For an example, if you register within
an Activity context, you receive broadcasts as long as the activity is
not destroyed. If you register with the Application context, you
receive broadcasts as long as the app is running.
I had to remove the receiver declaration in the Manifest completely and register my receiver during runtime, using the Application context!
IntentFilter filter = new IntentFilter("owner.custom.broadcast");
getContext().getApplicationContext().registerReceiver(new MyReceiver(), filter);
and then
public class MyReceiver extends BroadcastReceiver
{
#Override
public void onReceive(Context context, Intent intent)
{
context.unregisterReceiver(this);
// ....
}
}
Try this
I faced a similar problem year ago, I'm not pretty sure of this, but since its not allowed for background execution then execute it in foreground using Foreground Service, you can achieve that by starting a service that is connected to a notification, then in your service you can trigger your broadcast and that should work.
I hope my answer helps you.
I'm not sure why this solution worked (maybe someone else can elaborate on why) but I was able to get my broadcast receiver to trigger by declaring the permission in my Manifest itself and and also using the same. Find the code changes below :
<permission
android:name="owner.custom.permission"
android:protectionLevel="signatureOrSystem">
</permission>
.
.
.
<uses-permission android:name="owner.custom.permission" />
I'm trying to create a pinned shortcut on the desktop for an app. The CreateShortcut method is called from a button and presents the android create-shortcut dialog. When the caller selects ok, the broadcast receiver should get called and execute finish so the activity exits.
This is the first time I've used a broadcast receiver but it looks like it's pretty straight-forward. Just create a receiver, register it with an intent filter that has the same action as an intent and when the intent is sent it should cause the receiver to be called, right?
The shortcut is created just fine but the broadcast receiver never gets called. I'm not seeing any messages on logcat.
private void CreateShortcut(final Context c) {
if (ShortcutManagerCompat
.isRequestPinShortcutSupported(c)) {
Intent shortcutIntent = new Intent(
c, CreateAppHomeShortcut.class);
shortcutIntent.setAction(
Intent.ACTION_CREATE_SHORTCUT);
ShortcutInfoCompat shortcutInfo
= new ShortcutInfoCompat
.Builder(c, "shortcut")
.setShortLabel(c.getString(R.string.app_name))
.setIcon(IconCompat.createWithResource(
c, R.drawable.qmark)
)
.setIntent(shortcutIntent)
.build();
registerReceiver(new BroadcastReceiver() {
#Override
public void onReceive(
Context context, Intent intent) {
Log.d(TAG, "msg received");
unregisterReceiver(this);
finish();
}
}
, new IntentFilter(
Intent.ACTION_CREATE_SHORTCUT
)
);
PendingIntent successCallback =
PendingIntent.getBroadcast(
c, 99
, shortcutIntent, 0
);
ShortcutManagerCompat.requestPinShortcut(c,
shortcutInfo,
successCallback.getIntentSender()
);
}
}
I've been working on this several days and I'm stumped.
Thanks
I finally got the callback to my BroadcastReceiver. My main problem was that I was using the intents wrong. I thought that the brodcast receiver intent and the shortcut intent could be the same as long as the action was correct. Wrong! The shortcut intent must hava an action set but in the tests I did, it didn't seem to care what that action was. And the broadcast receiver was created as "Intent = new Intent(context, class); setAction(...); ", the shortcut would be created and function fine but the broadcast receiver was never invoked. The only way I could get the broadcast receiver to work was with an Intent just for it with nothing but the action set (or possibly extras) set. I couldn't get the program to work using the same intent to create the shortcut and invoke the broadcast receiver.
The other problem encountered was that the interface allows you to create multiple pinned shortcuts -- and would then call your broadcast receiver once for each shortcut created. I discovered you can query the interface for all pinned shortcuts and filter by id to find out if your shortcut already exists and use that info to avoid creating multiple identical pinned shortcuts on your home page.
The code below seems to work fine API26+ for creating a shortcut and the receiver gets called as long as the user accepts the shortcut. The docs state that they will only call your receiver on the user's acceptance. That of course makes detecting the end of the user's interaction rather difficult. Since the request gets buried in my actual app, the plan was to open this as part of a separate activity, but I don't have any way to detect that the user is done if he doesn't want the shortcut. If anyone has suggestions, I'd appreciate hearing them.
// Create a shortcut and exit the activity. If the shortcut
// already exists,just exit.
private void CreateShortcut(final Context c) {
if (Build.VERSION.SDK_INT >= 26) {
ShortcutManager sm =
getSystemService(ShortcutManager.class);
if (sm != null && sm.isRequestPinShortcutSupported()) {
final String shortcutId = "StartApp";
boolean shortcutExists = false;
// We create the shortcut multiple times if given the
// opportunity. If the shortcut exists, put up
// a toast message and exit.
List<ShortcutInfo> shortcuts
= sm.getPinnedShortcuts();
for (int i = 0;
i < shortcuts.size() && !shortcutExists; i++) {
shortcutExists
= shortcuts.get(i).getId().equals(shortcutId);
if (shortcutExists) {
Toast.makeText(c , String.format(
"Shortcut %s already exists."
, shortcutId
)
, Toast.LENGTH_LONG
).show();
finishActivity();
}
else {
// this is the intent that actually creates the
// shortcut.
Intent shortcutIntent
= new Intent(c, CreateAppHomeShortcut.class);
shortcutIntent.setAction(
Intent.ACTION_CREATE_SHORTCUT);
ShortcutInfo shortcutInfo = new ShortcutInfo
.Builder(c, shortcutId)
.setShortLabel(
c.getString(R.string.app_name))
.setIcon(createWithResource(c
, R.drawable.qmark))
.setIntent(shortcutIntent)
.build();
// this intent is used to wake up the broadcast
// receiver.
// I couldn't get createShortcutResultIntent to
// work but just a simple intent as used for a
// normal broadcast intent works fine.
Intent broadcastIntent
= new Intent(Intent.ACTION_CREATE_SHORTCUT);
// create an anonymous broadcaster. Unregister
// to prevent leaks when done.
registerReceiver(new BroadcastReceiver() {
#Override
public void onReceive(
Context c, Intent intent) {
unregisterReceiver(this);
Log.d(TAG, String.format(
"ShortcutReceiver activity = "
+ "\"$1%s\""
, intent.getAction()));
finishActivity();
}
}
, new IntentFilter(
Intent.ACTION_CREATE_SHORTCUT)
);
PendingIntent successCallback
= PendingIntent.getBroadcast(
c, 99
, broadcastIntent, 0);
// Shortcut gets created here.
sm.requestPinShortcut(shortcutInfo
, successCallback.getIntentSender());
}
}
}
}
I have the activity SingleSpecial where a user clicks to share and initiates the actions below:
inviteFriend.setOnClickListener(new View.OnClickListener() {
public void onClick(View arg0) {
// Send broadcast of the sharedId to the SharingAction
Intent i = new Intent();
i.setAction("com.example.specialSharing.SHARED_SPECIAL");
i.putExtra("specialId", specialId);
sendBroadcast(i);
// Open invite activity:
Intent specialSharing = new Intent(getBaseContext(), InviteFriendOrGroup.class);
startActivity(specialSharing);
}
}
The InviteFriendOrGroup.class is intended to open and the user selects a person to share with. Upon selecting the person to share, the SharingAction class will open and is supposed to accept the Broadcast from the activity two steps ago, from the SingleSpecial class.
I have setup the Broadcast receiver to accept the action, and setup in the onCreate method of SharingAction:
BroadcastReceiver:
public class SpecialInfoReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Log.i("Shared special received ", "received special id");
Bundle extra = intent.getExtras();
if (extra != null) {
String action = intent.getAction();
if (action.equals("com.example.specialSharing.SHARED_SPECIAL")) {
Toast.makeText(getApplicationContext(), "The shared special Id is ok", Toast.LENGTH_LONG).show();
}
}
}
}
receiver in the onCreate:
SpecialInfoReceiver specialInfoReceiver = new SpecialInfoReceiver();
IntentFilter filter = new IntentFilter("com.example.specialSharing.SHARED_SPECIAL");
this.registerReceiver(specialInfoReceiver, filter);
As can be seen, the receiver is to show a toast upon receiving the sepcialId action. But it does nothing.
How can I set this up to work?
As per android documentation for the constructor for Intent(String action):
Create an intent with a given action. All other fields (data, type, class) are null. Note that the action must be in a namespace because Intents are used globally in the system -- for example the system VIEW action is android.intent.action.VIEW; an application's custom action would be something like com.google.app.myapp.CUSTOM_ACTION.
As well as Intent.setAction()'s action parameter:
An action name, such as ACTION_VIEW. Application-specific actions should be prefixed with the vendor's package name.
Both suggest valid action names are ones that belong within your namespace (base package). Not prefixing the namespace can lead to widespread problems of clashing action names between different apps.
It is possible the broadcast was never successfully made due to an invalid action name. Try changing the action to <package>.SHARED_SPECIAL.
Consider using a LocalBroadcastManager if you only intend to send broadcasts within your application. It is safer (as in other app components won't suddenly trigger if they were listening on the Intent).
Have you added the Broadcast to the Manifest?
<receiver android:name="com.example.SpecialInfoReceiver"/>
Or if Broadcast is inside another class:
<receiver android:name="com.example.YourActivity.$SpecialInfoReceiver"/>
I'm wanting to implement what CommonsWare describes on this blog post: http://commonsware.com/blog/2010/08/11/activity-notification-ordered-broadcast.html. The post makes sense, and I was able to browse the example source here: https://github.com/commonsguy/cw-advandroid/tree/master/Broadcast.
What I'm curious about is if calling LocalBroadcastManager.getInstance(UnzipService.this).sendBroadcast(broadcast); inside of a service will still be picked up by a broadcast receiver of the type you define in your manifest.
In case what I'm asking isn't clear, what I'm trying to do is use the LocalBroadcastManager because the broadcasts from my service don't necessarily need to be seen system wide and I'd rather keep them private if possible, but I also want to display notifications if the user closes my app and the service is still running. Is there a way to combine both of those capabilities without sending a broadcast twice inside of the service?
(What I don't want to have to do) like:
LocalBroadcastManager.getInstance(UnzipService.this).sendBroadcast(broadcast);
sendOrderedBroadcast(broadcast);
What I'm curious about is if calling LocalBroadcastManager.getInstance(UnzipService.this).sendBroadcast(broadcast); inside of a service will still be picked up by a broadcast receiver of the type you define in your manifest.
No. LocalBroadcastManager only works with receivers registered with the LocalBroadcastManager singleton itself. Moreover, LocalBroadcastManager does not support ordered broadcasts, last I checked.
what I'm trying to do is use the LocalBroadcastManager because the broadcasts from my service don't necessarily need to be seen system wide and I'd rather keep them private if possible
So long as you are not using an <intent-filter> on your BroadcastReceiver in the manifest, and therefore are using an explicit Intent as the broadcast itself, your broadcast will only be seen by yourself and the bit of the OS that manages broadcasts. Other apps will not be able to spy upon it.
If you only have 2 objects that might handle your broadcast (in your case an Activity and a notifications controller), you can achieve the behavior of a ordered broadcast using only the LocalBroadcastManager.
The general idea is:
Set up your Service so that it broadcasts an Intent to your Activity with a particular action when you want to display your result
In your Activity create a BroadcastReceiver that handles your Service result Intent, and register it on the LocalBroadcastManager with an IntentFilter using the action from step 1
In your Service, when the results are available, try to send the result Intent using LocalBroadcastManager.getInstance(Context).sendBroadcast(Intent) this method returns a boolean that indicates if the broadcast has been sent to at least one receiver. If this boolean is false, it means that your Activity didn't handle your broadcast and you should show a notification instead.
In your service:
public UnzipService extends IntentService {
public static final String ACTION_SHOWRESULT = UnzipService.class.getCanonicalName() + ".ACTION_SHOWRESULT";
#Override
protected void onHandleIntent(Intent intent) {
Thread.sleep(500); // Do the hard work
// Then try to notify the Activity about the results
Intent activityIntent = new Intent(this, YourActivity.class);
activityIntent.setAction(ACTION_SHOWRESULT);
activityIntent.putExtra(SOME_KEY, SOME_RESULTVALUE); // Put the result into extras
boolean broadcastEnqueued = LocalBroadcastManager.getInstance(this).sendBroadcast(activityIntent);
if (!broadcastEnqueued) { // Fallback to notification!
PendingIntent pendingIntent = PendingIntent.getActivity(this, (int) System.currentTimeMillis(), activityIntent, PendingIntent.FLAG_UPDATE_CURRENT);
((NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE))
.notify(SOME_ID, new NotificationCompat.Builder(this)
.setContentIntent(pendingIntent)
.setTicker("results available")
.setContentText("results")
.build());
}
}
}
In your Activity:
public YourActivity extends Activity {
private BroadcastReceiver resultReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
processResult(intent); // Results Intent received through local broadcast
}
}
private IntentFilter resultFilter = new IntentFilter(UnzipService.ACTION_SHOWRESULT);
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate();
Intent intent = getIntent();
if (UnzipService.ACTION_SHOWRESULT.equals(intent.getAction())) {
// The Activity has been launched with a tap on the notification
processResult(intent); // Results Intent contained in the notification PendingIntent
}
}
#Override
protected void onResume() {
super.onResume();
LocalBroadcastManager.getInstance(this)
.registerReceiver(resultReceiver, resultFilter);
}
#Override
protected void onPause() {
LocalBroadcastManager.getInstance(this)
.unregisterReceiver(resultReceiver);
super.onPause();
}
private void processResult(Intent intent) {
// Show the results from Intent extras
}
}
This should be a complete working example.
I hope this helps who is trying to implement ordered broadcasts with LocalBroadcastManager from support library!
I understand you want to achieve the following:
"I have an event that occurs in the background. I want to update my activity, if the activity is on the screen. Otherwise, I want to raise a Notification." (#TheCommonsBlog)
You can achieve this behaviour by implementing a ResultReceiver.
Examples Restful API service and
http://itekblog.com/background-processing-with-intentservice-class/
What you basically do is instance a ResultReceiver in your Activity and pass it to the Service like a Parcelable parameter through an intent. Then, each time your service whats to update the UI, the service verifies the ResultReceiver object for NULL. If not NULL, you update the Ui via the onReceiveResult interface. Else, you raise a notification. When your activity dismisses, make sure you set the ResultReceiver on the Service to NULL.
Hope it helps.
PS: IMO, broadcasts are too much work and hard to control.
Use LocalBroadcastManager and broadcasts become easy to use.
I am not in favor of updating an Activity if an event occurs in the background. The user might already be doing something else in the Activity. Seems to me that a Notification is sufficient; it's always visible and remains until the user dismisses it. Gmail and Gcal work like this; Gmail doesn't update the current screen if a new mail comes in. If you want to know how to handle the task flow for handling a notification when the user is already in the app, see the Notifications API guide and also the [Notifying The User2 training class.
EDIT: I found the solution, see below
My first post on StackOverFlow. However I have been reading about this problem for a while without a solution that works.
What I would like to do is register the following Intent: android.nfc.action.TAG_DISCOVERED
I am doing the following in my Code:
IntentFilter filter = new IntentFilter();
filter.addAction("android.nfc.action.TAG_DISCOVERED");
filter.addCategory("android.intent.category.DEFAULT");
Log.d(TAG, "Created the new filter");
reciever = new NFCBroadcastReciever(this);
Log.d(TAG, "Created the new Broadcast Reciever");
this.registerReceiver(reciever, filter);
Log.d(TAG, "Registered new reciever");
The BroadCastReciever is defined as follows:
public class NFCBroadcastReciever extends BroadcastReceiver {
private Screen screen;
public static String TAG = "NFCBroadcastReciever";
NFCBroadcastReciever(Screen _screen){
screen = _screen;
}
#Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
Log.d(TAG, "Action recieved: "+action);
if(action != null && NfcAdapter.ACTION_TAG_DISCOVERED.equals(action)){
paymentScreen.onNewIntent(intent);
}
}
}
However I get an exception that the intent being fired from a tag read has no corresponding Activity. I would like to be able to only start listening for NFC events at a certain point in my application.
Thanks in advance for your help.
I found the solution to the problem actually, the key to getting NFC events to occur only on a specific activity while it is active and not when other activities are running. The sample in the Android SDK explains it: http://developer.android.com/resources/samples/ApiDemos/src/com/example/android/apis/nfc/ForegroundDispatch.html
I found the solution to the problem actually, the key to getting NFC events to occur only on a specific activity while it is active and not when other activities are running. The sample in the Android SDK explains it: http://developer.android.com/resources/samples/ApiDemos/src/com/example/android/apis/nfc/ForegroundDispatch.html
Is your intention to start an activity when the broadcast is received? It doesn't seem to me that paymentScreen.onNewIntent(intent); is going to accomplish that. Instead, you will likely need to build an intent that you can use with startActivity() and you'll likely want to include the relevant data from your broadcast receiver's intent into your activity intent in the form of extras.