嘿,我正在尝试构建一个从主机接收数据的Wifi-Direct P2P客户端。在获取数据之前,我需要建立连接,并且主机应该是组所有者(go_intent = 15)。建立连接之前,我需要知道它是否是我要查找的设备。为了进行测试,我想显示我所在区域中处于发现模式的所有设备。这意味着我还必须将自己置于发现模式下,才能从其他设备中被发现。
到目前为止,我一打开电源开关,或者在电源开关打开时WiFi再次出现时,就以MainActivity.class
在startFindPeers()
中启动发现模式。
虽然开关处于打开状态,但只要我的wifi仍处于打开状态,即使关闭应用程序并清除RAM,我也仍然可以被发现。
我的问题在于WifiP2pManager.PeerListListener
中的WIFI_P2P_PEERS_CHANGED_ACTION
一被触发就被触发。
我可以通过触发我的WiFiDirectBroadcastReceiver.class
的回调函数检查附近是否有新的同龄人。
在peerListListener
本身中,peerListListener
函数触发器将把所有新的对等项添加到我的onPeersAvailable
中的ListView中,但不是这样。
有什么建议吗?
清单
activity_main.xml
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="de.tu_chemnitz.dayliehelperprototype">
<!-- Need to permission to restart JobServices after phone being shut down -->
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<!-- Permissions to use WIFI-Direct -->
<uses-permission
android:name="android.permission.ACCESS_WIFI_STATE"
android:required="true" />
<uses-permission
android:name="android.permission.CHANGE_WIFI_STATE"
android:required="true" />
<uses-permission
android:name="android.permission.ACCESS_NETWORK_STATE"
android:required="true" />
<uses-permission
android:name="android.permission.CHANGE_NETWORK_STATE"
android:required="true" />
<uses-permission
android:name="android.permission.INTERNET"
android:required="true" />
<!-- Google Play filtering -->
<uses-feature android:name="android.hardware.wifi.direct" android:required="true"/>
<application
android:allowBackup="true"
android:fullBackupContent="true"
android:icon="@mipmap/ic_app_icon"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_app_icon_round"
android:supportsRtl="true"
android:theme="@style/Theme.AppCompat.Light.NoActionBar">
<activity
android:name=".MainActivity"
android:screenOrientation="portrait">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<action android:name="android.intent.action.VIEW"/>
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<service
android:name=".JobSchedulerService"
android:enabled="true"
android:exported="true"
android:permission="android.permission.BIND_JOB_SERVICE" />
</application>
</manifest>
MainActivity.class
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
android:id="@+id/main_layout"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity"
android:orientation="vertical">
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
app:title="@string/app_name"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="@color/colorPrimary"
android:elevation="4dp"
android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
app:popupTheme="@style/ThemeOverlay.AppCompat.Light"
android:fitsSystemWindows="true"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:paddingStart="16dp"
android:paddingEnd="0dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="0.15">
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center|start"
android:text="@string/main_page_titel"
android:textColor="@color/colorPrimaryDark"
android:textSize="28sp"
android:textStyle="bold" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="0.85"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="0.1"
android:orientation="horizontal"
android:baselineAligned="false">
<LinearLayout
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="0.5">
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="@string/feature_option_1"
android:textSize="25sp"
android:textColor="@color/colorPrimary"
android:gravity="center|start"/>
</LinearLayout>
<LinearLayout
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="0.5"
android:gravity="center|end">
<Switch
android:id="@+id/notify_switch"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
android:textSize="18sp"
android:switchMinWidth="52dp"
android:theme="@style/mySwitchStyle"
android:layout_marginEnd="35dp"/>
</LinearLayout>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="0.9"
android:orientation="vertical"
android:paddingEnd="30dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="0.15">
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="Discovered Devices"
android:gravity="center|start"
android:textSize="28sp"
android:textStyle="bold"
android:textColor="@color/colorPrimaryDark"/>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="0.85">
<ListView
android:id="@+id/peerListView"
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</LinearLayout>
</LinearLayout>
</LinearLayout>
</LinearLayout>
</LinearLayout>
WiFiDirectBroadcastReceiver.class
package de.tu_chemnitz.dayliehelperprototype;
import.*
import de.tu_chemnitz.dayliehelperprototype.utils.Utility;
public class MainActivity extends AppCompatActivity {
private static final String NETWORK_STATE = "NETWORK_STATE";
// UI elements
Switch switchNotify;
ListView listView;
//Wifi Direct
WifiP2pManager manager;
WifiP2pManager.Channel channel;
BroadcastReceiver receiver;
IntentFilter intentFilter;
List<WifiP2pDevice> peers = new ArrayList<WifiP2pDevice>();
String[] deviceNameArray;
WifiP2pDevice[] deviceArray;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// define UI elements
switchNotify = findViewById(R.id.notify_switch);
listView = findViewById(R.id.peerListView);
initializeWifiDirect();
// define toolbar
setSupportActionBar((Toolbar) findViewById(R.id.toolbar));
//load default switch states [false], otherwise get it from sharedPreferences
boolean state = Utility.getBool(this, "switch_states", "notify_switchkey");
switchNotify.setChecked(state);
switchNotify.setOnCheckedChangeListener(listener);
}
@Override
protected void onResume() {
super.onResume();
registerReceiver(receiver, intentFilter);
}
@Override
protected void onPause() {
super.onPause();
unregisterReceiver(receiver);
}
WifiP2pManager.PeerListListener peerListListener = new WifiP2pManager.PeerListListener() {
@Override
public void onPeersAvailable(WifiP2pDeviceList peerList) {
if(!peerList.getDeviceList().equals(peers)){
peers.clear();
peers.addAll(peerList.getDeviceList());
deviceNameArray = new String[peerList.getDeviceList().size()];
deviceArray = new WifiP2pDevice[peerList.getDeviceList().size()];
int index = 0;
// maybe we can get more information here
for(WifiP2pDevice device : peerList.getDeviceList()){
deviceNameArray[index] = device.deviceName;
deviceArray[index] = device;
index++;
}
Log.d("this is my array", "arr: " + Arrays.toString(deviceNameArray));
ArrayAdapter<String> adapter = new ArrayAdapter<String>(MainActivity.this, android.R.layout.simple_list_item_1, deviceNameArray);
listView.setAdapter(adapter);
}
if(peers.size() == 0){
Log.d("WIFIDIRECT", "No devices found");
}
}
};
/**
* OnCheckedListeners for the switches
*/
CompoundButton.OnCheckedChangeListener listener = new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
if (isChecked) {
if(Utility.isWiFiEnabled(MainActivity.this)){
Utility.customToastMsg(MainActivity.this,"Enabled", "#1abc9c");
startFindPeers();
}
else{
switchNotify.setChecked(false);
Utility.customToastMsg(MainActivity.this,"Wifi is disabled", "#FFB900");
isChecked = false;
}
} else {
Utility.customToastMsg(MainActivity.this,"Disabled", "#ef5350");
stopFindPeers();
}
// save current state [checked/unchecked]
Utility.saveBool(MainActivity.this, "switch_states", "notify_switchkey", isChecked);
}
};
public void startFindPeers(){
if(manager != null){
manager.discoverPeers(channel, new WifiP2pManager.ActionListener() {
@Override
public void onSuccess() {
Log.d(NETWORK_STATE, "Peer Discovery started");
}
@Override
public void onFailure(int reason) {
Log.d(NETWORK_STATE, "Peer Discovery starting failed, failcode: " + reason);
}
});
}
}
public void stopFindPeers(){
if(manager != null){
manager.stopPeerDiscovery(channel, new WifiP2pManager.ActionListener() {
@Override
public void onSuccess() {
Log.d(NETWORK_STATE, "Peer Discovery stopped");
}
@Override
public void onFailure(int reason) {
Log.d(NETWORK_STATE, "Peer Discovery stopping failed, failcode: " + reason);
}
});
}
}
public void initializeWifiDirect(){
//Wifi Direct
// This clall provides the API for managing Wifi peer-to-peer connectivity.
manager = (WifiP2pManager) getSystemService(Context.WIFI_P2P_SERVICE);
// A channel that connects the application to the Wifi p2p framework.
// Most p2p operations require a channel as an argument.
if (manager != null) {
channel = manager.initialize(this, getMainLooper(), null);
}
receiver = new WiFiDirectBroadcastReceiver(manager, channel, this);
intentFilter = new IntentFilter();
intentFilter.addAction(WifiP2pManager.WIFI_P2P_STATE_CHANGED_ACTION);
intentFilter.addAction(WifiP2pManager.WIFI_P2P_PEERS_CHANGED_ACTION);
intentFilter.addAction(WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION);
intentFilter.addAction(WifiP2pManager.WIFI_P2P_THIS_DEVICE_CHANGED_ACTION);
}
}
答案 0 :(得分:0)
我发现了我的错误。
基本上我的代码是正确的,但是与Android版本有关。 我在Android Oreo(API 26)设备上执行了应用程序,但没有像我提到的那样工作。 peerList仍然为空。
今天,我在Android Nougat(API 24-25)设备上进行了尝试,并且成功了! peerList可以像往常一样将设备靠近附近。
最后,我将maxSDKVersion设置为25,现在可以在我的Android Oreo设备上使用了。
我不能真正说出为什么它的行为如此,但我认为与permissions有关。
编辑:
没关系,我在这里发布的Android O +中遇到了这个问题
Peer discovery Issue with Oreo (Android 8+),解决方案是您需要获得SCAN_RESULTS_AVAILABLE_ACTION return empty list in Android 6.0此处提到的ACCESS_COARSE_LOCATION
的许可。