将图像从Android上传到GCS

我正尝试将Android上的图片直接上传到Google云端存储空间。 但是API似乎不起作用。 他们有一些与App引擎绑定的Java样本。 我没有看到任何certificate在Android上工作的示例。

在Android上,我尝试使用json api上传图片。 我能够上传图像对象,但似乎是腐败的。 而且生成authentication令牌似乎也很棘手。

我现在对此感到震惊。 有没有人试过用Java客户端或Json API从Android上载图像/video,并成功? 请有人指出我正确的方向。 Google的这个Storage api让我感到非常失望。 请分享你的经验,如果有人这样做。 下面是我尝试使用GCS的JSON API时从Android尝试的代码。

private static String uploadFile(RichMedia media) { DefaultHttpClient client = new DefaultHttpClient(); Bitmap bitmap = BitmapUtils.getBitmap(media.getLocalUrl()); HttpPost post = new HttpPost(GCS_ROOT + media.getLocalUrl() + "_" + System.currentTimeMillis()); if(media.getType() == RichMedia.RichMediaType.PICTURE) { post.setHeader("Content-Type", "image/jpeg"); } else { post.setHeader("Content-Type", "video/mp4"); } post.setHeader("Authorization", "AIzaSyCzdmCMwiMzl6LD7R2obF0xSgnnx5rEfeI"); //post.setHeader("Content-Length", String.valueOf(bitmap.getByteCount())); ByteArrayOutputStream stream = new ByteArrayOutputStream(); bitmap.compress(Bitmap.CompressFormat.JPEG, 100, stream); byte[] byteArray = stream.toByteArray(); try { post.setEntity(new StringEntity(new Gson().toJson(byteArray).toString())); HttpResponse response = client.execute(post); BufferedReader reader = new BufferedReader(new InputStreamReader(response.getEntity().getContent())); String eachLine = null; StringBuilder builder = new StringBuilder(); while ((eachLine = reader.readLine()) != null) { builder.append(eachLine); } Ld("response = " + builder.toString()); JSONObject object = new JSONObject(builder.toString()); String name = object.getString("name"); return name; } catch (IOException e) { L.print(e); } catch (JSONException e) { L.print(e); } return null; } 

我在这里遇到两个问题。

  1. 上传到服务器的文件已损坏。 我上传的图片不一样。 这是中断的。

  2. 授权密钥经常过期。 在我的情况下,我使用由gsutil生成的身份validation代码。

由于没有人回答这个问题,让我更新我解决这个问题的方式。 我结束了这个https://github.com/pliablematter/simple-cloud-storage项目。

我可以从我的Android应用程序上传图片/video到GCS。

固定为Android:

Android Studioconfiguration:

 dependencies { compile fileTree(dir: 'libs', include: ['*.jar']) compile files('libs/android-support-v4.jar') compile files('google-play-services.jar') compile 'com.wu-man:android-oauth-client:0.0.3' compile 'com.google.apis:google-api-services-storage:v1-rev17-1.19.0' compile(group: 'com.google.api-client', name: 'google-api-client', version:'1.19.0'){ exclude(group: 'com.google.guava', module: 'guava-jdk5') } } 

AndroidManifiest:

 <uses-permission android:name="android.permission.INTERNET"></uses-permission> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"></uses-permission> 

主要实施:

  new AsyncTask(){ @Override protected Object doInBackground(Object[] params) { try { CloudStorage.uploadFile("bucket-xxx", "photo.jpg"); } catch (Exception e) { if(DEBUG)Log.d(TAG, "Exception: "+e.getMessage()); e.printStackTrace(); } return null; } }.execute(); 

CloudStorage类:

 import com.google.api.services.storage.Storage; import com.google.api.services.storage.StorageScopes; import com.google.api.services.storage.model.Bucket; import com.google.api.services.storage.model.StorageObject; public static void uploadFile(String bucketName, String filePath)throws Exception { Storage storage = getStorage(); StorageObject object = new StorageObject(); object.setBucket(bucketName); File sdcard = Environment.getExternalStorageDirectory(); File file = new File(sdcard,filePath); InputStream stream = new FileInputStream(file); try { String contentType = URLConnection.guessContentTypeFromStream(stream); InputStreamContent content = new InputStreamContent(contentType,stream); Storage.Objects.Insert insert = storage.objects().insert(bucketName, null, content); insert.setName(file.getName()); insert.execute(); } finally { stream.close(); } } private static Storage getStorage() throws Exception { if (storage == null) { HttpTransport httpTransport = new NetHttpTransport(); JsonFactory jsonFactory = new JacksonFactory(); List<String> scopes = new ArrayList<String>(); scopes.add(StorageScopes.DEVSTORAGE_FULL_CONTROL); Credential credential = new GoogleCredential.Builder() .setTransport(httpTransport) .setJsonFactory(jsonFactory) .setServiceAccountId(ACCOUNT_ID_PROPERTY) //Email .setServiceAccountPrivateKeyFromP12File(getTempPkc12File()) .setServiceAccountScopes(scopes).build(); storage = new Storage.Builder(httpTransport, jsonFactory, credential).setApplicationName(APPLICATION_NAME_PROPERTY) .build(); } return storage; } private static File getTempPkc12File() throws IOException { // xxx.p12 export from google API console InputStream pkc12Stream = AppData.getInstance().getAssets().open("xxx.p12"); File tempPkc12File = File.createTempFile("temp_pkc12_file", "p12"); OutputStream tempFileStream = new FileOutputStream(tempPkc12File); int read = 0; byte[] bytes = new byte[1024]; while ((read = pkc12Stream.read(bytes)) != -1) { tempFileStream.write(bytes, 0, read); } return tempPkc12File; } 

这段代码对我来说非常适合将Android上传的文件直接上传到GCS。

 File file = new File(Environment.getExternalStorageDirectory(), fileName); HttpClient httpclient = new DefaultHttpClient(); HttpPost httppost = new HttpPost(url); FileBody filebody = new FileBody(file,ContentType.create(mimeType), file.getName()); MultipartEntityBuilder multipartEntity = MultipartEntityBuilder.create(); multipartEntity.setMode(HttpMultipartMode.BROWSER_COMPATIBLE); multipartEntity.addPart("file", filebody); httppost.setEntity(multipartEntity.build()); System.out.println( "executing request " + httppost.getRequestLine( ) ); try { HttpResponse response = httpclient.execute( httppost ); Log.i("response", response.getStatusLine().toString()); } catch (ClientProtocolException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } httpclient.getConnectionManager( ).shutdown( ); 

MultipartEntityBuilder类不包含在android标准库中,因此您需要下载httpclient并将其包含到您的项目中。

Hpsaturn的答案为我工作。 他错过了几个答案。 如何获得服务帐户ID和P12文件。 要获取这2个,请打开console.developers.google.com并select您的项目。 启用云端存储API。 您看到一条消息来创build凭据。 转到APIpipe理器中的凭证并通过select服务帐户密钥来创build凭证,并按照图中的详细信息。 您将从此屏幕上获得服务帐户ID和p12文件。

在这里输入图像说明

Hpsaturn也错过了提到AppData,这是您在manifest中定义的自定义应用程序类。 为了大家的方便,我在这里附上完整的CloudStorage类。

 package com.abc.xyz.utils; import android.net.Uri; import android.os.Environment; import android.util.Log; import com.abc.xyz.app.AppController; import com.google.api.client.auth.oauth2.Credential; import com.google.api.client.googleapis.auth.oauth2.GoogleCredential; import com.google.api.client.http.HttpTransport; import com.google.api.client.http.InputStreamContent; import com.google.api.client.http.javanet.NetHttpTransport; import com.google.api.client.json.JsonFactory; import com.google.api.client.json.jackson2.JacksonFactory; import com.google.api.services.storage.Storage; import com.google.api.services.storage.StorageScopes; import com.google.api.services.storage.model.StorageObject; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.URLConnection; import java.util.ArrayList; import java.util.List; /** * Created by wjose on 8/20/2016. */ public class CloudStorage { private static final String TAG = "CloudStorage"; public static void uploadFile(String bucketName, String name, Uri uri)throws Exception { Storage storage = getStorage(); StorageObject object = new StorageObject(); object.setBucket(bucketName); File sdcard = Environment.getExternalStorageDirectory(); //File file = new File(sdcard,filePath); File file = new File(uri.getPath()); InputStream stream = new FileInputStream(file); try { String contentType = URLConnection.guessContentTypeFromStream(stream); InputStreamContent content = new InputStreamContent(contentType,stream); Storage.Objects.Insert insert = storage.objects().insert(bucketName, null, content); insert.setName(name); StorageObject obj = insert.execute(); Log.d(TAG, obj.getSelfLink()); } finally { stream.close(); } } static Storage storage = null; private static Storage getStorage() throws Exception { if (storage == null) { HttpTransport httpTransport = new NetHttpTransport(); JsonFactory jsonFactory = new JacksonFactory(); List<String> scopes = new ArrayList<String>(); scopes.add(StorageScopes.DEVSTORAGE_FULL_CONTROL); Credential credential = new GoogleCredential.Builder() .setTransport(httpTransport) .setJsonFactory(jsonFactory) .setServiceAccountId("myuser-801@xxxyyyzzz.iam.gserviceaccount.com") //Email .setServiceAccountPrivateKeyFromP12File(getTempPkc12File()) .setServiceAccountScopes(scopes).build(); storage = new Storage.Builder(httpTransport, jsonFactory, credential).setApplicationName("MyApp") .build(); } return storage; } private static File getTempPkc12File() throws IOException { // xxx.p12 export from google API console InputStream pkc12Stream = MyApplication.getInstance().getAssets().open("xxxyyyzzz-0c80eed2e8aa.p12"); File tempPkc12File = File.createTempFile("temp_pkc12_file", "p12"); OutputStream tempFileStream = new FileOutputStream(tempPkc12File); int read = 0; byte[] bytes = new byte[1024]; while ((read = pkc12Stream.read(bytes)) != -1) { tempFileStream.write(bytes, 0, read); } return tempPkc12File; } } 

btb,我只在gradle中使用了依赖关系。

编译“com.google.apis:google-api-services-storage:+”

我已经尝试了所有上述的答案,他们没有一个直接为我工作。 以下是我所做的工作(仅通过编辑上述评论):

 package Your page name; import android.app.Activity; import android.content.res.AssetManager; import android.os.Environment; import android.util.Log; import com.google.api.client.auth.oauth2.Credential; import com.google.api.client.googleapis.auth.oauth2.GoogleCredential; import com.google.api.client.http.HttpTransport; import com.google.api.client.http.InputStreamContent; import com.google.api.client.http.javanet.NetHttpTransport; import com.google.api.client.json.JsonFactory; import com.google.api.client.json.jackson2.JacksonFactory; import com.google.api.services.storage.Storage; import com.google.api.services.storage.StorageScopes; import com.google.api.services.storage.model.Bucket; import com.google.api.services.storage.model.StorageObject; import java.io.File; import java.io.*; import java.io.InputStream; import java.net.URLConnection; import java.util.ArrayList; import java.util.List; public class CloudStorage { static Activity activity=null; //http://stackoverflow.com/questions/18002293/uploading-image-from-android-to-gcs static Storage storage=null; public static void uploadFile(Activity activity2,String bucketName, String filePath) { activity=activity2; try { Storage storage = getStorage(); StorageObject object = new StorageObject(); object.setBucket(bucketName); File sdcard = Environment.getExternalStorageDirectory(); File file = new File(filePath); InputStream stream = new FileInputStream(file); try { Log.d("Alkamli","Test"); String contentType = URLConnection.guessContentTypeFromStream(stream); InputStreamContent content = new InputStreamContent(contentType, stream); Storage.Objects.Insert insert = storage.objects().insert(bucketName, null, content); insert.setName(file.getName()); insert.execute(); } finally { stream.close(); } }catch(Exception e) { class Local {}; Log.d("Alkamli","Sub: "+Local.class.getEnclosingMethod().getName()+" Error code: "+e.getMessage()); e.printStackTrace(); } } private static Storage getStorage() { try { if (storage == null) { HttpTransport httpTransport = new NetHttpTransport(); JsonFactory jsonFactory = new JacksonFactory(); List<String> scopes = new ArrayList<String>(); scopes.add(StorageScopes.DEVSTORAGE_FULL_CONTROL); Credential credential = new GoogleCredential.Builder() .setTransport(httpTransport) .setJsonFactory(jsonFactory) .setServiceAccountId("Service-Email-Address") //Email .setServiceAccountPrivateKeyFromP12File(getTempPkc12File()) .setServiceAccountScopes(scopes).build(); storage = new Storage.Builder(httpTransport, jsonFactory, credential) .build(); } return storage; }catch(Exception e) { class Local {}; Log.d("Alkamli","Sub: "+Local.class.getEnclosingMethod().getName()+" Error code: "+e.getMessage()); } Log.d("Alkamli","Storage object is null "); return null; } private static File getTempPkc12File() { try { // xxx.p12 export from google API console InputStream pkc12Stream = activity.getResources().getAssets().open("Service-key.p12"); File tempPkc12File = File.createTempFile("temp_pkc12_file", "p12"); OutputStream tempFileStream = new FileOutputStream(tempPkc12File); int read = 0; byte[] bytes = new byte[1024]; while ((read = pkc12Stream.read(bytes)) != -1) { tempFileStream.write(bytes, 0, read); } return tempPkc12File; }catch(Exception e) { class Local {}; Log.d("Alkamli","Sub: "+Local.class.getEnclosingMethod().getName()+" Error code: "+e.getMessage()); } Log.d("Alkamli"," getTempPkc12File is null"); return null; } } 

我只编辑了几行以使其适用于我和gradle中的依赖项。您将只需要这三个。 (请记住,如果您使用的所有谷歌依赖项,可能会损害您的整个项目。在我的情况下,一些Android的function将不再工作)

  compile 'com.google.api-client:google-api-client:1.20.0' compile 'com.google.oauth-client:google-oauth-client-jetty:1.20.0' compile 'com.google.apis:google-api-services-storage:v1-rev17-1.19.0'