MyReceiver.java
public class MyReceiver extends BroadcastReceiver {
#Override
public void onReceive(final Context context, final Intent intent) {
Log.i("MyReceiver", "MyAction received!");
}
}
In AndroidManifest.xml (under the application tag)
<receiver android:name=".MyReceiver">
<intent-filter>
<action android:name="MyAction" />
</intent-filter>
</receiver>
MainActivity.Java
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
sendBroadcast(new Intent("MyAction"));
}
}
MyReceiver.onReceive method is never triggered.
Did I miss something?
I use Android 8.
Then you have to use an explicit Intent, one that identifies the receiver, such as:
sendBroadcast(new Intent(this, MyReceiver.class).setAction("MyAction"));
See Broacast limitations in Android 8 release docs.
In Android 8 onwords
We need to provide the explicite class for handling i.e setcomponent param along with action
Example :
private void triggerBroadCast(String firstFavApp, String secondFavApp) {
Intent intent = new Intent("FavAppsUpdated");
intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
intent.putExtra("FIRST_FAV_APP", firstFavApp);
intent.putExtra("SECOND_FAV_APP", secondFavApp);
intent.setComponent(new
ComponentName("com.android.systemui",
"com.android.systemui.statusbar.phone.FavAppsChanged"));
Log.i(TAG, "Trigger Fav Apps" + firstFavApp + " " + secondFavApp);
favouriteContract.getAppContext().sendBroadcast(intent);
}
Below Android 8
Only action is enough for receiving Broadcast
void broadCastParkingStates(Context context) {
Intent intent = new Intent("ReverseCameraStates");
intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
intent.putExtra("PARKING_GUIDE", ReverseCameraPreference.getParkingGuide(context));
intent.putExtra("PARKING_SENSOR", ReverseCameraPreference.getParkingSensor(context));
intent.putExtra("TRAJECTORY", ReverseCameraPreference.getTrajectory(context));
Log.i("BootCompletedReceiver", "Sending Reverse Camera settings states BaordCast");
Log.i("BootCompletedReceiver", "States Parking:Sensor:Trajectory="
+ intent.getExtras().getBoolean("PARKING_GUIDE")
+ ":" + intent.getExtras().getBoolean("PARKING_SENSOR")
+ ":" + intent.getExtras().getBoolean("TRAJECTORY")
);
context.sendBroadcast(intent);
}
If you have multiple receivers, you can send broadcast to all the receivers using only custom action defined in manifest for that you need to add the following flag while sending broadcast
Note: I have used adb to test it on Android 10, you can add it in application
FLAG_RECEIVER_INCLUDE_BACKGROUND = 0x01000000
adb shell am broadcast -a MyAction -f 0x01000000
In Kotlin:
val intent = Intent(this, MyBroadCastReceiver::class.java)
intent.addCategory(Intent.CATEGORY_DEFAULT)
intent.action = "my.custom.broadcast"
sendBroadcast(intent)
Change the MainActivity's code as follows:
Intent intent = new Intent(this, MyReceiver.class);
intent.setAction("MyAction");
sendBroadcast(intent);
The string itself does not matter, just need to be the same in all places and unique, I use fully qualified name of the constant.
<receiver android:name="com.mypackage.receivers.MyBroadcastReceiver">
<intent-filter>
<action android:name="com.mypackage.receivers.MyBroadcastReceiver.ACTION_CUSTOM"/>
</intent-filter>
</receiver>
The receiver:
package com.mypackage.receivers;
public class MyBroadcastReceiver extends BroadcastReceiver {
public static final String ACTION_CUSTOM = "com.mypackage.receivers.MyBroadcastReceiver.ACTION_CUSTOM";
#Override
public void onReceive(Context context, Intent intent) {
if (ACTION_CUSTOM.equals(intent.getAction())) {
// do custom action
}
}
}
To broadcast the intent:
sendBroadcast(new Intent(MyBroadcastReceiver.ACTION_CUSTOM));
Related
I'm trying to create an external broadcast service which sends a number. A client (external application) trying to send a request to my service and the service sends back a number. I registered my service and broadcast resiever in AndroidManifest.xml:
<service android:exported="true" android:enabled="true" android:name=".MyService"/>
<receiver android:exported="true" android:enabled="true" android:name=".MyStartServiceReceiver">
<intent-filter>
<action android:name="android.intent.action.SEND" />
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
</receiver>
my broadcast class:
public class MyStartServiceReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Intent intent1 = new Intent(context, MyService.class);
context.startService(intent1);
}
}
in MyService class I'm trying to put extra data
public void onStart(Intent intent, int startId) {
Log.i(TAG, "service started");
intent.setClass(getApplicationContext(), MyService.class);
intent.setAction(Intent.ACTION_SEND);
intent.putExtra("result", 10);
sendBroadcast(intent);
}
and send it back, but I keep getting zero. To check my service I use adb shell:
adb shell am broadcast -a android.intent.action.SEND
Broadcasting: Intent { act=android.intent.action.SEND }
Broadcast completed: result=0
Does anybody know what's wrong in my service?
You can see here:
http://developer.android.com/reference/android/content/Intent.html
that ACTION_SEND is activity action, it cannot be used with receiver.
So you must switch from receiver to activity, you can make it a hidden activity using Theme.NoDisplay
[edit]
some more explanation: BroadcastReceiver with intent-filter for them?
Try something like this.
Method to send broadcast, used within the MyService
public static void sendSomeBroadcast(Context context, String topic) {
Intent actionIntent = new Intent();
// I would use Constants for these Action/Extra values
actionIntent.setAction(ConstantClass.SEND_SOME_BROADCAST);
actionIntent.putExtra(ConstantClas.BROADCAST_RESULT, 10);
LocalBroadcastManager.getInstance(context).sendBroadcast(actionIntent);
}
In action
public void onStart(Intent intent, int startId) {
sendSomeBroadcast();
}
BroadcastReceiver
public class MyStartServiceReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
// do what you want with the intent, for example intent.getExtras()..
Intent intent1 = new Intent(context, MyService.class);
context.startService(intent1);
}
}
Binding the receiver and listening for specific Action
private void bindStartServiceReceiver() {
MyStartServiceReceiver startServiceReceiver = new MyStartServiceReceiver();
//This may need to be changed to fit your application
LocalBroadcastManager.getInstance(this).registerReceiver(subscribeTopicReceiver,
new IntentFilter(ConstantClass.SEND_SOME_BROADCAST));
}
In a class I want to send an intent to my Activity:
Intent broadcast = new Intent();
broadcast.setAction("coinchutc.ANNONCE");
Log.d("JoueurAgent", "Sending broadcast " + broadcast.getAction());
context.sendBroadcast(broadcast);
The Log can print out message correctly.
In my Activity class I declared a self-defined broadcast receiver:
myReceiver = new MyReceiver();
The class MyReceiver is like this:
private class MyReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Log.d("PartieActivity", "receive");
String action = intent.getAction();
if (action.equalsIgnoreCase("coinchutc.ANNONCE")) {
Log.d("PartieActivity", "Receive " + action);
annoncer();
}
}
}
I've registered my activity like this in the onCreate() method of the class:
IntentFilter annonceFilter = new IntentFilter();
annonceFilter.addAction("coinchutc.ANNONCE");
registerReceiver(myReceiver, annonceFilter);
But the Log in the MyReceiver class doesn't print anything at all.
Does anyone know any other possible reason why it is like this?
Thanks in advance!
Have you this in you Manifest?
<receiver android:name="xxx.MyReceiver">
<intent-filter>
<action android:name="coinchutc.ANNONCE" />
</intent-filter>
</receiver>
I also encountered such a problem. And I tried to change the action name, then the receiver can receive the intent. I don't know why, but you can have a try.
I am new to android, I have created intent's like this -
<receiver android:name=".IncommigCallListener" >
<intent-filter>
<action android:name="android.intent.action.PHONE_STATE" />
</intent-filter>
</receiver>
<receiver android:name=".OutgoingCallReciever" >
<intent-filter>
<action android:name="android.intent.action.NEW_OUTGOING_CALL" />
</intent-filter>
</receiver>
Now i created a service like this -
<service
android:name=".CallLogger"
android:exported="false"/>
Class CallLogger
public class CallLogger extends IntentService {
public CallLogger(String name) {
super(name);
// TODO Auto-generated constructor stub
}
#Override
protected void onHandleIntent(Intent arg0) {
// TODO Auto-generated method stub
System.out.println("service started");
}
}
I don't want to have any activity in my application, i just want to start the service so that it can work in background and receive PHONE_STATE and NEW_OUTGOING_CALL intent.
When i start this application, it doesn't log anything on PHONE_STATE or NEW_OUTGOING_CALL intent.
How can start service in background without using any activity ?
Edit :
public class OutgoingCallReciever extends BroadcastReceiver {
#Override
public void onReceive(Context ctx, Intent intent) {
String number = intent.getStringExtra(Intent.EXTRA_PHONE_NUMBER);
}
}
and
public class IncommigCallListener extends PhoneStateListener {
#Override
public void onCallStateChanged(int state, String incomingNumber) {
switch (state) {
case TelephonyManager.CALL_STATE_RINGING:
String incommingCallNumber = incomingNumber;
System.out.println("incomming call : " + incomingNumber);
break;
}
}
}
Just start service in your BroadcastReceiver's onReceive method. As you are registering BroadcastReceiver in AndroidManifist, It will always listen for Broadcasts even if application is not running (OS will run it for you).
Example
public class MyReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Intent service = new Intent(context, MyService.class);
context.startService(service);
}
}
EDIT
To start a service on Boot completed you can do something like this.
1) Add permission to your Manifist :
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
2) Register your Broadcast Receiver with BOOT COMPLETE action.
<receiver android:name="com.example.BootBroadcastReceiver">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
3) In BootBroadcastReceiver.java:
public class BootBroadcastReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Intent serviceIntent = new Intent(context, MyService.class);
context.startService(serviceIntent );
}
}
You should be able to do something like this in your receiver.
public class OutgoingCallReciever extends BroadcastReceiver {
#Override
public void onReceive(Context ctx, Intent intent) {
String number = intent.getStringExtra(Intent.EXTRA_PHONE_NUMBER);
Intent service = new Intent(context, CallLogger.class);
context.startService(service);
}
}
You need to create an intent and call startService() on it to "launch" the service.
Also for what it's worth you should get out of the habbit of System.out.println use Log.d(tag,msg) to print debugging information to the logcat. You can switch the d to other letters if you want to print in different channels.
Why nothing gets printed is only due to the problem that System.out.println does not work in Android! Where do you think the background process will "print" this thing?
You need to change that to Log.d(tag, msg) and then check your logcat to see the output! Otherwise I guess your code might be running properly.
I'm initiating new call from my activity. And trying to pass a boolean extra.
public class CallInitiatingActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Intent intent = new Intent(Intent.ACTION_CALL, Uri.parse("tel:" + number));
intent.putExtra("com.demoapp.CUSTOM_CALL", true);
startActivity(intent);
}
}
I also have a BroadcastReceiver registered, which listens for outgoing calls:
<receiver android:name=".OutgoingCallListener" android:exported="true" >
<intent-filter android:priority="0" >
<action android:name="android.intent.action.NEW_OUTGOING_CALL" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</receiver>
Basically what I'm expecting onReceive to see my extra, but somehow it is not passed:
public class OutgoingCallListener extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Bundle extras = intent.getExtras();
for (String key : extras.keySet()) {
Log.i(Constant.LOG_TAG, key + ": " + extras.get(key));
}
}
}
Output:
android.phone.extra.ALREADY_CALLED:false
android.intent.extra.PHONE_NUMBER:+370652xxxxx
com.htc.calendar.event_uri:null
android.phone.extra.ORIGINAL_URI:tel:+370652xxxxx
Your custom extra is present in the Intent that you use to start the "call" activity. But it isn't copied into the NEW_OUTGOING_CALL Intent that is broadcast as a part of the actual call mechanism. These 2 operations are distinct and only indirectly related to each other. Only the Android system itself can broadcast the NEW_OUTGOING_CALL Intent.
You can't add your own extras to this Intent. You'll need to come up with another way to do whatever it is you are trying to accomplish.
I have spent the last couple of hours looking through other questions on this topic and none that I found were able to give me any answers.
What is the best way to pass a string from an activity to a broadcast receiver in the background?
Here is my main activity
public class AppActivity extends DroidGap {
SmsReceiver mSmsReceiver = new SmsReceiver();
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ScrollView scroll;
scroll = new ScrollView(this);
Bundle bundle = getIntent().getExtras();
final String ownAddress = bundle.getString("variable");
registerReceiver(mSmsReceiver, new IntentFilter("MyReceiver"));
Intent intent = new Intent("MyReceiver");
intent.putExtra("passAddress", ownAddress);
sendBroadcast(intent);
Log.v("Example", "ownAddress: " + ownAddress);
}
}
Here is my broadcast receiver
public class AppReceiver extends BroadcastReceiver {
public void onReceive(Context context, Intent intent) {
final String ownAddress = intent.getStringExtra("passAddress");
Toast test = Toast.makeText(context,""+ownAddress,Toast.LENGTH_LONG);
test.show();
Log.v("Example", "ownAddress: " + ownAddress);
}
}
Here is the manifest for my receiver
<service android:name=".MyService" android:enabled="true"/>
<receiver android:name="AppReceiver">
<intent-filter android:priority="2147483647">
<action android:name="android.provider.Telephony.SMS_SENT"/>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
<receiver>
<service android:name=".MyServiceSentReceived" android:enabled="true"/>
<receiver android:name="AppReceiver">
<intent-filter android:priority="2147483645">
<action android:name="android.provider.Telephony.SMS_RECEIVED"/>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
When the broadcast receiver logs an event the app crashes. I need to have it run behind the scenes and pull a string from my main activity.
Can anyone help me with this or point me in the right direction?
Addition from comments and chat
Your String ownAddress will always be null unless the Intent has an String with the key passAddress in the the Bundle extras. Anytime your Receiver catches an Intent (whether from SMS_SENT, SMS_RECEIVED, or BOOT_COMPLETED) ownAddress will be null because the OS doesn't provide a String extra named passAddress. Hope that clears things up.
Original Answer
I haven't used DroidGap but this is what you want for a regular Android Activity.
Activity:
public class AppActivity extends Activity {
AppReceiver mAppReceiver = new AppReceiver();
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
registerReceiver(mAppReceiver, new IntentFilter("MyReceiver"));
String string = "Pass me.";
Intent intent = new Intent("MyReceiver");
intent.putExtra("string", string);
sendBroadcast(intent);
}
}
Receiver:
public class AppReceiver extends BroadcastReceiver {
public void onReceive(Context context, Intent intent) {
Toast.makeText(context, intent.getStringExtra("string"), Toast.LENGTH_LONG).show();
}
}
Don't forget to unregister the receiver in onDestroy(), like this:
#Override
protected void onDestroy() {
unregisterReceiver(mAppReceiver);
super.onDestroy();
}