我尝试为Googles Nearby Connections API实现一个小型测试应用程序 . 不幸的是,在3个经过测试的设备中,有2个Google Play服务在发现或广告时会崩溃 . (OnePlus One,Android 6.1; Acer Iconia,Android 4.4)

我看到其他设备,但当我连接到其中一个播放服务崩溃时(只有我的Honor 8继续工作) . 它表示连接是错误的,错误代码为1.根据Google,这意味着"A suspension cause informing that the service has been killed."

也许有些人可以提供帮助 . 我根据this教程制作了这段代码 . 没有进口的代码:

MainActivity.java

package com.example.steffen.nearbyconnectionsdemo;



public class MainActivity extends Activity implements
        GoogleApiClient.ConnectionCallbacks,
        GoogleApiClient.OnConnectionFailedListener,
        View.OnClickListener,
        Connections.ConnectionRequestListener,
        Connections.MessageListener,
        Connections.EndpointDiscoveryListener {

    // Identify if the device is the host
    private boolean mIsHost = false;
    GoogleApiClient mGoogleApiClient = null;
    Button bt_ad, bt_search, bt_send;
    TextView tv_status;
    CheckBox checkBox;
    Context c;
    String globalRemoteEndpointId = "";
    EditText editText;
    final int MY_PERMISSIONS_REQUEST = 666;

    private static int[] NETWORK_TYPES = {ConnectivityManager.TYPE_WIFI,
            ConnectivityManager.TYPE_ETHERNET};

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

        c = this;

        checkPermisson();

        editText = (EditText) findViewById(R.id.editText);

        bt_ad = (Button) findViewById(R.id.bt_ad);
        bt_ad.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                bt_search.setEnabled(false);
                startAdvertising();
            }
        });

        bt_search = (Button) findViewById(R.id.bt_search);
        bt_search.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                startDiscovery();
            }
        });

        bt_send = (Button) findViewById(R.id.bt_send);
        bt_send.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                String message = "message: " + editText.getText().toString();
                Toast.makeText(c, "Sending: " + message, Toast.LENGTH_SHORT).show();
                byte[] payload = message.getBytes();
                Nearby.Connections.sendReliableMessage(mGoogleApiClient, globalRemoteEndpointId, payload);
            }
        });

        tv_status = (TextView) findViewById(R.id.tv_status);
        checkBox = (CheckBox) findViewById(R.id.checkBox);

        mGoogleApiClient = new GoogleApiClient.Builder(this)
                .addConnectionCallbacks(this)
                .addOnConnectionFailedListener(this)
                .addApi(Nearby.CONNECTIONS_API)
                .build();

        getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
    }

    private boolean isConnectedToNetwork() {
        ConnectivityManager connManager =
                (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
        for (int networkType : NETWORK_TYPES) {
            NetworkInfo info = connManager.getNetworkInfo(networkType);
            if (info != null && info.isConnectedOrConnecting()) {
                return true;
            }
        }
        return false;
    }

    private void startAdvertising() {
        if (!isConnectedToNetwork()) {
            // Implement logic when device is not connected to a network
            tv_status.setText("No Network");
            return;
        }

        // Identify that this device is the host
        mIsHost = true;
        checkBox.setChecked(mIsHost);

        // Advertising with an AppIdentifer lets other devices on the
        // network discover this application and prompt the user to
        // install the application.
        List<AppIdentifier> appIdentifierList = new ArrayList<>();
        appIdentifierList.add(new AppIdentifier(getPackageName()));
        AppMetadata appMetadata = new AppMetadata(appIdentifierList);

        // The advertising timeout is set to run indefinitely
        // Positive values represent timeout in milliseconds
        long NO_TIMEOUT = 0L;

        String name = null;
        Nearby.Connections.startAdvertising(mGoogleApiClient, name, appMetadata, NO_TIMEOUT,
                this).setResultCallback(new ResultCallback<Connections.StartAdvertisingResult>() {
            @Override
            public void onResult(Connections.StartAdvertisingResult result) {
                if (result.getStatus().isSuccess()) {
                    // Device is advertising
                    tv_status.setText("Advertising");
                } else {
                    int statusCode = result.getStatus().getStatusCode();
                    // Advertising failed - see statusCode for more details
                    tv_status.setText("Error: " + statusCode);
                }
            }
        });
    }

    private void startDiscovery() {
        if (!isConnectedToNetwork()) {
            // Implement logic when device is not connected to a network
            tv_status.setText("No Network");
            return;
        }
        String serviceId = getString(R.string.service_id);

        // Set an appropriate timeout length in milliseconds
        long DISCOVER_TIMEOUT = 1000L;

        // Discover nearby apps that are advertising with the required service ID.
        Nearby.Connections.startDiscovery(mGoogleApiClient, serviceId, DISCOVER_TIMEOUT, this)
                .setResultCallback(new ResultCallback<Status>() {
                    @Override
                    public void onResult(Status status) {
                        if (status.isSuccess()) {
                            // Device is discovering
                            tv_status.setText("Discovering");
                        } else {
                            int statusCode = status.getStatusCode();
                            // Advertising failed - see statusCode for more details
                            tv_status.setText("Error: " + statusCode);
                        }
                    }
                });
    }

    @Override
    public void onEndpointFound(final String endpointId, String deviceId,
                                String serviceId, final String endpointName) {
        // This device is discovering endpoints and has located an advertiser.
        // Write your logic to initiate a connection with the device at
        // the endpoint ID

        Toast.makeText(this, "Found Device: " + serviceId + ", " + endpointName + ". Start Connection Try", Toast.LENGTH_SHORT).show();
        connectTo(endpointId, endpointName);
    }

    private void connectTo(String remoteEndpointId, final String endpointName) {
        // Send a connection request to a remote endpoint. By passing 'null' for
        // the name, the Nearby Connections API will construct a default name
        // based on device model such as 'LGE Nexus 5'.
        tv_status.setText("Connecting");

        String myName = null;
        byte[] myPayload = null;
        Nearby.Connections.sendConnectionRequest(mGoogleApiClient, myName,
                remoteEndpointId, myPayload, new Connections.ConnectionResponseCallback() {
                    @Override
                    public void onConnectionResponse(String remoteEndpointId, Status status,
                                                     byte[] bytes) {
                        if (status.isSuccess()) {
                            // Successful connection
                            tv_status.setText("Connected to " + endpointName);
                            globalRemoteEndpointId = remoteEndpointId;

                        } else {
                            // Failed connection
                            tv_status.setText("Connecting failed");
                        }
                    }
                }, this);
    }

    @Override
    public void onConnectionRequest(final String remoteEndpointId, String remoteDeviceId,
                                    final String remoteEndpointName, byte[] payload) {
        if (mIsHost) {
            byte[] myPayload = null;
            // Automatically accept all requests
            Nearby.Connections.acceptConnectionRequest(mGoogleApiClient, remoteEndpointId,
                    myPayload, this).setResultCallback(new ResultCallback<Status>() {
                @Override
                public void onResult(Status status) {
                    if (status.isSuccess()) {
                        String statusS = "Connected to " + remoteEndpointName;
                        Toast.makeText(c, statusS,
                                Toast.LENGTH_SHORT).show();
                        tv_status.setText(statusS);
                        globalRemoteEndpointId = remoteEndpointId;
                    } else {
                        String statusS = "Failed to connect to: " + remoteEndpointName;
                        Toast.makeText(c, statusS,
                                Toast.LENGTH_SHORT).show();
                        tv_status.setText(statusS);
                    }
                }
            });
        } else {
            // Clients should not be advertising and will reject all connection requests.
            Nearby.Connections.rejectConnectionRequest(mGoogleApiClient, remoteEndpointId);
        }
    }

    @Override
    public void onMessageReceived(String endpointId, byte[] payload, boolean b) {
        String message = payload.toString();
        Toast.makeText(this, "Received from " + endpointId + ": " + message, Toast.LENGTH_SHORT).show();
    }

    @Override
    public void onClick(View view) {

    }

    @Override
    public void onStart() {
        super.onStart();
        mGoogleApiClient.connect();
    }

    @Override
    public void onStop() {
        super.onStop();
        if (mGoogleApiClient != null && mGoogleApiClient.isConnected()) {
            mGoogleApiClient.disconnect();
        }
    }

    @Override
    public void onConnected(Bundle bundle) {

    }

    @Override
    public void onConnectionSuspended(int i) {
        tv_status.setText("Connection suspended because of " + i);

        mGoogleApiClient.reconnect();
    }

    @Override
    public void onConnectionFailed(ConnectionResult connectionResult) {
        tv_status.setText("Connection Failed");
    }


    @Override
    public void onEndpointLost(String s) {
        tv_status.setText("Endpoint lost: " + s);
    }



    @Override
    public void onDisconnected(String s) {
        tv_status.setText("Disconnected: " + s);
    }

    public void checkPermisson(){
        Toast.makeText(c, "Check permission", Toast.LENGTH_SHORT).show();

        // Here, thisActivity is the current activity
        if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_NETWORK_STATE) != PackageManager.PERMISSION_GRANTED) {
                ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_NETWORK_STATE}, MY_PERMISSIONS_REQUEST);
        }
    }

    @Override
    public void onRequestPermissionsResult(int requestCode,
                                           String permissions[], int[] grantResults) {
        switch (requestCode) {
            case MY_PERMISSIONS_REQUEST:
                // If request is cancelled, the result arrays are empty.
                if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                    // permission was granted, yay! Do the
                    // contacts-related task you need to do.
                    Toast.makeText(c, "Permission granted", Toast.LENGTH_SHORT).show();
                } else {
                    // permission denied, boo! Disable the
                    // functionality that depends on this permission.
                    Toast.makeText(c, "Permission not granted, app may fail", Toast.LENGTH_SHORT).show();
                }
                break;
            default:
                super.onRequestPermissionsResult(requestCode, permissions, grantResults);

        }
    }
}