ACTION_PICK_WIFI_NETWORK on a dialog with avaliable networks

前端 未结 2 1316
故里飘歌
故里飘歌 2021-01-14 15:41

I\'m trying to create a Dialog which shows something like ACTION_PICK_WIFI_NETWORK but instead of open Android Settings / WiFi open it

2条回答
  •  广开言路
    2021-01-14 16:26

    From the ui perspective you need a Custom adapter:

    private class WifiAdapter extends ArrayAdapter {
    
        public WifiAdapter(Context context, int resource, List objects) {
            super(context, resource, objects);
        }
    
        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            if (convertView == null) {
                convertView = getLayoutInflater().inflate(R.layout.wifi_item, parent, false);
            }
            ScanResult result = getItem(position);
            ((TextView) convertView.findViewById(R.id.wifi_name)).setText(formatSSDI(result));
            ((ImageView) convertView.findViewById(R.id.wifi_img)).setImageLevel(getNormalizedLevel(result));
            return convertView;
        }
    
        private int getNormalizedLevel(ScanResult r) {
            int level = WifiManager.calculateSignalLevel(r.level,
                    5);
            Log.e(getClass().getSimpleName(), "level " + level);
            return level;
        }
    
        private String formatSSDI(ScanResult r) {
            if (r == null || r.SSID == null || "".equalsIgnoreCase(r.SSID.trim())) {
                return "no data";
            }
            return r.SSID.replace("\"", "");
        }
    

    I slightly changed your showWifiListDialog:

    private void showWifiListDialog(List results) {
        Collections.sort(results, new Comparator() {
            @Override
            public int compare(ScanResult lhs, ScanResult rhs) {
                return rhs.level > lhs.level ? 1 : rhs.level < lhs.level ? -1 : 0;
            }
        });
        AlertDialog.Builder builderSingle = new AlertDialog.Builder(
                this);
        final WifiAdapter arrayAdapter = new WifiAdapter(
                this,
                android.R.layout.select_dialog_item, results);
    
        builderSingle.setNegativeButton(getString(android.R.string.cancel),
                new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        dialog.dismiss();
                    }
                });
        builderSingle.setAdapter(arrayAdapter,
                new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        String strName = arrayAdapter.getItem(which).SSID;
                        Toast.makeText(getApplicationContext(), "Selected " + strName, Toast.LENGTH_SHORT).show();
                    }
                });
        AlertDialog dialog = builderSingle.create();
        dialog.show();
    }
    

    the Wifi Item is

    
    
        
    
        
    
    

    and the drawable wifi_level is

    
    
        
        
        
        
    
        
    
    

    I took the five png from here

    For the Connection, the answer is yes it should be possible. Accordingly to the documentation at least. You can instantiate an object of WifiConfiguration, and feed it with info of the network you want to connect to (SSID and password). It is not a straightforward thing to do. If you have to take in consideration the different kind of keys encryption, (WPA, WEP, free wifi). Onceyou filled up the object, you have to call

    mWifiManager.disconect();
    int resId = mWifiManager.addNetwork(config);
    mWifiManager.enableNetwork(resId, true);
    

    Edit:

    If you want to show the wifi-signal-strength icon with and without padlock, you could use custom attribute

    
    
        
            
        
    
    

    and update its state in a subclass of ImageView:

     public class WifiImageView extends ImageView {
    
    private static final int[] STATE_LOCKED = {R.attr.state_locked};
    private boolean mWifiLocked;
    
    public WifiImageView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }
    
    @Override
    public int[] onCreateDrawableState(int extraSpace) {
        final int[] drawableState = super.onCreateDrawableState(extraSpace + 1);
        if (mWifiLocked) {
            mergeDrawableStates(drawableState, STATE_LOCKED);
        }
        return drawableState;
    }
    
    public void setStateLocked(boolean locked) {
        mWifiLocked = locked;
        refreshDrawableState();
    }
    

    }

    Now assuming that the android:src of your WifeImageView is a selector

    
    
        
        
    
    

    In your Adapter you can easily switch between the two level-list, adding the following two lines of code

     boolean protectedWifi = result.capabilities.contains ("WEP") || result.capabilities.contains("WPA");
     ((WifiImageView) convertView.findViewById(R.id.wifi_img)).setStateLocked(protectedWifi);
    

    protectedWifi is evaluated true if result.capabilities contains WEP or WPA, and setStateLocked(protectedWifi); will switch between the two level-lists accordingly to its value. Of course, in the wifi_item.xml, you have two change from ImageView, to the custom WifiImageView.

提交回复
热议问题