0%

[Android] Retrofit應用 - Google Photos API

以Google Photos API的uploads為例。用Jetpack新提供的相片挑選工具,取得要上送的照片URI後,轉換成InputStream上送至服務。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
public interface PhotoAPI {
@Headers({
"Content-type: application/octet-stream",
"X-Goog-Upload-Protocol: raw"
})
@POST("uploads")
Call<ResponseBody> uploadMediaItem(@Header("X-Goog-Upload-Content-Type") String mimeType, @Body RequestBody file);
}

public class MainActivity extends AppCompatActivity {
private ActivityResultLauncher<PickVisualMediaRequest> pickMultipleMedia =
registerForActivityResult(new ActivityResultContracts.PickMultipleVisualMedia(50), uris -> {
if (uris.isEmpty()) {
Log.d("Mike", "No media selected");
return;
}
Log.d("Mike", "Number of items selected: " + uris.size());
for (Uri uri : uris) {
ContentResolver contentResolver = getContentResolver();
try (Cursor cursor = contentResolver.query(uri, null, null, null, null)) {
if (cursor.moveToFirst()) {
String displayName = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.MediaColumns.DISPLAY_NAME));
uploadMediaItem(displayName, contentResolver.getType(uri), contentResolver.openInputStream(uri));
}
} catch (Exception e) {
Log.e("Mike", e.getMessage(), e);
}
}
});

public void onUploadClick() {
pickMultipleMedia.launch(new PickVisualMediaRequest.Builder()
.setMediaType(ActivityResultContracts.PickVisualMedia.ImageAndVideo.INSTANCE)
.build());
}

public void uploadMediaItem(String fileName, String mimeType, InputStream in) {
OkHttpClient.Builder httpBuilder = new OkHttpClient.Builder()
.addInterceptor(new TokenInterceptor());
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("https://photoslibrary.googleapis.com/v1/")
.client(httpBuilder.build())
.addConverterFactory(GsonConverterFactory.create())
.build();

RequestBody body = new RequestBody() {
@Nullable
@Override
public MediaType contentType() {
return MediaType.parse(mimeType);
}

@Override
public void writeTo(BufferedSink sink) throws IOException {
try (Source source = Okio.source(in)) {
sink.writeAll(source);
}
}
};

retrofit.create(PhotoAPI.class).uploadMediaItem(mimeType, body)
.enqueue(new Callback<ResponseBody>() {
@Override
public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {

}

@Override
public void onFailure(Call<ResponseBody> call, Throwable t) {

}
});
}
}

參考資料

  1. https://developers.google.com/photos/library/guides/upload-media?hl=en#uploading-bytes
  2. https://developer.android.com/training/data-storage/shared/photopicker?hl=zh-tw