Reception may be lost as a result of moving out of coverage, switching on the airplane mode or for any other reason. I am not interested in the reason, but I just want to know when reception is restored.
Is there a intent which can be registered to fire up a broadcast receiver?
A connectivity change receiver using android.net.conn.CONNECTIVITY_CHANGE does not seem to work for this purpose.
Any help will be appreciated.
You can use a PhoneStateListener. You do this using a receiver for PHONE_STATE.
In the manifest:
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<receiver android:name=".PhoneStateReceiver">
<intent-filter>
<action android:name="android.intent.action.PHONE_STATE" />
</intent-filter>
</receiver>
The BroadcastReceiver:
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.telephony.PhoneStateListener;
import android.telephony.TelephonyManager;
class PhoneStateReceiver extends BroadcastReceiver {
TelephonyManager telephonyManager;
public void onReceive(Context context, Intent intent) {
ServiceStateListener phoneListener = new ServiceStateListener();
telephonyManager = (TelephonyManager) context
.getSystemService(Context.TELEPHONY_SERVICE);
telephonyManager.listen(phoneListener, PhoneStateListener.LISTEN_SERVICE_STATE);
}
public void onDestroy() {
telephonyManager.listen(null, PhoneStateListener.LISTEN_NONE);
}
}
The PhoneStateListener:
import android.telephony.PhoneStateListener;
class ServiceStateListener extends PhoneStateListener {
public void onServiceStateChanged (ServiceState serviceState) {
boolean connected = (serviceState.getState() == ServiceState.STATE_IN_SERVICE);
// Do work based on "connected"
}
}
Related
I am working on an android application that listens to Boot Complete Broadcast and performs some processes.
This broadcast works on my Moto G5 and simulator, however, on Oneplus the application never receives it.
Create a BroadCastReciver class like this :
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.widget.Toast;
public class RebootService extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Toast.makeText(context,"Service is running", Toast.LENGTH_LONG).show();
}
}
Define your service in AndroidManifest.
<receiver android:name=".RebootService">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED"/>
</intent-filter>
</receiver>
And finally :
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
I am trying to make a simple app which will notify if there is internet connection available or not on internet connectivity change. i have found some solution on internet and tries to implement them but somehow its not working. my broadcast receiver which i have registered on my manifest file is not calling on network connectivity change.
Manifest
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<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=".NetworkStateChangeReceiver">
<intent-filter >
<action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
</intent-filter>
</receiver>
</application>
Broadcast Receiver
package com.gdm.internetconnectivitycheck;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.support.v4.content.LocalBroadcastManager;
import android.util.Log;
import static android.content.Context.CONNECTIVITY_SERVICE;
public class NetworkStateChangeReceiver extends BroadcastReceiver {
public static final String NETWORK_AVAILABLE_ACTION = "com.gdm.retailalfageek.NetworkAvailable";
public static final String IS_NETWORK_AVAILABLE = "isNetworkAvailable";
#Override
public void onReceive(Context context, Intent intent) {
Intent networkStateIntent = new Intent(NETWORK_AVAILABLE_ACTION);
networkStateIntent.putExtra(IS_NETWORK_AVAILABLE, isConnectedToInternet(context));
LocalBroadcastManager.getInstance(context).sendBroadcast(networkStateIntent);
Log.e("Network Available ", "On receive called");
}
private boolean isConnectedToInternet(Context context) {
try {
if (context != null) {
ConnectivityManager connectivityManager = (ConnectivityManager) context.getSystemService(CONNECTIVITY_SERVICE);
NetworkInfo networkInfo = connectivityManager.getActiveNetworkInfo();
return networkInfo != null && networkInfo.isConnected();
}
return false;
} catch (Exception e) {
Log.e(NetworkStateChangeReceiver.class.getName(), e.getMessage());
return false;
}
}
}
Main Activity
package com.gdm.internetconnectivitycheck;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.support.v4.content.LocalBroadcastManager;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.design.widget.Snackbar;
import static com.gdm.internetconnectivitycheck.NetworkStateChangeReceiver.IS_NETWORK_AVAILABLE;
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
IntentFilter intentFilter = new IntentFilter(NetworkStateChangeReceiver.NETWORK_AVAILABLE_ACTION);
LocalBroadcastManager.getInstance(this).registerReceiver(new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
boolean isNetworkAvailable = intent.getBooleanExtra(IS_NETWORK_AVAILABLE, false);
String networkStatus = isNetworkAvailable ? "connected" : "disconnected";
Snackbar.make(findViewById(R.id.main_activity), "Network Status: " + networkStatus, Snackbar.LENGTH_LONG).show();
}
}, intentFilter);
}
}
Apps targeting Android 7.0 (API level 24) and higher must register the
following broadcasts with
registerReceiver(BroadcastReceiver,IntentFilter)
Declaring a receiver in the manifest does not work.
CONNECTIVITY_ACTION
Beginning with Android 8.0 (API level 26), the
system imposes additional restrictions on manifest-declared receivers.
If your app targets API level 26 or higher, you cannot use the
manifest to declare a receiver for most implicit broadcasts
(broadcasts that do not target your app specifically). You can still
use a context-registered reciever when the user is actively using your
app.
directly from official doc.
you need to register for CONNECTIVITY_CHANGE action at runtime from activity.
using registerReceiver.
IntentFilter filter = new IntentFilter();
filter.addAction("android.net.conn.CONNECTIVITY_CHANGE");
registerReceiver(new NetworkStateChangeReceiver(), filter);
And don't forget to unregister.
I have written a small program to turn on the camera flash LED in the event of an incoming call. It worked fine for the first time, but the second time the application crashed. And now the application wouldn't work. I even re-installed the app!
I'm using TelephonyManager and PhoneStateListener. Can anyone please indicate what's wrong with the program? It's been more than an hour, and I've got no clue! Any help would be appreciated.
Here is the manifest declaration:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.firefly"
android:versionCode="1"
android:versionName="1.0">
<uses-sdk android:minSdkVersion="14" />
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
<uses-permission android:name="android.permission.CAMERA" />
<uses-feature android:name="android.hardware.camera" />
<application android:icon="#drawable/ic_launcher" android:label="Firefly">
<receiver android:name="MainActivity">
<intent-filter>
<action android:name="android.intent.action.PHONE_STATE"/>
</intent-filter>
</receiver>
</application>
</manifest>
Actual code:
package com.firefly;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.hardware.Camera;
import android.hardware.Camera.Parameters;
import android.telephony.PhoneStateListener;
import android.telephony.TelephonyManager;
import android.util.Log;
import android.widget.Toast;
public class MainActivity extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
try {
TelephonyManager tmgr = (TelephonyManager) context
.getSystemService(Context.TELEPHONY_SERVICE);
// Create Listener
MyPhoneStateListener PhoneListener = new MyPhoneStateListener(context);
// Register listener for LISTEN_CALL_STATE
tmgr.listen(PhoneListener, PhoneStateListener.LISTEN_CALL_STATE);
} catch (Exception e) {
Log.e("Phone Receive Error", " " + e);
}
}
private class MyPhoneStateListener extends PhoneStateListener {
private Context ctx;
private boolean flashavailable;
private Camera camera;
private MyPhoneStateListener(Context ctx) {
this.ctx=ctx;
}
public void onCallStateChanged(int state, String incomingNumber) {
flashavailable=ctx.getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA_FLASH);
if (state == TelephonyManager.CALL_STATE_RINGING) {
if (flashavailable){
//Turning on the flash LED
camera = Camera.open();
final Parameters p = camera.getParameters();
p.setFlashMode(Parameters.FLASH_MODE_TORCH);
camera.setParameters(p);
camera.startPreview();
}
String msg = "New Phone Call Event. Incomming Number : "+incomingNumber;
Toast.makeText(ctx, msg, Toast.LENGTH_LONG).show();
}
}
}
}
I know the AlarmManagerBroadcastReceiver will stay system to keep watch over SMS after I installed the .apk
Will the AlarmManagerBroadcastReceiver expend battery even if I never receive s SMS?
Do I need disable the AlarmManagerBroadcastReceiver when I stop watch SMS ?
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.enabledisablebroadcastreceiver"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="8" />
<application
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<activity
android:name="com.code4reference.enabledisablebroadcastreceiver.EnableDisableBroadcastReceiver"
android:label="#string/title_activity_enable_disable_boradcast_receiver" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<!-- Broadcast receiver -->
<receiver android:name="com.code4reference.enabledisablebroadcastreceiver.AlarmManagerBroadcastReceiver" >
<intent-filter>
<action android:name="android.provider.Telephony.SMS_RECEIVED" />
</intent-filter>
</receiver>
<service android:name="com.code4reference.enabledisablebroadcastreceiver.MyInternetServer"></service>
</application>
<uses-permission android:name="android.permission.SEND_SMS"/>
<uses-permission android:name="android.permission.RECEIVE_SMS"/>
</manifest>
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.telephony.SmsMessage;
import android.util.Log;
public class AlarmManagerBroadcastReceiver extends BroadcastReceiver {
private static final String ACTION = "android.provider.Telephony.SMS_RECEIVED";
#Override
public void onReceive(Context context, Intent intent) {
if (intent != null && intent.getAction() != null && ACTION.compareToIgnoreCase(intent.getAction()) == 0) {
Object[] pduArray = (Object[]) intent.getExtras().get("pdus");
SmsMessage[] messages = new SmsMessage[pduArray.length];
for (int i = 0; i < pduArray.length; i++) {
messages[i] = SmsMessage.createFromPdu((byte[]) pduArray[i]);
//Log.d("CWCGR1",
// "From: " + messages[i].getOriginatingAddress()+
// " Msg: " + messages[i].getMessageBody());
HandleMsg(context,messages[i].getOriginatingAddress(), messages[i].getMessageBody());
}
}
}
private void HandleMsg(Context context,String address, String body ){
Intent msgIntent = new Intent(context,MyInternetServer.class);
msgIntent.putExtra("address", address);
msgIntent.putExtra("body", body);
context.startService(msgIntent);
}
}
import com.example.enabledisablebroadcastreceiver.R;
import android.app.Activity;
import android.app.AlarmManager;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.Toast;
public class EnableDisableBroadcastReceiver extends Activity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button btnExit=(Button)findViewById(R.id.btnExit);
btnExit.setOnClickListener(new OnClickListener(){
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
finish();
}
});
}
public void enableBroadcastReceiver(View view){
ComponentName receiver = new ComponentName(this, AlarmManagerBroadcastReceiver.class);
PackageManager pm = this.getPackageManager();
pm.setComponentEnabledSetting(receiver,
PackageManager.COMPONENT_ENABLED_STATE_ENABLED,
PackageManager.DONT_KILL_APP);
Toast.makeText(this, "Enabled broadcast receiver", Toast.LENGTH_SHORT).show();
}
public void disableBroadcastReceiver(View view){
ComponentName receiver = new ComponentName(this, AlarmManagerBroadcastReceiver.class);
PackageManager pm = this.getPackageManager();
pm.setComponentEnabledSetting(receiver,
PackageManager.COMPONENT_ENABLED_STATE_DISABLED,
PackageManager.DONT_KILL_APP);
Toast.makeText(this, "Disabled broadcst receiver", Toast.LENGTH_SHORT).show();
}
}
As discussed here, an incoming SMS belongs to a special group of low-level system events that will cause the CPU to wake from the battery-saving "sleep mode" (this group includes incoming calls, incoming mobile data packets and AlarmManager events). The device's GSM radio will listen to incoming SMS regardless of your broadcast receiver being set or not. When an SMS arrives, the system will choose which receiver(s) will handle it. Thus, having a SMS broadcast receiver registered has no impact in the battery consumption. Besides, energy consumption due to a registered receiver in memory is not significant.
You can unregister the broadcast receiver programmatically if there is a functional requirement to do so.
Because you have fined your AlarmManagerBroadcastReceiver in the android manifest, android will wake up your app and call the AlarmManagerBroadcastReceiver every time an sms is received.
If no SMS are received, your app won't be woken up so there won't be any impact on battery.
If you want control over when to receive those broadcasts, register and unregister your receiver programmatically through the registerReceiver(BroadcastReceiver receiver, IntentFilter filter) method on a Context (e.g. Activity).
I try to implement the network receiver, here is my following code:
package com.example.androidtablayout;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.util.Log;
public class NetworkReceiver extends BroadcastReceiver { // <1>
public static final String TAG = "NetworkReceiver";
boolean isConnected = true;
Context c;
#Override
public void onReceive(Context context, Intent intent) {
boolean isNetworkDown = intent.getBooleanExtra(
ConnectivityManager.EXTRA_NO_CONNECTIVITY, false); // <2>
if (isNetworkDown) {
Log.d(TAG, "onReceive: NOT connected, stopping UpdaterService");
// context.stopService(new Intent(context, UpdaterService.class)); // <3>
} else {
Log.d(TAG, "onReceive: connected, starting UpdaterService");
// context.startService(new Intent(context, UpdaterService.class)); // <4>
}
}
}
In the Manifest.xml
<application>
<receiver android:name=".NetworkReceiver">
<intent-filter>
<action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
</intent-filter>
</receiver>
</application>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
My problem is when I switch off the wifi, the log still shows that "Connected",
I think the the network receiver didn't receiver the intenet connectivity correctly.Any help will be greatly appreciated.
Here is a sample class that shows you how to do it. I think this is exactly what you need and it might help resolve your issue. In this sample the BroadcastReceiver is registered programmatically instead of the Manifest, but I think it won't be a problem for you.
Let me know if works.