I need to upload a binary file bundled in an apk to a server using okhttp. Using urlconnection, you can simply get an inputstream to an asset and then put that into your request. However, okhttp only gives you the option of uploading byte arrays, strings, or files. Since you can't get a file path for an asset bundled in the apk, is the only option to copy the file to the local file directory (I'd rather not do that) and then give the file to okhttp? Is there no way to simply make a request using the assetinputstream directly to the web server?
EDIT: I used the accepted answer but instead of making a static utility class I simply subclassed RequestBody
public class InputStreamRequestBody extends RequestBody {
private InputStream inputStream;
private MediaType mediaType;
public static RequestBody create(final MediaType mediaType, final InputStream inputStream) {
return new InputStreamRequestBody(inputStream, mediaType);
}
private InputStreamRequestBody(InputStream inputStream, MediaType mediaType) {
this.inputStream = inputStream;
this.mediaType = mediaType;
}
@Override
public MediaType contentType() {
return mediaType;
}
@Override
public long contentLength() {
try {
return inputStream.available();
} catch (IOException e) {
return 0;
}
}
@Override
public void writeTo(BufferedSink sink) throws IOException {
Source source = null;
try {
source = Okio.source(inputStream);
sink.writeAll(source);
} finally {
Util.closeQuietly(source);
}
}
}
My only concern with this approach is the unreliability of inputstream.available() for content-length. The static constructor is to match okhttp's internal implementation
See Question&Answers more detail:
os 与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…