Develop
Develop
Select your platform

Media View showcase - Cloud integration and design guidelines

Updated: Sep 29, 2025

Download new media onto the device using Google Drive integration

Viewing sample media is a good starting point, but providing a way for users to get their own content onto the device and into the media viewer is the actual functionality intended for this app. Google Drive is a great example of a cloud storage provider that can be integrated to help users seamlessly transfer files to their headset.
Media View’s Google Drive integration lets users personalize their VR experiences by accessing their own media collections. It’s built with security in mind, ensuring user data and privacy are protected. The integration involves these key components:

Google Drive Picker

A user-friendly, web-based interface provided by Google for selecting files from a user’s Google Drive account. It is seamlessly hosted within a WebView in Media View’s UploadActivity.kt, allowing users to browse their Drive files and select the media they want to download.

Custom JavaScript Interface

Acts as a bridge between the Android code and the JavaScript code executing within the WebView. Enables smooth communication and data exchange between the native app and the Google Drive Picker. It’s defined by two essential classes.

DriveConfigJavaScriptInterface

Provides configuration parameters to the Google Drive Picker, including API keys, client ID, and the necessary scopes for accessing Drive files. Here’s an example from DriveConfig.kt
```kotlin
data class DriveConfig(
val scopes: String, // Required scopes for Drive API access
val clientId: String, // Google Cloud Project Client ID
val apiKey: String,  // Google Cloud Project API key
val appId: String,  // Google Cloud Project App ID
)
```

DriveJavaScriptInterface

Handles events triggered by the Google Drive Picker, such as:
  • Successful user authorization
  • File download progress updates
  • Potential errors during the process. This is illustrated in the code snippet from DriveJavaScriptInterface.kt:
      class DriveJavaScriptInterface(
      private val onAuthCompleted: (token: String?) -> Unit, // Callback for successful authorization
          private val onMediaDownloaded: (media: DriveMedia) -> Unit,  // Callback for file download progress
          private val onDownloadFailed: (reason: String) -> Unit,  // Callback for download errors
      ) {
          @JavascriptInterface
          fun onAccessTokenReceived(token: String?) {
              onAuthCompleted(token)
          }
    
          @JavascriptInterface
          fun downloadFile(
              // ... file information (ID, base64 data, mime type, etc.)
          ) {
              // ... decode base64 data, create DriveMedia object, and invoke onMediaDownloaded callback
          }
    
          @JavascriptInterface
          fun onGetFileFailed(reason: String) {
              onDownloadFailed(reason)
          }
      }
    

Authorization flow

When the user opens the Upload Panel, the WebView loads the Google Drive Picker HTML page. The user is securely prompted to sign in to their Google account and grant Media View permission to access their Drive files (using OAuth 2.0). The DriveJavaScriptInterface receives the access token upon successful authorization, enabling the initiation of file downloads.

File download and storage

The user selects their desired media file(s) from the Google Drive Picker. The Picker communicates the file ID and download URL to the DriveJavaScriptInterface. The native Android code initiates a download request using the URL, receiving the file data in manageable chunks. As data chunks are received, the DriveJavaScriptInterface keeps the user informed by updating the download progress. Downloaded media is securely stored on the device using the DeviceGalleryService. The DeviceGalleryService interacts with the Android MediaStore to create a new MediaStore entry for the downloaded file, expertly handles the writing of data to the file, and sets the appropriate flags to indicate that the file is ready for viewing. This process is shown in UploadViewModel.kt:
fun onDownload(driveMedia: DriveMedia) = viewModelScope.launch {
    try {
        // Create or get a MediaStore entry for the file
        val (contentValues, uri) = galleryRepository.createMediaFile(
            driveMedia.fileName,
            driveMedia.mimeType,
            null,
            StorageType.GoogleDrive
        )

        // Write downloaded data to the file
        galleryRepository.writeMediaFile(uri!!) { fos ->
            fos.write(driveMedia.blob)
        }

        // ... Update file progress and completion status
    } catch (t: Throwable) {
        // ... Handle download errors
    }
}

Security considerations

Media View’s Google Drive integration prioritizes user privacy and data security:
  • Secure Authorization: Employs the official Google Drive API and OAuth 2.0 for secure user authentication and authorization.
  • Scoped Access: Requests only the essential scopes (read access to Drive files) to minimize the app’s permissions.
  • Token Handling: Access tokens are handled securely, avoiding storage in plain text or insecure locations.

Future enhancements

  • Support for Other Cloud Providers: Expand integration to include popular cloud storage services such as Dropbox, OneDrive, and iCloud, giving users more options.
  • Direct Upload to Google Drive: Enable users to upload media they capture within the VR environment directly to their Google Drive accounts, streamlining content creation.

Conclusion

Google Drive integration empowers Media View users to personalize their virtual reality experiences by seamlessly accessing their media collections. It’s built on a foundation of security, ensuring the protection of user data and privacy. Media View’s modular design allows for future expansion to incorporate other cloud storage providers, further enhancing the app’s flexibility and user appeal.

Design guidelines

Did you find this page helpful?
Thumbs up icon
Thumbs down icon