android - 具有可用网络的对话框中的 ACTION_PICK_WIFI_NETWORK

标签 android

我正在尝试创建一个 Dialog,它显示类似 ACTION_PICK_WIFI_NETWORK 的内容,但不是打开 Android Settings/WiFi 上打开它code>Dialog,如果可能的话,用户可以连接到该 Dialog 可用的任何网络。我现在打开的是一个 Dialog,其中包含 Android 中可用 Wi-Fi 网络的 List,但这个 List 不是与 Android Settings/WiFi 相同,这就是为什么我要问是否可以在对话框中打开此 ACTION_PICK_WIFI_NETWORK 并使用它。如果无法连接到网络,请点击 Dialog 中的 Item 并提供可用的 WiFi?

到目前为止我尝试过的是

我有一个BroadcastReceiver()

wifiReceiver = new BroadcastReceiver(){
@Override
  public void onReceive(Context c, Intent intent){  
       if(mWifiManager != null) {
          List<ScanResult> results = mWifiManager.getScanResults();
          showWifiListDialog(results);
       }
  }
};

一个RegisterReceiver()

registerReceiver(wifiReceiver,new IntentFilter(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION));

这是执行 WifiScan

的方法
private void startWifiScans() {
 mWifiManager = (WifiManager)getSystemService(Context.WIFI_SERVICE);
 mWifiManager.startScan();
}

这是显示 SCAN_RESULTS_AVAILABLE_ACTION 的简单 Dialog

private void showWifiListDialog(List<ScanResult> results) {
    AlertDialog.Builder builderSingle = new AlertDialog.Builder(
            this);
    final ArrayAdapter<String> arrayAdapter = new ArrayAdapter<String>(
            this,
            android.R.layout.select_dialog_item);

    for (ScanResult r: results) {
        if(r == null || r.SSID == null) continue;
        if("".equalsIgnoreCase(r.SSID.trim())) continue;
        String name = r.SSID.replace("\"", "");
        arrayAdapter.add(name);
    }
    builderSingle.setNegativeButton(getString(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);
                    Toast.makeText(getApplicationContext(),"Selected "+strName, Toast.LENGTH_SHORT).show();
                }
            });
    AlertDialog dialog = builderSingle.create();
    dialog.show();
}

图片示例

Thisthis是示例或我正在寻找的内容。

编辑(这就是我现在看到我的对话框的方式,但我还不喜欢它....)

enter image description here

我想用 icon 显示网络信号强度,就像 android 一样 example .我想我需要一个 ListAdapter 左右?然后添加网络名称、强度连接、图标等……我错了吗?

几乎一样的题对there ..

我想通过 Notification 打开它,显然我是在那个 APP 上还是在其他 APP 上并不重要...我只是想将它作为一个对话框打开然后让用户看到用户正在观看的内容。

现在我得到的是:

enter image description here

我正在使用 Theme,但它没有按照我的要求进行。

<style name="dialogtest" parent="AppTheme">
    <item name="android:windowFrame">@android:color/transparent</item>
    <item name="android:windowIsFloating">true</item>
    <item name="android:windowIsTranslucent">true</item>
    <item name="android:windowNoTitle">true</item>
    <item name="android:background">@android:color/transparent</item>
    <item name="android:windowBackground">@android:color/transparent</item>
</style>

这就是风格,我这样调用它:

 protected void onCreate(Bundle savedInstanceState) {
    setTheme(R.style.dialogtest);
    super.onCreate(savedInstanceState);

最佳答案

从用户界面的角度来看,您需要一个自定义适配器:

private class WifiAdapter extends ArrayAdapter<ScanResult> {

    public WifiAdapter(Context context, int resource, List<ScanResult> 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("\"", "");
    }

我稍微改变了你的showWifiListDialog:

private void showWifiListDialog(List<ScanResult> results) {
    Collections.sort(results, new Comparator<ScanResult>() {
        @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();
}

Wifi 项目是

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="horizontal">

    <TextView
        android:textSize="16sp"
        android:padding="5dp"
        android:layout_gravity="center_vertical"
        android:id="@+id/wifi_name"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_weight="1" />

    <ImageView
        android:id="@+id/wifi_img"
        android:layout_gravity="center_vertical"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:src="@drawable/wifi_level" />
</LinearLayout>

可绘制的 wifi_level 是

<?xml version="1.0" encoding="utf-8"?>
<level-list xmlns:android="http://schemas.android.com/apk/res/android">
    <item
        android:drawable="@drawable/ic_signal_wifi_0_bar_black_24dp"
        android:maxLevel="0" />
    <item
        android:drawable="@drawable/ic_signal_wifi_1_bar_black_24dp"
        android:maxLevel="1" />
    <item
        android:drawable="@drawable/ic_signal_wifi_2_bar_black_24dp"
        android:maxLevel="2" />
    <item
        android:drawable="@drawable/ic_signal_wifi_3_bar_black_24dp"
        android:maxLevel="3" />

    <item
        android:drawable="@drawable/ic_signal_wifi_4_bar_black_24dp"
        android:maxLevel="4" />
</level-list>

我从 here 中取出了五个 png

对于连接,答案是是的,它应该是可能的。至少根据文档。您可以实例化 WifiConfiguration 的对象,并向其提供您要连接的网络的信息(SSIDpassword)。这不是一件简单的事情。如果您必须考虑不同类型的 key 加密,(WPAWEPfree wifi)。一旦你填满了对象,你必须调用

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

编辑:

如果你想显示带挂锁和不带挂锁的 wifi 信号强度图标,你可以使用自定义属性

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <declare-styleable name="wifi">
        <attr name="state_locked" format="boolean" />
    </declare-styleable>
</resources>

并在 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();
}

现在假设 WifeImageView 的 android:src 是一个选择器

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:custom="http://schemas.android.com/apk/res-auto">
    <item custom:state_locked="false" android:drawable="@drawable/wifi_level" />
    <item custom:state_locked="true" android:drawable="@drawable/wifi_level_lock" />
</selector>

在你的Adapter中你可以轻松的在两个level-list之间切换,添加下面两行代码

 boolean protectedWifi = result.capabilities.contains ("WEP") || result.capabilities.contains("WPA");
 ((WifiImageView) convertView.findViewById(R.id.wifi_img)).setStateLocked(protectedWifi);
如果 result.capabilities 包含 WEPWPA,并且 setStateLocked( protectedWifi); 将根据其值在两个 level-list 之间切换。当然,在 wifi_item.xml 中,您有两个更改,从 ImageView 到自定义 WifiImageView

关于android - 具有可用网络的对话框中的 ACTION_PICK_WIFI_NETWORK,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31162492/

相关文章:

java - 列出 arraylist 中的数据

android - 向 View 添加 XML 内容

带有对象的 Android ArrayAdapter 并从该对象获取一些数据

android - 有没有办法在屏幕已经解锁的情况下启动 Genymotion 模拟器?

Android Sqlite 查询

javascript - 不显示来自 Phonegap 的联系人图像

android - 如何判断 Android 应用程序是否真的在泄漏内存?

java - 从 Java 中嵌套函数的内部函数返回外部函数的值(或不返回任何值)

android - 那里有 "Google Keyboard"窃窃私语者吗? API19

android - 如何区分Android中不同布局文件夹中的布局文件(.xml文件)