package com.xypower.mpremote; import androidx.annotation.NonNull; import androidx.appcompat.app.AppCompatActivity; import androidx.core.app.ActivityCompat; import androidx.core.content.ContextCompat; import android.Manifest; import android.app.AlertDialog; import android.content.BroadcastReceiver; import android.content.Context; import android.content.DialogInterface; import android.content.Intent; import android.content.IntentFilter; import android.content.SharedPreferences; import android.content.pm.PackageManager; import android.graphics.Color; import android.graphics.Typeface; import android.net.ConnectivityManager; import android.net.Network; import android.net.NetworkCapabilities; import android.net.NetworkInfo; import android.net.NetworkRequest; import android.net.wifi.ScanResult; import android.net.wifi.WifiConfiguration; import android.net.wifi.WifiInfo; import android.net.wifi.WifiManager; import android.net.wifi.WifiNetworkSpecifier; import android.net.wifi.WifiNetworkSuggestion; import android.os.Bundle; import android.os.Handler; import android.os.Parcelable; import android.text.TextUtils; import android.text.format.Formatter; import android.util.Log; import android.view.Menu; import android.view.MenuItem; import android.view.View; import android.view.ViewGroup; import android.widget.AdapterView; import android.widget.SimpleAdapter; import android.widget.TextView; import com.xypower.mpremote.databinding.ActivityMainBinding; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; public class MainActivity extends AppCompatActivity { // Used to load the 'mpremote' library on application startup. static { System.loadLibrary("mpremote"); } private static final String TAG = "ADB"; private static final boolean DEBUG = true; public static final int RSSI_LEVELS = 5; private static final String DEFAULT_PRE_SHARED_KEY = SettingsActivity.DEFAULT_PRE_SHARED_KEY; private static final int REQUEST_CODE_PERMISSIONS = 1025; private static final int REQUEST_CODE_SETTINGS = SettingsActivity.REQUEST_CODE_SETTINGS; private static final String WIFI_IP_PREFIX = "192.168."; // private static final String WIFI_IP_DEVIDE = "192.168.50.1"; private static final String WIFI_IP_DEVICE = "192.168.50.137"; private ActivityMainBinding binding; private Handler mHandler; private List mScanResults = new ArrayList<>(); private ScanResult mCurrentScanResult; private String mPassword = DEFAULT_PRE_SHARED_KEY; private WifiAdaper mAdapter; private List> mItems = new ArrayList>(); private ConnectivityManager mConnectivityManager; private NetworkConnectChangedReceiver mNetworkConnectChangedReceiver; private ConnectivityManager.NetworkCallback mNetworkCallback; public class WifiAdaper extends SimpleAdapter{ public WifiAdaper(Context context, List> items, int resource, String[] from, int[] to) { super(context, items, resource, from, to); } public View getView(int position, View convertView, ViewGroup parent){ convertView = super.getView(position, convertView, parent); TextView textView = (TextView)convertView.findViewById(R.id.id_text); ScanResult scanResult = mScanResults.get(position); // if (scanResult.) String text = (String)mItems.get(position).get("text"); if (text.startsWith("XY") || text.startsWith("xy")) { textView.setTextColor(Color.RED); textView.setTypeface(Typeface.defaultFromStyle(Typeface.BOLD)); } else { textView.setTextColor(Color.BLACK); textView.setTypeface(Typeface.defaultFromStyle(Typeface.NORMAL)); } return convertView; } } @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); binding = ActivityMainBinding.inflate(getLayoutInflater()); setContentView(binding.getRoot()); loadSettings(); mHandler = new Handler(); mConnectivityManager = (ConnectivityManager)getSystemService(Context.CONNECTIVITY_SERVICE); binding.listView.setOnItemClickListener(new AdapterView.OnItemClickListener() { @Override public void onItemClick(AdapterView adapterView, View view, int position, long l) { WifiManager wifiManager = (WifiManager) getApplicationContext().getSystemService(Context.WIFI_SERVICE); if (!wifiManager.isWifiEnabled()) { wifiManager.setWifiEnabled(true); } mCurrentScanResult = mScanResults.get(position); WifiInfo wifiInfo = wifiManager.getConnectionInfo(); String s1 = normalizeSSID(mCurrentScanResult.SSID); String s2 = normalizeSSID(wifiInfo.getSSID()); if (TextUtils.equals(s1, s2)) { openDeviceActivity(); } else { startActivity(new Intent(android.provider.Settings.ACTION_WIFI_SETTINGS)); } // connectWifi(mCurrentScanResult.SSID, mCurrentScanResult.BSSID, mPassword); } }); if (applyForPermissions()) { scanWifi(); } } @Override protected void onDestroy() { super.onDestroy(); if (mConnectivityManager != null && mNetworkCallback != null) { mConnectivityManager.bindProcessToNetwork(null); mConnectivityManager.unregisterNetworkCallback(mNetworkCallback); } } @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.main_activity_actions, menu); return true; } @Override public boolean onOptionsItemSelected(MenuItem item) { int id = item.getItemId(); //当点击不同的menu item 是执行不同的操作 switch (id) { case R.id.action_refresh: scanWifi(); break; case R.id.action_settings: { Intent intent = new Intent(getApplicationContext(), SettingsActivity.class); startActivityForResult(intent, REQUEST_CODE_SETTINGS); } break; default: break; } return super.onOptionsItemSelected(item); } @Override public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) { super.onRequestPermissionsResult(requestCode, permissions, grantResults); try { ArrayList requestList = new ArrayList<>();//允许询问列表 ArrayList banList = new ArrayList<>();//禁止列表 for(int i = 0; i < permissions.length; i++) { if (grantResults[i] == PackageManager.PERMISSION_GRANTED) { Log.i(TAG,"【"+permissions[i]+"】权限授权成功"); } else { //判断是否允许重新申请该权限 boolean nRet = ActivityCompat.shouldShowRequestPermissionRationale(this,permissions[i]); Log.i(TAG,"shouldShowRequestPermissionRationale nRet="+nRet); if (nRet) {//允许重新申请 requestList.add(permissions[i]); } else {//禁止申请 banList.add(permissions[i]); } } } //优先对禁止列表进行判断 if (banList.size() > 0) { //告知该权限作用,要求手动授予权限 showFinishedDialog(); } else if (requestList.size() > 0) { //告知权限的作用,并重新申请 showTipDialog(requestList); } else { // showToast("权限授权成功"); scanWifi(); } } catch (Exception e) { e.printStackTrace(); // showToast("权限申请回调中发生异常"); } } public void showFinishedDialog() { AlertDialog dialog = new AlertDialog.Builder(getApplicationContext()) .setTitle("警告") .setMessage("请前往设置中打开相关权限,否则功能无法正常运行!") .setPositiveButton("确定", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { // 一般情况下如果用户不授权的话,功能是无法运行的,做退出处理 finish(); } }) .create(); dialog.show(); } @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); if (requestCode == REQUEST_CODE_SETTINGS) { loadSettings(); } } public void showTipDialog(ArrayList pmList){ AlertDialog dialog = new AlertDialog.Builder(getApplicationContext()) .setTitle("提示") .setMessage("【"+pmList.toString()+"】权限为应用必要权限,请授权") .setPositiveButton("确定", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { String[] sList=pmList.toArray(new String[0]); //重新申请该权限 ActivityCompat.requestPermissions(MainActivity.this, sList, REQUEST_CODE_PERMISSIONS); } }) .create(); dialog.show(); } protected void scanWifi() { mScanResults.clear(); (new Thread(new Runnable() { @Override public void run() { WifiManager wifiManager = (WifiManager) getApplicationContext().getSystemService(Context.WIFI_SERVICE); wifiManager.startScan(); List scanResults = wifiManager.getScanResults(); Map ssids = new HashMap<>(); for (ScanResult scanResult : scanResults) { if (TextUtils.isEmpty(scanResult.SSID)) { continue; } if (ssids.containsKey(scanResult.SSID)) { continue; } ssids.put(scanResult.SSID, scanResult.SSID); mScanResults.add(scanResult); } // mAdapter = new ArrayAdapter<>() mHandler.post(new Runnable() { @Override public void run() { refreshListView(); } }); } })).start(); } private void connectWifi(String ssid, String bssid, String pwd) { WifiManager wifiManager = (WifiManager) getApplicationContext().getSystemService(Context.WIFI_SERVICE); // Android 10 if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.Q) { WifiNetworkSuggestion suggestion = new WifiNetworkSuggestion.Builder() .setSsid(ssid) .setWpa2Passphrase((pwd)) .setIsAppInteractionRequired(true) .build(); List suggestionsList = new ArrayList<>(); suggestionsList.add(suggestion); wifiManager.removeNetworkSuggestions(suggestionsList); int status = wifiManager.addNetworkSuggestions(suggestionsList); // step2 if ((status == WifiManager.STATUS_NETWORK_SUGGESTIONS_SUCCESS) || (status == WifiManager.STATUS_NETWORK_SUGGESTIONS_ERROR_ADD_DUPLICATE)) { WifiNetworkSpecifier wifiNetworkSpecifier = new WifiNetworkSpecifier.Builder() .setSsid(ssid) .setWpa2Passphrase(pwd) .build(); NetworkRequest request = new NetworkRequest.Builder() .addTransportType(NetworkCapabilities.TRANSPORT_WIFI) .removeCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET) .setNetworkSpecifier(wifiNetworkSpecifier) .build(); mNetworkCallback = new ConnectivityManager.NetworkCallback() { @Override public void onAvailable(@NonNull Network network) { super.onAvailable(network); NetworkInfo networkInfo = mConnectivityManager.getNetworkInfo(network); WifiInfo wifiInfo = wifiManager.getConnectionInfo(); String s1 = normalizeSSID(wifiInfo.getSSID()); String s2 = normalizeSSID(mCurrentScanResult.SSID); if (TextUtils.equals(s1, s2)) { runOnUiThread(new Runnable() { @Override public void run() { // requires android.permission.INTERNET mConnectivityManager.bindProcessToNetwork(network); openDeviceActivity(); } }); } } @Override public void onUnavailable() { super.onUnavailable(); runOnUiThread(new Runnable() { @Override public void run() { mConnectivityManager.bindProcessToNetwork(null); } }); } }; mConnectivityManager.requestNetwork(request, mNetworkCallback); } else { } } else { WifiConfiguration wifiConfiguration = new WifiConfiguration(); wifiConfiguration.SSID = "\"" + ssid + "\""; wifiConfiguration.BSSID = "\"" + bssid + "\""; wifiConfiguration.preSharedKey = "\"" + pwd + "\""; int nerworkId = wifiManager.addNetwork(wifiConfiguration); try { wifiManager.disconnect(); } catch (Exception ex) { ex.printStackTrace(); } /* if (mNetworkConnectChangedReceiver != null) { unregisterReceiver(mNetworkConnectChangedReceiver); mNetworkConnectChangedReceiver = null; registerNetworkConnectChangeReceiver(); } */ wifiManager.enableNetwork(nerworkId, true); wifiManager.reconnect(); } } private void refreshListView() { mAdapter = new WifiAdaper(this, getData(), R.layout.list_item, new String[] { "img", "text" }, new int[] { R.id.id_img, R.id.id_text }); binding.listView.setAdapter(mAdapter); } private List> getData() { mItems.clear(); WifiManager wifiManager = (WifiManager) getApplicationContext().getSystemService(Context.WIFI_SERVICE); WifiInfo wifiInfo = wifiManager.getConnectionInfo(); String ssid = ""; if (wifiInfo != null) { ssid = wifiInfo.getSSID(); if (!TextUtils.isEmpty(ssid)) { if (ssid.startsWith("\"") && ssid.endsWith("\"")) { ssid = ssid.substring(1, ssid.length() - 1); } } } for (ScanResult scanResult : mScanResults) { Map map = new HashMap(); int signalLevel = WifiManager.calculateSignalLevel(scanResult.level, RSSI_LEVELS); int drawableId = R.drawable.ic_wifi_signal_0; boolean connected = TextUtils.equals(ssid, scanResult.SSID); switch (signalLevel) { case 1: drawableId = connected ? R.drawable.ic_wifi_signal_1_green : R.drawable.ic_wifi_signal_1; break; case 2: drawableId = connected ? R.drawable.ic_wifi_signal_2_green : R.drawable.ic_wifi_signal_2; break; case 3: drawableId = connected ? R.drawable.ic_wifi_signal_3_green : R.drawable.ic_wifi_signal_3; break; case 4: drawableId = connected ? R.drawable.ic_wifi_signal_4_green : R.drawable.ic_wifi_signal_4; break; default: drawableId = connected ? R.drawable.ic_wifi_signal_0_green : R.drawable.ic_wifi_signal_0; break; } map.put("img", drawableId); // if (scanR) map.put("text", scanResult.SSID); mItems.add(map); } return mItems; } class NetworkConnectChangedReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { String action = intent.getAction(); Bundle extras = intent.getExtras(); // 这个监听wifi的连接状态即是否连上了一个有效无线路由,当上边广播的状态是WifiManager.WIFI_STATE_DISABLING,和WIFI_STATE_DISABLED的时候,根本不会接到这个广播。 // 在上边广播接到广播是WifiManager.WIFI_STATE_ENABLED状态的同时也会接到这个广播,当然刚打开wifi肯定还没有连接到有效的无线 if (WifiManager.NETWORK_STATE_CHANGED_ACTION.equals(action)) { Parcelable parcelableExtra = intent.getParcelableExtra(WifiManager.EXTRA_NETWORK_INFO); WifiInfo wifiInfo = intent.getParcelableExtra(WifiManager.EXTRA_WIFI_INFO); String bssid = intent.getStringExtra(WifiManager.EXTRA_BSSID); if (null == parcelableExtra) { return; } if (mCurrentScanResult != null) { return; } NetworkInfo networkInfo = (NetworkInfo) parcelableExtra; NetworkInfo.State state = networkInfo.getState(); // Log.e("NetWork Sate Change:"+state+" connectedBssid:" + connectedBssid); if(state == NetworkInfo.State.CONNECTED) { String ssid = wifiInfo.getSSID(); String addSSID = mCurrentScanResult.SSID; if (!(mCurrentScanResult.SSID.startsWith("\"") && mCurrentScanResult.SSID.endsWith("\""))) { addSSID = "\"" + addSSID + "\""; } // Log.i(ssid + "***>" + mCurrentScanResult.SSID); // Log.i("总共耗时:"+((System.currentTimeMillis()-start)/1000.0)); if (ssid.equals(addSSID)) { unregisterReceiver(mNetworkConnectChangedReceiver); mNetworkConnectChangedReceiver = null; } } } } } private void registerNetworkConnectChangeReceiver() { IntentFilter filter = new IntentFilter(); filter.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION); filter.addAction(WifiManager.WIFI_STATE_CHANGED_ACTION); filter.addAction(ConnectivityManager.CONNECTIVITY_ACTION); filter.addAction(WifiManager.SUPPLICANT_CONNECTION_CHANGE_ACTION); filter.addAction(WifiManager.SUPPLICANT_STATE_CHANGED_ACTION); mNetworkConnectChangedReceiver = new NetworkConnectChangedReceiver(); registerReceiver(mNetworkConnectChangedReceiver, filter); } public boolean applyForPermissions() { String[] PM_MULTIPLE = { Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.READ_PHONE_STATE, Manifest.permission.CHANGE_NETWORK_STATE, Manifest.permission.CHANGE_WIFI_STATE, Manifest.permission.ACCESS_FINE_LOCATION }; try { ArrayList pmList = new ArrayList<>(); //获取当前未授权的权限列表 for(String permission:PM_MULTIPLE) { int nRet = ContextCompat.checkSelfPermission(this,permission); if(nRet != PackageManager.PERMISSION_GRANTED) { pmList.add(permission); } } if (pmList.size() > 0) { // Log.i(TAG,"进行权限申请..."); String[] sList = pmList.toArray(new String[0]); ActivityCompat.requestPermissions(this, sList,REQUEST_CODE_PERMISSIONS); return false; } } catch(Exception e){ e.printStackTrace(); } return true; } protected void loadSettings() { SharedPreferences preferences = getSharedPreferences("mpremote", MODE_PRIVATE); mPassword = preferences.getString("password", DEFAULT_PRE_SHARED_KEY); } protected void openDeviceActivity() { String ipAddressByWifi = null; WifiManager wifiManager = (WifiManager) getApplicationContext().getSystemService(Context.WIFI_SERVICE); if (wifiManager != null) { ipAddressByWifi = Formatter.formatIpAddress(wifiManager.getDhcpInfo().ipAddress); if (!wifiManager.isWifiEnabled()) { wifiManager.setWifiEnabled(true); } if (ipAddressByWifi.contains(WIFI_IP_PREFIX)) { String deviceIP = Formatter.formatIpAddress(wifiManager.getDhcpInfo().gateway); if (DEBUG) { deviceIP = WIFI_IP_DEVICE; } Intent intent = new Intent(MainActivity.this, DeviceActivity.class); // intent1.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); intent.putExtra("deviceIp", deviceIP); intent.putExtra("SSID", mCurrentScanResult.SSID); startActivity(intent); } } } private String normalizeSSID(String ssid) { if (TextUtils.isEmpty(ssid)) { return ssid; } if (!(ssid.startsWith("\"") && ssid.endsWith("\""))) { return "\"" + ssid + "\""; } return ssid; } /** * A native method that is implemented by the 'mpremote' native library, * which is packaged with this application. */ public native String stringFromJNI(); }