【问题标题】:Why Wifi direct discovery getting failed on Android 10?为什么 Wifi 直接发现在 Android 10 上失败?
【发布时间】:2020-07-31 09:13:39
【问题描述】:

在今年年初,我开发了一个应用程序 Wifi Direct 在所有其他设备上都可以正常工作,即 Discovery 凝视和搜索其他设备,但在 Android 10 上我收到 Discovery Failed 错误。

这是我的课

public class NotificationsFragment extends Fragment implements View.OnClickListener{

private NotificationsViewModel notificationsViewModel;
private static final int MY_PERMISSIONS_REQUEST_ACCESS_COARSE_LOCATION = 1;
private static final int MY_PERMISSIONS_REQUEST_RECORD_AUDIO = 2;
private static final int MY_PERMISSIONS_REQUEST_REQUIRED_PERMISSION = 3;
private static final int SEPRATION_DIST_THRESHOLD = 50;

private static int device_count = 0;

public RippleBackground rippleBackground;
ImageView centerDeviceIcon;

ArrayList<Point> device_points = new ArrayList<>();

public TextView connectionStatus;

WifiManager wifiManager;
WifiP2pManager mManager;
WifiP2pManager.Channel mChannel;

public static final int PORT_USED = 9584;

BroadcastReceiver mReceiver;
IntentFilter mIntentFilter;

ArrayList<CustomDevice> custom_peers = new ArrayList<>();

ServerClass serverClass;
ClientClass clientClass;

private Menu menu;


public View onCreateView(@NonNull LayoutInflater inflater,
                         ViewGroup container, Bundle savedInstanceState) {
    notificationsViewModel =
            ViewModelProviders.of(this).get(NotificationsViewModel.class);
    View root = inflater.inflate(R.layout.fragment_notifications, container, false);
    getPermissions();
    initialSetup();
    connectionStatus = root.findViewById(R.id.connectionStatus);
    rippleBackground = root.findViewById(R.id.content);
    centerDeviceIcon = root.findViewById(R.id.centerImage);
    centerDeviceIcon.setOnClickListener(this);



    return root;
}
private boolean onCreateOptionsMenu(Menu menu) {
    MenuInflater menu_inflater = getActivity().getMenuInflater();
    menu_inflater.inflate(R.menu.main_menu3, menu);
    this.menu = menu;
    return true;
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    int id = item.getItemId();
    if(id == R.id.wifi_toggle) {
        toggleWifiState();
    }
    return super.onOptionsItemSelected(item);
}

public class ServerClass extends Thread{
    Socket socket;
    ServerSocket serverSocket;

    @Override
    public void run() {
        try {
            serverSocket = new ServerSocket(PORT_USED);
            socket = serverSocket.accept();

            com.vikaskonaparthi.origin.SocketHandler.setSocket(socket);

            startActivity(new Intent(getActivity().getApplicationContext(), com.vikaskonaparthi.origin.ChatWindow.class));
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

public class ClientClass extends Thread{
    Socket socket;
    String hostAddress;

    ClientClass(InetAddress address){
        this.socket = new Socket();
        this.hostAddress = address.getHostAddress();
    }

    @Override
    public void run() {
        try {
            socket.connect(new InetSocketAddress(hostAddress, PORT_USED), 500);

            com.vikaskonaparthi.origin.SocketHandler.setSocket(socket);

            startActivity(new Intent(getActivity().getApplicationContext(), com.vikaskonaparthi.origin.ChatWindow.class));
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

@Override
public void onPause() {
    super.onPause();
    getActivity().unregisterReceiver(mReceiver);
}

@Override
public void onResume() {
    super.onResume();
    getActivity().registerReceiver(mReceiver, mIntentFilter);
}

private void initialSetup() {
    // layout files

    // add onClick Listeners

    // center button position
    Display display = getActivity().getWindowManager().getDefaultDisplay();
    Point size = new Point();
    display.getSize(size);
    device_points.add(new Point(size.x / 2, size.y / 2));
    Log.d("Tab1", size.x + "  " + size.y);

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

    mManager = (WifiP2pManager) getActivity().getSystemService(WIFI_P2P_SERVICE);
    mChannel = mManager.initialize(getActivity(), getMainLooper(), null);

    mReceiver = new com.vikaskonaparthi.origin.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);
}

void checkLocationEnabled(){
    LocationManager lm = (LocationManager)NotificationsFragment.this.getActivity().getSystemService(Context.LOCATION_SERVICE);
    boolean gps_enabled = false;
    boolean network_enabled = false;


    try {
        gps_enabled = lm.isProviderEnabled(LocationManager.GPS_PROVIDER);
    } catch(Exception ex) {}

    try {
        network_enabled = lm.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
    } catch(Exception ex) {}

    if(!gps_enabled && !network_enabled) {
        // notify user
        new AlertDialog.Builder(getActivity())
                .setTitle(R.string.gps_network_not_enabled_title)
                .setMessage(R.string.gps_network_not_enabled)
                .setPositiveButton(R.string.open_location_settings, new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface paramDialogInterface, int paramInt) {
                        NotificationsFragment.this.startActivity(new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS));
                    }
                })
                .setNegativeButton(R.string.Cancel,null)
                .show();
    }
}

@Override
public void onClick(View v) {
    int view_id = v.getId();

    if(getIndexFromIdPeerList(view_id) != -1){
        int idx = getIndexFromIdPeerList(view_id);
        final WifiP2pDevice device = custom_peers.get(idx).device;
        WifiP2pConfig config = new WifiP2pConfig();
        config.deviceAddress = device.deviceAddress;

        mManager.connect(mChannel, config, new WifiP2pManager.ActionListener() {
            @Override
            public void onSuccess() {
                Toast.makeText(getActivity().getApplicationContext(), "Connected to "+device.deviceName, Toast.LENGTH_SHORT).show();
            }

            @Override
            public void onFailure(int reason) {
                Toast.makeText(getActivity().getApplicationContext(), "Error in connecting to "+device.deviceName, Toast.LENGTH_SHORT).show();
            }
        });
    }else{
        switch (v.getId()){
            case R.id.centerImage:
                rippleBackground.startRippleAnimation();
                checkLocationEnabled();
                discoverDevices();
                break;
            default:
                break;
        }
    }
}

private int getIndexFromIdPeerList(int id){
    for(CustomDevice d : custom_peers){
        if(d.id == id){
            return custom_peers.indexOf(d);
        }
    }
    return -1;
}

private int checkPeersListByName(String deviceName){
    for(CustomDevice d :custom_peers) {
        if (d.deviceName.equals(deviceName)) {
            return custom_peers.indexOf(d);
        }
    }
    return -1;
}

private void discoverDevices() {
    mManager.discoverPeers(mChannel, new WifiP2pManager.ActionListener() {
        @Override
        public void onSuccess() {
            connectionStatus.setText("Discovery Started");
        }

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

public WifiP2pManager.PeerListListener peerListListener = new WifiP2pManager.PeerListListener() {
    @Override
    public void onPeersAvailable(WifiP2pDeviceList peersList) {
        Log.d("DEVICE_NAME", "Listener called"+peersList.getDeviceList().size());
        if(peersList.getDeviceList().size() != 0){

            // first make a list of all devices already present
            ArrayList<CustomDevice> device_already_present = new ArrayList<>();

            for(WifiP2pDevice device : peersList.getDeviceList()){
                int idx = checkPeersListByName(device.deviceName);
                if(idx != -1){
                    // device already in list
                    device_already_present.add(custom_peers.get(idx));
                }
            }

            if(device_already_present.size() == peersList.getDeviceList().size()){
                // all discovered devices already present
                return;
            }

            // clear previous views
            clear_all_device_icons();

            // this will remove all devices no longer in range
            custom_peers.clear();
            // add all devices in range
            custom_peers.addAll(device_already_present);

            // add all already present devices to the view
            for(CustomDevice d : device_already_present){
                rippleBackground.addView(d.icon_view);
            }

            for(WifiP2pDevice device : peersList.getDeviceList()) {
                if (checkPeersListByName(device.deviceName) == -1) {
                    // device not already present
                    View tmp_device = createNewDevice(device.deviceName);
                    rippleBackground.addView(tmp_device);
                    foundDevice(tmp_device);

                    CustomDevice tmp_device_obj = new CustomDevice();
                    tmp_device_obj.deviceName = device.deviceName;
                    tmp_device_obj.id = tmp_device.getId();
                    tmp_device_obj.device = device;
                    tmp_device_obj.icon_view = tmp_device;

                    custom_peers.add(tmp_device_obj);
                }
            }
        }

        if(peersList.getDeviceList().size() == 0){
            Toast.makeText(getActivity().getApplicationContext(), "No Peers Found", Toast.LENGTH_SHORT).show();
        }
    }
};

public void clear_all_device_icons(){
    if(!custom_peers.isEmpty()){
        for(CustomDevice d : custom_peers){
            rippleBackground.removeView(getActivity().findViewById(d.id));
        }
    }
}

public WifiP2pManager.ConnectionInfoListener connectionInfoListener = new WifiP2pManager.ConnectionInfoListener() {
    @Override
    public void onConnectionInfoAvailable(WifiP2pInfo info) {
        final InetAddress groupOwnerAddress = info.groupOwnerAddress;

        if(info.groupFormed && info.isGroupOwner){
            connectionStatus.setText("HOST");
            serverClass = new ServerClass();
            serverClass.start();
        }else if(info.groupFormed){
            connectionStatus.setText("CLIENT");
            clientClass = new ClientClass(groupOwnerAddress);
            clientClass.start();
        }
    }
};

Point generateRandomPosition(){
    Display display = getActivity().getWindowManager().getDefaultDisplay();
    Point size = new Point();
    display.getSize(size);
    int SCREEN_WIDTH = size.x;
    int SCREEN_HEIGHT = size.y;

    int height_start = SCREEN_HEIGHT / 2 - 300;
    int x = 0;
    int y = 0;

    do{
        x = (int)(Math.random() * SCREEN_WIDTH);
        y = (int)(Math.random() * height_start);
    }while(checkPositionOverlap(new Point(x, y)));

    Point new_point = new Point(x, y);
    device_points.add(new_point);

    return new_point;

}

boolean checkPositionOverlap(Point new_p){
    //  if overlap, then return true, else return false
    if(!device_points.isEmpty()){
        for(Point p:device_points){
            int distance = (int)Math.sqrt(Math.pow(new_p.x - p.x, 2) + Math.pow(new_p.y - p.y, 2));
            Log.d(TAG, distance+"");
            if(distance < SEPRATION_DIST_THRESHOLD){
                return true;
            }
        }
    }
    return false;
}

public View createNewDevice(String device_name){
    View device1 = LayoutInflater.from(getActivity()).inflate(R.layout.device_icon, null);
    Point new_point = generateRandomPosition();
    RippleBackground.LayoutParams params = new RippleBackground.LayoutParams(350,350);
    params.setMargins(new_point.x, new_point.y, 0, 0);
    device1.setLayoutParams(params);

    TextView txt_device1 = device1.findViewById(R.id.myImageViewText);
    int device_id = (int)System.currentTimeMillis() + device_count++;
    txt_device1.setText(device_name);
    device1.setId(device_id);
    device1.setOnClickListener(this);

    device1.setVisibility(View.INVISIBLE);
    return device1;
}

private void foundDevice(View foundDevice){
    AnimatorSet animatorSet = new AnimatorSet();
    animatorSet.setDuration(400);
    animatorSet.setInterpolator(new AccelerateDecelerateInterpolator());
    ArrayList<Animator> animatorList=new ArrayList<Animator>();
    ObjectAnimator scaleXAnimator = ObjectAnimator.ofFloat(foundDevice, "ScaleX", 0f, 1.2f, 1f);
    animatorList.add(scaleXAnimator);
    ObjectAnimator scaleYAnimator = ObjectAnimator.ofFloat(foundDevice, "ScaleY", 0f, 1.2f, 1f);
    animatorList.add(scaleYAnimator);
    animatorSet.playTogether(animatorList);
    foundDevice.setVisibility(View.VISIBLE);
    animatorSet.start();
}

private void toggleWifiState() {
    if(wifiManager.isWifiEnabled()){
        wifiManager.setWifiEnabled(false);
        menu.findItem(R.id.wifi_toggle).setTitle("Turn Wifi On");
    }else{
        wifiManager.setWifiEnabled(true);
        menu.findItem(R.id.wifi_toggle).setTitle("Turn Wifi Off");
    }
}

public void getPermissions() {
    if ((ContextCompat.checkSelfPermission(getActivity(),
            Manifest.permission.RECORD_AUDIO)
            != PackageManager.PERMISSION_GRANTED)
            || (ContextCompat.checkSelfPermission(getActivity(),
            Manifest.permission.ACCESS_COARSE_LOCATION)
            != PackageManager.PERMISSION_GRANTED)) {
        ActivityCompat.requestPermissions(getActivity(),
                new String[]{Manifest.permission.RECORD_AUDIO,
                        Manifest.permission.ACCESS_COARSE_LOCATION
                },
                MY_PERMISSIONS_REQUEST_REQUIRED_PERMISSION);
    }
}
}

class CustomDevice{
int id;
String deviceName;
WifiP2pDevice device;
View icon_view;
CustomDevice(){

   }
}

Discovery 仅在 Android 10 上失败,而我这边的一切和逻辑都很好。

这里是包含的权限

<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" /> <!-- <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/> -->
<!-- <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> -->
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />

<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />

<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<!-- <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/> -->
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />

提前致谢

这个世界上没有人来帮助我

【问题讨论】:

    标签: java android wifi service-discovery wifip2p


    【解决方案1】:

    android 中的 Wifi-Direct 联盟正在发展,我们需要了解发现是如何工作的。 如果位置服务被禁用,Wifi-Direct 发现将永远无法工作。

    如何检查?

    LocationManager manager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
            if (!manager.isProviderEnabled(LocationManager.GPS_PROVIDER)) {
                Toast.makeText(this, "please enable location services", Toast.LENGTH_LONG).show();
                startActivity(new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS));
            }
    

    如果发现仍然无法正常工作,那么它来自操作系统,请从 Wifi-Direct 发现中的 Wifi-Preferences 检查,您的设备是否可见?如果没有,请重新启动您的手机。

    关于 Android 10 和 Wifi-Direct

    简单地说,如果它在 Android 9 上运行,它应该可以在 Android 10 上运行。

    注意: 请记住,当位置精度很高时,Wifi-direct 效果最好。

    请取消注释清单中的 FINE_LOCATION 权限,并在运行时从代码中询问它。

    【讨论】:

      【解决方案2】:

      我在升级到 Android 10 时遇到了同样的问题。

      不过,我通过激活 GPS 定位服务解决了这个问题。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-04-01
        • 2019-03-15
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多