如何初始化WifiP2pManager.Channel?代码空指针异常排查
嘿,来解决你的Wi-Fi Direct空指针问题!
先看你的错误日志,核心问题很明确:WifiP2pManager实例是null,导致调用initialize方法时触发了空指针异常。咱们一步步拆解问题,搞定它:
1. 为什么WifiP2pManager会变成null?
调用getSystemService(Context.WIFI_P2P_SERVICE)返回null,通常有这几个原因:
- 你的设备不支持Wi-Fi Direct功能(部分老设备或入门机型可能没有这个模块)
- 没在
AndroidManifest.xml里加必要的权限和功能声明 - Android 6.0+系统下,没动态申请Wi-Fi相关的权限
先检查AndroidManifest.xml,必须加上这些内容:
<!-- 必备权限 --> <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" /> <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" /> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> <uses-permission android:name="android.permission.INTERNET" /> <!-- 声明应用依赖Wi-Fi Direct硬件 --> <uses-feature android:name="android.hardware.wifi.direct" android:required="true" />
划重点:Android 6.0及以上,ACCESS_FINE_LOCATION需要动态申请,不然Wi-Fi Direct根本跑不起来。
2. 代码里的初始化错误
你的代码里重复调用了manager.initialize,这完全没必要:
manager.initialize(this,getMainLooper(),null); // 这一行是多余的,白跑了 channel=manager.initialize(this,getMainLooper(),null); // 只需要这一行就够了
WifiP2pManager.initialize()方法的返回值就是你要的WifiP2pManager.Channel,所以直接调用一次,把返回值赋值给channel就行。
3. 加个空指针防护更稳妥
为了避免设备不支持Wi-Fi Direct时崩溃,建议在使用manager前先做非空判断:
manager=(WifiP2pManager) getSystemService(Context.WIFI_P2P_SERVICE); if (manager == null) { Log.e(TAG, "设备不支持Wi-Fi Direct功能"); Toast.makeText(this, "抱歉,你的设备不支持Wi-Fi Direct", Toast.LENGTH_SHORT).show(); finish(); // 或者做其他降级处理,比如提示用户用别的方式传文件 return; } // 这里建议加上ChannelListener,通道断开时能自动重连 channel = manager.initialize(this, getMainLooper(), new WifiP2pManager.ChannelListener() { @Override public void onChannelDisconnected() { // 通道意外断开时,重新初始化 channel = manager.initialize(MainActivity.this, getMainLooper(), this); } });
4. 补上动态权限申请(Android 6.0+)
如果你的应用要兼容6.0以上系统,必须动态申请权限,不然getSystemService可能返回null。给你加个示例:
private static final int PERMISSIONS_REQUEST = 1001; private String[] neededPermissions = { Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.CHANGE_WIFI_STATE, Manifest.permission.ACCESS_WIFI_STATE }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // 先检查权限,没授权就申请 if (checkSelfPermission(Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) { requestPermissions(neededPermissions, PERMISSIONS_REQUEST); return; } // 权限没问题,再初始化Wi-Fi Direct initWifiDirect(); } private void initWifiDirect() { manager=(WifiP2pManager) getSystemService(Context.WIFI_P2P_SERVICE); if (manager == null) { Log.e(TAG, "设备不支持Wi-Fi Direct"); Toast.makeText(this, "设备不支持Wi-Fi Direct", Toast.LENGTH_SHORT).show(); finish(); return; } channel = manager.initialize(this, getMainLooper(), new WifiP2pManager.ChannelListener() { @Override public void onChannelDisconnected() { channel = manager.initialize(MainActivity.this, getMainLooper(), this); } }); broadcastReceiver=new WiFiDirectBroadcastReceiver(manager,channel,this); // 初始化IntentFilter mIntentFilter = new IntentFilter(); mIntentFilter.addAction(WifiP2pManager.WIFI_P2P_STATE_CHANGED_ACTION); mIntentFilter.addAction(WifiP2pManager.WIFI_P2P_PEERS_CHANGED_ACTION); mIntentFilter.addAction(WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION); mIntentFilter.addAction(WifiP2pManager.WIFI_P2P_THIS_DEVICE_CHANGED_ACTION); // 开始搜索设备 manager.discoverPeers(channel, new WifiP2pManager.ActionListener() { @Override public void onSuccess() { Log.d(TAG, "onSuccess: 已开始搜索附近设备"); } @Override public void onFailure(int reasonCode) { Log.d(TAG, "onFailure: 搜索失败,错误码 "+reasonCode); } }); } @Override public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { super.onRequestPermissionsResult(requestCode, permissions, grantResults); if (requestCode == PERMISSIONS_REQUEST) { boolean allGranted = true; for (int result : grantResults) { if (result != PackageManager.PERMISSION_GRANTED) { allGranted = false; break; } } if (allGranted) { initWifiDirect(); } else { Toast.makeText(this, "需要授予权限才能使用Wi-Fi Direct", Toast.LENGTH_SHORT).show(); finish(); } } }
把这些修改应用到你的代码里,应该就能解决空指针问题,同时正确初始化WifiP2pManager.Channel啦。
内容的提问来源于stack exchange,提问作者Ganesh Tiwari
相关产品推荐
相关产品推荐

