三星 10 plus 不允许 wifi p2p 发现

Posted

技术标签:

【中文标题】三星 10 plus 不允许 wifi p2p 发现【英文标题】:Samsung 10 plus won't allow wifi p2p discovery 【发布时间】:2020-06-16 12:19:32 【问题描述】:

我编写了一个 android 应用,允许设备通过 Wi-Fi P2P 发现来发现附近的设备。我正在关注this doc。

该应用程序在我的三星 Tab E 平板电脑上运行良好——当该应用程序在平板电脑上运行时,我能够扫描和查找其他设备。但在我的三星 Galaxy S10 Plus 上运行应用程序时,我什至无法激活对等发现过程。除非我手动进入 Galaxy S10 Plus 的设置并启用Wi-Fi Discovery Mode,否则我的三星 s10 Plus 甚至不会出现在我的平板电脑的可用对等设备列表中。那时,我的 Tab E 平板电脑可以“看到”我的 Galaxy S10 Plus,但是一旦我退出 Galaxy s10 Plus 上的设置屏幕,Wi-Fi 发现就会重新关闭,我无法再看到它潜在的 p2p 对等点。

有没有办法允许在三星 s10 Plus 上进行对等发现?如果没有它,我将无法测试我的应用程序,并且宁愿不必购买另一个 Tab E 来测试 p2p 连接。

以下是我的应用运行的代码供参考:

import androidx.appcompat.app.AppCompatActivity;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.IntentFilter;
import android.net.wifi.WifiManager;
import android.net.wifi.p2p.WifiP2pDevice;
import android.net.wifi.p2p.WifiP2pDeviceList;
import android.net.wifi.p2p.WifiP2pManager;
import android.os.Bundle;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;

import java.util.ArrayList;
import java.util.List;

public class MainActivity extends AppCompatActivity 

    Button btnOnOff, btnDiscover, btnSend;
    ListView listView;
    TextView read_msg_box, connectionStatus;
    EditText writeMsg;

    //For programmatically turning wifi on and off:
    WifiManager wifiManager;
    WifiP2pManager mManager;
    WifiP2pManager.Channel mChannel;

    BroadcastReceiver mReceiver;
    IntentFilter mIntentFilter = new IntentFilter();

    //For keeping track of available clients to connect to
    List<WifiP2pDevice> peers = new ArrayList<WifiP2pDevice>();
    String[] deviceNameArray;
    WifiP2pDevice[] deviceArray;


    @Override
    protected void onCreate(Bundle savedInstanceState) 
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        //initialWork();
        //initializeButtonOnClickListeners();

        mManager = (WifiP2pManager) getSystemService(Context.WIFI_P2P_SERVICE);
        mChannel = mManager.initialize(this, getMainLooper(), null);
        mReceiver = new WiFiDirectBroadcastReceiver(mManager, mChannel, this);

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

        btnDiscover = (Button)findViewById(R.id.discover);
        connectionStatus = (TextView) findViewById(R.id.connectionStatus);

//        btnSend = (Button)findViewById(R.id.sendButton);
        listView = (ListView)findViewById(R.id.peerListView);
//        read_msg_box = (TextView) findViewById(R.id.readMsg);
//        writeMsg = (EditText)findViewById(R.id.writeMsg);

        wifiManager = (WifiManager)getApplicationContext().getSystemService(Context.WIFI_SERVICE);
        initializeOnClickListeners();
    


    private void initializeOnClickListeners() 

        //Set up functionality for when the discover button is clicked.
        btnDiscover.setOnClickListener(new View.OnClickListener() 
            @Override
            public void onClick(View v) 
                Toast.makeText(getApplicationContext(), "looking for a new peer", Toast.LENGTH_SHORT).show();
                mManager.discoverPeers(mChannel, new WifiP2pManager.ActionListener() 
                    @Override
                    public void onSuccess() 
                        connectionStatus.setText("Discovery Started");
                    

                    @Override
                    public void onFailure(int reason) 
                        connectionStatus.setText("Discovery Failed to start");
                    
                );
            
        );
    

    //Define the logic for when a new peer is discovered
    WifiP2pManager.PeerListListener peerListListener = new WifiP2pManager.PeerListListener() 
        @Override
        public void onPeersAvailable(WifiP2pDeviceList peerList) 
            if(!peerList.getDeviceList().equals(peers)) 
                //clear the peers
                peers.clear();

                //store device list
                peers.addAll(peerList.getDeviceList());

                deviceNameArray = new String[peerList.getDeviceList().size()];
                deviceArray = new WifiP2pDevice[peerList.getDeviceList().size()];
                int index = 0;

                for(WifiP2pDevice device : peerList.getDeviceList()) 
                    deviceNameArray[index] = device.deviceName;
                    deviceArray[index] = device;
                    index++;
                

                ArrayAdapter<String> adapter = new ArrayAdapter<String>(getApplicationContext(),
                        android.R.layout.simple_list_item_1,
                        deviceNameArray);

                listView.setAdapter(adapter);
            

            if(peers.size() == 0) 
                Toast.makeText(getApplicationContext(), "No Devices Found :(", Toast.LENGTH_SHORT).show();
            

        
    ;



    @Override
    protected void onResume() 
        super.onResume();
        registerReceiver(mReceiver, mIntentFilter);
    

    @Override
    protected void onPause() 
        super.onPause();
        unregisterReceiver(mReceiver);
    


import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.net.wifi.p2p.WifiP2pManager;
import android.widget.Toast;

public class WiFiDirectBroadcastReceiver extends BroadcastReceiver 
    private WifiP2pManager mManager;
    private WifiP2pManager.Channel mChannel;
    private MainActivity mActivity;

    WifiP2pManager.PeerListListener myPeerListListener;

    public WiFiDirectBroadcastReceiver(WifiP2pManager mManager, WifiP2pManager.Channel mChannel, MainActivity mActivity) 
        this.mManager = mManager;
        this.mChannel = mChannel;
        this.mActivity = mActivity;
    

    @Override
    public void onReceive(Context context, Intent intent) 
        String action = intent.getAction();
        System.out.println("The following action was received: " + action);

        if(WifiP2pManager.WIFI_P2P_STATE_CHANGED_ACTION.equals(action))
            int state = intent.getIntExtra(WifiP2pManager.EXTRA_WIFI_STATE, -1);

            //if wifi is enabled
            if(state == WifiP2pManager.WIFI_P2P_STATE_ENABLED) 
                Toast.makeText(context, "Wifi is ON", Toast.LENGTH_LONG).show();
             else 
                Toast.makeText(context, "Wifi is OFF", Toast.LENGTH_LONG).show();
            
         else if(WifiP2pManager.WIFI_P2P_PEERS_CHANGED_ACTION.equals(action)) 
            Toast.makeText(context, "INSIDE THE P2P_PEERS_CHANGED_ACTION", Toast.LENGTH_LONG).show();
            if(mManager != null) 
                mManager.requestPeers(mChannel, mActivity.peerListListener);
                Toast.makeText(context, "A new peer has been found!!!", Toast.LENGTH_LONG).show();
            
         else if(WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION.equals(action)) 
            //do something
         else if(WifiP2pManager.WIFI_P2P_THIS_DEVICE_CHANGED_ACTION.equals(action)) 
            //do something
        
    


【问题讨论】:

【参考方案1】:

我有时不会在 Android 中编码,但我认为我的经验可能仍然有效,你可以尝试一下。

如果我错了,请纠正我,因此,您开发了一个应用程序,该应用程序允许您的设备发现并相互连接,而无需访问手机的设置。对于您的 S10,您已经安装并打开了该应用,但您无法通过 Tab 找到它,除非您在设置中手动打开它?

首先,确保您的应用在使用应用时添加和请求了所有必需的权限。

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.android.nsdchat"
    ...
    <uses-permission
        android:required="true"
        android:name="android.permission.ACCESS_FINE_LOCATION"/>
    <uses-permission
        android:required="true"
        android:name="android.permission.ACCESS_WIFI_STATE"/>
    <uses-permission
        android:required="true"
        android:name="android.permission.CHANGE_WIFI_STATE"/>
    <uses-permission
        android:required="true"
        android:name="android.permission.INTERNET"/>

为了确保您的应用具有权限,请将权限添加到下面的代码中以获得相应的权限:

if (ContextCompat.checkSelfPermission(thisActivity, Manifest.permission.CHANGE_WIFI_STATE)
        != PackageManager.PERMISSION_GRANTED) 
    // Permission is not granted

...

其次,看代码库版本。由于s10+相当新,Android实际上从Android 8.0开始增强了隐私和安全性。由于库版本的原因,您编写的代码可能已过时,并且某些 API 可能已被弃用。

【讨论】:

以上是关于三星 10 plus 不允许 wifi p2p 发现的主要内容,如果未能解决你的问题,请参考以下文章

WiFi P2P导致设备WiFi自动连接功能不起作用?

Wifi P2P 服务发现间歇性工作

Wifi Direct P2P 无法在 Android 10+ 设备上运行,无法发现设备

三星工艺似乎不过关,骁龙888plus再成火龙

Android WiFi Direct android.net.wifi.p2p.PEERS_CHANGED 收到无休止

三星970EVO Plus及NvMe系列固态硬盘对比测试