-1

我再次遇到了我的应用程序的问题。我使用NSDAPI 来发现和连接服务,并使用数组adapter来获取有关服务的数据,例如 IP 地址和服务名称,并将其打印在应用程序屏幕上。到目前为止,我在显示服务名称时没有任何问题,但我不能不显示服务的 IP 地址。但是,当我将它记录到日志时,我可以打印 IP 地址,如果我打开应用程序而不是 IP 地址,它会显示文本“null”。

有人对此有任何建议或经验吗?

这是 MainActivity.java

public class MainActivity extends AppCompatActivity {

private String SERVICE_TYPE = "_printer._tcp."; // change to normal


private InetAddress hostAddress;
private int hostPort;
private NsdManager mNsdManager;
ArrayList<NsdServiceInfo> services;
private NsdServiceInfoAdapter mAdapter;


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


    //Getting toolbar by id
    Toolbar toolbar = findViewById(R.id.toolbar);
    setSupportActionBar(toolbar);


    services = new ArrayList<>();
    mAdapter = new NsdServiceInfoAdapter(this, R.id.TextView_serviceName, services);
    ListView listView = findViewById(R.id.ListViewServices);
    listView.setAdapter(mAdapter); // we add custom adapter to the listview to display data from adapter.


    //disabling default title text
    getSupportActionBar().setDisplayShowTitleEnabled(false);


    //NSD stuff

    mNsdManager = (NsdManager) getSystemService(Context.NSD_SERVICE);
    mNsdManager.discoverServices(SERVICE_TYPE, NsdManager.PROTOCOL_DNS_SD, mDiscoveryListener);

    listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
        @Override
        public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
            Object serviceObj = adapterView.getItemAtPosition(i);
            NsdServiceInfo selectedService = (NsdServiceInfo) serviceObj;
            //mNsdManager.stopServiceDiscovery(mDiscoveryListener);
            //mNsdManager.resolveService(selectedService, mResolveListener);

        }
    });
}


NsdManager.DiscoveryListener mDiscoveryListener = new NsdManager.DiscoveryListener() {
    @Override
    public void onStartDiscoveryFailed(String serviceType, int errorCode) {
        Log.e("TAG", "DiscoveryFailed: Error code: " + errorCode);
        mNsdManager.stopServiceDiscovery(this);

    }

    @Override
    public void onStopDiscoveryFailed(String serviceType, int errorCode) {
        Log.e("TAG", "Discovery failed : Error code: " + errorCode);
    }

    @Override
    public void onDiscoveryStarted(String regType) {
        Log.d("TAG", "Service discovery started");

    }

    @Override
    public void onDiscoveryStopped(String serviceType) {
        Log.i("TAG", "Discovery stopped: " + serviceType);

    }

    @Override
    public void onServiceFound(final NsdServiceInfo serviceInfo) {

        Log.d("TAG", "Service discovery success : " + serviceInfo);
        Log.d("TAG", "Host = " + serviceInfo.getServiceName());
        Log.d("TAG", "Port = " + serviceInfo.getPort());
        services.add(serviceInfo);

        NsdManager.ResolveListener mResolveListener2 = new NsdManager.ResolveListener() {
            @Override
            public void onResolveFailed(NsdServiceInfo nsdServiceInfo, int errorCode) {
                Log.e("TAG", "Resolved failed " + errorCode);
                Log.e("TAG", "Service = " + nsdServiceInfo);
            }

            @Override

            public void onServiceResolved(NsdServiceInfo nsdServiceInfo) {

                Log.d("TAG", "bbz" + nsdServiceInfo);


                Log.d("TAG", "Resolve Succeeded " + nsdServiceInfo);

                if (nsdServiceInfo.getServiceType().equals(SERVICE_TYPE)) {
                    Log.d("TAG", "Same IP");
                    return;
                }


                hostPort = nsdServiceInfo.getPort();
                hostAddress = nsdServiceInfo.getHost();
                Log.d("hello", String.valueOf(hostAddress));


                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        mAdapter.notifyDataSetChanged();


                    }
                });
            }
        };
        mNsdManager.resolveService(serviceInfo, mResolveListener2);

    }


    @Override
    public void onServiceLost(NsdServiceInfo nsdServiceInfo) {
        Log.d("TAG", "Service lost " + nsdServiceInfo);
        NsdServiceInfo serviceToRemove = new NsdServiceInfo();
        for (NsdServiceInfo currentService : services) {
            if (currentService.getHost() == nsdServiceInfo.getHost() && currentService.getPort() == currentService.getPort() && currentService.getServiceName() == currentService.getServiceName()) {
                serviceToRemove = currentService;
            }
        }
        if (serviceToRemove != null) {
            services.remove(serviceToRemove);
            runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    mAdapter.notifyDataSetChanged();
                }
            });
        }
        Log.d("TAG", "Xd" + services);
    }

};

这是我的ArrayAdapter

//Creating new custom NsdServiceInfoAdapter which extends ArrayAdapter

public class NsdServiceInfoAdapter extends ArrayAdapter<NsdServiceInfo> {
private Context mContext;
private ArrayList<NsdServiceInfo> services;

//Creating new constructor with parameters such as this class(context), layout id (list item layout Id) and data model.

public NsdServiceInfoAdapter(@NonNull Context context, int layoutId, ArrayList<NsdServiceInfo> list) {
    super(context, layoutId, list);
    mContext = context;
    services = list;
}

@NonNull
@Override

// Creating method get(), which is called when listItem needs to be populated with data.
//Get a View that displays the data at the specified position in the data set.
public View getView(int position, @Nullable View convertView, @NonNull ViewGroup parent) {
    View listItem = convertView;

    //Checking if view is empty then we inflate our list  layout.
    if (listItem == null)
        listItem = LayoutInflater.from(mContext).inflate(R.layout.list_item, parent, false);

    //Getting data's position in the data set.
    NsdServiceInfo currentService = (NsdServiceInfo) services.get(position);

    //We asign the the view to the item layout as a TextView
    TextView t = listItem.findViewById(R.id.TextView_serviceName);

    //We set text as a services name.
    t.setText(String.valueOf(currentService.getHost()));
    //t.setText(currentService.getServiceName());

    Log.d("tag", "service name" + currentService.getServiceName());


    return listItem;
}

}

这是日志

我的日志

这是我的应用程序屏幕

带有列表的应用程序屏幕

4

1 回答 1

0

移动这一行:

services.add(serviceInfo); 

onServiceResolved函数内部并尝试。

nsdServiceInfo注意:您应该改为作为参数传递serviceInfo

于 2019-08-30T11:03:35.490 回答