利用android 传送文件需要解决一下几个问题。
1,发送方选中文件时如何获取文件地址?
以下这段代码作用是返回你选择文件的uri,因此你要重写
onActivityResult来获取返回的uri。但是这里有有两种情况存在先看下图。
Intent intent = new Intent(Intent.ACTION_PICK); intent.setType("*/*"); startActivityForResult(intent, 1);
当你选择图库的时候选择其中一张图片返回的uri为:content://media/external/images/media/530405 后面的数字是图片存储在图库数据库中的_id,
当你选择文件管理的时候选择其中的一个文件返回的uri为: file:///storage/emulated/0/tencent/QQfile_recv/%E9%A2%98%E7%9B%AE.txt
因此要获取文件的地址需要分两种情况进行获取。
情况一:你可以利用
ContentResolver这个类根据图片的_id获取图片存储在数据库中地址。
一下代码可以获取在图库中图片地址
String path=null;
ContentResolver resolver = this.getContentResolver();
//uri.getLastPathSegment()这个是获取content://media/external/images/media/530405后面的数字也就是_id path = getFilePath(resolver, uri, uri.getLastPathSegment());
//
private String getFilePath(ContentResolver resolver,Uri uri,String _id) { String _data=null; Cursor cursor = resolver.query(uri, null,"_id="+_id, null, null); while (cursor.moveToNext()) { _data = cursor.getString(cursor.getColumnIndex("_data"));//表示文件的存储路径 String displayName = cursor.getString(cursor.getColumnIndex("_display_name"));//表示文件名 String mimeType = cursor.getString(cursor.getColumnIndex("mime_type"));//媒体类型:image/jpeg之类的 Log.d("test", "_data:" + _data + ",displayName:" + displayName + ",mimeType:" + mimeType); } return _data; }
情况二:这个uri你可以利用path=uri.getPath();这个方法获取uri的路径以下是我获取选中文件的路径
/storage/emulated/0/tencent/QQfile_recv/题目.txt
2,接受方如何获取发送方的文件名及文件类型?
这里我是发送方文件名和路径前后放一个标识然后将其写入流中,接受方然后解析出文件类型及文件名,
//发送及读取文件,这里发送文件要放在子线程中不然传送大文件时会导致主线程阻塞
class ReceiveFile extends Thread { private BluetoothSocket socket; private InputStream inputStream; private File receiveFile; private String filePath; private String name; private String content; private volatile FileOutputStream outputStream=null; public ReceiveFile(BluetoothSocket socket) { this.socket = socket; filePath = Environment.getExternalStorageDirectory().getPath(); File file = new File(filePath, "you"); if (!file.exists()) { file.mkdir(); } filePath = file.getPath(); } @Override public void run() { try { inputStream = socket.getInputStream(); } catch (Exception e) { e.printStackTrace(); } while (true) { try { handler.sendEmptyMessage(3); byte[] buff = new byte[1024]; int length = 0; //当没有数据时会阻塞,却并不会返回-1, // 并且这里不建议使用,while((length=inputStream.read(buff,0,buff.length))!-1)这种写法 length = inputStream.read(buff); //文件名包含在第一个数据块中 content = new String(buff, 0, length); /*Log.d("test", "content--->:" + content);*/ Log.d("test", "begin:" + content.startsWith("begin")); if (content.startsWith("begin")) { //保证再次传送数据时数据不会写入第一个文件中,这句很重要 outputStream=null; if (outputStream == null) { Log.d("test", "outputStream ===null"); }else { Log.d("test", "outputStream !=null"); } flag++; name = getFileName(content); Log.d("test", "flag:" + flag+",name:"+name); /*outputStream=null*/;//解决 } outputStream = getOutputStream(filePath, name); if (content.startsWith("begin")) { outputStream.write(getBytes(content)); continue; } outputStream.write(buff, 0, length); } catch (Exception e) { e.printStackTrace(); } } } //一个传送只得到一个FileOutputStream private synchronized FileOutputStream getOutputStream(String path, String name) { Log.d("test", "getOutput"); if (outputStream == null) { try { receiveFile=new File(path, name); if (!receiveFile.exists()) { receiveFile.createNewFile(); } outputStream = new FileOutputStream(receiveFile); Log.d("test", "receiveFile:" + receiveFile.getName()); } catch (Exception e) { e.printStackTrace(); } }else { Log.d("test", "getOutPutStream outputStream !=null"); } return outputStream; } //返回解析传来的真实数据 private synchronized byte[] getBytes(String content) { int end = content.lastIndexOf("end"); byte[] bytes = content.substring(end + 3).getBytes(); return bytes; } //根据传送过来的数据解析出文件名 private synchronized String getFileName(String content) { int begin = content.indexOf("begin"); int end = content.lastIndexOf("end"); String name = content.substring(begin + 5, end); return name; } //先将标识,文件及文件名写入流中,然后将文件数据写入流中 public void SendFile(File file) { try { Log.d("test", file.getPath() + ":" + file.getName()); String name = "begin" + file.getName() + "end"; FileInputStream inputStream = new FileInputStream(file); OutputStream outputStream = socket.getOutputStream(); byte[] buff = new byte[1024]; int length = 0; //第一次写入的是名字 outputStream.write(name.getBytes()); //第二次写入的是数据 while ((length = inputStream.read(buff, 0, buff.length)) != -1) { outputStream.write(buff, 0, length); } inputStream.close(); } catch (Exception e) { e.printStackTrace(); } } }