Android localbroadcast causes app to crash - android

We are having trouble with local broadcasts. For some reason in 2 androids(my own phone + boss's phone) it works fine. On another phone(galaxy s3 mini like my boss) and on boss's tablet it however crash. Program crash if the tmp.sendBroadcast command is but not right away(it still does bit after that). However it never gets to receiver.
public class UpdaterIntent extends IntentService {
...
Intent intent = new Intent("my-event");
intent.putExtra("action", "update_workplaces");
intent.putExtra("parameters", time);
LocalBroadcastManager'tmp=LocalBroadcastManager.getInstance(myInst);
if(tmp!=null) {
tmp.sendBroadcast(intent);
}
I have registered receiver like this:
LocalBroadcastManager.getInstance(this).registerReceiver(mMessageReceiver,
new IntentFilter("my-event"));
Receiver is this:
private BroadcastReceiver mMessageReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
Toast.makeText(myContext, "received message", Toast.LENGTH_SHORT).show();
}
}
};
I have tried to search for some reason why it might be so. Thought it might have been too long parameters as putExtra but even after trimming it to two strings(one seen in code, one is just a date that comes from server like "2014-03-28 12:20:02" etc so now there shouldn't be danger of exceeding some hard coded limit.
Any suggestions? Don't like any workarounds to this that I have come up with being clumsy as hell.

LocalBroadcastManager.getInstance(this).sendBroadcast(intent);

Related

Why Calendar broadcasts too many intents?

I have registered BroadcastReceiver for Calendar Provider. Code works fine but when I just change one calendar event - I get several broadcasted intents. This would not be too much annoying but each intent in my app causes download all calendar events for specific time period. There could be lots of events in several days and each includes String texts and other data. Extra broadcasted intents force exchange too many extra data. And this all happens on mobile device connected to cellular or Wi-Fi network. This wastes traffic and battery.
I do not know - is there a way to separate really creative intent from others. Code is simple:
class RegisterReceiver implements Runnable
{
private Activity a;
private CalendarReceiver receiver;
public RegisterReceiver(Activity _a){
a = _a;
}
public void run(){
IntentFilter filter = new IntentFilter();
filter.addAction(Intent.ACTION_PROVIDER_CHANGED);
filter.addDataScheme("content");
filter.addDataAuthority("com.android.calendar", null);
a.registerReceiver(receiver = new CalendarReceiver(), filter);
}
public CalendarReceiver getreceiver()
{
return receiver;
}
}
class CalendarReceiver extends BroadcastReceiver
{
public void onReceive(Context context, Intent intent)
{
MainControl.DebugMessage( intent.getAction() );
MainControl.calendarChanged();
}
}
The MainControl.calendarChanged(); forces further processing. The intent.getAction() just contains info this is a "provider changed" intent. On each calendar action it appears several times with long delays. It is the same when I add calendar events, delete ot change them. Is there a way how to define which one intent is "my"? Is there any description of how to separate new, deleted, changed event intents?

Start Activity from a Broadcast Receiver

I've got the following scenario for Android: I have an app that when launched starts a service. That service checks a url every 30 minutes. If it gets a specific response, it sends a Broadcast which the app receives and processes. That scenario is working great for me.
I'd also like my service to continue running after the user has stopped running the application (app out of foreground.) Which I've got working as well.
The problem that I'm facing is that when the Activity receives the Broadcast message, I can't get the Activity to move back to the foreground. I've tried various combinations of intents, but haven't figured it out. What am I doing wrong?
My BroadcastReceiver code looks like this:
private BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
launchApp();
}
};
private void launchApp() {
Intent vukaniActivity = new Intent(this, Vukani.class);
// I've tried multiple different flags to no avail.
vukaniActivity.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(vukaniActivity);
}
The flags you want are:
vukaniActivity.setFlags( Intent.FLAG_ACTIVITY_NEW_TASK
| Intent.FLAG_ACTIVITY_CLEAR_TOP
| Intent.FLAG_ACTIVITY_SINGLE_TOP);
Also, make sure you're running on the UI Thread.
runOnUiThread(new Runnable(){
#Override
public void run(){
launchApp();
}
});

Android activity not getting broadcast from local service

From the examples this looked straightforward. Maybe you can show me what I did wrong. I can't get an activity to receive a broadcast sent from a local service.
I have Activity1 that start Service1:
startService(new Intent(Activity1.this, Service1.class));
Activity1 then starts Activity2:
startActivity(new Intent(Activity1.this, Activity2.class));
Service1, a local service, listens for downloads:
protected final BroadcastReceiver service2DownloadBroadcastReceiver = new BroadcastReceiver()
{
public void onReceive(final Context context, final Intent intent)
{
...
broadcastDownloadFinished(Uri.fromFile(downloadedFile));
The broadcast receiver of Service1 then broadcasts its own message:
protected Intent broadcastDownloadFinished(final Uri uri)
{
final Intent intent = new Intent(ACTION_DOWNLOAD_FINISHED).setData(checkNotNull(uri));
sendBroadcast(intent);
Activity2, which is in the foreground at the time, listens for the ACTION_DOWNLOAD_FINISHED intent using its own broadcast receiver:
private final BroadcastReceiver activity2DownloadBroadcastReceiver = new BroadcastReceiver()
{
public void onReceive(final Context context, final Intent intent)
{
Log.i(Activity2.class.getSimpleName(), "Received download event: " + intent.getAction() + " " + intent.getData());
Activity2 of course registers the receiver:
protected void onResume()
{
super.onResume();
final IntentFilter downloadIntentFilter = new IntentFilter();
downloadIntentFilter.addAction(ACTION_DOWNLOAD_FINISHED);
registerReceiver(activity2DownloadBroadcastReceiver, downloadIntentFilter);
In case it matters, ACTION_DOWNLOAD_FINISHED is something like "com.example.intent.action.DOWNLOAD_FINISHED".
Service1 receives the download manager event in its receiver and apparently broadcasts its own custom event, but Activity2 never seems to receive it. What did I do wrong? Is it a problem to broadcast an intent in the middle of processing another one? (I wouldn't think so---this is asynchronous, right?)
Update: Just to make sure there is no problem sending a broadcast in the middle of receiving a broadcast, I changed my broadcast code to actually perform the broadcast three seconds later on the main thread:
Log.i(getClass().getSimpleName(), "...ready to broadcast");
final Intent intent = new Intent(ACTION_DOWNLOAD_FINISHED).setData(checkNotNull(uri));
mainThreadHandler.postDelayed(new Runnable()
{
public void run()
{
Log.i(getClass().getSimpleName(), "...broadcasting");
sendBroadcast(intent);
Log.i(getClass().getSimpleName(), "...broadcasted");
}
}, 3000);
Log.i(getClass().getSimpleName(), "...scheduled to broadcast");
As expected, the log says:
...ready to broadcast
...scheduled to broadcast
...broadcasting
...broadcasted
Yet nothing is received in the activity. Please help.
Eureka! I found it! The problem is that I supplied a data URI in my broadcast intent. The Android intent matching rules get a little complicated. If you supply a data URI, then your intent filter must specify a matching MIME type.
Unfortunately, although the Android documentation says that the data type can be inferred from the data URI, apparently Android doesn't know that a file://.../example.jpg is an image. So this doesn't work:
intentFilter.addDataType("image/*");
However, instead of specifying a type, I can specify a scheme that I accept:
intentFilter.addDataScheme("file");
That works! It's a little rough---and a little artificial to restrict my broadcasts to file: URIs, but as that's all I'm using for the moment, it works.
Note that apparently I could manually specify the MIME type in the intent when I broadcast it, but that's too much trouble for now, as I'm downloading images from Picasa so I already know that they are images (and don't care the specific MIME type). And if it gets too much trouble, I could ditch the whole setData() thing altogether and set an extra---but of course I want to do things the Right Way.
have you included your receiver in your activity's manifest?
<receiver
android:name=".YourReceiver">
<intent-filter>
<action
android:name="intent_name"></action>
</intent-filter>
</receiver>

Programmatic Intent Filter for NFC

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.

Why doesn't my BroadcastReceiver receive broadcasts from another app?

App A has this BroadcastReceiver in its manifest (within <application>):
And this receiver:
public class RemoteControl extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Log.w(TAG, "Look what I did!");
}
}
I'm trying to trigger this from App B:
public void onClick(View v) {
Log.w(TAG, "Sending stuff");
Intent i = new Intent("app.a.remotecontrol");
i.setData("http://test/url");
sendBroadcast(i);
}
For whatever reason, the onReceive() in App A is never triggered even though it's broadcasted from App B. What can be the cause of this?
EDIT & SOLUTION: I forgot to write that I used setData() on the Intent before broadcasting it. That was indeed the problem: as soon as I removed setData(), the broadcast worked as intended.
Originally I forgot to write that I used setData() on the Intent before broadcasting it. That was indeed the problem: as soon as I removed setData(), the broadcast worked as intended.
I've switched to use putExtra() instead for the Intent metadata:
Intent i = new Intent("app.a.remotecontrol");
i.putExtra("url", "http://test/url");
sendBroadcast(i);

Categories

Resources