I'm broadcasting an intent in my app and receiving it with a broadcast receiver. I can handle the broadcasting and receiving. No problem with that. However, I want to register the receiver completely programmatically instead of doing it in the manifest file. Notice, that in the manifest file, there are two attributes of the receiver android:enabled="true" and android:exported="false". I need to know, how do I specifically set these two attributes when I register the receiver programmatically?
My AndroidManifest.xml file:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.mybroadcastapplication">
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:roundIcon="#mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="#style/Theme.MyBroadcastApplication">
<activity
android:name=".MainActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<receiver
android:name=".MyBroadcastReceiver"
android:enabled="true"
android:exported="false">
</receiver>
</application>
</manifest>
My MainActivity.java file:
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
MyBroadcastReceiver myReceiver;
IntentFilter intentFilter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
myReceiver = new MyBroadcastReceiver();
intentFilter = new IntentFilter();
intentFilter.addAction("com.example.mybroadcastapplication.EXPLICIT_INTENT");
findViewById(R.id.button1).setOnClickListener(this);
}
public void broadcastIntent() {
Intent intent = new Intent();
intent.setAction("com.example.mybroadcastapplication.EXPLICIT_INTENT");
getApplicationContext().sendBroadcast(intent);
}
#Override
protected void onPostResume() {
super.onPostResume();
registerReceiver(myReceiver, intentFilter);
}
#Override
protected void onStop() {
super.onStop();
unregisterReceiver(myReceiver);
}
#Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.button1:
broadcastIntent();
break;
default:
}
}
}
My MyBroadcastReceiver.java file:
public class MyBroadcastReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction() != null && intent.getAction().equals("com.example.mybroadcastapplication.EXPLICIT_INTENT"))
Toast.makeText(context, "Explicit intent received.", Toast.LENGTH_LONG).show();
}
}
Regards
You don't need to declare the BroadcastReceiver in the manifest if you are registering/unregistering programmatically. You only need to declare BroadcastReceivers in the manifest if you want them to be instantiated from external triggers (for example, on device boot, or from the Alarm Manager, etc.)
Related
I'm trying to send a simply customized broadcast by clicking a button, and the receiver will push a toast as it receives the broadcast. But as I clicked the button, nothing toasted with an error message in the logcat:
2021-01-18 16:23:18.870 480-480/? E/netmgr: Failed to open QEMU pipe 'qemud:network': Invalid argument
2021-01-18 16:23:20.931 485-485/? E/wifi_forwarder: qemu_pipe_open_ns:62: Could not connect to the 'pipe:qemud:wififorward' service: Invalid argument
2021-01-18 16:23:20.931 485-485/? E/wifi_forwarder: RemoteConnection failed to initialize: RemoteConnection failed to open pipe
The MainActivity is:
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button button = (Button) findViewById(R.id.button);
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent("com.example.broadcasttest2.MY_BROADCAST");
sendBroadcast(intent);
}
});
}
And the BroadcastReceiver is:
public class MyBroadcastReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
// TODO: This method is called when the BroadcastReceiver is receiving
// an Intent broadcast.
Toast.makeText(context, "My Broadcast Received", Toast.LENGTH_SHORT).show();
throw new UnsupportedOperationException("Not yet implemented");
}
}
I have also registered the action inside the BroadcastReceiver:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.broadcasttest2">
<application
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:roundIcon="#mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="#style/Theme.BroadcastTest2"
>
<receiver
android:name=".MyBroadcastReceiver"
android:enabled="true"
android:exported="true">
<intent-filter>
<action android:name="com.example.broadcasttest2.MY_BROADCAST" />
</intent-filter>
</receiver>
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
Could anyone help me with that? Many thanks!
for in app broadcast communication you have to register the broadcast receiver in the Activity, in your case you missing an syntax inside onCreate like this one:
BroadcastReceiver myReceiver = new MyBroadcastReceiver();
registerReceiver(myReceiver, new IntentFilter('com.example.broadcasttest2.MY_BROADCAST'));
for more reference - Broadcast Receiver class and registerReceiver method
It's toasting until I didn't restart my phone but after restarting broadcastreceiver2 doesn't receive and nothing happens.
I followed http://stacktips.com/tutorials/android/how-to-start-an-application-at-device-bootup-in-android and many other but nothing happens.
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.k2.alarmmanagerdemo">
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:roundIcon="#mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="#style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<receiver android:name="com.k2.alarmmanagerdemo.MyBroadcastReceiver"
android:enabled="true">
</receiver>
<receiver android:name="com.k2.alarmmanagerdemo.BroadCastRecevier2"
android:enabled="true"
android:exported="true"
android:permission="android.permission.RECEIVE_BOOT_COMPLETED">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED"/>
<action android:name="android.intent.action.QUICKBOOT_POWERON"/>
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</receiver>
</application>
</manifest>
MainActivity.java
public class MainActivity extends Activity {
Button b1;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
b1=(Button) findViewById(R.id.button1);
b1.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
startAlert();
}
});
}
public void startAlert() {
EditText text = (EditText) findViewById(R.id.time);
int i = Integer.parseInt(text.getText().toString());
Intent intent = new Intent(this, MyBroadcastReceiver.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(
this.getApplicationContext(), 234324243, intent, 0);
AlarmManager alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP,System.currentTimeMillis(),
1000 * 5,pendingIntent);
Toast.makeText(this, "Alarm set in " + i + " seconds",Toast.LENGTH_LONG).show();
}
}
MyBroadcastReceiver.java
public class MyBroadcastReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Toast.makeText(context, "Alarm...." + System.currentTimeMillis(), Toast.LENGTH_SHORT).show();
Log.i("Alarm.", "alarm called" + System.currentTimeMillis());
}
}
BroadCastRecevier2.java
public class BroadCastRecevier2 extends BroadcastReceiver {
MainActivity activity = new MainActivity();
#Override
public void onReceive(Context context, Intent intent) {
activity.startAlert();
if (intent.getAction().equals("android.intent.action.BOOT_COMPLETED")) {
Intent i = new Intent();
i.setClassName("com.k2.alarmmanagerdemo",
"com.k2.alarmmanagerdemo.MainActivity");
i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(i);
Toast.makeText(context, "BOOT", Toast.LENGTH_SHORT).show();
Log.i("myboot","boot compleated inside");
}
}
}
Remove this line from your <receiver> declaration for BroadcastReceiver2:
android:permission="android.permission.RECEIVE_BOOT_COMPLETED"
That line in the <receiver> tag is telling the system that only packages which have this permission are allowed to send your class the Intent. Its' likely confusing the system and preventing the Intent from being sent to your receiver.
You may also find this article helpful when learning about alarms and the boot complete receiver.
I want to monitor an incoming sms in a phone by making a Toast message pop up when a sms is received. However, with the following code, I don't receive the Toast message even when a sms is received. Why is that so? I'm using Android Studio 3.0.1 and there are no errors when I run the code.
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="mapp.com.sg.broadcastreceiver">
<uses-permission android:name="android.permission.RECEIVE_SMS"></uses-permission>
<uses-permission android:name="android.permission.READ_SMS"></uses-permission>
<uses-permission android:name="android.permission.SEND_SMS"></uses-permission>
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:supportsRtl="true"
android:theme="#style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
MainActivity.java
public class MainActivity extends Activity {
private static final int NOTIFY_ME_ID = 1337;
private BroadcastReceiver the_receiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
int duration = Toast.LENGTH_LONG;
Toast toast = Toast.makeText(context, "SMS Message Received!", duration);
toast.show();
}
};
private IntentFilter filter = new IntentFilter("android.provider.Telephony.SMS_RECEIVED");
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
#Override
protected void onResume() {
// Register receiver if activity is in front
this.registerReceiver(the_receiver, filter);
super.onResume();
}
#Override
protected void onPause() {
// Unregister receiver if activity is not in front
this.unregisterReceiver(the_receiver);
super.onPause();
}
}
Do as following by adding the receiver in the manifest file
<receiver
android:name=".receivers.SMSReceiver"
android:permission="android.permission.BROADCAST_SMS">
<intent-filter>
<action android:name="android.provider.Telephony.SMS_RECEIVED" />
</intent-filter>
</receiver>
and then create SMSReceiver class
public class SMSReceiver extends BroadcastReceiver {
public void onReceive(Context context, Intent intent) {
Bundle myBundle = intent.getExtras();
SmsMessage[] messages;
if (myBundle != null) {
Toast toast = Toast.makeText(context, "SMS Message Received!",duration);
}
}
}
My LocalBroadcastManager callback function dosen' receive messeges. Can someone tell my why?
I try to do it on my Samsung Galaxy S3 mini (4.1.2 -Jelly Bean, API 16).
SenderClass:
public static final String BROADCAST = "com.android.SOME_BROADCAST";
private Context context;
public SenderClass(Context context) {
this.context = context;
//...
Intent intent = new Intent(BROADCAST);
//intent.putExtra(EXTRA_SOMEEXTRA, "some extra");
LocalBroadcastManager.getInstance(context).sendBroadcast(intent);
//just to keep it simple i do it here
}
MainActivity
private BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
Log.d(TAG, "onReceive"); //this is never called!
}
};
#Override
protected void onResume() {
super.onResume();
Log.d(TAG, "onResume()");
LocalBroadcastManager.getInstance(this).registerReceiver(
broadcastReceiver,
new IntentFilter(SenderClass.BROADCAST)
);
}
#Override
protected void onPause() {
super.onPause();
Log.d(TAG, "onPause()");
LocalBroadcastManager.getInstance(this).unregisterReceiver(broadcastReceiver);
}
edit: here the manifest
Manifest
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.android....">
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.INTERNET" />
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:supportsRtl="true"
android:theme="#style/AppTheme">
<activity android:name=".Activities.MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<service
android:name=".Services.MyService"
android:enabled="true"
android:exported="false"></service>
</application>
</manifest>
Try this step:-
Register your broadcast in onCreate and Unregister broadcast in onDestroy of Activity.
Thanks,
It may helpful for you.
I am making a very simple app in which I want that a service should run infinitely just like Whatsapp service runs in background, even if the app is removed from Recent Apps by swiping out.
Below is my code.
AndroidManifest.xml:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.net.gs.servicetesting" >
<application
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<activity
android:name=".MainActivity"
android:label="#string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<service
android:name=".MyService"
android:process=":com">
<intent-filter>
<action
android:name="com.net.gs.servicetesting.MyService" />
</intent-filter>
</service>
</application>
</manifest>
MyService.java:
public class MyService extends Service {
private String TAG = "MyService";
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.d(TAG,"Service Strated");
return START_STICKY;
}
#Override
public void onDestroy() {
Log.d(TAG,"Service Destoryed");
super.onDestroy();
}
}
MainActivity.java:
public class MainActivity extends ActionBarActivity {
String TAG = "MainActivity";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Log.d(TAG, "Activity Strated");
startService(new Intent(MyService.class.getName()));
}
}
In your Service#onStartCommand method store the starting intent to a field variable, let's say mIntent.
Then implement the Service#onTaskRemoved method like this:
#Override
#TargetApi(14)
public void onTaskRemoved(Intent rootIntent) {
startService(mIntent);
}