BroadcastReceiver not being called after activity resume - android

First of all I'm a novice to android, so this could probably be a silly issue, nevertheless I've already spent a couple of days trying to get to a solution.
I'm trying to build a wifi module for localization purpouses, so I wrote a BroadcastReceiver in order to handle the wifi scanning and the localization. The application works and does its (quite simple at this stage) job, with anu kind of issues both when I change the orientation of the screen and when I hit the back button on my Desire HD and then open the application again. But when I hit the HOME key, going to the main screen, and then enter again my app the Broadcast Receiver seems not to work anymore, and if I close the application I get an error message.
Here's the code, partially adapted from here.
public class WiFiDemo extends Activity implements OnClickListener {
private static final String TAG = "WiFiDemo";
WifiManager wifi;
BroadcastReceiver receiver;
WifiManager.WifiLock lock;
boolean wifiPrevState;
boolean scanON = false;
String header;
TextView textStatus;
Button buttonScan;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
// Setup UI
textStatus = (TextView) findViewById(R.id.textStatus);
buttonScan = (Button) findViewById(R.id.buttonScan);
buttonScan.setOnClickListener(this);
// Setup WiFi
if (wifi == null){
wifi = (WifiManager) getSystemService(Context.WIFI_SERVICE);
}
//checking WiFi status, enabling it if needed and locking it.
wifiPrevState = wifi.isWifiEnabled();
wifi.setWifiEnabled(true);
if (lock == null){
lock = wifi.createWifiLock("lock");
}
lock.acquire();
// Get WiFi status
WifiInfo info = wifi.getConnectionInfo();
header="\n\nWiFi Status: \n" + info.toString() + "\n\nAvailable nets:";
textStatus.append(header);
// Register Broadcast Receiver
if (receiver == null)
receiver = new WiFiScanReceiver(this);
registerReceiver(receiver, new IntentFilter(
WifiManager.SCAN_RESULTS_AVAILABLE_ACTION));
Log.d(TAG, "onCreate()");
}
/*
#Override
protected void onPause(){
super.onPause();
wifi.setWifiEnabled(wifiPrevState);
lock.release();
unregisterReceiver(receiver);
Log.d(TAG, "onPause()");
}
#Override
protected void onResume(){
super.onResume();
wifi.setWifiEnabled(true);
lock.acquire();
registerReceiver(receiver, new IntentFilter(
WifiManager.SCAN_RESULTS_AVAILABLE_ACTION));
Log.d(TAG, "onResume()");
}
*/
#Override
public void onStop() {
super.onStop();
wifi.setWifiEnabled(wifiPrevState);
lock.release();
unregisterReceiver(receiver);
}
public void onClick(View view) {
Toast.makeText(this, "On Click Clicked. Toast to that!!!",
Toast.LENGTH_LONG).show();
if (view.getId() == R.id.buttonScan) {
Log.d(TAG, "onClick() wifi.startScan()");
scanON = !scanON;
wifi.startScan();
}
}
}
And this is the BroadcastReceiver
public class WiFiScanReceiver extends BroadcastReceiver {
private static final String TAG = "WiFiScanReceiver";
WiFiDemo wifiDemo;
ScanResult storedBest;
public WiFiScanReceiver(WiFiDemo wifiDemo) {
super();
this.wifiDemo = wifiDemo;
storedBest = null;
}
#Override
public void onReceive(Context c, Intent intent) {
List<ScanResult> results = wifiDemo.wifi.getScanResults();
ScanResult bestSignal = null;
wifiDemo.textStatus.setText(wifiDemo.header);
for (ScanResult result : results) {
if (bestSignal == null
|| WifiManager.compareSignalLevel(bestSignal.level, result.level) < 0)
bestSignal = result;
wifiDemo.textStatus.append("\n\n" + result.toString());
}
if ( storedBest == null || ((bestSignal.SSID.compareTo(storedBest.SSID)!=0) && bestSignal.level>-50)){
storedBest = bestSignal;
String locationMessage = String.format("You are near %s's Access Point",
bestSignal.SSID);
Toast.makeText(wifiDemo, locationMessage, Toast.LENGTH_LONG).show();
}
String message = String.format("%s networks found. %s is the strongest. Its level is %s",
results.size(), bestSignal.SSID, bestSignal.level);
if (wifiDemo.scanON) wifiDemo.wifi.startScan();
Log.d(TAG, "onReceive() message: " + message);
}
}

When posting, its best to post the error message that you are getting so we know the problem you are having.
That being said, the reason it probably isn't working is because you unregister your receiver in onStop and you only register your receiver in onCreate. You should typically do these type of calls in life cycle stages that match.
onCreate/onDestroy
onStart/onStop
onResume/onPause.
To fix your problem, try registering your receiver in onStart instead of onCreate.

Your onResume() method is commented out...
Are you sure that's the correct IntentFilter?

Related

Getting notified about change in state of WiFi on android device?

I am aiming to build a android app which record everything going on with devices WiFi adapter. For example WiFi being turned on/off, device getting connected/moving out of range of a WiFi router, etc.
My app should be able to record these events as soon as the device is turned on. Clearing the app from RECENTS should not affect the ability of the app to record these events.
I have gone through BroadcastReceiver. It gets tied to the life cycle of the app and hence will not record the events once app gets cleared from RECENTS.
public class MainActivity extends Activity {
BroadcastReceiver mybroadcastReceiver;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mybroadcastReceiver = new WifiBroadcastReceiver(this);
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(WifiManager.SUPPLICANT_STATE_CHANGED_ACTION);
registerReceiver(mybroadcastReceiver, intentFilter);
}
#Override
protected void onDestroy() {
super.onDestroy();
unregisterReceiver(mybroadcastReceiver);
}
}
public class WifiBroadcastReceiver extends BroadcastReceiver {
final String TAG = "WifiBroadcastReceiver";
final String desiredMacAddress = "02:17:1c:96:42:fa";
Activity activity;
WifiBroadcastReceiver(Activity activity) {
this.activity = activity;
}
#Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (WifiManager.SUPPLICANT_STATE_CHANGED_ACTION.equals(action)) {
SupplicantState state = intent.getParcelableExtra(WifiManager.EXTRA_NEW_STATE);
if (SupplicantState.isValidState(state) && state == SupplicantState.COMPLETED)
checkConnectedToDesiredWifi();
}
}
/** Detect you are connected to a specific network. */
private void checkConnectedToDesiredWifi() {
WifiManager myWifiManager = (WifiManager)activity.getSystemService(Context.WIFI_SERVICE);
WifiInfo wifiInfo = myWifiManager.getConnectionInfo();
if (wifiInfo != null) {
// get current router MAC address
String bssid = wifiInfo.getBSSID();
if (desiredMacAddress.equals(bssid))
Log.d(TAG, "Connected to " + bssid + " i.e., desiredMacAddress");
else
Log.d(TAG, "Connected to " + bssid + " not " + desiredMacAddress);
}
}
}
One solution could be to run the BroadcastReceiver from a Service that doesn't depend on the lifecycle of any Activity.
1) Declare the network state permission usage in the manifest
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
1) Create a Service class
public class WifiService extends Service {
private BroadcastReceiver mReceiver;
#Nullable
#Override
public IBinder onBind(Intent intent) {
// When creating the service, register a broadcast receiver
// to listen for network state changes
IntentFilter filter = new IntentFilter();
filter.addAction("android.net.conn.CONNECTIVITY_CHANGE");
mReceiver = new WifiReceiver();
registerReceiver(mReceiver, filter);
return null;
}
#Override
public boolean onUnbind(Intent intent) {
// Unregister the receiver when unbinding the service
unregisterReceiver(mReceiver);
mReceiver = null;
return super.onUnbind(intent);
}
}
2) Create a BroadcastReceiver
public class WifiReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
ConnectivityManager manager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo networkInfo = manager.getActiveNetworkInfo();
boolean isConnected = networkInfo != null &&
networkInfo.isConnectedOrConnecting();
if (isConnected) {
switch (networkInfo.getType()) {
case ConnectivityManager.TYPE_WIFI:
// Connected via wifi
checkConnectedToDesiredWifi();
break;
case ConnectivityManager.TYPE_ETHERNET:
// Connected via ethernet
break;
case ConnectivityManager.TYPE_MOBILE:
// Connected via mobile data
break;
}
}
}
private void checkConnectedToDesiredWifi() {
// ...
}
}
3) Declare the service in the manifest
<service android:name=".receivers.WifiService"
android:stopWithTask="false"
android:enabled="true"/>

Failed to receive data over usb using Usbserial example

I am using following UsbSerial example from below link https://github.com/felHR85/SerialPortExample. I want receive data from over usb from the device shown in the photo.
Device is basically a counter machine which is sending counter data over serial port.
I am able to connect device and open port from it but unable to read data stream from it. Below is the code used. code is not giving any error
Mainactivity class
public class MainActivity extends AppCompatActivity {
/*
* Notifications from UsbService will be received here.
*/
private final BroadcastReceiver mUsbReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
switch (intent.getAction()) {
case UsbService.ACTION_USB_PERMISSION_GRANTED: // USB PERMISSION GRANTED
Toast.makeText(context, "USB Ready", Toast.LENGTH_SHORT).show();
break;
case UsbService.ACTION_USB_PERMISSION_NOT_GRANTED: // USB PERMISSION NOT GRANTED
Toast.makeText(context, "USB Permission not granted", Toast.LENGTH_SHORT).show();
break;
case UsbService.ACTION_NO_USB: // NO USB CONNECTED
Toast.makeText(context, "No USB connected", Toast.LENGTH_SHORT).show();
break;
case UsbService.ACTION_USB_DISCONNECTED: // USB DISCONNECTED
Toast.makeText(context, "USB disconnected", Toast.LENGTH_SHORT).show();
break;
case UsbService.ACTION_USB_NOT_SUPPORTED: // USB NOT SUPPORTED
Toast.makeText(context, "USB device not supported", Toast.LENGTH_SHORT).show();
break;
}
}
};
private UsbService usbService;
private TextView display;
private EditText editText;
private MyHandler mHandler;
private final ServiceConnection usbConnection = new ServiceConnection() {
#Override
public void onServiceConnected(ComponentName arg0, IBinder arg1) {
usbService = ((UsbService.UsbBinder) arg1).getService();
usbService.setHandler(mHandler);
}
#Override
public void onServiceDisconnected(ComponentName arg0) {
usbService = null;
}
};
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mHandler = new MyHandler(this);
display = (TextView) findViewById(R.id.textView1);
editText = (EditText) findViewById(R.id.editText1);
Button sendButton = (Button) findViewById(R.id.buttonSend);
sendButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (!editText.getText().toString().equals("")) {
String data = editText.getText().toString();
if (usbService != null) { // if UsbService was correctly binded, Send data
display.append(data);
usbService.write(data.getBytes());
}
}
}
});
}
#Override
public void onResume() {
super.onResume();
setFilters(); // Start listening notifications from UsbService
startService(UsbService.class, usbConnection, null); // Start UsbService(if it was not started before) and Bind it
}
#Override
public void onPause() {
super.onPause();
unregisterReceiver(mUsbReceiver);
unbindService(usbConnection);
}
private void startService(Class<?> service, ServiceConnection serviceConnection, Bundle extras) {
if (!UsbService.SERVICE_CONNECTED) {
Intent startService = new Intent(this, service);
if (extras != null && !extras.isEmpty()) {
Set<String> keys = extras.keySet();
for (String key : keys) {
String extra = extras.getString(key);
startService.putExtra(key, extra);
}
}
startService(startService);
}
Intent bindingIntent = new Intent(this, service);
bindService(bindingIntent, serviceConnection, Context.BIND_AUTO_CREATE);
}
private void setFilters() {
IntentFilter filter = new IntentFilter();
filter.addAction(UsbService.ACTION_USB_PERMISSION_GRANTED);
filter.addAction(UsbService.ACTION_NO_USB);
filter.addAction(UsbService.ACTION_USB_DISCONNECTED);
filter.addAction(UsbService.ACTION_USB_NOT_SUPPORTED);
filter.addAction(UsbService.ACTION_USB_PERMISSION_NOT_GRANTED);
registerReceiver(mUsbReceiver, filter);
}
/*
* This handler will be passed to UsbService. Data received from serial port is displayed through this handler
*/
private static class MyHandler extends Handler {
private final WeakReference<MainActivity> mActivity;
public MyHandler(MainActivity activity) {
mActivity = new WeakReference<>(activity);
}
#Override
public void handleMessage(Message msg) {
mActivity.get().display.append("Handle:");
switch (msg.what) {
case UsbService.MESSAGE_FROM_SERIAL_PORT:
String data = (String) msg.obj;
mActivity.get().display.append(data);
break;
}
}
}
}
I know it's bit late, however just to help others who might come across similar issue, did you find solution to your problem? If not, I cannot see the other java file corresponding to the service (USBService.java) as described in the example referred by you. The same file contains following code snippet which you would like to debug to find out what's going wrong (could be a problem with byte to string conversion or so). Hope this helps.
/*
* Data received from serial port will be received here. Just populate onReceivedData with your code
* In this particular example. byte stream is converted to String and send to UI thread to
* be treated there.
*/
private UsbSerialInterface.UsbReadCallback mCallback = new UsbSerialInterface.UsbReadCallback()
{
#Override
public void onReceivedData(byte[] arg0)
{
try
{
String data = new String(arg0, "UTF-8");
if(mHandler != null)
mHandler.obtainMessage(MESSAGE_FROM_SERIAL_PORT,data).sendToTarget();
} catch (UnsupportedEncodingException e)
{
e.printStackTrace();
}
}
};

programmatically register Receivers and services in android

I'm trying to register two receivers, one that will receive messages from my app server through GCM and onother that will load messages from my server.
all this are in an activity called ChatActivity
private BroadcastReceiver mMessageReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
d("Broadcast received FROM MMESSAGERECEIVER");
Toast.makeText(context, "mMessageReceiver started", Toast.LENGTH_LONG).show();
if(cust != null && adapter != null){
SharedPreferences sharedPref = ChatActivity.this.getSharedPreferences(PREFERENCES_FILE, Context.MODE_PRIVATE);
long userID = sharedPref.getLong(AllSystems.PREFERENCES_KEY_LOGGED_IN_USER_ID, -1);
// Extract data included in the Intent
String message = intent.getStringExtra("message");
String dateCreated = intent.getStringExtra("dateCreated");
Date d = new Date(Long.parseLong(dateCreated));
long senderId = Long.parseLong(intent.getStringExtra("senderId"));
Toast.makeText(context, "mMessageReceiver in the first if", Toast.LENGTH_LONG).show();
if(senderId == userID || senderId == cust.getId()){
Toast.makeText(context, "mMessageReceiver in the second if", Toast.LENGTH_LONG).show();
adapter.add(new ChatMessageData(senderId == cust.getId(), message, new DateTime(d)));
Bundle results = getResultExtras(true);
results.putBoolean(INTERCEPTED, true);
playSound();
}
}
}
};
private BroadcastReceiver mLoadedReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
d("Broadcast received");
d("Conversation loaded broadcast received");
if(task != null && cust != null){
d("Contact and task not null");
long contactId = intent.getLongExtra("contactId", -1);
if(contactId == cust.getId()){
d("Executing conversation loading task");
task.execute();
}
}
}
};
private void playSound(){
try {
Uri notification = Uri.parse("android.resource://com.me.myapp/" + R.raw.notif);
Ringtone r = RingtoneManager.getRingtone(getApplicationContext(), notification);
r.play();
} catch (Exception e) {
e.printStackTrace();
}
}
#Override
protected void onResume() {
super.onResume();
registerReceiver(mMessageReceiver, new IntentFilter("com.google.android.c2dm.intent.RECEIVE"));
LocalBroadcastManager.getInstance(this).registerReceiver(mLoadedReceiver, loadedFilter);
}
//Must unregister onPause()
#Override
protected void onPause() {
super.onPause();
unregisterReceiver(mMessageReceiver);
LocalBroadcastManager.getInstance(this).unregisterReceiver(mLoadedReceiver);
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_chats);
LocalBroadcastManager.getInstance(this).registerReceiver(mLoadedReceiver, loadedFilter);
registerReceiver(mMessageReceiver,new IntentFilter("com.google.android.c2dm.intent.RECEIVE"));
}
PROBLEM
the broadcast instance mMessageReceiver (the 1st line) isn't been registered since dialog(Toast) that are supposed to be activated in its onReceive method aren't been activated. this instance should receive GCM messages that why i have registed it like this ` registerReceiver(mMessageReceiver, new IntentFilter("com.google.android.c2dm.intent.RECEIVE"));
Question
Where am going wrong ? i have tried to follow the Try Cloud Messaging for Android and even the example at gitlab but all in vain. my previous question relation to this issue is here.
You need to declare a few permissions, services and GCMReceiver inside the manifest in order for GCM to work as intended.
Different page in the official documentation addresses GCM set up on an Android client in more depth. (refer here and sample here)
Hope this helped.

Why Android devices won't read NFC tags after a long sleep?

I'm sorry for my bad English.
I develop an Android app using NFC. I added a method that stops unsecured keyguards temporarily to the app for the purpose of quickly uses NFC tags.
However, I thought stopping keyguards causes battery drains when sleeping, so I added a method that recovers keyguards when devices are sleeping.
As a result, I wrote codes shown below.
public class MainActivity extends Activity {
private NfcAdapter mAdapter;
private PowerManager mPowerManager;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// regist screen on / off actions receiver
IntentFilter scFilter = new IntentFilter();
scFilter.addAction(Intent.ACTION_SCREEN_ON);
scFilter.addAction(Intent.ACTION_SCREEN_OFF);
scFilter.addAction(Intent.ACTION_USER_PRESENT);
registerReceiver(mScreenReceiver, scFilter);
}
#Override
public void onNewIntent(Intent intent) {
super.onNewIntent(intent);
String action = intent.getAction();
if (action != null && (action.equals(NfcAdapter.ACTION_TAG_DISCOVERED)
|| action.equals(NfcAdapter.ACTION_TECH_DISCOVERED)
|| action.equals(NfcAdapter.ACTION_NDEF_DISCOVERED))) {
// manage NFC Tags here
Log.d("MainActivity", "NFC Tags detected");
Toast.makeText(getApplicationContext(), "NFC Tags detected", Toast.LENGTH_SHORT).show();
}
}
#Override
public void onResume() {
super.onResume();
// enableForegroundDispatch
if (mAdapter == null) {
mAdapter = NfcAdapter.getDefaultAdapter(getApplicationContext());
}
if (mAdapter != null) {
Intent nfcIntent = new Intent(this, getClass());
nfcIntent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, nfcIntent, 0);
mAdapter.enableForegroundDispatch(this, pendingIntent, null, null);
} else {
Log.d("MainActivity", "failed getDefaultAdapter()");
}
}
#Override
public void onPause() {
if (mPowerManager != null) {
if (!mPowerManager.isScreenOn()) {
// clearWindowFlags only when device is sleeping
getWindow().clearFlags(WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD);
}
}
// disableForegroundDispatch
if (mAdapter != null) {
mAdapter.disableForegroundDispatch(this);
mAdapter = null;
}
super.onPause();
}
#Override
public void onDestroy() {
try {
// unregist screen on / off actions receiver
unregisterReceiver(mScreenReceiver);
} catch (IllegalArgumentException e) {
}
super.onDestroy();
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
return false;
}
private BroadcastReceiver mScreenReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction() == null) {
return;
}
if (intent.getAction().equals(Intent.ACTION_SCREEN_OFF)) {
getWindow().clearFlags(WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD);
} else if (intent.getAction().equals(Intent.ACTION_SCREEN_ON)) {
getWindow().addFlags(WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD);
} else if (intent.getAction().equals(Intent.ACTION_USER_PRESENT)) {
}
}
};
}
But, this code didn't perform as intended on my device.
I use Nexus 7 (1st, OS 4.3, Slide lock enabled).
First, when I launched the app and put my device into sleep, keyguards didn't recover with a probability of 30%. It sounds read sound effects with NFC tags even when sleeping.
Second, my device rarely won't read NFC tags after about an hour sleep with using the app. It will not even sound anything with NFC tags. But the condition goes off after sleep again or terminating the app.
Who does know causes of the bugs?

How null pointer exception can be removed

I am trying to find the signal strength of Wifi but I m getting a null pointer exception.
While fetching the network informatiopns like SSID etc. Can anyone suggest me a solution how to remove the null pointer exception.
enter code here:
public class MyReciever extends BroadcastReceiver{
WifiManager wifi;
#Override
public void onReceive(Context context, Intent intent) {
// TODO Auto-generated method stub
List<ScanResult> results=wifi.getScanResults();
ScanResult bestSignal=null;
for(ScanResult result:results)
{
if(bestSignal==null || WifiManager.compareSignalLevel(bestSignal.level, result.level)<0)
bestSignal=result;
}
String message=String.format("%s networks found. %s is the strongest", results.size(),bestSignal.SSID);
Toast.makeText(context, message, Toast.LENGTH_LONG).show();
Log.d("Debug","onRecieve() message:" +message);
}
}
public class MainActivity extends Activity {
TextView textStatus;
WifiManager wifi;
BroadcastReceiver receiver;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textStatus=(TextView)findViewById(R.id.textStatus);
wifi=(WifiManager)getSystemService(Context.WIFI_SERVICE);
WifiInfo info=wifi.getConnectionInfo();
textStatus.append("\n\nWifi Status: " +info.toString());
List<WifiConfiguration> configs=wifi.getConfiguredNetworks();
for(WifiConfiguration config:configs)
{
textStatus.append("\n\n" +config.toString());
}
if(receiver==null)
receiver = new MyReciever();
registerReceiver(receiver, new IntentFilter(
WifiManager.SCAN_RESULTS_AVAILABLE_ACTION));
Log.d("TAG", "onCreate()");
}
#Override
public void onStop() {
unregisterReceiver(receiver);
super.onStop();
}
}
Problem could be at String message=String.format("%s networks found. %s is the strongest", results.size(),bestSignal.SSID);
When there is no 'bestSignal' found, variable 'bestSignal' will be null and you are trying to execute bestSignal.SSID which might cause NPE.
Change you code like
if (bestSignal != null) {
String message=String.format("%s networks found. %s is the strongest", results.size(),bestSignal.SSID);
}
Hope it helps :)

Categories

Resources