Прямое соединение с сервером Wi-Fi / клиент
Я пишу приложение для Android с поддержкой WiFi Direct, следуя инструкциям руководства Google для разработчиков. Я только начинаю учиться. Я застрял в отправке изображения с клиента на сервер. Ниже приведена кодировка клиента и сервера, взятая из демонстрации:
Это код для вызова Client Intent (MainActivity):
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode ==SELECT_IMAGE) {
Log.d(MainActivity.TAG, "onActivityResult Start");
Log.d(MainActivity.TAG, "requestCode "+requestCode);
Uri uri = data.getData();
Intent serviceIntent = new Intent(this, FileTransferService.class);
serviceIntent.setAction(FileTransferService.ACTION_SEND_FILE);
serviceIntent.putExtra(FileTransferService.EXTRAS_FILE_PATH, uri.toString());
Log.d(MainActivity.TAG, "file path " + uri.toString());
serviceIntent.putExtra(FileTransferService.EXTRAS_ADDRESS, IP_SERVER);
serviceIntent.putExtra(FileTransferService.EXTRAS_PORT, PORT);
this.startService(serviceIntent);
} else {
Log.d(MainActivity.TAG, "Service transfer failed");
}
}
Это код для клиента (я использовал IntentService в отдельном классе):
public class FileTransferService extends IntentService {
public static final int SOCKET_TIMEOUT = 5000;
public static final String ACTION_SEND_FILE = "com.moon.android.wifidirectproject_moon.action.SEND_FILE";
public static final String EXTRAS_ADDRESS = "go_host";
public static final String EXTRAS_FILE_PATH = "file_url";
public static final String EXTRAS_PORT = "go_port";
Socket socket = new Socket();
public FileTransferService() {
super("FileTransferService");
}
@Override
protected void onHandleIntent(Intent intent) {
Context context = getApplicationContext();
if (intent.getAction().equals(ACTION_SEND_FILE)) {
String fileUri = intent.getExtras().getString(EXTRAS_FILE_PATH);
String host = intent.getExtras().getString(EXTRAS_ADDRESS);
int port = intent.getExtras().getInt(EXTRAS_PORT);
try {
Log.d(MainActivity.TAG, "Opening client socket - ");
Log.d(MainActivity.TAG, "fileUri" + fileUri);
Log.d(MainActivity.TAG, "host" + host);
socket.bind(null);
socket.connect((new InetSocketAddress(host, port)), SOCKET_TIMEOUT);
Log.d(MainActivity.TAG, "Client socket - " + socket.isConnected());
OutputStream stream = socket.getOutputStream();
ContentResolver cr = context.getContentResolver();
InputStream is = null;
try {
is = cr.openInputStream(Uri.parse(fileUri));
Log.d(MainActivity.TAG, "is - " + is);
} catch (FileNotFoundException e) {
Log.d(MainActivity.TAG, e.toString());
}
copyFile(is, stream);
Log.d(MainActivity.TAG, "Client: Data written");
} catch (IOException e) {
Log.e(MainActivity.TAG, e.getMessage());
} finally {
if (socket != null) {
if (socket.isConnected()) {
try {
socket.close();
} catch (IOException e) {
// Give up
e.printStackTrace();
}
}
}
}
}
}
public static boolean copyFile(InputStream inputStream, OutputStream out) {
byte buf[] = new byte[1024];
int len;
try {
while ((len = inputStream.read(buf)) != -1) {
out.write(buf, 0, len);
}
out.close();
inputStream.close();
} catch (IOException e) {
Log.d(MainActivity.TAG, e.toString());
return false;
}
return true;
}
}
Это вызов к намерению сервера
@Override
public void onConnectionInfoAvailable(WifiP2pInfo info) {
if (info.groupFormed && info.isGroupOwner) {
InetAddress groupOwnerAddress = info.groupOwnerAddress;
ownerIP = groupOwnerAddress.getHostAddress();
Log.d(MainActivity.TAG, "Owner connected" + ownerIP);
Intent serverIntent = new Intent(mActivity, ServerService.class);
serverIntent.putExtra("port",MainActivity.PORT);
mActivity.startService(serverIntent);
.....
Следующее является Службой Намерения Сервера:
public class ServerService extends IntentService {
public static String mClientIP;
public ServerService() {
super("ServerService");
}
@Override
protected void onHandleIntent(Intent intent) {
Context context = getApplicationContext();
Integer port = intent.getExtras().getInt("port");
try {
ServerSocket serverSocket = new ServerSocket(port);
Socket client = serverSocket.accept();
Log.d(MainActivity.TAG, "Server: Socket opened");
Log.d(MainActivity.TAG, "clientIP" + client.getInetAddress().toString());
mClientIP = client.getInetAddress().toString();
Log.d(MainActivity.TAG, "Server: connection done");
/*
*************I am stuck here******************************
*/
final File f = new File(Environment.getExternalStorageDirectory() + "/"
+ context.getPackageName() + "/wifip2pshared-" + System.currentTimeMillis()
+ ".jpg");
File dirs = new File(f.getParent());
if (!dirs.exists())
dirs.mkdirs();
f.createNewFile();
Log.d(MainActivity.TAG, "server: copying files " + f.toString());
InputStream inputstream = client.getInputStream();
copyFile(inputstream, new FileOutputStream(f));
serverSocket.close();
} catch (IOException e) {
Log.e(MainActivity.TAG, e.getMessage());
} finally {
stopSelf();
}
}
public static boolean copyFile(InputStream inputStream, OutputStream out) {
byte buf[] = new byte[1024];
int len;
try {
while ((len = inputStream.read(buf)) != -1) {
out.write(buf, 0, len);
}
out.close();
inputStream.close();
} catch (IOException e) {
Log.d(MainActivity.TAG, e.toString());
return false;
}
return true;
}
}
Наконец, ниже мой LogCat. Я ставлю звездочки там, где в Сервере нет дальнейшего прогресса.
1) Server device (Initial State)
: search start
: WiFi_enabled
: Owner connected192.168.49.1
2) Client Device(sending image):
...............................
Opening client socket -
: fileUricontent://media/external/images/media/16871
: host192.168.49.1
: Client socket - true
: WiFi_enabled
: is - android.os.ParcelFileDescriptor$AutoCloseInputStream@3c520d34
3) Again Server Device
: Server: Socket opened
: clientIP/192.168.49.133
: Server: connection done
: open failed: ENOENT (No such file or directory)
Я должен признаться, что я не полностью понимаю сервер / клиент. У меня просто грубые знания. Однако, если вы дадите мне подсказку, в чем я не прав, я постараюсь узнать больше для себя. Я провел несколько дней, работая над этим, но не мог решить это. Спасибо за чтение этого поста.