0

I am trying to build a Reminder App. In this app, user will select a WiFi name which is saved on the phone. And when the user connects to that WiFi, Phone is going to vibrate. And after phone vibrates, service is going to die.

I have tried to write a Service to check the WiFi name in every 1 minute. When I close the app, it runs again but not as I expected.

Service Implementation:

public class AlarmService extends Service {
private static final String TAG = "com.wificheckalways";
public static String wifiToCheck = MainActivity.wifiName;

public AlarmService(){

}

public int onStartCommand(Intent intent, int flags, int startId){
    Log.i(TAG, "onStartCommand called");

    Runnable runnable = new Runnable() {
        @Override
        public void run() {
            String ssid = "";
            ConnectivityManager connManager = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
            NetworkInfo networkInfo = connManager.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
            if (networkInfo.isConnected()) {
                final WifiManager wifiManager = (WifiManager) getApplicationContext().getSystemService(Context.WIFI_SERVICE);
                final WifiInfo connectionInfo = wifiManager.getConnectionInfo();
                if (connectionInfo != null && !TextUtils.isEmpty(connectionInfo.getSSID())) {
                    ssid = connectionInfo.getSSID();
                }
            }

            while(!wifiToCheck.equals(ssid)){
                Log.i(TAG, "Goes to SLEEP");
                synchronized (this){
                    try{
                        Thread.sleep(60000);
                        Log.i(TAG, "WAKE UP");
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                networkInfo = connManager.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
                if (networkInfo.isConnected()) {
                    final WifiManager wifiManager = (WifiManager) getApplicationContext().getSystemService(Context.WIFI_SERVICE);
                    final WifiInfo connectionInfo = wifiManager.getConnectionInfo();
                    if (connectionInfo != null && !TextUtils.isEmpty(connectionInfo.getSSID())) {
                        ssid = connectionInfo.getSSID();
                        Log.i(TAG, "Compare " + wifiToCheck + " with " + ssid);
                    }
                }

            }

            if(wifiToCheck.equals(ssid)) {
                Vibrator v = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE);
                v.vibrate(2000); // 2000 miliseconds = 2 seconds
            }
        }
    };

    Thread alarmThread = new Thread(runnable);
    alarmThread.start();

    return Service.START_STICKY; //Restart service if it got destroyed
}

public void onDestroy(){
    Log.i(TAG, "onDestroyCommand called");
}

@Nullable
@Override
public IBinder onBind(Intent intent) {
    return null;
}

Where I start the service in MainActivity.java:

public void SetAlarm(View view) {
    if (!wifiName.equals("")) {
        Toast.makeText(getApplicationContext(), "Alarm set for: " + wifiName, Toast.LENGTH_SHORT).show();

        Intent intent = new Intent(this, AlarmService.class);
        startService(intent);
    }
    else{
        Toast.makeText(getApplicationContext(), "Please choose a WiFi name!!!", Toast.LENGTH_SHORT).show();
    }
}

wifiName is the choosen Wifi.

What is wrong with this code?

Ege
  • 305
  • 1
  • 3
  • 9
  • I would use broadcast receiver inside service that will receive message when WiFi connection changes. From that message I would extract information about connection and check if WiFi's SSID is equal to saved SSID. If it is, phone would vibrate. That way you wouldn't have to use threads. – Stefan Golubović Mar 18 '18 at 12:45
  • So, service will run to check if the WiFi connection has changed? If yes, then I will get the current SSID and compare with the chosen SSID. Am I right? But I still can't understand how to use Broadcast Receiver in it :/ – Ege Mar 18 '18 at 13:01
  • [Context-registered broadcast receiver](https://developer.android.com/guide/components/broadcasts.html#context-registered_receivers), [broadcast receiver for connection change](https://stackoverflow.com/a/47202596/4778343). When creating service (`onCreate`) register for connection change (and of course unregister in `onDestroy`). Your code for checking if user is connected to particular SSID would go inside broadcast receiver's method `onReceive`. In this case, you would stop service after vibration. – Stefan Golubović Mar 18 '18 at 13:14
  • One last question, what happens if the WiFi that the user connected, if not the chosen WiFi? – Ege Mar 18 '18 at 13:38
  • Nothing. You're still going to have `if (wifiToCheck.equals(ssid))`. If they're not equal, your service will still wait for user to connect to particular (chosen) WiFi. If they're equal, phone will vibrate and you will stop your service. – Stefan Golubović Mar 18 '18 at 14:05

2 Answers2

1

As I suggested in the comments, your service could look like this:

public class AlarmService extends Service {
    public AlarmService() {}

    @Override
    public void onCreate() {
        super.onCreate();
        IntentFilter intentFilter = new IntentFilter(WifiManager.NETWORK_STATE_CHANGED_ACTION);
        registerReceiver(receiver, intentFilter);
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        unregisterReceiver(receiver);
    }

    private BroadcastReceiver receiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();
            if (action.equals(WifiManager.NETWORK_STATE_CHANGED_ACTION)) {
                NetworkInfo networkInfo = intent.getParcelableExtra(WifiManager.EXTRA_NETWORK_INFO);
                if (networkInfo.isConnected()) {
                    if (networkInfo.getType() == ConnectivityManager.TYPE_WIFI) {
                        WifiManager wifiManager = (WifiManager) getApplicationContext().getSystemService(Context.WIFI_SERVICE);
                        String ssid = wifiManager.getConnectionInfo().getSSID();
                        if (ssid.equals(<<ENTERED_SSID>>)) {
                            Vibrator vibrator = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE);
                            vibrator.vibrate(2000);
                            stopSelf();
                        }
                    }
                }
            }
        }
    };
} 

The only part that's "missing" is entered SSID.

Stefan Golubović
  • 1,225
  • 1
  • 16
  • 21
0

I guess you have to stop the service in activty onPause() or onDestroy() methods like stopService(new Intent(MainActivity.this,AlarmService.class));

ruben
  • 1,745
  • 5
  • 25
  • 47
  • From MainActivity? But I don't know when the user is going to connect to the chosen WiFi. So when should I call stopService? – Ege Mar 18 '18 at 13:03