¿Cómo publicar el nombre del dispositivo (Variable) sobre WiFi, como algunas aplicaciones de transferencia de archivos hacer?
Quiero publicar o anunciar mi nombre de dispositivo a través de WiFi, que es variable y puede ser cambiado por el usuario.
Por ejemplo, Tome una aplicación de transferencia de archivos Xender
. Podemos ver el nombre del dispositivo establecido por los usuarios en la pantalla cuando seleccionamos la opción de receive
en la aplicación. Aquí está la captura de pantalla.
- Manejo de eventos de aplicaciones de Android
- ¿Cuál es la estructura / patrón de android / java para organizar las llamadas de servicio web http en el proyecto?
- Establecer la fecha / hora de Android mediante programación
- Notificación de no hacer sonido o vibración?
- Ejemplo de uso de pestañas de Android con Vistas en lugar de Actividades?
Usted puede ver en la imagen que el nombre shah.kaushal
está apareciendo.
He buscado muchos resultados en Internet, pero no puedo averiguar cuál es exactamente lo que es.
Sé sobre el nombre de host, pero creo que en general no se cambia por tales aplicaciones y creo que necesita algunos privilegios especiales en Android para hacerlo. Así que estoy seguro de que no es el nombre de host, que podemos obtener fácilmente de la dirección IP.
Ten en cuenta que no estoy copiando ninguna otra aplicación. Quiero esto en mi aplicación de reproductor de música para compartir canciones.
Para ello, he utilizado la conexión TCP entre dispositivos. Y puedo enviar canciones con éxito de un dispositivo a otro. Pero requiere la dirección IP del dispositivo. Que no es fácil de usar.
Aquí está la captura de pantalla de mi actividad de compartir música básica, que lista las direcciones IP disponibles y el usuario tiene que seleccionar una IP de la lista.
Aquí, en lugar de direcciones IP, quiero mostrar los nombres de los dispositivos.
Mi código para enviar el archivo es:
@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; }
Y el código para recibir el archivo es:
@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; }
He incluido el código de referencia. Gracias.
- Creación de un registro WiFi NDEF utilizando application / vnd.wfa.wsc en Android
- La mejor manera de ejecutar periódicamente AsyncTasks en Android
- ¿Cómo convertir la fecha del calendario en cadena?
- Objeto comparable no de clasificación
- RoboSpice y ORMLite - Acceso a los datos
- Cómo hacer anotaciones como destacar, tachar, subrayar, dibujar, añadir texto, etc en android para un visor de pdf?
- ¿Por qué mis elementos de ListView no se pueden hacer clic?
- Cómo interactuar con diferentes navegadores de Android (obtener url)
Sólo tiene el nombre establecido y almacenado en SharedPreferences
o en cualquier lugar como una cadena, a continuación, cuando muestre la pantalla donde está listando la IP, conecte a cada uno de ellos y la transferencia de esta cadena y mostrar en lugar de la IP. Algo así como Enviar una cadena en lugar de byte a través de socket en Java para transferir la cadena.
Cuando desee publicar el nombre de un dispositivo, inicie este servicio y detenerlo cuando no deba publicar el nombre:
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"); } }
Luego, cuando desee mostrar la lista de receptores, conéctese a cada uno y haga lo siguiente:
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(); }
Puede realizar otras llamadas a startService()
si desea cambiar el nombre cuando se está ejecutando.
Te recomiendo que uses Service
o IntentService
para tus transferencias de archivos, AsyncTask
no es apropiado.
Pruebe esto: Para cada dirección IP, puede resolver el nombre de host utilizando la clase InetAddress
InetAddress addr = InetAddress.getByName("IP-ADDRESS"); String host = addr.getHostName(); Log.i("host:",host);
Espero que esto ayude. Si no, puedo sugerir otros enfoques.
- IPhone o Android que utilizan la autenticación basada en SMS?
- GetDrawable () en TypedArray devolver null?