我尝试从Android Studio上传图像/视频,这在所有其他Android版本中运行良好,但面临与牛轧糖的问题。
任何人都可以帮助我做到这一点。
包com.ethosapp.ethos.jobs;
import android.app.Notification;
import android.app.NotificationManager;
import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Matrix;
import android.graphics.RectF;
import android.media.RingtoneManager;
import android.net.Uri;
import android.os.Build;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v7.app.NotificationCompat;
import android.util.Log;
import com.amazonaws.mobileconnectors.s3.transferutility.TransferListener;
import com.amazonaws.mobileconnectors.s3.transferutility.TransferObserver;
import com.amazonaws.mobileconnectors.s3.transferutility.TransferState;
import com.amazonaws.services.s3.model.CannedAccessControlList;
import com.birbit.android.jobqueue.Job;
import com.birbit.android.jobqueue.Params;
import com.birbit.android.jobqueue.RetryConstraint;
import com.ethosapp.ethos.EthosApplication;
import com.ethosapp.ethos.R;
import com.ethosapp.ethos.models.Entry;
import com.ethosapp.ethos.models.PostEntry;
import com.ethosapp.ethos.services.AmazonSyncService;
import com.ethosapp.ethos.services.ApiServiceFactory;
import com.ethosapp.ethos.services.EntryService;
import org.apache.commons.io.FilenameUtils;
import org.apache.commons.io.IOUtils;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import retrofit2.Call;
/**
* Created by jaya on 25/05/16.
*/
public class UploadFileToS3Job extends Job {
public static final int PRIORITY = 1;
protected String filename;
protected String uri;
protected String extension;
protected String fileId;
protected String entryId;
protected long type;
protected String state;
public UploadFileToS3Job(String filename, String uri, String extension, String fileId, String entryId, long type) {
super(new Params(PRIORITY).requireNetwork().persist());
this.filename = filename;
this.uri = uri;
this.extension = extension;
this.fileId = fileId;
this.type = type;
this.entryId = entryId;
try {
Uri fileUri = Uri.parse(uri);
File f = new File(fileUri.getPath());
JSONObject props = new JSONObject();
props.put("entryId", this.entryId);
props.put("fileId", this.fileId);
props.put("extension", this.extension);
props.put("fileSize", f.length());
EthosApplication.mixPanelTrack("BeginUploadFile", props);
} catch (JSONException jsonException) {
Log.e("MYAPP", "Unable to add properties to JSONObject", jsonException);
}
}
public UploadFileToS3Job(String filename) {
super(new Params(PRIORITY).requireNetwork().persist());
Log.e("tag", "fileNAAM" + filename);
this.filename = filename;
}
@Override
public void onAdded() {
}
@Override
public void onRun() throws Throwable {
switch ((int) this.type) {
case Entry.Type.IMAGE:
uploadImageFiles();
break;
case Entry.Type.AUDIO:
uploadVideoAudioFiles();
break;
case Entry.Type.VIDEO:
uploadVideoAudioFiles();
break;
}
}
@Override
protected void onCancel(int cancelReason) {
}
@Override
protected RetryConstraint shouldReRunOnThrowable(Throwable throwable, int runCount, int maxRunCount) {
return null;
}
@Nullable
private File saveFileToTempFolder(Uri uri, String name, String extension) throws Throwable {
InputStream inputStream = EthosApplication.getInstance().getContentResolver().openInputStream(uri);
File outputDir = EthosApplication.getInstance().getBaseContext().getCacheDir(); // context being the Activity pointer
File tempFile = File.createTempFile(name, extension, outputDir);
FileOutputStream out = new FileOutputStream(tempFile);
IOUtils.copy(inputStream, out);
inputStream.close();
out.close();
return tempFile;
}
private void uploadVideoAudioFiles() throws Throwable {
Uri fileUri = Uri.parse(uri);
File file = new File(fileUri.getPath());
Log.e("FFFFFFFFF====","=="+"content://com.ethosapp.ethos.provider/external_files/EthOS/EthOS%20movies/"+filename);
if (file.exists()) {
String parent = fileId + "/";
uploadFileToS3(parent + filename, file, CannedAccessControlList.PublicRead);
// Now schedule a media-transcode
// Update the Entry
PostEntry postEntry = new PostEntry();
postEntry.setFileId(fileId);
EntryService service = ApiServiceFactory.createRetrofitService(EntryService.class, ApiServiceFactory.API_BASE_URL);
Call<Entry> entryCall = service.scheduleMediaTranscode(this.entryId, postEntry);
Entry entry = entryCall.execute().body();
PostEntry postEntry1 = new PostEntry();
postEntry.setType("0");
Call<Entry> entryCall1 = service.updateEntry(this.entryId, postEntry1);
Entry entry1 = entryCall1.execute().body();
// TODO: Some Validation to verify the entry is uploaded successfully
Intent intent = new Intent();
intent.setAction("com.ethosapp.ethos.CUSTOM_INTENT");
EthosApplication.getInstance().getBaseContext().sendBroadcast(intent);
} else {
// TODO : Error Handling
}
}
@NonNull
private void uploadImageFiles() throws Throwable {
Log.e("tag", "images" + uri);
Uri fileUri = Uri.parse(uri);
Log.e("tag", "<----fileUri---->" + uri);
String fileNameWithOutExt = FilenameUtils.removeExtension(filename);
String fileExtension = FilenameUtils.getExtension(filename);
String parent = fileId + "/";
// Upload preview image
// name : name-preview.jpg (230x0)
// Dimensions: 230 x 0
// Quality: 70
String previewImageFilename = fileNameWithOutExt + "-preview" + "." + fileExtension;
File previewImage = resizeImage(fileUri, 230, 230, previewImageFilename, 70);
uploadFileToS3(parent + previewImageFilename, previewImage, CannedAccessControlList.PublicRead);
previewImage.delete();
// Upload resized image
// name : name-resized.jpg (230x0)
// Dimensions: 1024 x 768
// Quality: 70
String resizedImageFilename = fileNameWithOutExt + "-resized" + "." + fileExtension;
File resizedImage = resizeImage(fileUri, 1024, 768, resizedImageFilename, 70);
uploadFileToS3(parent + resizedImageFilename, resizedImage, CannedAccessControlList.PublicRead);
resizedImage.delete();
// Upload resized image
// name : name-resized.jpg (230x0)
// Dimensions: 480 x 800
// Quality: 60
String resized1XImageFilename = fileNameWithOutExt + "-resized-1x" + "." + fileExtension;
File resized1XImage = resizeImage(fileUri, 480, 800, resized1XImageFilename, 60);
uploadFileToS3(parent + resizedImageFilename, resized1XImage, CannedAccessControlList.PublicRead);
resized1XImage.delete();
// Upload resized image
// name : name-resized.jpg (230x0)
// Dimensions: 1024 x 768
// Quality: 60
String resized2XImageFilename = fileNameWithOutExt + "-resized-2x" + "." + fileExtension;
File resized2XImage = resizeImage(fileUri, 1024, 768, resized2XImageFilename, 60);
uploadFileToS3(parent + resizedImageFilename, resized2XImage, CannedAccessControlList.PublicRead);
resized2XImage.delete();
// Upload thumbnail image
// name : name-tn.jpg (230x0)
// Dimensions: 80 x 80
// Quality: 70
String thumbnailImageFilename = fileNameWithOutExt + "-tn" + "." + fileExtension;
File thumbnailImage = resizeImage(fileUri, 80, 80, thumbnailImageFilename, 70);
uploadFileToS3(parent + thumbnailImageFilename, thumbnailImage, CannedAccessControlList.PublicRead);
thumbnailImage.delete();
//File image = saveFileToTempFolder(fileUri, filename, extension);
File image = new File(fileUri.getPath());
uploadFileToS3(parent + filename, image, CannedAccessControlList.Private);
// Update the Entry
PostEntry postEntry = new PostEntry();
postEntry.setType("0");
EntryService service = ApiServiceFactory.createRetrofitService(EntryService.class, ApiServiceFactory.API_BASE_URL);
Call<Entry> entryCall = service.updateEntry(this.entryId, postEntry);
Entry entry = entryCall.execute().body();
int id=1;
Context baseContext = EthosApplication.getInstance().getBaseContext();
// // intent triggered, you can add other intent for other actions
// Intent intent = new Intent(baseContext, ProjectEntriesActivity.class);
// PendingIntent pIntent = PendingIntent.getActivity(baseContext, 0, intent, 0);
NotificationManager mNotifyManager =
(NotificationManager) baseContext.getSystemService(Context.NOTIFICATION_SERVICE);
NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(baseContext);
mBuilder.setContentTitle("Entry Uploaded")
.setContentText("Entry has uploaded successfully.")
.setSmallIcon(R.drawable.ic_logo)
.setPriority(Notification.PRIORITY_HIGH);
Uri alarmSound = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
mBuilder.setSound(alarmSound);
mNotifyManager.notify(id, mBuilder.build());
//Log.e("tag","1111");
// TODO: Some Validation to verify the entry is uploaded successfully
//Intent intent = new Intent();
//intent.setAction("com.ethosapp.ethos.CUSTOM_INTENT");
//EthosApplication.getInstance().getBaseContext().sendBroadcast(intent);
}
private void uploadFileToS3(String filename, File file, CannedAccessControlList acl) throws Throwable {
Log.e("FILE=======","=="+file);
Log.e("FILE=======","=="+filename);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N)
{
String ff="content://com.ethosapp.ethos.provider/external_files/EthOS/EthOS%20Pictures/"+filename;
Log.e("FFFF==","=="+ff);
}
String ff="content://com.ethosapp.ethos.provider/external_files/EthOS/EthOS%20Pictures/"+filename;
Log.e("FFFF==","=="+ff);
Log.e("1111","===================");
AmazonSyncService syncService = new AmazonSyncService(EthosApplication.getInstance().getBaseContext());
TransferObserver transferObserver = syncService.startUpload(filename, file, acl);
transferObserverListener(transferObserver);
// Code to make the thread to wait for upload completion.
// Entire code will be running in a background thread, so there is no
// issue in waiting for it to complete.
while (true) {
if (TransferState.COMPLETED.equals(transferObserver.getState())
|| TransferState.FAILED.equals(transferObserver.getState())) {
break;
}
}
if (TransferState.FAILED.equals(transferObserver.getState())) {
throw new Exception("Upload File to S3 failed.");
}
}
private void transferObserverListener(TransferObserver transferObserver) {
transferObserver.setTransferListener(new TransferListener() {
@Override
public void onStateChanged(int id, TransferState state) {
Log.e("statechange", state + "");
try {
Uri fileUri = Uri.parse(uri);
File f = new File(fileUri.getPath());
JSONObject props = new JSONObject();
props.put("entryId", entryId);
props.put("fileId", fileId);
props.put("extension", extension);
props.put("fileSize", f.length());
EthosApplication.mixPanelTrack("UploadedFile", props);
} catch (JSONException jsonException) {
Log.e("MYAPP", "Unable to add properties to JSONObject", jsonException);
}
}
@Override
public void onProgressChanged(int id, long bytesCurrent, long bytesTotal) {
int percentage = (int) (bytesCurrent / bytesTotal * 100);
Log.e("percentage", percentage + "");
if(type == Entry.Type.VIDEO){
try {
Uri fileUri = Uri.parse(uri);
File f = new File(fileUri.getPath());
JSONObject props = new JSONObject();
props.put("entryId", entryId);
props.put("fileId", fileId);
props.put("extension", extension);
props.put("fileSize", f.length());
props.put("percentage", percentage);
EthosApplication.mixPanelTrack("UploadingFile", props);
} catch (JSONException jsonException) {
Log.e("MYAPP", "Unable to add properties to JSONObject", jsonException);
}
}
}
@Override
public void onError(int id, Exception ex) {
Log.e("error", "error");
}
});
}
private File resizeImage(Uri fileUri, int width, int height, String resizedFilename, int quality) throws Throwable {
int inWidth = 0;
int inHeight = 0;
InputStream inputStream = EthosApplication.getInstance().getContentResolver().openInputStream(fileUri);
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
Bitmap bitmapOrg = BitmapFactory.decodeStream(inputStream, null, options);
inputStream.close();
// save width and height
inWidth = options.outWidth;
inHeight = options.outHeight;
inputStream = EthosApplication.getInstance().getContentResolver().openInputStream(fileUri);
options = new BitmapFactory.Options();
// calc rough re-size (this is no exact resize)
options.inSampleSize = Math.max(inWidth / width, inHeight / height);
// decode full image
Bitmap roughBitmap = BitmapFactory.decodeStream(inputStream, null, options);
// calc exact destination size
Matrix m = new Matrix();
RectF inRect = new RectF(0, 0, roughBitmap.getWidth(), roughBitmap.getHeight());
RectF outRect = new RectF(0, 0, width, height);
m.setRectToRect(inRect, outRect, Matrix.ScaleToFit.CENTER);
float[] values = new float[9];
m.getValues(values);
// resize bitmap
Bitmap resizedBitmap = Bitmap.createScaledBitmap(roughBitmap, (int) (roughBitmap.getWidth() * values[0]), (int) (roughBitmap.getHeight() * values[4]), true);
File outputDir = EthosApplication.getInstance().getBaseContext().getCacheDir(); // context being the Activity pointer
File tempFile = File.createTempFile(resizedFilename, "jpg", outputDir);
Log.e("outputDir=====","=="+outputDir);
Log.e("tempFile=====","=="+tempFile);
FileOutputStream out = new FileOutputStream(tempFile);
resizedBitmap.compress(Bitmap.CompressFormat.JPEG, quality, out);
return tempFile;
}
}
public class AmazonSyncService {
// Initialize the Amazon Cognito credentials provider
public static CognitoCachingCredentialsProvider credentialsProvider;
// Create an S3 client
private AmazonS3 s3;
private TransferUtility transferUtility;
private Context context;
private final String MY_APP_BUCKET = "ethosappcom-production-media";
private final String MY_APP_BUCKET_PROFILE = "ethosappcom-production-user";
public AmazonSyncService(Context context){
this.context = context;
credentialsProvider = new CognitoCachingCredentialsProvider(
this.context.getApplicationContext(),
"us-east-1:e1922be7-9b7a-421e-bf3f-ae41b0a61315", // Identity Pool ID
Regions.US_EAST_1 // Region
);
s3 = new AmazonS3Client(credentialsProvider);
s3.setRegion(Region.getRegion(Regions.US_EAST_1));
transferUtility = new TransferUtility(s3, this.context.getApplicationContext());
}
public CognitoCachingCredentialsProvider getCredentialProvider(){
return credentialsProvider;
}
public TransferObserver startUpload(String filename, File file, CannedAccessControlList acl){
return transferUtility.upload(MY_APP_BUCKET, filename, file, acl);
}
}
答案 0 :(得分:2)
问题在于这一行(无论何处写)
Uri fileUri = Uri.parse(uri);
此行为在Android Nougat中已更改。与牛轧糖达到同样的效果
请关注this thread作为参考。当您将targetSDK设置为24并更改以下内容时,它将向您展示如何使用文件提供程序。在private static Uri getImageFileUri()
方法
更改此行
Uri fileUri = Uri.parse(uri);
到
Uri fileUri = FileProvider.getUriForFile(context, context.getApplicationContext().getPackageName() + ".provider", createImageFile());
希望这可以帮助您解决问题。
更多信息,请访问 -
Setting Up File Sharing - Offical documentation