org.wahtod.wififixer.ui.KnownNetworksFragment.java Source code

Java tutorial

Introduction

Here is the source code for org.wahtod.wififixer.ui.KnownNetworksFragment.java

Source

/*
 * Wifi Fixer for Android
 *        Copyright (C) 2010-2016  David Van de Ven
 *
 *        This program is free software: you can redistribute it and/or modify
 *        it under the terms of the GNU General Public License as published by
 *        the Free Software Foundation, either version 3 of the License, or
 *        (at your option) any later version.
 *
 *        This program is distributed in the hope that it will be useful,
 *        but WITHOUT ANY WARRANTY; without even the implied warranty of
 *        MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *        GNU General Public License for more details.
 *
 *        You should have received a copy of the GNU General Public License
 *        along with this program.  If not, see http://www.gnu.org/licenses
 */

package org.wahtod.wififixer.ui;

import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.*;
import android.graphics.Color;
import android.graphics.PorterDuff;
import android.net.wifi.ScanResult;
import android.net.wifi.WifiConfiguration;
import android.net.wifi.WifiManager;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.support.v4.app.Fragment;
import android.support.v7.app.ActionBarActivity;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.view.ActionMode;
import android.support.v7.view.ActionMode.Callback;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.*;
import android.widget.AdapterView.OnItemLongClickListener;

import org.wahtod.wififixer.R;
import org.wahtod.wififixer.WFMonitor;
import org.wahtod.wififixer.prefs.PrefConstants;
import org.wahtod.wififixer.prefs.PrefUtil;
import org.wahtod.wififixer.utility.AsyncWifiManager;
import org.wahtod.wififixer.utility.BroadcastHelper;
import org.wahtod.wififixer.utility.NotifUtil;
import org.wahtod.wififixer.utility.StringUtil;

import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.List;

public class KnownNetworksFragment extends Fragment {
    public static final String ATTWIFI = "attwifi";
    private static final int SCAN_MESSAGE = 31337;
    private static final int REFRESH_MESSAGE = 2944;
    private static final int SCAN_DELAY = 15000;
    private static final String NETWORKS_KEY = "NETWORKS_KEY";
    private static final String SSID_KEY = "SSID";
    private static WeakReference<KnownNetworksFragment> self;
    private static NetworkListAdapter adapter;
    private static List<String> knownnetworks;
    private static List<String> known_in_range;
    private static ListView mListView;
    private static Handler scanhandler = new Handler() {
        @Override
        public void handleMessage(Message message) {
            if (self.get().getActivity() == null)
                return;

            switch (message.what) {

            case SCAN_MESSAGE:
                /*
                 * If wifi is on, scan. If not, make sure no networks in range
                */
                if (AsyncWifiManager.getWifiManager(self.get().getActivity()).isWifiEnabled())
                    AsyncWifiManager.get(self.get().getActivity()).startScan();
                else {
                    if (known_in_range != null && known_in_range.size() >= 1) {
                        known_in_range.clear();
                        if (adapter != null)
                            adapter.notifyDataSetChanged();
                    }
                }
                scanhandler.sendEmptyMessageDelayed(SCAN_MESSAGE, SCAN_DELAY);
                break;

            case REFRESH_MESSAGE:
                refreshNetworkAdapter(message.getData().getStringArrayList(NETWORKS_KEY));
                break;

            }
        }
    };
    public Callback mActionModeCallback = new Callback() {
        @Override
        public boolean onCreateActionMode(ActionMode mode, Menu menu) {
            if (!isWifiOn(getContext()))
                return false;

            mFragmentPauseRequestListener.onFragmentPauseRequest(false);

            MenuInflater inflater = mode.getMenuInflater();
            mode.setTitle(mSSID);
            int n = PrefUtil.getNid(getContext(), mSSID);
            if (getStatusFromSSID(getContext(), mSSID))
                inflater.inflate(R.menu.enable, menu);
            else
                inflater.inflate(R.menu.disable, menu);

            if (known_in_range.contains(mSSID))
                inflater.inflate(R.menu.connect, menu);

            if (PrefUtil.readManagedState(getContext(), n))
                inflater.inflate(R.menu.managed, menu);
            else
                inflater.inflate(R.menu.nonmanaged, menu);

            inflater.inflate(R.menu.remove, menu);
            return true;
        }

        @Override
        public void onDestroyActionMode(ActionMode mode) {
            mActionMode = null;
            mFragmentPauseRequestListener.onFragmentPauseRequest(true);
        }

        @Override
        public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
            return false;
        }

        @Override
        public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
            int n = PrefUtil.getNid(getContext(), mSSID);
            int i = item.getItemId();
            switch (i) {
            case R.id.menu_enable:
                PrefUtil.setNetworkState(getContext(), n, false);
                PrefUtil.writeNetworkState(getContext(), n, false);
                adapter.notifyDataSetChanged();
                break;

            case R.id.menu_disable:
                PrefUtil.setNetworkState(getContext(), n, true);
                PrefUtil.writeNetworkState(getContext(), n, true);
                adapter.notifyDataSetChanged();
                break;

            case R.id.menu_managed:
                PrefUtil.writeManagedState(getContext(), n, false);
                adapter.notifyDataSetChanged();
                break;

            case R.id.menu_nonmanaged:
                PrefUtil.writeManagedState(getContext(), n, true);
                adapter.notifyDataSetChanged();
                break;

            case R.id.menu_connect:
                if (!getStatusFromSSID(getContext(), mSSID)) {
                    Intent intent = new Intent(WFMonitor.CONNECTINTENT);
                    intent.putExtra(WFMonitor.NETWORKNAME, PrefUtil.getStringfromNetwork(getContext(), n));
                    BroadcastHelper.sendBroadcast(getContext(), intent, true);
                } else {
                    AsyncWifiManager.get(getContext()).enableNetwork(n, true);
                }
                break;

            case R.id.menu_remove:
                AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
                builder.setMessage("Remove network:" + mSSID).setPositiveButton("Yes", dialogClickListener)
                        .setNegativeButton("No", dialogClickListener).show();
                break;
            }
            mode.finish();
            return true;
        }
    };
    protected Object mActionMode;
    protected String mSSID;
    DialogInterface.OnClickListener dialogClickListener = new DialogInterface.OnClickListener() {
        @Override
        public void onClick(DialogInterface dialog, int which) {
            switch (which) {
            case DialogInterface.BUTTON_POSITIVE:
                removeNetwork(PrefUtil.getNid(getContext(), mSSID));
                break;

            case DialogInterface.BUTTON_NEGATIVE:
                // Ok, do nothing
                break;
            }
        }
    };
    private OnFragmentPauseRequestListener mFragmentPauseRequestListener;
    private OnItemLongClickListener il = new OnItemLongClickListener() {

        @SuppressLint("NewApi")
        @Override
        public boolean onItemLongClick(AdapterView<?> parent, View v, int p, long id) {

            TextView ssid = (TextView) v.findViewById(R.id.ssid);
            mSSID = ssid.getText().toString();
            if (mActionMode != null || (PrefUtil.readBoolean(getActivity(), PrefConstants.Pref.ATT_BLACKLIST.key()))
                    && mSSID.equals(ATTWIFI)) {
                return false;
            }
            AppCompatActivity activity = (AppCompatActivity) getActivity();
            mActionMode = activity.startSupportActionMode(mActionModeCallback);
            v.setSelected(true);
            return true;

        }
    };
    private BroadcastReceiver receiver = new BroadcastReceiver() {
        public void onReceive(Context context, Intent intent) {
            /*
             * we know this is going to be a scan result notification
            */
            Message msg = Message.obtain();
            msg.what = REFRESH_MESSAGE;
            Bundle data = new Bundle();
            data.putStringArrayList(NETWORKS_KEY, getKnownAPArray(context));
            msg.setData(data);
            scanhandler.sendMessage(msg);
        }
    };

    public static KnownNetworksFragment newInstance(int num) {
        KnownNetworksFragment f = new KnownNetworksFragment();
        // Supply num input as an argument.
        Bundle args = new Bundle();
        args.putInt("num", num);
        f.setArguments(args);
        return f;
    }

    public static List<String> getNetworks(Context context) {
        WifiManager wm = AsyncWifiManager.getWifiManager(context);
        List<WifiConfiguration> wifiConfigs = wm.getConfiguredNetworks();
        if (wifiConfigs == null || wifiConfigs.isEmpty())
            return new ArrayList<>();

        List<String> networks = new ArrayList<String>();
        for (WifiConfiguration wfResult : wifiConfigs) {
            /*
             * Make sure there's a 1:1 correlation between
            * getConfiguredNetworks() and the array
            */
            if (wfResult.SSID != null && wfResult.SSID.length() > 0)
                networks.add(StringUtil.removeQuotes(wfResult.SSID));
            else
                networks.add(context.getString(R.string.null_ssid));
        }
        return networks;
    }

    private static void refreshNetworkAdapter(ArrayList<String> networks) {
        /*
         * Don't refresh if knownnetworks is empty (wifi is off)
        */
        knownnetworks = getNetworks(self.get().getActivity());
        if (knownnetworks.size() > 0) {
            known_in_range = networks;
            if (adapter == null) {
                adapter = self.get().new NetworkListAdapter(knownnetworks);
                mListView.setAdapter(adapter);
            } else {
                refreshArray();
                adapter.notifyDataSetChanged();
            }
        }
    }

    private static boolean isWifiOn(Context ctxt) {
        return AsyncWifiManager.getWifiManager(ctxt).isWifiEnabled();
    }

    private static void refreshArray() {
        if (knownnetworks.equals(adapter.ssidArray))
            return;

        ArrayList<String> remove = new ArrayList<String>();

        for (String ssid : knownnetworks) {
            if (!adapter.ssidArray.contains(ssid))
                adapter.ssidArray.add(ssid);
        }

        for (String ssid : adapter.ssidArray) {
            if (!knownnetworks.contains(ssid))
                remove.add(ssid);
        }

        for (String ssid : remove) {
            adapter.ssidArray.remove(ssid);
        }
    }

    @Override
    public void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        /*
         * Preserve ActionMode state
         */
        if (mActionMode != null) {
            outState.putString(SSID_KEY, mSSID);
        }
    }

    @Override
    public void onActivityCreated(Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        if (savedInstanceState != null && savedInstanceState.containsKey(SSID_KEY)) {
            mSSID = savedInstanceState.getString(SSID_KEY);
            AppCompatActivity activity = (AppCompatActivity) getActivity();
            mActionMode = activity.startSupportActionMode(mActionModeCallback);
            for (int c = 1; c < adapter.getCount(); c++) {
                if (adapter.getItem(c).equals(mSSID)) {
                    mListView.setSelection(c);
                }
            }
        }
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        self = new WeakReference<KnownNetworksFragment>(this);
        super.onCreate(savedInstanceState);
    }

    public boolean getStatusFromSSID(Context context, String ssid) {
        WifiConfiguration net = PrefUtil.getNetworkByNID(context, PrefUtil.getNid(context, ssid));
        if (net == null)
            return false;
        else {
            boolean enabled = net.status == WifiConfiguration.Status.DISABLED;
            return enabled;
        }
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View v = inflater.inflate(R.layout.knownnetworks, null);
        mListView = (ListView) v.findViewById(R.id.knownlist);
        adapter = self.get().new NetworkListAdapter(knownnetworks);
        mListView.setAdapter(adapter);
        mListView.setOnItemLongClickListener(il);
        return v;
    }

    @Override
    public void onAttach(Activity activity) {
        /*
         * Grab and set up ListView
        */
        knownnetworks = getNetworks(getContext());
        known_in_range = new ArrayList<>();
        mFragmentPauseRequestListener = (OnFragmentPauseRequestListener) activity;
        super.onAttach(activity);
    }

    @SuppressLint("NewApi")
    @Override
    public void onPause() {
        unregisterReceiver();
        super.onPause();
    }

    @Override
    public void onResume() {
        super.onResume();
        registerReceiver();
    }

    private ArrayList<String> getKnownAPArray(Context context) {

        WifiManager wm = AsyncWifiManager.getWifiManager(context);

        List<ScanResult> scanResults = wm.getScanResults();
        /*
         * Catch null if scan results fires after wifi disabled or while wifi is
        * in intermediate state
        */
        if (scanResults == null) {
            return null;
        }
        /*
         * Iterate the known networks over the scan results, adding found known
        * networks.
        */
        ArrayList<String> known_in_range = new ArrayList<String>();
        for (ScanResult sResult : scanResults) {
            /*
             * Add known networks in range
            */

            if (knownnetworks.contains(sResult.SSID)) {
                /*
                 * Add result to known_in_range
                */
                known_in_range.add(sResult.SSID);
            }
        }

        return known_in_range;
    }

    private void registerReceiver() {
        IntentFilter filter = new IntentFilter(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION);
        BroadcastHelper.registerReceiver(getContext(), receiver, filter, false);
        scanhandler.sendEmptyMessage(SCAN_MESSAGE);
    }

    private void unregisterReceiver() {
        BroadcastHelper.unregisterReceiver(getContext(), receiver);
        scanhandler.removeMessages(SCAN_MESSAGE);
        scanhandler.removeMessages(REFRESH_MESSAGE);
    }

    private void removeNetwork(int network) {
        NotifUtil.showToast(getContext(), getContext().getString(R.string.removing_network) + mSSID);
        AsyncWifiManager.getWifiManager(getActivity()).removeNetwork(network);
        AsyncWifiManager.getWifiManager(getActivity()).saveConfiguration();
        scanhandler.sendEmptyMessage(SCAN_MESSAGE);
    }

    public interface OnFragmentPauseRequestListener {
        public void onFragmentPauseRequest(boolean state);
    }

    /*
     * custom adapter for Network List ListView
     */
    private class NetworkListAdapter extends BaseAdapter {
        private List<String> ssidArray;
        private LayoutInflater inflater;

        public NetworkListAdapter(List<String> knownnetworks) {
            inflater = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            ssidArray = knownnetworks;
        }

        /*
         * Disable ATTWIFI when it's disabled.
         */
        @Override
        public boolean isEnabled(int position) {
            String item = ssidArray.get(position);
            if (item != null) {
                return !blackListCheck(item);
            }
            return super.isEnabled(position);
        }

        public int getCount() {
            return ssidArray.size();
        }

        public Object getItem(int position) {
            return ssidArray.get(position);
        }

        public long getItemId(int position) {
            return position;
        }

        public View getView(int position, View convertView, ViewGroup parent) {
            ViewHolder holder;
            if (convertView == null) {
                convertView = inflater.inflate(R.layout.known_list_layout, null);
                holder = new ViewHolder();
                holder.text = (TextView) convertView.findViewById(R.id.ssid);
                holder.icon = (ImageView) convertView.findViewById(R.id.NETWORK_ICON);
                convertView.setTag(holder);
            } else {
                holder = (ViewHolder) convertView.getTag();
            }
            if (ssidArray.get(position) != null) {
                if (known_in_range.contains(ssidArray.get(position)))
                    holder.text.setTextColor(Color.GREEN);
                else
                    holder.text.setTextColor(Color.WHITE);
                /*
                 * Set SSID text and color
                */
                holder.text.setText(ssidArray.get(position));
                if (PrefUtil.readManagedState(getContext(), position))
                    holder.text.setTextColor(Color.BLACK);
                else {
                    if (!getStatusFromSSID(getContext(), ssidArray.get(position)))
                        holder.icon.setColorFilter(Color.WHITE, PorterDuff.Mode.SRC_ATOP);
                    else
                        holder.icon.setColorFilter(Color.BLACK, PorterDuff.Mode.SRC_ATOP);
                    if (blackListCheck(holder.text.getText().toString())) {
                        holder.text.setTextColor(Color.RED);
                    }
                }
            }
            return convertView;
        }

        private boolean blackListCheck(String item) {
            if (!PrefUtil.readBoolean(getContext(), PrefConstants.Pref.ATT_BLACKLIST.key()))
                return false;
            else
                return (item.equals(ATTWIFI));
        }

        private class ViewHolder {
            TextView text;
            ImageView icon;
        }
    }
}