📜 ⬆️ ⬇️

These Funny Broadcast Receivers

image A small observation about the different behavior of BroadcastReceiver 's when registering through AndroidManifest.xml and directly in the code. This article is not a step-by-step guide for beginners, but is only intended to save time for those who have not yet had the opportunity to step on a similar rake.

So it happened, by the will of the project manager of fate, I had the opportunity to write a program that blocks everything and everyone for the benefit of defenseless children. Let us leave aside the ethical component of the issue and the mental adequacy of parents who throw out three or four euros on a smartphone for a child, and then with enviable persistence are looking for software that will turn this high-tech device into a brick a decade ago: without the Internet, without SMS, without calls, no applications ... no hope for the future. Attempting to replace parenting with total control is a sure way to grow a weak-willed imbecile, but the Chukchi is not a solver here, Chukchi is a Kodo-writer, so I suggest focusing on the technical side of things.

A specific subtask of such programs: receive notifications about the change of the state of the mobile Internet, Wi-Fi, Bluetooth and block them depending on the degree of paranoid carer. As you know, this kind of notification in android implemented through BroadcastReceiver 's. Also, it is no secret that you can register a receiver in two ways: in the AndroidManifest.xml file and directly in the Activity (or Service , as an option). Consider both ways.

AndroidManifest.xml
/* */ . Without further ado, we subscribe to the events we need. In this case, this action ’s somehow contains a change .
 <receiver android:name="com.demo.WiFiReceiver" android:enabled="true" > <intent-filter> <action android:name="android.net.wifi.WIFI_STATE_CHANGED" /> </intent-filter> </receiver> <receiver android:name="com.demo.DataReceiver" android:enabled="true" > <intent-filter> <action android:name="android.net.conn.CONNECTIVITY_CHANGE" /> </intent-filter> </receiver> <receiver android:name="com.demo.BluetoothReceiver" android:enabled="true"> <intent-filter> <action android:name="android.bluetooth.adapter.action.STATE_CHANGED" /> </intent-filter> </receiver> 

The corresponding classes do not look much more complicated and, in general, correspond to the following pattern:
 public class MyReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { Log.d("MyReceiver", "onReceive"); } } 

We are interested in the chronology of calls, so we will keep a log of the onset of major events.
The result on the person in LogCat :
ApplicationTagText
com.habrMyActivityonCreate
and at each on / off of the corresponding option we get for example:
ApplicationTagText
com.habrWiFiReceiveronReceive
Everything is pretty predictable.
')
Programmatically.
First, let's do this simple trick using the example of Bluetooth .
 @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); Log.d("MyActivity", "onCreate"); } @Override protected void onResume() { super.onResume(); receiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { Log.e("BluetoothReceiver", "onReceive"); } }; registerReceiver(receiver, new IntentFilter(BluetoothAdapter.ACTION_SCAN_MODE_CHANGED)); } @Override protected void onPause() { super.onPause(); unregisterReceiver(receiver); } 

Behavior will be identical to previous launches and many people have probably not the first time the thought “why, does he do us a doctor, and who does he treat here at all?” ConnectivityManager.CONNECTIVITY_ACTION and here, hello to the guys from android, you will find that LogCat shows the following:
ApplicationTagText
com.habrMyActivityonCreate
com.habrWiFiReceiveronReceive
com.habrDataReceiveronReceive
In fact, this means that both onReceive both receivers volunteered immediately, generally regardless of the state of the corresponding options, and only Bluetooth behaved correctly.

Conclusion
Imagine a simple situation: the task of the application is to interrupt the Internet. At the time of installation of the application, it can be both on and off. If it is already enabled, and you register via AndroidManifest.xml , then you just have to be sure, you will have to call the lock code from the receiver yourself, since you will not be notified by the system, and this is correct, because you are late for lunch, the corresponding notification was missed when you were not in the system with your application. If you did everything programmatically, then you do not have to make a separate call. Again, provided that the case does not concern Bluetooth . If you ask the question “Oh, sobsna, why?”, Then the answer is likely to be “Because you can!”. As for me, it's a pure bug and no logic is visible. I hope this article will save someone the day that I killed, in order to understand the reason for the disobedience of the hellish machine.

All of the above is reproduced on all versions of Android , starting with Gingerbread and above (below just did not test).

As for the methods of filtering calls, SMS, Internet, etc., then, if I'm not mistaken, the topic has already been partially covered, for example, here . But, if this is interesting, then I could try to do my bit so as not to duplicate anyone.

Source: https://habr.com/ru/post/149875/


All Articles