通过 Wifi Direct 传输文件
Posted
技术标签:
【中文标题】通过 Wifi Direct 传输文件【英文标题】:file transfer through Wifi Direct 【发布时间】:2017-11-16 09:30:19 【问题描述】:我正在尝试编写一个 android 应用程序,该应用程序将从第一台设备拍摄的图像通过摄像头传输到具有 WiFi Direct 的第二台设备。
我正在尝试使用这个 GitHub 项目,WiFiDIrectDemo,我设法连接了设备并只发送了一个文件。 当我尝试发送第二个文件时,我没有收到任何错误,并且从日志中,一切似乎都正常,但第二个设备没有收到任何文件。
这是一个已知问题吗?我试图在互联网上查找,但找不到任何可以帮助我的东西。
我正在附加我的文件传输服务类:
public class FileTransferService extends IntentService
Handler mHandler;
public static final int SOCKET_TIMEOUT = 50000; //ms
public static final String ACTION_SEND_FILE = "com.example.android.wifidirect.SEND_FILE";
public static final String EXTRAS_FILE_PATH = "file_url";
public static final String EXTRAS_GROUP_OWNER_ADDRESS = "go_host";
public static final String EXTRAS_GROUP_OWNER_PORT = "go_port";
public static int PORT = 8888;
public static final String inetaddress = "inetaddress";
public static final int ByteSize = 512;
public static final String Extension = "extension";
public static final String Filelength = "filelength";
public FileTransferService(String name)
super(name);
public FileTransferService()
super("FileTransferService");
@Override
public void onCreate()
// TODO Auto-generated method stub
super.onCreate();
mHandler = new Handler();
@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_GROUP_OWNER_ADDRESS);
Socket socket = new Socket();
InputStream is = null;
int port = intent.getExtras().getInt(EXTRAS_GROUP_OWNER_PORT);
String extension = intent.getExtras().getString(Extension);
String filelength = intent.getExtras().getString(Filelength);
try
if(!socket.isConnected())
Log.d(WiFiDirectActivity.TAG, "Opening client socket - ");
socket.bind(null);
socket.setReuseAddress(true);
socket.connect((new InetSocketAddress(host, port)),5000); // ..,socket_timeout)
Log.e("File Transfer Service"," socket connect");
Log.d(WiFiDirectActivity.TAG, "Client socket - " + socket.isConnected());
OutputStream stream = socket.getOutputStream();
Log.e("file transfer" +
" service", "get output stream");
ContentResolver cr = context.getContentResolver();
Long FileLength = Long.parseLong(filelength);
WiFiTransferModal transObj = null;
ObjectOutputStream oos = new ObjectOutputStream(stream);
if(transObj == null) transObj = new WiFiTransferModal();
transObj = new WiFiTransferModal(extension,FileLength);
oos.writeObject(transObj);
try
is = cr.openInputStream(Uri.parse(fileUri));
catch (FileNotFoundException e)
Log.d(WiFiDirectActivity.TAG, e.toString());
DeviceDetailFragment.copyFile(is, stream);
Log.d(WiFiDirectActivity.TAG, "Client: Data written");
oos.flush();
oos.close(); //close the ObjectOutputStream after sending data.
catch (IOException e)
Log.e("file transfer service","unable to connect: " + e.toString() );
finally
if (socket != null)
if (socket.isConnected())
try
socket.close();
catch (Exception e)
// Give up
e.printStackTrace();
Log.e("File transfer service","exception socket.close: " + e.toString());
else Log.e("file transfer service","socket is already null");
编辑
接收代码:
public class FileServerAsyncTask extends AsyncTask<String, String, String>
// private TextView statusText;
private Context mFilecontext;
private String Extension, Key;
private File EncryptedFile;
private long ReceivedFileLength;
private int PORT;
public FileServerAsyncTask(Context context, int port)
this.mFilecontext = context;
handler = new Handler();
this.PORT = port;
@Override
protected String doInBackground(String... params)
try
Log.e("device detail fragment", "File Async task port-> " + PORT);
ServerSocket serverSocket = new ServerSocket();
Log.e("device detail fragment"," new server");
serverSocket.setReuseAddress(true);
Log.e("device detail fragment","set reuse address");
serverSocket.bind(new InetSocketAddress(PORT));
Log.e("device detail fragment","socket bind");
Socket client = serverSocket.accept();
Log.e("device detail fragment "," socket client accept");
Log.e("Device detail fragment ", "client inet address" + client.getInetAddress());
WiFiClientIp = client.getInetAddress().getHostAddress();
Log.e("device detail fragment"," get client ip: " + WiFiClientIp);
ObjectInputStream ois = new ObjectInputStream(
client.getInputStream());
Log.e("device detail fragment","object input stream + " + ois.toString());
WiFiTransferModal obj = null;
String InetAddress;
try
obj = (WiFiTransferModal) ois.readObject();
Log.e("device detail fragment"," read object");
if (obj != null)
Log.e("device detail fragment"," obj != null ");
InetAddress = obj.getInetAddress();
Log.e("device detail fragment"," get inet address: " +
InetAddress);
if (InetAddress != null
&& InetAddress
.equalsIgnoreCase(FileTransferService.inetaddress))
SharedPreferencesHandler.setStringValues(mFilecontext,
mFilecontext.getString(R.string.pref_WiFiClientIp), WiFiClientIp);
//set boolean true which identify that this device will act as server.
SharedPreferencesHandler.setStringValues(mFilecontext,
mFilecontext.getString(R.string.pref_ServerBoolean), "true");
ois.close(); // close the ObjectOutputStream object
Log.e("device detail fragment"," output stream close");
// after saving
serverSocket.close();
Log.e("device detail fragment","close");
return "Demo";
Log.e("device detail fragment","FileName got from socket on other side->>> "+
obj.getFileName());
final File f = new File(
Environment.getExternalStorageDirectory() + "/"
+ FolderName + "/"
+ obj.getFileName());
Log.e("background"," new file f from inputstream");
File dirs = new File(f.getParent());
Log.e("device detail fragment"," f get parent()");
if (!dirs.exists())
dirs.mkdirs();
f.createNewFile();
Log.e("device detail fragment","create new file");
/**
* Receive file length and copy after it
*/
this.ReceivedFileLength = obj.getFileLength();
InputStream inputstream = client.getInputStream();
Log.e("device detail fragment","input stream client get input");
Message msg = Message.obtain();
msg.what = 1;
try
// send the images to the image view through handler
Bitmap bitmap = BitmapFactory.decodeStream(inputstream);
Log.e("device detail fragment", "decode stream");
Bundle b = new Bundle();
b.putParcelable("bitmap", bitmap);
msg.setData(b);
Log.e("device detail fragment","message: " + msg.toString());
messageHandler.sendMessage(msg);
catch (Exception e)
Log.e("device detail fragment","stream not decoded into bitmap with" +
"exception: " + e.toString());
copyRecievedFile(inputstream, new FileOutputStream(f),
ReceivedFileLength);
Log.e("device detail fragment","copy input stream into file");
ois.close(); // close the ObjectOutputStream object after saving
// file to storage.
Log.e("device detail fragment","ois close");
/**
* Set file related data and decrypt file in postExecute.
* */
this.Extension = obj.getFileName();
this.EncryptedFile = f;
final Uri uri = Uri.fromFile(f);
return f.getAbsolutePath();
catch (ClassNotFoundException e)
e.printStackTrace();
catch (Exception e)
e.printStackTrace();
Log.e("device detail fragment", e.getMessage());
return "";
catch (IOException e)
Log.e("device detail fragment", e.getMessage());
return null;
@Override
protected void onPostExecute(String result)
if (result != null)
if (!result.equalsIgnoreCase("Demo"))
Log.e("On Post Execute","result +" + result);
else if (!TextUtils.isEmpty(result))
/**
* To initiate socket again we are initiating async task
* in this condition.
*/
FileServerAsyncTask FileServerobj = new
FileServerAsyncTask(mFilecontext, FileTransferService.PORT);
if (FileServerobj != null)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB)
FileServerobj.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, new String[]null);
Log.e("Post Execute", "FileServerobj.execute on executor");
else
FileServerobj.execute();
Log.e("Post Execute", "FileServerobj.execute");
@Override
protected void onPreExecute()
if (mProgressDialog == null)
mProgressDialog = new ProgressDialog(mFilecontext);
if(imageView == null)
imageView = new ImageView(mFilecontext);
【问题讨论】:
您发布的代码中有很多我不明白的地方。但是如果接收方没有收到第二个文件,那么在接收方看到你使用的代码也不错。 感谢您的回答,很抱歉我没有写一个完整的问题。我将编辑问题并将接收方也放入。 只发布服务器异步任务。不是完整的活动或片段。 服务器将接收一个文件,然后通过让用户选择一个应用程序来显示该文件来打开它。你能证实这一点吗?然后服务器异步任务完成。因此无法接收到新文件。因此,如果您说日志表明一切正常,我不相信您。您的客户端套接字无法连接。一切都是有目的的行为。 一开始服务器收到一个文件,然后用另一个函数打开它,我已经更改了代码,现在,接收到的应该是图像的文件被处理为图像视图.您是在建议我以错误的方式使用此任务?所以我应该修改它,使它不会结束连接和结束? 【参考方案1】:服务器将接收一个文件,然后通过让用户选择一个应用程序来显示该文件来打开它。然后服务器异步任务完成。因此无法接收到新文件。因此,如果您说日志表明一切正常,我不相信您。您的客户端套接字无法连接。一切都是有目的的行为。
* To initiate socket again we are initiating async task * in this condition..
您的代码没有出现。
您必须再次启动异步任务才能接收下一个文件。
【讨论】:
再次感谢,我将修改代码并寻找解决方案:) 得到它我会尽快发布它 很简单:再次启动异步任务并显示文件。以上是关于通过 Wifi Direct 传输文件的主要内容,如果未能解决你的问题,请参考以下文章
通过 Wi-Fi Direct 传输文件时是不是可以使用移动数据?
使用 WiFi Direct 或 Air/AS3 中的热点连接应用程序
如何在android中获取通过wifi直接传输的文件的文件名?