I have the following code in a service which is called with an AlarmManager (this works well) but when when I start the wifi scan (which returns true) I never receive the results in the BroadcastReceiver I created:
public class WifiCheckerService extends IntentService {
WifiManager wifiManager;
List<Wifi> savedWifis;
List<Wifi> wifisInRange;
List<ScanResult> wifisInRangeResults;
BroadcastReceiver broadcastReceiver;
public WifiCheckerService() {
super("WifiCheckerService");
}
#Override
public void onCreate() {
super.onCreate();
setScanAlwaysAvailable();
if(broadcastReceiver == null)
broadcastReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
check();
}
};
if (wifiManager == null)
wifiManager = (WifiManager) getSystemService(Context.WIFI_SERVICE);
registerReceiver(broadcastReceiver,
new IntentFilter(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION));
}
#Override
protected void onHandleIntent(Intent intent) {
if (intent != null) {
wifiManager.startScan();
}
}
private void check() {
// irrelevant stuff
Intent intent = new Intent(Constants.BROADCAST_UPDATE_WIFI);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
sendBroadcast(intent);
}
}
public List<Wifi> getSavedWifisInRange(List<Wifi> savedWifis,
List<ScanResult> wifisInRangeResults) {
List<Wifi> wifisInRange = new ArrayList<Wifi>();
for (Wifi wifi : savedWifis) {
for (int i = 0; i < wifisInRangeResults.size(); i++) {
if (wifi.getSsid().equals(wifisInRangeResults.get(i).SSID)) {
wifi.setRssi(String.valueOf(wifisInRangeResults.get(i).level));
wifisInRange.add(wifi);
}
}
}
return wifisInRange;
}
public void setScanAlwaysAvailable() {
/* Set scan always available if it is turned off*/
WifiManager wifiManager = (WifiManager) getSystemService(Context.WIFI_SERVICE);
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.JELLY_BEAN_MR2) {
if (!wifiManager.isScanAlwaysAvailable()) {
startActivity(new Intent(WifiManager.ACTION_REQUEST_SCAN_ALWAYS_AVAILABLE));
}
}
}
public boolean isTetheringActive() {
//irrelevant stuff
return false;
}
private boolean isAnySavedWifiInRange() {
//irrelevant stuff
return true;
}
#Override
public void onDestroy() {
super.onDestroy();
unregisterReceiver(wifiScanReceiver);
}
}
I have used BroadcastReceiver's with wifi scans before, but I don't know why this is not working.
What's wrong?
EDIT: AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="com.android.vending.BILLING" />
<application
android:name=".WifiSentinelApp"
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"
android:label="#string/app_name"
android:screenOrientation="portrait"
android:theme="#style/AppTheme.NoActionBar">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name=".activities.DonateActivity"
android:label="#string/donate"
android:screenOrientation="portrait"
android:theme="#style/AppTheme.NoActionBar" />
<activity
android:name=".activities.SettingsActivity"
android:label="#string/settings"
android:screenOrientation="portrait" />
<receiver android:name=".receivers.AlarmReceiver" />
<receiver android:name=".receivers.BootReceiver"
android:enabled="false">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
<service android:name=".services.WifiCheckerService" />
</application>
My understanding of the IntentService is that it will only be active for the time needed to handle the request (ie, the time needed to run onHandleIntent()). I haven't tested your code, but my guess is that your broadcast receiver is being unregistered right away when onDestroy() runs, before the scan results are delivered. Probably an IntentService is not right for this. You might need to create a "regular" (long living background) service. Or, maybe it just makes more sense to have your BroadcastReceiver in the activity where you will show the scan results and get rid of this IntentService altogether. WifiManager::startScan() is asynchronous so it shouldn't be necessary to call that on a background service anyway.
Related
I'm using a BroadcastReceiver to check network state which extends a class rather than initializing BroadcastReceiver. So, is it possible to unregister it anywhere?
If yes then how, if not then what would be the alternate solution of doing that.
I see a solution here but it isn't the actual answer of the question.
Here's my class where I am using BroadcastReceiver.
public class CheckNetworkState extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
final ConnectivityManager connMgr = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
/*check WIFI state*/
final android.net.NetworkInfo wifi = connMgr.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
/*check network state*/
final android.net.NetworkInfo mobile = connMgr.getNetworkInfo(ConnectivityManager.TYPE_MOBILE);
if (wifi.isAvailable() || mobile.isAvailable()) {
//Toast.makeText(context, "connection established", Toast.LENGTH_SHORT).show();
} else {
/*shows dialogue*/
Intent alertDialogueIntent = new Intent(context, DialogueUtils.class);
alertDialogueIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(alertDialogueIntent);
}
}
}
And here's my Manifest.xml
<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" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.hardware.camera" />
<uses-permission android:name="android.hardware.camera.autofocus" />
<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=".Utils.DialogueUtils" />
<receiver
android:name=".Utils.CheckNetworkState"
android:enabled="true">
<intent-filter>
<action
android:name="android.net.conn.CONNECTIVITY_CHANGE"
tools:ignore="BatteryLife" />
</intent-filter>
</receiver>
<activity android:name=".UserAuth.ChangePassword"></activity>
<activity android:name=".QRScanner.CustomScanner" />
<activity android:name=".WaterMetersList.WaterMeters" />
<activity android:name=".UserAuth.Login" />
<activity
android:name=".ControlCharts.Charts"
android:label="#string/title_activity_bottom_navigation" />
<activity android:name=".Splash">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
In your application class create static receiver as follows:
public class YourApplication extends Application {
public static BroadcastReceiver receiver;
public void onCreate() {
super.onCreate();
receiver = new CheckNetworkState();
}
}
After that you can register your receiver anywhere as:
IntentFilter filter = new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION);
this.registerReceiver(YourApplication.receiver, filter);
After that you can unregister it as:
getContext().unregisterReceiver(YourApplication.receiver);
i have created a BroadcastReceiver called Autostart to be called, when the device is booted:
public class Autostart extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent arg1)
{
Log.i("mydebug","autostart");
Intent intent = new Intent(context, RegisterService.class);
context.startService(intent);
}
}
this is the Service that is supposed to be called:
public class RegisterService extends Service {
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.i("mydebug","service");
BroadcastReceiver receiver = new NetWatcher();
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION);
registerReceiver(receiver, intentFilter);
return super.onStartCommand(intent, flags, startId);
}
}
and here my Manifest:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.ginso.podcasts">
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<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=".NetWatcher">
<intent-filter>
<action android:name="android.net.conn.CONNECTIVITY_CHANGE"/>
</intent-filter>
</receiver>
<receiver android:name=".Autostart">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
<service android:name=".RegisterService"/>
</application>
</manifest>
i also register the NetWatcher in my MainActivity the same way. Now when i start the app, the Netwatcher immediatly gets called and also everytime i change my wifi state. When i restart my phone, the autostart calls the service, which registers the NetWatcher, which also gets immediatly called. But if i change the wifi state now, nothing happens
register NetWatcher in onCreate() of your service
Try Changing your action to android.net.conn.CONNECTIVITY_CHANGE instead WifiManager.NETWORK_STATE_CHANGED_ACTION
I have a Broadcast Receiver for connectivity changes and it works fine for all the devices running below android N but its not working on android N. I cannot find any thing relevant regarding this whether they changes something in N or not. DO anyone has any idea why this is happening?
MANIFEST FILE
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.admin.movies">
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<application
android:name=".MovieSingleton"
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:supportsRtl="true"
android:theme="#style/AppTheme">
<activity android:name=".SplashActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<receiver
android:name=".NetworkBroadcastReceiver"
android:exported="false"
android:enabled="true">
<intent-filter>
<action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
</intent-filter>
</receiver>
</application>
Here is my broadcast receiver
public class NetworkBroadcastReceiver extends BroadcastReceiver {
private static final String TAG = NetworkBroadcastReceiver.class.getSimpleName();
public NetworkBroadcastReceiver() {
}
#Override
public void onReceive(Context context, Intent intent) {
Log.d(TAG, "onReceive: network change");
if(isOnline(context)){
Log.d(TAG, "onReceive: connected");
} else {
Log.d(TAG, "onReceive: not connected");
}
}
public boolean isOnline(Context mContext) {
ConnectivityManager connMgr = (ConnectivityManager)
mContext.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo networkInfo = connMgr.getActiveNetworkInfo();
return (networkInfo != null && networkInfo.isConnected());
}
}
Since many apps register to receive this broadcast, a single network switch can cause them all to wake up and process the broadcast at once.
In Android Nougat, You have to register your BroadcastReceiver with Context.registerReceiver().
This change is part of Android 7.0 background optimizations and performance improvements.
I have a PackageBroadcastReceiver running ok while the app is in the background. I need it to keep listening to packages added/removed when it is closed. But, it is not.
Is there any way to do this with a BroadcastReceiver or should I move to a service?
Here the code:
<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"/>
<uses-sdk
android:minSdkVersion="11"
android:targetSdkVersion="23" />
<application
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<activity
android:name="com.cresan.antivirus.StockingActivity"
android:label="#string/app_name"
android:screenOrientation="portrait">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<receiver android:name="com.tech.applications.coretools.advertising.PackageBroadcastReceiver">
<intent-filter>
<action android:name="android.intent.action.PACKAGE_INSTALL" />
<action android:name="android.intent.action.PACKAGE_ADDED" />
<data android:scheme="package"/>
</intent-filter>
</receiver>
</application>
And my PackageBroadcastReceiver:
public class PackageBroadcastReceiver extends BroadcastReceiver
{
static IPackageChangesListener _listener;
static public void setPackageBroadcastListener(IPackageChangesListener listener)
{
_listener=listener;
}
#Override
public void onReceive(Context ctx, Intent intent)
{
if(_listener!=null && Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction()))
_listener.OnPackageAdded(intent);
if(_listener!=null && Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction()))
_listener.OnPackageRemoved(intent);
}
}
Cheers.
You will definitely need to implement a background service to do this. See the developer guide.
You can then programmatically register a BroadcastReceiver in your service:
private PackageBroadcastReceiver packageBroadcastReceiver;
#Override
public void onCreate() {
super.onCreate();
this.packageBroadcastReceiver = new PackageBroadcastReceiver();
this.packageBroadcastReceiver.setPackageBroadcastListener(new IPackageChangesListener() {
public void OnPackageAdded(Intent i) {
//do something here- probably start an activity
}
...
});
IntentFilter packageFilter = new IntentFilter("android.intent.action.PACKAGE_ADDED");
packageFilter.addAction("android.intent.action.PACKAGE_INSTALL");
packageFilter.addDataScheme("package");
this.registerReceiver(this.packageBroadcastReceiver, packageFilter);
}
#Override
public void onDestroy(){
super.onDestroy();
this.unregisterReceiver(this.packageBroadcastReceiver);
}
Try registering broadcast receiver in service. After activity is destroyed, receiver will be destroyed to so you will not get broadcast event.
I have a problem that I made a service which executes a task in background after every 5 seconds, for this I made a receiver in manifest and autostarter class but it is not excuted in my app. Means the service is not running in the app. I don't know why? Please suggest me for the right answer.
Android Manifest:
<application android:icon="#drawable/icon" android:label="#string/app_name">
<receiver android:name="com.halosys.TvAnyTime.ServiceAutoStarter">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
<activity android:name=".MainScreen"
android:label="#string/app_name" android:screenOrientation="portrait" android:theme="#android:style/Theme.NoTitleBar">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name=".IntroVideo" android:label="#string/app_name" android:theme="#style/CustomTheme" android:screenOrientation="landscape"/>
<activity android:name=".WelcomeScreen1" android:theme="#android:style/Theme.NoTitleBar" android:screenOrientation="portrait"/>
<activity android:name=".IntroFaceBookScreen" android:theme="#android:style/Theme.NoTitleBar" android:screenOrientation="portrait"/>
</application>
<uses-permission xmlns:android="http://schemas.android.com/apk/res/android"
android:name="android.permission.INTERNET"></uses-permission>
<uses-permission android:name="android.permission.CHANGE_WIFI_MULTICAST_STATE"/>
<uses-permission android:name="android.permission.READ_INPUT_STATE"></uses-permission>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_MOCK_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-sdk android:minSdkVersion="3" />
</manifest>
ServiceAutoStarter:
public class ServiceAutoStarter extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Intent myIntent = new Intent(context, ServiceTemplate.class);
myIntent.putExtra("extraData", "somedata");
context.startService(myIntent);
}
}
ServiceTemplate.java:
public class ServiceTemplate extends Service {
Runnable refresher;
public static int HashesInPattern=32; // 32 64byte hashes in the pattern
public static int BytesInHash =64;
static byte[] hashPattern;
ArrayList<byte[]> finalHashafterXor = new ArrayList<byte[]>();
byte[] finaldatafile = new byte[2097152];
byte[] finalhash;
InputStream is;
byte[] bytesafterXor,bytes;
String strLine;
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onCreate() {
//code to execute when the service is first created
}
#Override
public void onDestroy() {
//code to execute when the service is shutting down
}
#Override
public void onStart(Intent intent, int startid) {
//code to execute when the service is starting up
final Handler handler = new Handler();
refresher = new Runnable() {
public void run() {
// some action
try{
Encrypt();
Toast.makeText(getApplicationContext(), "Hello World", Toast.LENGTH_SHORT).show();
}
catch(Exception e)
{
e.printStackTrace();
}
handler.postDelayed(refresher, 2000);
}
};
}
Thanks in advance.
I haven't gone through whole of your code but i saw manifest file
Like activities (and other components), you must declare all services in your application's manifest file.
Please do change and try.