我正在尝试从应用程序上传图像和视频到我的外部服务器。我用Google搜索并发现HttpClient程序很好,所以我下载了库并执行以下代码,这些代码通常适用于每个文件,但对于某些视频,它不会上传视频。
public void executeMultipartPost(String uri) throws Exception {
try {
File file = new File(uri);
Uri imageUri = Uri.fromFile(file);
ByteArrayOutputStream bos = new ByteArrayOutputStream();
byte[] data = readBytes(imageUri);
HttpClient httpClient = new DefaultHttpClient();
HttpPost postRequest = new HttpPost(
"http://example.com/ccs-business/upload.php");
ByteArrayBody bab = new ByteArrayBody(data, file.getName());
MultipartEntity reqEntity = new MultipartEntity(HttpMultipartMode.BROWSER_COMPATIBLE);
reqEntity.addPart("uploaded_video", bab);
reqEntity.addPart("number", new StringBody("123456"));
postRequest.setEntity(reqEntity);
HttpResponse response = httpClient.execute(postRequest);
BufferedReader reader = new BufferedReader(new InputStreamReader(
response.getEntity().getContent(), "UTF-8"));
String sResponse;
StringBuilder s = new StringBuilder();
while ((sResponse = reader.readLine()) != null) {
s = s.append(sResponse);
}
Log.v("ONMESSAGE", "Response: " + s);
dialog.dismiss();
} catch (Exception e) {
// handle exception here
Log.e(e.getClass().getName(), e.getMessage());
dialog.dismiss();
}
}
public byte[] readBytes(Uri uri) throws IOException {
InputStream inputStream = getContentResolver().openInputStream(uri);
ByteArrayOutputStream byteBuffer = new ByteArrayOutputStream();
int bufferSize = 1024;
byte[] buffer = new byte[bufferSize];
int len = 0;
while ((len = inputStream.read(buffer)) != -1) {
byteBuffer.write(buffer, 0, len);
}
return byteBuffer.toByteArray();
}
我的要求是上传最多20mb的文件。
我已经厌倦了使用以下代码附加上传文件并且工作正常:
public class UploadService extends IntentService {
/**
* Utility method that creates the intent that starts the background
* file upload service.
*
* @param task object containing the upload request
* @throws IllegalArgumentException if one or more arguments passed are invalid
* @throws MalformedURLException if the server URL is not valid
*/
public static void startUpload(final UploadRequest task)
throws IllegalArgumentException, MalformedURLException {
if (task == null) {
throw new IllegalArgumentException("Can't pass an empty task!");
} else {
task.validate();
final Intent intent = new Intent(UploadService.class.getName());
intent.setAction(ACTION_UPLOAD);
intent.putExtra(PARAM_NOTIFICATION_CONFIG, task.getNotificationConfig());
intent.putExtra(PARAM_ID, task.getUploadId());
intent.putExtra(PARAM_URL, task.getServerUrl());
intent.putExtra(PARAM_METHOD, task.getMethod());
intent.putParcelableArrayListExtra(PARAM_FILES, task.getFilesToUpload());
intent.putParcelableArrayListExtra(PARAM_REQUEST_HEADERS, task.getHeaders());
intent.putParcelableArrayListExtra(PARAM_REQUEST_PARAMETERS, task.getParameters());
task.getContext().startService(intent);
}
}
public UploadService() {
super(SERVICE_NAME);
}
@Override
public void onCreate() {
super.onCreate();
notificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
notification = new NotificationCompat.Builder(this);
PowerManager pm = (PowerManager) getSystemService(POWER_SERVICE);
wakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, TAG);
}
@Override
protected void onHandleIntent(Intent intent) {
if (intent != null) {
final String action = intent.getAction();
if (ACTION_UPLOAD.equals(action)) {
notificationConfig = intent.getParcelableExtra(PARAM_NOTIFICATION_CONFIG);
final String uploadId = intent.getStringExtra(PARAM_ID);
final String url = intent.getStringExtra(PARAM_URL);
final String method = intent.getStringExtra(PARAM_METHOD);
final ArrayList<FileToUpload> files = intent.getParcelableArrayListExtra(PARAM_FILES);
final ArrayList<NameValue> headers = intent.getParcelableArrayListExtra(PARAM_REQUEST_HEADERS);
final ArrayList<NameValue> parameters = intent.getParcelableArrayListExtra(PARAM_REQUEST_PARAMETERS);
lastPublishedProgress = 0;
wakeLock.acquire();
try {
createNotification();
handleFileUpload(uploadId, url, method, files, headers, parameters);
} catch (Exception exception) {
broadcastError(uploadId, exception);
} finally {
wakeLock.release();
}
}
}
}
private void handleFileUpload(final String uploadId,
final String url,
final String method,
final ArrayList<FileToUpload> filesToUpload,
final ArrayList<NameValue> requestHeaders,
final ArrayList<NameValue> requestParameters)
throws IOException {
final String boundary = getBoundary();
final byte[] boundaryBytes = getBoundaryBytes(boundary);
HttpURLConnection conn = null;
OutputStream requestStream = null;
try {
conn = getMultipartHttpURLConnection(url, method, boundary);
setRequestHeaders(conn, requestHeaders);
requestStream = conn.getOutputStream();
setRequestParameters(requestStream, requestParameters, boundaryBytes);
uploadFiles(uploadId, requestStream, filesToUpload, boundaryBytes);
final byte[] trailer = getTrailerBytes(boundary);
requestStream.write(trailer, 0, trailer.length);
final int serverResponseCode = conn.getResponseCode();
final String serverResponseMessage = conn.getResponseMessage();
broadcastCompleted(uploadId, serverResponseCode, serverResponseMessage);
} finally {
closeOutputStream(requestStream);
closeConnection(conn);
}
}
private String getBoundary() {
final StringBuilder builder = new StringBuilder();
builder.append("---------------------------")
.append(System.currentTimeMillis());
return builder.toString();
}
private byte[] getBoundaryBytes(final String boundary)
throws UnsupportedEncodingException {
final StringBuilder builder = new StringBuilder();
builder.append(NEW_LINE)
.append(TWO_HYPHENS)
.append(boundary)
.append(NEW_LINE);
return builder.toString().getBytes("US-ASCII");
}
private byte[] getTrailerBytes(final String boundary)
throws UnsupportedEncodingException {
final StringBuilder builder = new StringBuilder();
builder.append(NEW_LINE)
.append(TWO_HYPHENS)
.append(boundary)
.append(TWO_HYPHENS)
.append(NEW_LINE);
return builder.toString().getBytes("US-ASCII");
}
private HttpURLConnection getMultipartHttpURLConnection(final String url,
final String method,
final String boundary)
throws IOException {
final HttpURLConnection conn = (HttpURLConnection) new URL(url).openConnection();
conn.setDoInput(true);
conn.setDoOutput(true);
conn.setUseCaches(false);
conn.setChunkedStreamingMode(0);
conn.setRequestMethod(method);
conn.setRequestProperty("Connection", "Keep-Alive");
conn.setRequestProperty("ENCTYPE", "multipart/form-data");
conn.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + boundary);
return conn;
}
private void setRequestHeaders(final HttpURLConnection conn,
final ArrayList<NameValue> requestHeaders) {
if (!requestHeaders.isEmpty()) {
for (final NameValue param : requestHeaders) {
conn.setRequestProperty(param.getName(), param.getValue());
}
}
}
private void setRequestParameters(final OutputStream requestStream,
final ArrayList<NameValue> requestParameters,
final byte[] boundaryBytes)
throws IOException, UnsupportedEncodingException {
if (!requestParameters.isEmpty()) {
for (final NameValue parameter : requestParameters) {
requestStream.write(boundaryBytes, 0, boundaryBytes.length);
byte[] formItemBytes = parameter.getBytes();
requestStream.write(formItemBytes, 0, formItemBytes.length);
}
}
}
private void uploadFiles(final String uploadId,
final OutputStream requestStream,
final ArrayList<FileToUpload> filesToUpload,
final byte[] boundaryBytes)
throws UnsupportedEncodingException,
IOException,
FileNotFoundException {
final long totalBytes = getTotalBytes(filesToUpload);
long uploadedBytes = 0;
for (FileToUpload file : filesToUpload) {
requestStream.write(boundaryBytes, 0, boundaryBytes.length);
byte[] headerBytes = file.getMultipartHeader();
requestStream.write(headerBytes, 0, headerBytes.length);
final InputStream stream = file.getStream();
byte[] buffer = new byte[BUFFER_SIZE];
long bytesRead;
try {
while ((bytesRead = stream.read(buffer, 0, buffer.length)) > 0) {
requestStream.write(buffer, 0, buffer.length);
uploadedBytes += bytesRead;
broadcastProgress(uploadId, uploadedBytes, totalBytes);
}
} finally {
closeInputStream(stream);
}
}
}
private long getTotalBytes(final ArrayList<FileToUpload> filesToUpload) {
long total = 0;
for (FileToUpload file : filesToUpload) {
total += file.length();
}
return total;
}
private void closeInputStream(final InputStream stream) {
if (stream != null) {
try {
stream.close();
} catch (Exception exc) { }
}
}
private void closeOutputStream(final OutputStream stream) {
if (stream != null) {
try {
stream.flush();
stream.close();
} catch (Exception exc) { }
}
}
private void closeConnection(final HttpURLConnection connection) {
if (connection != null) {
try {
connection.disconnect();
} catch (Exception exc) { }
}
}
private void broadcastProgress(final String uploadId, final long uploadedBytes, final long totalBytes) {
final int progress = (int) (uploadedBytes * 100 / totalBytes);
if (progress <= lastPublishedProgress) return;
lastPublishedProgress = progress;
updateNotificationProgress(progress);
final Intent intent = new Intent(BROADCAST_ACTION);
intent.putExtra(UPLOAD_ID, uploadId);
intent.putExtra(STATUS, STATUS_IN_PROGRESS);
intent.putExtra(PROGRESS, progress);
sendBroadcast(intent);
}
private void broadcastCompleted(final String uploadId, final int responseCode, final String responseMessage) {
final String filteredMessage;
if (responseMessage == null) {
filteredMessage = "";
} else {
filteredMessage = responseMessage;
}
if (responseCode >= 200 && responseCode <= 299)
updateNotificationCompleted();
else
updateNotificationError();
final Intent intent = new Intent(BROADCAST_ACTION);
intent.putExtra(UPLOAD_ID, uploadId);
intent.putExtra(STATUS, STATUS_COMPLETED);
intent.putExtra(SERVER_RESPONSE_CODE, responseCode);
intent.putExtra(SERVER_RESPONSE_MESSAGE, filteredMessage);
sendBroadcast(intent);
}
private void broadcastError(final String uploadId, final Exception exception) {
updateNotificationError();
final Intent intent = new Intent(BROADCAST_ACTION);
intent.setAction(BROADCAST_ACTION);
intent.putExtra(UPLOAD_ID, uploadId);
intent.putExtra(STATUS, STATUS_ERROR);
intent.putExtra(ERROR_EXCEPTION, exception);
sendBroadcast(intent);
}
private void createNotification() {
notification.setContentTitle(notificationConfig.getTitle())
.setContentText(notificationConfig.getMessage())
.setSmallIcon(notificationConfig.getIconResourceID())
.setProgress(100, 0, true)
.setOngoing(true);
startForeground(UPLOAD_NOTIFICATION_ID, notification.build());
}
private void updateNotificationProgress(final int progress) {
notification.setContentTitle(notificationConfig.getTitle())
.setContentText(notificationConfig.getMessage())
.setSmallIcon(notificationConfig.getIconResourceID())
.setProgress(100, progress, false)
.setOngoing(true);
startForeground(UPLOAD_NOTIFICATION_ID, notification.build());
}
private void updateNotificationCompleted() {
stopForeground(notificationConfig.isAutoClearOnSuccess());
if (!notificationConfig.isAutoClearOnSuccess()) {
notification.setContentTitle(notificationConfig.getTitle())
.setContentText(notificationConfig.getCompleted())
.setSmallIcon(notificationConfig.getIconResourceID())
.setProgress(0, 0, false)
.setOngoing(false);
notificationManager.notify(UPLOAD_NOTIFICATION_ID_DONE, notification.build());
}
}
private void updateNotificationError() {
stopForeground(false);
notification.setContentTitle(notificationConfig.getTitle())
.setContentText(notificationConfig.getError())
.setSmallIcon(notificationConfig.getIconResourceID())
.setProgress(0, 0, false)
.setOngoing(false);
notificationManager.notify(UPLOAD_NOTIFICATION_ID_DONE, notification.build());
}
}
有关完整的源代码,请参阅qazxsw poi