2016-12-15 17 views
9

Chcę opublikować lub reklamować nazwę mojego urządzenia przez WiFi, które jest zmienne i może być zmieniane przez użytkownika.Jak opublikować nazwę urządzenia (zmienną) przez Wi-Fi, jak robią to niektóre aplikacje do przesyłania plików?

Na przykład Weź aplikację do przesyłania plików Xender. Możemy zobaczyć nazwę urządzenia ustawioną przez użytkowników na ekranie po wybraniu opcji receive w aplikacji. Oto zrzut ekranu.

enter image description here

można zobaczyć w obrazie, który pojawia się nazwa shah.kaushal.

Przeszukałem wiele wyników w Internecie, ale nie wiem, co to jest.

Wiem o nazwie hosta, ale myślę, że generalnie nie jest ona zmieniana przez takie aplikacje i myślę, że potrzebuje na Androida specjalnych uprawnień. Jestem więc pewien, że nie jest to nazwa hosta, którą możemy łatwo uzyskać z adresu IP.

Uwaga Nie kopiuję żadnych innych funkcji aplikacji. Chcę to w mojej aplikacji odtwarzacza muzyki, aby udostępniać utwory.

Aby to zrobić, użyłem połączenia TCP między urządzeniami. I mogę z powodzeniem wysyłać utwory z jednego urządzenia na drugie. Ale wymaga adresu IP urządzenia. Co nie jest przyjazne dla użytkownika.

Oto zrzut ekranu mojej podstawowej działalności związanej z udostępnianiem muzyki, która zawiera listę dostępnych adresów IP, a użytkownik musi wybrać jedno IP z listy.

enter image description here

Tutaj zamiast adresów IP, chcę, aby wyświetlić nazwy urządzeń.

Mój kod do wysyłania pliku jest:

@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; 
} 

i kod do umieszczenia pliku jest:

@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 = x-n; 
       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; 
} 

podaję kod odniesienia. Dzięki.

Odpowiedz

1

Po prostu ustaw i zapisz nazwę w lub w dowolnym miejscu jako Ciąg, a następnie, gdy wyświetli się ekran z listą IP, połącz się z każdym z nich i prześlij ten Łańcuch i wyświetl go zamiast adresu IP. Coś jak Send a string instead of byte through socket in Java przesłać String.

Gdy chcesz opublikować nazwę z urządzenia uruchomić tę usługę, a zatrzymać go, gdy nie powinno być już opublikowanie nazwy:

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"); 
    } 
} 

Wtedy, gdy chcemy, aby wyświetlić listę odbiorców, podłącz do każdego z nich i wykonaj następujące czynności:

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(); 
    } 

można zrobić kolejne połączenia do startService() jeśli chcesz zmienić nazwę, gdy jest uruchomiony.

Zalecam stosowanie Service lub IntentService do przesyłania plików, AsyncTask nie jest właściwe.

+0

Mówisz więc, że muszę połączyć się z każdym dostępnym urządzeniem, aby to uzyskać. łańcuch nazwy urządzenia przed faktycznym łączeniem się z nim w celu transferu plików? Czy mam rację? – Kaushal28

+0

Zobacz zaktualizowaną odpowiedź, przetestowano i działało. –

+0

I tak, połączysz się z każdym IP w getClientList(), zanim wyświetlisz listę odbiorników i wyślesz pliki. –

0

Wypróbuj to: dla każdego adresu IP, można rozwiązać nazwy hosta za pomocą InetAddress klasa

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

nadzieję, że to pomaga. Jeśli nie, mogę zaproponować inne podejścia.

+0

ok dzięki za zainteresowanie. Ale myślę, że nazwy tych hostów nie są zmienne. A także nie jest przyjazny dla użytkownika. na przykład przeważnie są alfanumeryczne. Potrzebna jest zmienna nazwa urządzenia, którą może ustawić użytkownik, tak jak to robimy w Xender (aplikacja do przesyłania plików w sklepie Play). – Kaushal28

Powiązane problemy