如何通过WiFi发布设备名称(variables),如某些文件传输应用程序所做的那样?

我想通过WiFi发布或公布我的设备名称,这是可变的,可以由用户更改。

例如,拿一个文件传输应用程序Xender 。 当我们在应用中selectreceive选项时,我们可以在屏幕上看到用户设置的设备名称。 这里是屏幕截图。

在这里输入图像说明

你可以在图像中看到名字shah.kaushal正在出现。

我在互联网上search了很多结果,但无法弄清楚它到底是什么。

我知道主机名称,但我认为一般这是不会改变这样的应用程序,我认为它需要一些特殊的权限在Android上这样做。 所以我确定它不是主机名,我们可以从IP地址轻松获得。

请注意我没有复制任何其他应用程序的function。 我想在我的音乐播放器应用程序中分享歌曲。

为此,我在设备之间使用了TCP连接。 而且我可以成功地将歌曲从一台设备发送到另一台。 但是它需要设备的IP地址。 这不是用户友好的。

以下是我的基本音乐共享活动的屏幕截图,其中列出了可用的IP地址,用户必须从列表中select一个IP。

在这里输入图像说明

在这里,而不是IP地址,我想显示设备名称。

我的发送文件的代码是:

  @Override protected Void doInBackground(Void... voids) { System.out.println("array list"); ArrayList<File> files = new ArrayList<>(); System.out.println("about to create."); files.add(new File(wholePath)); System.out.println("file created.."); try { //Receiving IP addresses which are available to send our files(Music)!! a = getClientList(); //update the UI to display the received IP addresses!! publishProgress(); //busy waiting for user to select appropriate IP address to send files! while (destinationAddress.equals("-1")){ } //User has selected something, It's time to send files there! socket = new Socket(destinationAddress,5004); System.out.println("Connecting..."); DataInputStream dis = new DataInputStream(new BufferedInputStream(socket.getInputStream())); DataOutputStream dos = new DataOutputStream(new BufferedOutputStream(socket.getOutputStream())); System.out.println(files.size()); //write the number of files to the server dos.writeInt(files.size()); dos.flush(); //write file size for(int i = 0;i< files.size();i++){ int file_size = Integer.parseInt(String.valueOf(files.get(i).length())); dos.writeLong(file_size); dos.flush(); } //write file names for(int i = 0 ; i < files.size();i++){ dos.writeUTF(files.get(i).getName()); dos.flush(); } //buffer for file writing, to declare inside or outside loop? int n = 0; byte[]buf = new byte[4092]; //outer loop, executes one for each file for(int i =0; i < files.size(); i++){ System.out.println(files.get(i).getName()); //create new fileinputstream for each file FileInputStream fis = new FileInputStream(files.get(i)); //write file to dos while((n =fis.read(buf)) != -1){ dos.write(buf,0,n); dos.flush(); } } dos.close(); } catch (IOException e) { // TODO Auto-generated catch block xceptionFlag = true; e.printStackTrace(); } Log.i("===end of start ====", "=="); try{ if(!socket.isClosed()){ socket.close(); } } catch (Exception e){ xceptionFlag = true; e.printStackTrace(); } return null; } 

而接收文件的代码是:

  @Override protected Void doInBackground(Void... voids) { try { //this is done isntead of above line because it was givind error of address is already in use. ss = new ServerSocket(); ss.setReuseAddress(true); ss.bind(new InetSocketAddress(5004)); System.out.println("waiting"); Socket socket = ss.accept(); System.out.println("Accepted!"); DataInputStream dis = new DataInputStream(new BufferedInputStream(socket.getInputStream())); DataOutputStream dos = new DataOutputStream(new BufferedOutputStream(socket.getOutputStream())); //read the number of files from the client int number = dis.readInt(); ArrayList<File>files = new ArrayList<File>(number); System.out.println("Number of Files to be received: " +number); ArrayList<Long> fileSize = new ArrayList<>(number); for(int i = 0; i < number ;i++){ long size = dis.readLong(); System.out.println(size); fileSize.add(size); } //read file names, add files to arraylist for(int i = 0; i< number;i++){ File file = new File(dis.readUTF()); files.add(file); } int n = 0; byte[]buf = new byte[4092]; //outer loop, executes one for each file for(int i = 0; i < files.size();i++){ System.out.println("Receiving file: " + files.get(i).getName()); //Create new Folder for our app, if it is not there and store received files there in our separate folder. File folder = new File(Environment.getExternalStorageDirectory() + File.separator + "File"); boolean success = true; if (!folder.exists()) { success = folder.mkdirs(); } if (success) { // Do something on success } else { // Do something else on failure } //create a new fileoutputstream for each new file FileOutputStream fos = new FileOutputStream("mnt/sdcard/File/" +files.get(i).getName()); //read file while (fileSize.get(i) > 0 && (n = dis.read(buf, 0, (int)Math.min(buf.length, fileSize.get(i)))) != -1) { fos.write(buf,0,n); long x = fileSize.get(i); x = xn; fileSize.set(i,x); } fos.close(); } } catch (IOException e) { // TODO Auto-generated catch block xceptionFlag = true; e.printStackTrace(); } //////////////////// Log.i("== the end of read ====", "=="); try{ if(!ss.isClosed()){ ss.close(); } } catch (Exception e){ xceptionFlag = true; e.printStackTrace(); } return null; } 

我已经包含了代码以供参考。 谢谢。

Solutions Collecting From Web of "如何通过WiFi发布设备名称(variables),如某些文件传输应用程序所做的那样?"

只需将名称设置并存储在SharedPreferences或String中的任何位置,然后当显示列出IP的屏幕时,连接到其中的每一个,然后传输此String并显示它,而不是IP。 就像通过Java中的套接字发送string而不是字节来传输string。

当您想要从设备发布名称时,请启动此服务,并在不再发布该名称时停止该服务:

 public class NameService extends Service { private volatile boolean running; private volatile String myName; private volatile ServerSocket serverSocket; public NameService() { } @Override public void onCreate() { super.onCreate(); try { serverSocket = new ServerSocket(); serverSocket.bind(new InetSocketAddress(5006)); serverSocket.setReuseAddress(true); serverSocket.setSoTimeout(2000); } catch (IOException e) { e.printStackTrace(); } } @Override public int onStartCommand(Intent intent, int flags, int startId) { myName = PreferenceManager.getDefaultSharedPreferences(getApplicationContext()) .getString("NAME_STRING", "TEST.NAME"); if (!running) { running = true; new Thread(new Runnable() { @Override public void run() { while (running) { try { Socket socket = serverSocket.accept(); PrintWriter writer = new PrintWriter(new BufferedWriter( new OutputStreamWriter(socket.getOutputStream())), true); writer.println(myName); writer.close(); socket.close(); } catch (IOException e) { e.printStackTrace(); } } } }).start(); } return START_NOT_STICKY; } @Override public void onDestroy() { running = false; super.onDestroy(); } @Override public IBinder onBind(Intent intent) { // TODO: Return the communication channel to the service. throw new UnsupportedOperationException("Not yet implemented"); } } 

然后,当想要显示接收者列表时,连接到每个接收者并执行以下操作:

 try { Socket socket = new Socket(); socket.connect(new InetSocketAddress(ipAddress, 5006), 5000); BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream())); String message = reader.readLine(); reader.close(); socket.close(); Log.i("TAG", message); } catch (IOException e) { e.printStackTrace(); } 

如果要在运行时更改名称,可以进一步调用startService()

我build议你使用ServiceIntentService来进行文件传输, AsyncTask是不合适的。

试试这个:对于每个IP地址,你可以使用InetAddress类来parsing主机名

 InetAddress addr = InetAddress.getByName("IP-ADDRESS"); String host = addr.getHostName(); Log.i("host:",host); 

希望这可以帮助。 如果没有,我可以build议一些其他的方法。