ANDROID STUDIO Persistent wifi scanner - android

I'm currently working on a wifi scanner project on an Android API 19
My problem is when the screen is off, after about 10 minutes it stops scanning the wifi
and when I turn on my device the scan starts again correctly.
I can not remove deep sleep :/
how to do a persistent wifi scan properly ??
someone has a suggestion ??
Thanks for your help

I am root on my device, this is my service background scan wifi
AndroidManifest :
<service android:name=".wifi" android:process=":my_service" android:enabled="true" android:priority="999" android:exported="true" android:label="Preferences"/>
service WIFI
class scanner_wifi extends Service implements TextToSpeech.OnInitListener {
private TextToSpeech tts;
public void onCreate() {
tts = new TextToSpeech(this, this);
final WifiManager mWifiManager = (WifiManager) getSystemService(WIFI_SERVICE);
if(mWifiManager.getWifiState() == WifiManager.WIFI_STATE_ENABLED) {
IntentFilter filter = new IntentFilter();
filter.addAction(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION);
registerReceiver(new BroadcastReceiver(){
#Override
public void onReceive(Context context, Intent intent) {
Log.e("WIFI_SCAN","NEW SCAN WIFI");
tts.speak("WIFI", TextToSpeech.QUEUE_FLUSH, null);
List<ScanResult> results = mWifiManager.getScanResults();
final int N = results.size();
for(int i=0; i < N; ++i) {
Log.e("WIFI_SCAN", " BSSID =" + results.get(i).BSSID);
Log.e("WIFI_SCAN", " SSID =" + results.get(i).SSID);
Log.e("WIFI_SCAN", " Capabilities=" + results.get(i).capabilities);
Log.e("WIFI_SCAN", " Frequency =" + results.get(i).frequency);
Log.e("WIFI_SCAN", " Level =" + results.get(i).level);
Log.e("WIFI_SCAN", "---------------");
}
}
}, filter);
mWifiManager.startScan();
}
}
#Override
public void onInit(int status) {
if (status == TextToSpeech.SUCCESS) {
int result = tts.setLanguage(Locale.FRENCH);
if (result == TextToSpeech.LANG_MISSING_DATA || result == TextToSpeech.LANG_NOT_SUPPORTED) {
Log.e("WIFI_SCAN", "This Language is not supported");
}
} else {
Log.e("WIFI_SCAN", "Initilization Failed!");
}
}
public void onDestroy(){
Toast.makeText(this, "Service Destroyed", Toast.LENGTH_SHORT).show();
super.onDestroy();
}
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
}
my code works well but after x minutes of screen off , the device close my apps :/
Thanks for your help

Related

How to get notification when a device connects to your android wifi tethering AP?

I enable wi-fi tethering through my application in my android device. How do I get notification in my application when someone connects to the Wi-Fi network tethered by my application? Do I need to register for some specific broadcast receivers?
I have pasted below the application source code
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
((ToggleButton) findViewById(R.id.toggle_tethering)).setOnCheckedChangeListener(this);
}
#Override
public void onCheckedChanged(CompoundButton button, boolean isChecked) {
WifiManager wifiManager = (WifiManager) getSystemService(WIFI_SERVICE);
Boolean result = false;
WifiConfiguration config = new WifiConfiguration();
config.SSID = "Tab3OpenWifi";
config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
String setWifiApConfigurationMethodName = "setWifiApConfiguration";
Method setWifiApConfigurationMethod = wifiManager.getClass().getMethod(setWifiApConfigurationMethodName, WifiConfiguration.class);
result = (Boolean) setWifiApConfigurationMethod.invoke(wifiManager, config);
if (result) {
String setWifiApEnableMethodName = "setWifiApEnabled";
Method setWifiApEnableMethod = wifiManager.getClass().getMethod(setWifiApEnableMethodName, WifiConfiguration.class, boolean.class);
String message;
if (isChecked) {
result = (Boolean) setWifiApEnableMethod.invoke(wifiManager, null, true);
if (result) {
message = "Enabling tethering successfully";
} else {
message = "Enabling tethering failed";
}
} else {
result = (Boolean) setWifiApEnableMethod.invoke(wifiManager, null, false);
if (result) {
message = "Disabling tethering successfully";
} else {
message = "Disabling tethering failed";
}
}
Toast.makeText(this, message, Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(this, "Failed to update Wifi Tethering config.", Toast.LENGTH_SHORT).show();
}
}
I used below broadcast receiver to get the AP state.
private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
Log.d(TAG,"mReceiver.onReceive>>");
String action = intent.getAction();
if (WIFI_AP_STATE_CHANGED_ACTION.equals(action)) {
Log.d(TAG,"WIFI_AP_STATE_CHANGED_ACTION");
} else if (ACTION_TETHER_STATE_CHANGED.equals(action)) {
ArrayList<String> available = intent.getStringArrayListExtra(
EXTRA_AVAILABLE_TETHER);
ArrayList<String> active = intent.getStringArrayListExtra(
EXTRA_ACTIVE_TETHER);
ArrayList<String> errored = intent.getStringArrayListExtra(
EXTRA_ERRORED_TETHER);
Log.d(TAG,"==Available==");
for(String str : available)
Log.d(TAG, ""+str);
Log.d(TAG,"==Active==");
for(String str : active)
Log.d(TAG, ""+active);
Log.d(TAG,"==Error==");
for(String str : errored)
Log.d(TAG, ""+str);
} else if (Intent.ACTION_AIRPLANE_MODE_CHANGED.equals(action)) {
}
Log.d(TAG,"mReceiver.onReceive<<");
}
};
I don't think there is an API for that, nor any broadcast event which you can listen to.
The only option that I can think of is operating at a lower level, i.e. the kernel level. I am no expert, but I used to monitor the /proc/net/tcp file to look for open connections. That may be a starting point for you.
I also wrote a simple library, if you want to get a glimpse of how I did it. You can find it here: https://github.com/dextorer/AndroidTCPSourceApp

WIFI P2P stops discovering peers and doesn't accept connections after 2 minutes

I have been messing around with the following issue for about 2 months now.
I am building an application on a custom android board which will act as a wifi display (WFD). When I boot the board, I can easily connect from several different phones (LG Optimus G, LG Optimus G pro, Samsung S3 and S4). After connecting and watching the screen being duplicated on the TV screen attached to the custom board, I can then disconnect and if I reconnect within 2 minutes, I can connect again.
If I boot the board (or disconnect) and then wait 2 minutes, the device no longer sees the phones, and the phones sometimes sees the board, and sometimes not. If the phone sees the board, I can initiate a connect, but I cannot connect succesfully.
I have tried all kind of options, but none seem viable.
The board is running on AOSP 4.2.2
I have right now some complicated code that does restart the discoverPeers function every 40 seconds, as normally it stops after 30 seconds. Besides that I disable WFD and re-enable it, with a 4 second delay between it.
I also tried disabling and reenabling p2p and the channel, all with no result.
Below is my code, the receiver is in a separate class.
#Override
protected void onCreate(Bundle savedInstanceState)
{
Settings.System.putInt(getContentResolver(), Settings.System.WIFI_SLEEP_POLICY, Settings.System.WIFI_SLEEP_POLICY_NEVER);
AudioManager audioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
audioManager.setStreamVolume(AudioManager.STREAM_MUSIC,
audioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC), 0);
setContentView(R.layout.wifi_direct_discovery);
connectPicture = findViewById(R.id.LinearLayout1);
Log.d(TAG, "onCreate");
isConnecting = false;
localWifiP2pWfdInfo = new WifiP2pWfdInfo();
localWifiP2pWfdInfo.setWfdEnabled(true);
localWifiP2pWfdInfo.setDeviceType(1);
localWifiP2pWfdInfo.setSessionAvailable(true);
localWifiP2pWfdInfo.setControlPort(7236);
localWifiP2pWfdInfo.setMaxThroughput(50);
final PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
PowerManager.WakeLock wl = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "My Tag");
wl.acquire();
super.onCreate(savedInstanceState);
}
#Override
public void onPeersAvailable(WifiP2pDeviceList peers)
{
List<WifiP2pDevice> peersList = new ArrayList<WifiP2pDevice>();
final ArrayList<String> list = new ArrayList<String>();
final ListView listview = (ListView) findViewById(R.id.deviceListView);
peersList.clear();
peersList.addAll(peers.getDeviceList());
if (peersList.size() == 0)
{
Log.d(TAG, "No devices found");
list.clear();
if ((pd != null) && pd.isShowing() && (isConnecting == false))
{
pd.dismiss();
Log.d(TAG, "Closed connecting dialog, restarting P2P");
Toast.makeText(this, "Connection failed please try again", Toast.LENGTH_LONG).show();
restartP2p(false);
}
else if (isConnecting == false)
{
restartP2p(false);
}
listview.setAdapter(new ArrayAdapter<String>(this, R.layout.list_black_text, R.id.list_content, list));
return;
}
else
{
int i = 0;
boolean found = false;
for (i = 0; i < peersList.size(); i++)
{
Log.d(TAG, "Found device: " + peersList.get(i).toString());
list.add(peersList.get(i).deviceName);
if ((pd != null) && pd.isShowing())
{
if (peersList.get(i).deviceAddress.equalsIgnoreCase(client.deviceAddress))
{
found = true;
}
}
}
if (!found)
{
if ((pd != null) && pd.isShowing())
{
Log.d(TAG, "Failed to find current client: closed connecting dialog, restarting P2P");
Toast.makeText(this, "Disconnected please try again", Toast.LENGTH_LONG).show();
restartP2p(false);
}
else
{
Log.d(TAG, "Failed to find current client, but we weren't trying to connect");
}
}
}
listview.setAdapter(new ArrayAdapter<String>(this, R.layout.list_black_text, R.id.list_content, list));
}
#Override
public void onConnectionInfoAvailable(WifiP2pInfo p2pInfo)
{
if (p2pInfo.isGroupOwner)
{
stopP2PDispeerTimeoutThread();
Log.d(TAG, "Connected as group owner");
int i = p2pInfo.mWfdRtspPort;
Log.d(TAG, "------------------------- onConnectionInfoAvailable rtsp port = " + i);
// get the ip addres from the connected client. Mac address is in
// client
String sourceIP = null;
while (sourceIP == null)
{
sourceIP = getIPFromMac(client.deviceAddress);
millisleep(250);
if (sourceIP == null)
{
Log.e(TAG, "Failed to get client address!!!!! from " + client.deviceAddress);
}
}
if (i == 0)
{
// this is not a wfd source, so let's get into client mode for
// upgrade etc.
Log.e(TAG, "This device is not a WFD source, so switch to client mode, device = "
+ client.deviceAddress);
}
else
{
Log.d(TAG, "Start connect to source : " + sourceIP);
if ((pd != null) && pd.isShowing())
pd.dismiss();
// need to stop the connection timeout thread here..
stopConnectTimeoutThread();
Intent intent = new Intent(getBaseContext(), WFDPlayActivity.class);
intent.putExtra("SOURCE_IP", sourceIP);
intent.putExtra("RTSPPORT", i);
startActivityForResult(intent, 210);
}
}
else
{
Log.e(TAG, "Connected as peer, this is very very wrong!!!!, restartP2P");
restartP2p(false);
startP2PDispeerTimeoutThread(34);
}
}
#Override
public void onConnectionRequested(WifiP2pDevice arg0, WifiP2pConfig arg1)
{
Log.d(TAG, "------------------------------------- onConnectionRequested");
stopP2PDispeerTimeoutThread();
isConnecting = true;
client = arg0;
if ((pd != null) && (pd.isShowing()))
{
pd.dismiss();
}
if (client != null)
{
createConnectionProgressDialog(client.deviceName);
}
}
public void onResume()
{
if (first_time == false)
{
Log.d(TAG, "onResume");
intentFilter.addAction("android.net.wifi.p2p.STATE_CHANGED");
intentFilter.addAction("android.net.wifi.p2p.PEERS_CHANGED");
intentFilter.addAction("android.net.wifi.p2p.CONNECTION_STATE_CHANGE");
intentFilter.addAction("android.net.wifi.p2p.THIS_DEVICE_CHANGED");
registerReceiver(receiver, intentFilter);
if (!mP2PDispeerThread.isRunning)
startP2PDispeerTimeoutThread(34);
manager.setDialogListener(channel, this);
manager.discoverPeers(channel, new WifiP2pManager.ActionListener()
{
#Override
public void onSuccess()
{
Log.d(TAG, "discoverPeers success");
}
#Override
public void onFailure(int reasonCode)
{
Log.d(TAG, "discoverPeers failed");
}
});
}
else
{
Log.d(TAG, "onResume, first time");
restartP2p(first_time);
first_time = false;
}
getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_HIDE_NAVIGATION);
super.onResume();
}
public void restartP2p(boolean first)
{
if (first)
{
mWifiManager = ((WifiManager) getSystemService("wifi"));
mWifiManager.setWifiEnabled(true);
sleep(4); // was 4
manager = (WifiP2pManager) getSystemService(Context.WIFI_P2P_SERVICE);
channel = manager.initialize(this, getMainLooper(), null);
manager.enableP2p(channel);
sleep(3); // was 3
mDisplayManager = ((DisplayManager) getSystemService("display"));
intentFilter.addAction(WifiP2pManager.WIFI_P2P_STATE_CHANGED_ACTION);
intentFilter.addAction(WifiP2pManager.WIFI_P2P_PEERS_CHANGED_ACTION);
intentFilter.addAction(WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION);
intentFilter.addAction(WifiP2pManager.WIFI_P2P_THIS_DEVICE_CHANGED_ACTION);
mlock = mWifiManager.createWifiLock(WifiManager.WIFI_MODE_FULL_HIGH_PERF , "LockTag");
mlock.acquire();
instance = this;
receiver = new WiFiDirectBroadcastReceiver(manager, channel, this);
registerReceiver(receiver, intentFilter);
manager.setWFDInfo(channel, localWifiP2pWfdInfo, new WifiP2pManager.ActionListener()
{
public void onFailure(int paramAnonymousInt)
{
Log.d(TAG, "Failed to set WFD info with reason " + paramAnonymousInt + ".");
}
public void onSuccess()
{
Log.d(TAG, "updateWfdEnableState");
}
});
sleep(1);
manager.setDialogListener(channel, this);
manager.discoverPeers(channel, new WifiP2pManager.ActionListener()
{
#Override
public void onSuccess()
{
Log.d(TAG, "discoverPeers success");
}
#Override
public void onFailure(int reasonCode)
{
Log.d(TAG, "discoverPeers failed");
}
});
}
else
{
manager.stopPeerDiscovery(channel, new WifiP2pManager.ActionListener()
{
#Override
public void onSuccess()
{
Log.d(TAG, "stopPeerDiscovery success");
}
#Override
public void onFailure(int reasonCode)
{
Log.d(TAG, "stopPeerDiscovery failed");
}
});
localWifiP2pWfdInfo.setWfdEnabled(false);
manager.setWFDInfo(channel, localWifiP2pWfdInfo, new WifiP2pManager.ActionListener()
{
public void onFailure(int paramAnonymousInt)
{
Log.d(TAG, "Failed to set WFD info with reason " + paramAnonymousInt + ".");
}
public void onSuccess()
{
Log.d(TAG, "updateWfdEnableState");
}
});
sleep(4);
localWifiP2pWfdInfo.setWfdEnabled(true);
manager.setWFDInfo(channel, localWifiP2pWfdInfo, new WifiP2pManager.ActionListener()
{
public void onFailure(int paramAnonymousInt)
{
Log.d(TAG, "Failed to set WFD info with reason " + paramAnonymousInt + ".");
}
public void onSuccess()
{
Log.d(TAG, "updateWfdEnableState");
}
});
manager.discoverPeers(channel, new WifiP2pManager.ActionListener()
{
#Override
public void onSuccess()
{
Log.d(TAG, "discoverPeers success");
}
#Override
public void onFailure(int reasonCode)
{
Log.d(TAG, "discoverPeers failed");
}
});
}
if (first)
startP2PDispeerTimeoutThread(40); // only start the thread 1 time...
}
In the logging initially I see that the device and the phone connect successfully.
After disconnect, I see the devices being lost in the log, and after that, when I try to connect, I see the message:
I/wpa_supplicant(1839): [CTRL_IFACE]p2p0: P2P_CONNECT da:57:ef:cb:8e:be pbc go_intent=0
After this everything stops, the application is still running, I could see that from a log line that runs every second in the thread that stops and restarts the discovery every 40 seconds.
If anyone has any idea left why this behavior is happening, let me know. The only way to recover right now is to reboot the board (but that is not an option).
Thanks for your replies,
Arvy

How to connect using wifi direct for transfer file?

i want to build an application using wifi direct to transfer files and i'm using NFC to reduce pairing time. I've already follow the instruction in http://developer.android.com/guide/topics/connectivity/wifip2p.html and http://developer.android.com/training/connect-devices-wirelessly/wifi-direct.html but my apps won't connect. and i took the code from wifi direct demo from android example.
when i trace the problem is when wifi direct broadcast receiver WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION the network info won't to connect with other device so, in my main class that implements ConnectionInfoListener that have a method onConnectionInfoAvailable it's never triggered.
can anyone help me? thx before
the code is like this
Wifi Direct BroadCast Receiver
`
public void onReceive(Context arg0, Intent intent) {
// TODO Auto-generated method stub
String action = intent.getAction();
if (WifiP2pManager.WIFI_P2P_STATE_CHANGED_ACTION.equals(action)) {
// UI update to indicate wifi p2p status.
int state = intent.getIntExtra(WifiP2pManager.EXTRA_WIFI_STATE, -1);
if (state == WifiP2pManager.WIFI_P2P_STATE_ENABLED) {
// Wifi Direct mode is enabled
activity.setIsWifiP2pEnabled(true);
} else {
activity.setIsWifiP2pEnabled(false);
//activity.resetData();
}
//Log.d(WiFiDirectActivity.TAG, "P2P state changed - " + state);
} else if (WifiP2pManager.WIFI_P2P_PEERS_CHANGED_ACTION.equals(action)) {
// request available peers from the wifi p2p manager. This is an
// asynchronous call and the calling activity is notified with a
// callback on PeerListListener.onPeersAvailable()
if (manager != null) {
}
//Log.d(WiFiDirectActivity.TAG, "P2P peers changed");
} else if (WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION.equals(action)) {
if (manager == null) {
return;
}
NetworkInfo networkInfo = (NetworkInfo) intent
.getParcelableExtra(WifiP2pManager.EXTRA_NETWORK_INFO);
if (networkInfo.isConnected()) {
// we are connected with the other device, request connection
// info to find group owner IP
manager.requestConnectionInfo(channel, activity);
} else {
// It's a disconnect
}
} else if (WifiP2pManager.WIFI_P2P_THIS_DEVICE_CHANGED_ACTION.equals(action)) {
WifiP2pDevice device = (WifiP2pDevice) intent.getParcelableExtra(WifiP2pManager.EXTRA_WIFI_P2P_DEVICE);
activity.myname = device.deviceName + " " + device.deviceAddress + " " + device.primaryDeviceType + " " + device.secondaryDeviceType + " " + device.status;
}
}`
my main class
`
// how to connect
WifiP2pConfig config = new WifiP2pConfig();
config.deviceAddress = names[1];
config.wps.setup = WpsInfo.PBC;
config.groupOwnerIntent = 15;
connect(config);
public void connect(WifiP2pConfig config) {
manager.connect(channel, config, new ActionListener() {
#Override
public void onSuccess() {
// WiFiDirectBroadcastReceiver will notify us. Ignore for now.
}
#Override
public void onFailure(int reason) {
Toast.makeText(getApplicationContext(), "Connect failed. Retry.", Toast.LENGTH_SHORT).show();
}
});
}
public void disconnect() {
manager.removeGroup(channel, new ActionListener() {
#Override
public void onFailure(int reasonCode) {
//Log.d(TAG, "Disconnect failed. Reason :" + reasonCode);
Toast.makeText(getApplicationContext(), "Disconnect failed. Reason :" + reasonCode, Toast.LENGTH_SHORT).show();
}
#Override
public void onSuccess() {
Toast.makeText(getApplicationContext(), "Disconnected", Toast.LENGTH_SHORT).show();
}
});
}
public void onChannelDisconnected() {
// we will try once more
if (manager != null && !retryChannel) {
Toast.makeText(this, "Channel lost. Trying again", Toast.LENGTH_LONG).show();
//resetData();
retryChannel = true;
manager.initialize(this, getMainLooper(), this);
} else {
Toast.makeText(this,
"Severe! Channel is probably lost premanently. Try Disable/Re-Enable P2P.",
Toast.LENGTH_LONG).show();
}
}
public void onConnectionInfoAvailable(WifiP2pInfo info) {
// TODO Auto-generated method stub
this.info = info;
// After the group negotiation, we can determine the group owner.
if (info.groupFormed && info.isGroupOwner) {
// Do whatever tasks are specific to the group owner.
// One common case is creating a server thread and accepting
// incoming connections.
Toast.makeText(getApplicationContext(), "Owner", Toast.LENGTH_SHORT).show();
} else if (info.groupFormed) {
// The other device acts as the client. In this case,
// you'll want to create a client thread that connects to the group
// owner.
Toast.makeText(getApplicationContext(), "Client", Toast.LENGTH_SHORT).show();
}
}
`
onConnectionInfoAvailable will never be executed because the networkInfo.isConnected() is never true.
Please help me.. Thx..

BroadcastReceiver not being called after activity resume

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?

Android - Passing changing data from BroadcastReceiver to another Object?

I have a Wifi class that has a couple of broadcast receivers that listen out for changes in Wifi connection state, Wifi Rssi levels etc...
I want to be able to pass this data to another "Engine" Object and still keep the data changing dynamically.
I currently create a Wifi object within the "Engine" class and run its methods, the data is then dynamically displayed fine in Log statements in the log cat.
My problem is trying to get the dynamically changing data to the Engine, when I try to get data over it gets the first value and leaves it at that without ever updating.
So I was wondering what my options are on how to do this?
Below is my current code setup if that is any help:
Wifi Class
public Wifi(Context context){
mainWifi = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
}
public int getCurrentWifiState() {
return currentWifiState;
}
public void setCurrentWifiState(int currentWifiState) {
this.currentWifiState = currentWifiState;
}
public String getConnectedSSID() {
return connectedSSID;
}
public void setConnectedSSID(String connectedSSID) {
this.connectedSSID = connectedSSID;
}
public int getConnectedLevel() {
return connectedLevel;
}
public void setConnectedLevel(int connectedLevel) {
this.connectedLevel = connectedLevel;
}
//method to do a scan and receive info about all access points available
public List<ScanResult> scan(final Context context){
receiverWifi = new WifiReceiver();
mainWifi = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
context.registerReceiver(receiverWifi, new IntentFilter(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION));
mainWifi.startScan();
Log.d("WIFI DEBUG","\nStarting Scan...\n");
wifiList = mainWifi.getScanResults();
return wifiList;
}
class WifiReceiver extends BroadcastReceiver {
public void onReceive(Context c, Intent intent) {
sb = new StringBuilder();
wifiList = mainWifi.getScanResults();
ListIterator<ScanResult> results = wifiList.listIterator();
while (results.hasNext()) {
ScanResult info = results.next();
String wifiInfo = "Name: " + info.SSID + "; capabilities = " + info.capabilities + "; sig str = " + info.level + "dBm";
Log.v("WiFi", wifiInfo);
Log.d("Signal Level", "Signal Level : " + mainWifi.calculateSignalLevel(info.level, 5));
}
}
}
//method to listen for changes in the level of the wifi connection
public void initializeWiFiListener(Context context){
Log.d("WIFI", "executing initializeWiFiListener");
String connectivity_context = Context.WIFI_SERVICE;
final WifiManager wifi = (WifiManager)context.getSystemService(connectivity_context);
if(!wifi.isWifiEnabled()){
if(wifi.getWifiState() != WifiManager.WIFI_STATE_ENABLING){
//wifi.setWifiEnabled(true);
}
}
rssiListener = new BroadcastReceiver(){
#Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if(WifiManager.RSSI_CHANGED_ACTION.equals(action)){
WifiInfo data = mainWifi.getConnectionInfo();
Log.d("WIFI", "RSSI has changed");
if(mainWifi.getConnectionInfo()!=null){
setConnectedSSID(data.getSSID());
setConnectedLevel(data.getRssi());
Log.d("WIFI", "new RSSI = " + data.getSSID()+ " " + data.getRssi() + "dBm");
}
}
}
};
//leak here - need to de reg receiver
context.registerReceiver(rssiListener, new IntentFilter(WifiManager.RSSI_CHANGED_ACTION));
}
//method to listen for changes in the connection to a wifi access point
public void changeWiFiListener(Context context){
Log.d("WIFI", "executing initializeWiFiListener");
String connectivity_context = Context.WIFI_SERVICE;
final WifiManager wifi = (WifiManager)context.getSystemService(connectivity_context);
if(!wifi.isWifiEnabled()){
if(wifi.getWifiState() != WifiManager.WIFI_STATE_ENABLING){
//wifi.setWifiEnabled(true);
}
}
wifiChangeListener = new BroadcastReceiver(){
#Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if(WifiManager.WIFI_STATE_CHANGED_ACTION.equals(action)){
Log.d("WIFI", "WIFI has changed");
int wifiState = intent.getIntExtra(WifiManager.EXTRA_WIFI_STATE, -1);
Log.d("WIFI", "WIFI State = " + wifiState);
setCurrentWifiState(wifiState);
}
}
};
//Leak here - not unregistering receiver
context.registerReceiver(wifiChangeListener, new IntentFilter(WifiManager.WIFI_STATE_CHANGED_ACTION));
}
public WifiReceiver getReceiverWifi() {
return receiverWifi;
}
public void setReceiverWifi(WifiReceiver receiverWifi) {
this.receiverWifi = receiverWifi;
And my Engine Code:
public Engine(Context aContext){
context = aContext;
cm = new CallManager(aContext);
wifiManager = new Wifi(context);
wifiManager.initializeWiFiListener(context);
wifiManager.changeWiFiListener(context);
clc = new CallLogController();
}
public void controlCalls(){
int currentWifiState = wifiManager.getCurrentWifiState();
cm.monitorOutgoingCalls(context, currentWifiState, clc);
}
public void unRegAllRecievers(){
wifiManager.unregRegisters(context);
cm.unRegReciever(context);
}
public void doWifiScan(){
scanTask = new TimerTask() {
public void run() {
handler.post(new Runnable() {
public void run() {
wifiManager.scan(context);
Log.d("TIMER", "Timer set off");
}
});
}};
t.schedule(scanTask, 300, 30000);
}
public void stopScan(){
scanTask.cancel();
t.cancel();
//boolean tf = scanTask.cancel();
//Log.d("TIMER", "Timer True or False? : " + tf);
}
}
So I'm just wondering what would be the best solution to make sure the data from the Wifi class is constantly updated in the engine when it receives changes from the broadcast receiver?
depends if your class, the one that should be notified of the latest state.
If it's a class that is not created in an Activity and is static (singletone or Application based) then you should probably have the Reciver update the singletone class.
If it's Activity based, you need stick Broadcasts, and once the broadcast is recieved remove the sticky broadcast.

Categories

Resources