ACTION_PICK_WIFI_NETWORK 在具有可用网络的对话框上

2023-12-08

我正在尝试创建一个Dialog这显示了类似的东西ACTION_PICK_WIFI_NETWORK但不是打开Android Settings / WiFi打开它Dialog如果可能的话,用户可以连接到该网络可用的任何网络Dialog。我现在所拥有的是打开一个Dialog with a ListAndroid 中可用的 Wi-Fi 网络,但这List不等于Android Settings / WiFi这就是为什么我问是否可以打开这个ACTION_PICK_WIFI_NETWORK在对话框上并使用它。如果不可能,我如何连接到网络,单击Item从我的Dialog有可用的 WiFi 吗?

到目前为止我尝试过的是

我有一个BroadcastReceiver()

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

A RegisterReceiver()

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

这是执行以下操作的方法WifiScan

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

这就是简单的Dialog这表明SCAN_RESULTS_AVAILABLE_ACTION

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

带图像的示例

This and this是例子或我正在寻找的东西。

编辑(这就是我如何看待我的Dialog目前,但我还不喜欢它......)

enter image description here

我想向网络展示icon像 Android 一样具有信号强度example。我想我需要一个 ListAdapter 左右?然后添加网络名称、连接强度、图标等...我错了吗?

几乎同样的问题对there..

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

现在我得到的是这样的:

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);

从 ui 角度来看,您需要一个自定义适配器:

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>

我从其中取出了五个pnghere

对于连接,答案是是的,应该有可能。至少根据文档。您可以实例化一个对象Wifi配置,并向其提供您要连接的网络的信息(SSID and password)。这不是一件简单的事情。如果您必须考虑不同类型的密钥加密,(WPA, WEP, free wifi)。一旦你填写了对象,你必须调用

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

Edit:

如果您想显示带或不带挂锁的 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();
}

}

现在假设你的 android:srcWifeImageView是一个选择器

<?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>

在您的适配器中,您可以轻松地在两者之间切换level-list,添加以下两行代码

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

protectedWifi被评估为真,如果result.capabilities包含WEP or WPA, and setStateLocked(protectedWifi);会在两者之间切换level-lists 相应于其值。当然,在wifi_item.xml,你有两个变化ImageView, 到定制WifiImageView.

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

ACTION_PICK_WIFI_NETWORK 在具有可用网络的对话框上 的相关文章

随机推荐