我想通过WiFi发布或宣传我的设备名称,这是可变的,可由用户更改。
例如,选择文件传输应用程序Xender
。当我们在应用中选择receive
选项时,我们可以在屏幕上看到用户设置的设备名称。这是屏幕截图。
您可以在图片中看到名称shah.kaushal
正在出现。
我在互联网上搜索了很多结果,但无法弄清楚究竟是什么。
我知道主机名,但我认为通常不会被这些应用程序更改,我认为它需要一些特殊权限才能在Android上执行此操作。所以我确定它不是主机名,我们可以从IP地址轻松获取。
请注意我不会复制任何其他应用功能。我希望在我的音乐播放器应用程序中共享歌曲。
为此,我在设备之间使用了TCP连接。我可以成功地将歌曲从一个设备发送到另一个设备。但它需要设备的IP地址。哪个用户不友好。
以下是我的基本音乐分享活动的屏幕截图,其中列出了可用的IP地址,用户必须从列表中选择一个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 = 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;
}
我已将代码包含在内以供参考。感谢。
答案 0 :(得分:1)
只需将名称设置并存储在SharedPreferences
或任何地方作为字符串,然后当您显示列出IP的屏幕时,连接到它们中的每一个并传输此字符串并显示它而不是知识产权。像Send a string instead of byte through socket in Java这样的东西来转移字符串。
如果要从设备发布名称,请启动此服务,并在不再发布名称时停止该服务:
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()
。
我建议您使用Service
或IntentService
进行文件传输,AsyncTask
不合适。
答案 1 :(得分:0)
试试这个:
对于每个IP地址,您可以使用InetAddress
类
InetAddress addr = InetAddress.getByName("IP-ADDRESS");
String host = addr.getHostName();
Log.i("host:",host);
希望这会有所帮助。如果没有,我可以提出一些其他方法。