2

我已经在这个问题上搞砸了大约 2 个月了。

我正在定制的 android 板上构建一个应用程序,它将充当 wifi 显示器 (WFD)。当我启动电路板时,我可以轻松地连接几部不同的手机(LG Optimus G、LG Optimus G pro、三星 S3 和 S4)。连接并观看连接到自定义板的电视屏幕上复制的屏幕后,我可以断开连接,如果我在 2 分钟内重新连接,我可以再次连接。

如果我启动电路板(或断开连接)然后等待 2 分钟,设备将不再看到电话,电话有时会看到电路板,有时看不到。如果手机看到板子,我可以发起连接,但我无法连接成功。

我尝试了各种选择,但似乎没有一个可行。

该板在 AOSP 4.2.2 上运行

我现在有一些复杂的代码,它每 40 秒重新启动一次 discoverPeers 函数,通常它会在 30 秒后停止。除此之外,我禁用 WFD 并重新启用它,中间有 4 秒的延迟。

我还尝试禁用和重新启用 p2p 和频道,但都没有结果。

下面是我的代码,接收器在一个单独的类中。

    @Override
protected void onCreate(Bundle savedInstanceState)
{       
    Settings.System.putInt(getContentResolver(), Settings.System.WIFI_SLEEP_POLICY, Settings.System.WIFI_SLEEP_POLICY_NEVER);
    AudioManager audioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
    audioManager.setStreamVolume(AudioManager.STREAM_MUSIC,
            audioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC), 0);
    setContentView(R.layout.wifi_direct_discovery);
    connectPicture = findViewById(R.id.LinearLayout1);

    Log.d(TAG, "onCreate");
    isConnecting = false;
    localWifiP2pWfdInfo = new WifiP2pWfdInfo();

    localWifiP2pWfdInfo.setWfdEnabled(true);
    localWifiP2pWfdInfo.setDeviceType(1);
    localWifiP2pWfdInfo.setSessionAvailable(true);
    localWifiP2pWfdInfo.setControlPort(7236);
    localWifiP2pWfdInfo.setMaxThroughput(50);
    final PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
    PowerManager.WakeLock wl = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "My Tag");
    wl.acquire();
    super.onCreate(savedInstanceState);
}

    @Override
public void onPeersAvailable(WifiP2pDeviceList peers)
{
    List<WifiP2pDevice> peersList = new ArrayList<WifiP2pDevice>();

    final ArrayList<String> list = new ArrayList<String>();
    final ListView listview = (ListView) findViewById(R.id.deviceListView);

    peersList.clear();
    peersList.addAll(peers.getDeviceList());

    if (peersList.size() == 0)
    {
        Log.d(TAG, "No devices found");
        list.clear();
        if ((pd != null) && pd.isShowing() && (isConnecting == false))
        {
            pd.dismiss();
            Log.d(TAG, "Closed connecting dialog, restarting P2P");
            Toast.makeText(this, "Connection failed please try again", Toast.LENGTH_LONG).show();
            restartP2p(false);
        }
        else if (isConnecting == false)
        {
            restartP2p(false);
        }
        listview.setAdapter(new ArrayAdapter<String>(this, R.layout.list_black_text, R.id.list_content, list));
        return;
    }
    else
    {
        int i = 0;
        boolean found = false;
        for (i = 0; i < peersList.size(); i++)
        {
            Log.d(TAG, "Found device: " + peersList.get(i).toString());
            list.add(peersList.get(i).deviceName);
            if ((pd != null) && pd.isShowing())
            {
                if (peersList.get(i).deviceAddress.equalsIgnoreCase(client.deviceAddress))
                {

                    found = true;
                }
            }
        }
        if (!found)
        {
            if ((pd != null) && pd.isShowing())
            {
                Log.d(TAG, "Failed to find current client: closed connecting dialog, restarting P2P");
                Toast.makeText(this, "Disconnected please try again", Toast.LENGTH_LONG).show();
                restartP2p(false);
            }
            else
            {
                Log.d(TAG, "Failed to find current client, but we weren't trying to connect");

            }
        }
    }
    listview.setAdapter(new ArrayAdapter<String>(this, R.layout.list_black_text, R.id.list_content, list));
}

@Override
public void onConnectionInfoAvailable(WifiP2pInfo p2pInfo)
{
    if (p2pInfo.isGroupOwner)
    {
        stopP2PDispeerTimeoutThread();
        Log.d(TAG, "Connected as group owner");
        int i = p2pInfo.mWfdRtspPort;
        Log.d(TAG, "------------------------- onConnectionInfoAvailable rtsp port = " + i);

        // get the ip addres from the connected client. Mac address is in
        // client

        String sourceIP = null;
        while (sourceIP == null)
        {
            sourceIP = getIPFromMac(client.deviceAddress);
            millisleep(250);
            if (sourceIP == null)
            {
                Log.e(TAG, "Failed to get client address!!!!! from " + client.deviceAddress);
            }
        }
        if (i == 0)
        {
            // this is not a wfd source, so let's get into client mode for
            // upgrade etc.
            Log.e(TAG, "This device is not a WFD source, so switch to client mode, device = "
                    + client.deviceAddress);
        }
        else
        {
            Log.d(TAG, "Start connect to source : " + sourceIP);
            if ((pd != null) && pd.isShowing())
                pd.dismiss();
            // need to stop the connection timeout thread here..
            stopConnectTimeoutThread();
            Intent intent = new Intent(getBaseContext(), WFDPlayActivity.class);
            intent.putExtra("SOURCE_IP", sourceIP);
            intent.putExtra("RTSPPORT", i);
            startActivityForResult(intent, 210);
        }
    }
    else
    {
        Log.e(TAG, "Connected as peer, this is very very wrong!!!!, restartP2P");
        restartP2p(false);
        startP2PDispeerTimeoutThread(34);
    }
}

@Override
public void onConnectionRequested(WifiP2pDevice arg0, WifiP2pConfig arg1)
{
    Log.d(TAG, "------------------------------------- onConnectionRequested");
    stopP2PDispeerTimeoutThread();

    isConnecting = true;
    client = arg0;
    if ((pd != null) && (pd.isShowing()))
    {
        pd.dismiss();
    }
    if (client != null)
    {
        createConnectionProgressDialog(client.deviceName);
    }
}

public void onResume()
{
    if (first_time == false)
    {
        Log.d(TAG, "onResume");

        intentFilter.addAction("android.net.wifi.p2p.STATE_CHANGED");
        intentFilter.addAction("android.net.wifi.p2p.PEERS_CHANGED");
            intentFilter.addAction("android.net.wifi.p2p.CONNECTION_STATE_CHANGE");
        intentFilter.addAction("android.net.wifi.p2p.THIS_DEVICE_CHANGED");
        registerReceiver(receiver, intentFilter);
        if (!mP2PDispeerThread.isRunning)
            startP2PDispeerTimeoutThread(34);
        manager.setDialogListener(channel, this);
        manager.discoverPeers(channel, new WifiP2pManager.ActionListener()
        {
            @Override
            public void onSuccess()
            {
                Log.d(TAG, "discoverPeers success");
            }

            @Override
            public void onFailure(int reasonCode)
            {
                Log.d(TAG, "discoverPeers failed");
            }
        });
    }
    else
    {
        Log.d(TAG, "onResume, first time");
        restartP2p(first_time);
        first_time = false;
    }
    getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_HIDE_NAVIGATION);
    super.onResume();
}


public void restartP2p(boolean first)
{
    if (first)
    {
        mWifiManager = ((WifiManager) getSystemService("wifi"));
        mWifiManager.setWifiEnabled(true);
        sleep(4); // was 4
        manager = (WifiP2pManager) getSystemService(Context.WIFI_P2P_SERVICE);
        channel = manager.initialize(this, getMainLooper(), null);
        manager.enableP2p(channel);
        sleep(3); // was 3
        mDisplayManager = ((DisplayManager) getSystemService("display"));
        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);
        mlock = mWifiManager.createWifiLock(WifiManager.WIFI_MODE_FULL_HIGH_PERF , "LockTag");
        mlock.acquire();
        instance = this;

        receiver = new WiFiDirectBroadcastReceiver(manager, channel, this);
        registerReceiver(receiver, intentFilter);

        manager.setWFDInfo(channel, localWifiP2pWfdInfo, new WifiP2pManager.ActionListener()
        {
            public void onFailure(int paramAnonymousInt)
            {
                Log.d(TAG, "Failed to set WFD info with reason " + paramAnonymousInt + ".");
            }

            public void onSuccess()
            {
                Log.d(TAG, "updateWfdEnableState");
            }
        });
        sleep(1);
        manager.setDialogListener(channel, this);
        manager.discoverPeers(channel, new WifiP2pManager.ActionListener()
        {
            @Override
            public void onSuccess()
            {
                Log.d(TAG, "discoverPeers success");
            }

            @Override
            public void onFailure(int reasonCode)
            {
                Log.d(TAG, "discoverPeers failed");
            }
        });
    }
    else
    {
        manager.stopPeerDiscovery(channel, new WifiP2pManager.ActionListener()
        {
            @Override
            public void onSuccess()
            {
                Log.d(TAG, "stopPeerDiscovery success");
            }

            @Override
            public void onFailure(int reasonCode)
            {
                Log.d(TAG, "stopPeerDiscovery failed");
            }
        });

        localWifiP2pWfdInfo.setWfdEnabled(false);
        manager.setWFDInfo(channel, localWifiP2pWfdInfo, new WifiP2pManager.ActionListener()
        {
            public void onFailure(int paramAnonymousInt)
            {
                Log.d(TAG, "Failed to set WFD info with reason " + paramAnonymousInt + ".");
            }

            public void onSuccess()
            {
                Log.d(TAG, "updateWfdEnableState");
            }
        });
        sleep(4);
        localWifiP2pWfdInfo.setWfdEnabled(true);
        manager.setWFDInfo(channel, localWifiP2pWfdInfo, new WifiP2pManager.ActionListener()
        {
            public void onFailure(int paramAnonymousInt)
            {
                Log.d(TAG, "Failed to set WFD info with reason " + paramAnonymousInt + ".");
            }

            public void onSuccess()
            {
                Log.d(TAG, "updateWfdEnableState");
            }
        });

        manager.discoverPeers(channel, new WifiP2pManager.ActionListener()
        {
            @Override
            public void onSuccess()
            {
                Log.d(TAG, "discoverPeers success");
            }

            @Override
            public void onFailure(int reasonCode)
            {
                Log.d(TAG, "discoverPeers failed");
            }
        });
    }

    if (first)
        startP2PDispeerTimeoutThread(40); // only start the thread 1 time...
}

在最初的日志记录中,我看到设备和手机连接成功。断开连接后,我在日志中看到设备丢失,之后,当我尝试连接时,我看到消息: I/wpa_supplicant(1839): [CTRL_IFACE]p2p0: P2P_CONNECT da:57:ef:cb:8e :be pbc go_intent=0

在这一切都停止之后,应用程序仍在运行,我可以从每 40 秒停止并重新启动发现的线程中每秒运行的日志行中看到这一点。

如果有人知道为什么会发生这种行为,请告诉我。现在恢复的唯一方法是重新启动电路板(但这不是一个选项)。

谢谢你的回复,阿维

4

0 回答 0