cc.psdev.heywifi.MainService.java Source code

Java tutorial

Introduction

Here is the source code for cc.psdev.heywifi.MainService.java

Source

/*
 * Copyright 2015 Park Si Hyeon
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package cc.psdev.heywifi;

import android.app.ActivityManager;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
import android.media.AudioManager;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.net.wifi.ScanResult;
import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;
import android.os.Build;
import android.os.IBinder;
import android.support.v4.app.NotificationCompat;
import android.util.Log;

import java.util.List;

public class MainService extends Service implements Runnable {

    WifiManager wm;
    ConnectivityManager cm;
    List<ScanResult> scanResult;
    NetworkInfo ni;
    AudioManager audm;
    ActivityManager actm;
    NotificationManager nm;

    DBManager dm;
    Cursor csr;
    SharedPrefSettings pref;

    String[] resbssid;
    int[] ressignal;
    String[] bssid;
    String[] ssid;
    int[] autoon;
    int[] ringmode;
    int sleepTime;
    int alreadyNoticed = 0;

    boolean autoonstatus;

    // TODO: DATABASE_VERSION
    static int DATABASE_VERSION = 5;

    static int SDK_VERSION = Build.VERSION.SDK_INT;
    static int SDK_21 = Build.VERSION_CODES.LOLLIPOP;

    static int SIGNAL_MINIMUM = -85;

    @Override
    public void onCreate() {
        super.onCreate();
    }

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

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

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        Log.i("onStartCommand", "called");
        wm = (WifiManager) getSystemService(Context.WIFI_SERVICE);
        cm = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
        ni = cm.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
        dm = new DBManager(getApplicationContext(), "data", null, DATABASE_VERSION);
        audm = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
        actm = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
        nm = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
        pref = new SharedPrefSettings(this);
        Thread thread = new Thread(this);
        thread.start();

        return START_STICKY;
    }

    @Override
    public void run() {
        while (true) {
            loadDB();

            if (shouldRun()) {
                showTurnedoffNoti(0);

                searchWifi();

                autoonstatus = autoOn();
                if (!autoonstatus && pref.getOffOutofRange() == 1) {
                    wm.setWifiEnabled(false);
                    if (pref.getOffOutofRangeData() == 1) {
                        if (SDK_VERSION > SDK_21) {
                            // TODO: find how to disable mobile network on lollipop and above
                        } else {
                            cm.stopUsingNetworkFeature(ConnectivityManager.TYPE_MOBILE,
                                    "android.net.conn.CONNECTIVITY_CHANGE");
                        }
                    }
                }
                if (!changeRingmode() && pref.getRingmodeSaveEnabled() == 1 && pref.getRingmodeSaved() != -1) {
                    changeFromSavedRingmode(pref.getRingmodeSaved() - 10);
                    pref.putRingmodeSaved(-1);
                }

                if (autoonstatus && pref.getOffData() == 1) {
                    if (SDK_VERSION > SDK_21) {
                        // TODO: same as up
                    } else {
                        cm.stopUsingNetworkFeature(ConnectivityManager.TYPE_MOBILE,
                                "android.net.conn.CONNECTIVITY_CHANGE");
                    }
                }
            } else {
                showTurnedoffNoti(1);
            }

            try {
                Thread.sleep(sleepTime - 2000);
            } catch (InterruptedException ex) {
            }
        }
    }

    private void loadDB() {
        ssid = new String[20];
        bssid = new String[20];
        autoon = new int[20];
        ringmode = new int[20];

        // To handle CursorWindowAllocationException
        try {
            csr = dm.select();
            csr.moveToFirst();

            for (int i = 0; !csr.isAfterLast(); i++) {
                ssid[i] = csr.getString(0);
                bssid[i] = csr.getString(1);
                autoon[i] = csr.getInt(3);
                ringmode[i] = csr.getInt(4);

                csr.moveToNext();
            }
        } finally {
            if (csr != null) {
                csr.close();
            }
        }

        sleepTime = pref.getSleeptime() * 1000;
    }

    private boolean shouldRun() {
        return pref.getRunservice() == 1;
    }

    private void searchWifi() {
        wm.startScan();
        try {
            Thread.sleep(2000);
        } catch (InterruptedException ex) {
        }

        scanResult = wm.getScanResults();
        resbssid = new String[30];
        ressignal = new int[30];

        int i = 0;
        for (ScanResult result : scanResult) {
            if (i < 30) {
                resbssid[i] = result.BSSID;
                ressignal[i] = result.level;
                i++;
            }
        }
    }

    private boolean autoOn() {
        for (int i = 0; i < 30; i++) {
            try {
                for (int j = 0; j < 20; j++) {
                    if (autoon[j] == 1 && resbssid[i].equals(bssid[j])) {

                        if (pref.getSignal() == 1 && ressignal[i] < SIGNAL_MINIMUM) {
                            continue;
                        } else {
                            wm.setWifiEnabled(true);
                            return true;
                        }

                    }
                }
            } catch (NullPointerException ex) {
            }
        }
        return false;
    }

    private boolean changeRingmode() {
        for (int i = 0; i < 30; i++) {
            try {
                for (int j = 0; j < 20; j++) {
                    if (ringmode[j] != -1 && resbssid[i].equals(bssid[j])) {

                        if (pref.getSignal() == 1 && ressignal[i] < SIGNAL_MINIMUM) {
                            continue;
                        } else {

                            if (pref.getRingmodeSaved() < 10) {
                                switch (audm.getRingerMode()) {
                                case 2:
                                    pref.putRingmodeSaved(12);
                                    break;
                                case 1:
                                    pref.putRingmodeSaved(11);
                                    break;
                                case 0:
                                    pref.putRingmodeSaved(10);
                                    break;
                                }
                            }

                            switch (ringmode[j]) {
                            case 2:
                                audm.setRingerMode(AudioManager.RINGER_MODE_NORMAL);
                                return true;
                            case 1:
                                audm.setRingerMode(AudioManager.RINGER_MODE_VIBRATE);
                                return true;
                            case 0:
                                audm.setRingerMode(AudioManager.RINGER_MODE_SILENT);
                                return true;
                            }

                        }
                    }
                }
            } catch (NullPointerException ex) {
            }
        }

        return false;
    }

    // 1 - show notification, 0 - disable notification
    private void showTurnedoffNoti(int type) {
        if (type == 1 && alreadyNoticed == 0) {
            NotificationCompat.Builder noti = new NotificationCompat.Builder(this);
            noti.setSmallIcon(R.drawable.ic_notification);
            noti.setContentTitle(getResources().getString(R.string.stopnoti_title));
            noti.setTicker(getResources().getString(R.string.stopnoti_ticker));
            noti.setContentText(getResources().getString(R.string.stopnoti_text));
            noti.setOngoing(true);

            Intent notiIntent = new Intent(this, SelectRunServiceActivity.class);
            notiIntent.setFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);

            // TODO: pendingIntent
            PendingIntent pendingIntent = PendingIntent.getActivity(this, 1320001, notiIntent,
                    PendingIntent.FLAG_UPDATE_CURRENT);
            noti.setContentIntent(pendingIntent);

            nm.notify(1111, noti.build());
            alreadyNoticed = 1;
        } else if (type == 0) {
            nm.cancel(1111);
            alreadyNoticed = 0;
        }
    }

    private void changeFromSavedRingmode(int ringmode) {
        switch (ringmode) {
        case 2:
            audm.setRingerMode(AudioManager.RINGER_MODE_NORMAL);
            break;
        case 1:
            audm.setRingerMode(AudioManager.RINGER_MODE_VIBRATE);
            break;
        case 0:
            audm.setRingerMode(AudioManager.RINGER_MODE_SILENT);
            break;
        }
    }
}