Ng File Upload to Upload Photo From Camera and Not Gallery in Chrome Mobile Device Type

1. Introduction

What you will build

In this codelab, you'll build a field trip app, Field Trippa, that enables users to share photos.

Learn how to use the Google Photos Library API to dorsum a media sharing experience in your own application.

The app for this codelab was built using Flutter, Google's UI toolkit for building beautiful, natively compiled applications for mobile, web, and desktop from a single codebase. Learn more at https://flutter.dev.

e66d61f546945f12.png

What you'll learn

  • How to utilize the Google Photos Library API to upload media and share albums
  • How to apply Google Sign-In in Flutter
  • How to brand Google API calls from Palpitate

What you'll need

  • Flutter development environment
  • Two Google user accounts set up on different emulators or devices that have admission to Google Photos, and then you can test sharing between users
  • An Android device, emulator or concrete iOS device - the iOS simulator is not supported due to missing camera hardware

In this codelab you lot will build an app to share photos for an excursion or field trip, built using the Google Photos Library API.

The user logs in using Google Sign-In and authorizes the application to use the Google Photos Library API.

Then, the user can create a trip for uploading photos with a clarification. Each trip can be shared with other members of the application, who tin can also contribute photos.

146953eced1f4f92.png

Under the hood, each trip is stored as a shared album inside Google Photos. The app handles sharing and uploading to this album, but you can also share the anthology with others who practise not accept the app direct through a URL to Google Photos.

2f043957ae32c9d7.png

What would you similar to learn from this codelab?

I'thousand new to the topic, and I want a good overview. I know something about this topic, merely I want a refresher. I'chiliad looking for instance code to utilize in my project. I'g looking for an explanation of something specific.

2. Download the Lawmaking

b2f84ff91b0e1396.pngDownload the source lawmaking for this codelab:

To clone the GitHub repository from the command line, use the following command:

git clone https://github.com/flutter/codelabs flutter-codelabs          

The sample lawmaking is cloned into a flutter-codelabs directory that contains the lawmaking for a collection of codelabs. The lawmaking for this codelab is in palpitate-codelabs/photos-sharing. You can also browse the code on GitHub.

The directory structure under flutter-codelabs/photos-sharing contains the initial and the final steps. The starter lawmaking is in initial, so locating the matching files is as easy equally:

cd flutter-codelabs/photos-sharing/initial          

If you want to skip forrad, or see what something should look similar after a step, look in the final directory that contains the finished code for this codelab.

b2f84ff91b0e1396.pngOpen up the initial code:

Open the directory flutter-codelabs/photos-sharing/initial in your preferred Flutter IDE, for example VSCode or Android Studio with the Dart and Flutter plugins installed.

iii. Run the App

Follow these steps to go your evolution surroundings fix upward, if you haven't developed with Flutter before.

To run the "Field Trippa" app click the "run" button in your evolution IDE, or use the post-obit command from the root directory of the source code:

flutter run          

You lot should see the "Connect with Google Photos" screen:

6bfc7e3fab746b8d.png

four. Set up the Google Photos Library API

The Google Photos Library API requires y'all to cosign your users using OAuth 2.0. Users sign into the application and authorize it to interact with the API on their behalf.

You can notice some additional troubleshooting tips at the cease of this step.

Create a new Firebase project and annals your app

b2f84ff91b0e1396.png Go to the Firebase console and select "+ Add Project". Enter a project name and select "Create Project" to continue. Do not follow any other steps in the Firebase console. Instead, return to this codelab and keep to the "Android" or "iOS" parts below to configure the application.

Android only: If you lot are running the app on Android, annals an Android app:

b2f84ff91b0e1396.png Click the Android icon to open up the Android app registration screen.

b2f84ff91b0e1396.png For package, enter: com.google.codelab.photos.sharing

b2f84ff91b0e1396.png Retrieve the signing certificate SHA-1 from your car:

On Windows run the following command:

keytool -alias androiddebugkey -keystore %USERPROFILE%\.android\debug.keystore -list -5 -storepass android          

On Mac or Linux, run the following command:

keytool -alias androiddebugkey -keystore ~/.android/debug.keystore -list -v -storepass android          

b2f84ff91b0e1396.png Click "annals app" to continue.

b2f84ff91b0e1396.png Download the google-service.json file to your computer and motility it into the directory "android/app/". (Tip: In Android Studio, you tin elevate the downloaded file straight into the correct location in the project side panel.)

This file contains the project configuration for the Firebase and Google Developers project you have just set upwardly.

(See the documentation for the package google_sign_in for details.)

Yous don't have to complete whatever other steps in the Firebase console. The Firebase SDK has already been added to the application.

iOS just: If you are running the app on iOS, register an iOS app in Firebase:

b2f84ff91b0e1396.png Click the iOS icon to open up the iOS app registration screen.

b2f84ff91b0e1396.png For iOS package ID, enter: com.google.codelab.photos.sharing

b2f84ff91b0e1396.png Click "adjacent" to continue.

b2f84ff91b0e1396.png Download the GoogleService-Info.plist file to your estimator.

b2f84ff91b0e1396.png Open the Flutter projection in Xcode

b2f84ff91b0e1396.png Right click on Runner directory, select "Add Files to Runner" and select the GoogleService-Info.plist file you lot have downloaded to add it to the Runner module.

b2f84ff91b0e1396.png Edit the source code of the file ios/Runner/Info.plist and add the value of the holding REVERSED_CLIENT_ID from the file GoogleService-Info.plist. Replace the entry at the lesser of the file:

ios/Runner/Info.plist

            <!-- Google Sign-in Section --> <fundamental>CFBundleURLTypes</key> <array>   <dict>     <primal>CFBundleTypeRole</key>     <string>Editor</string>     <key>CFBundleURLSchemes</key>     <assortment>       <string>COPY_REVERSED_CLIENT_ID_HERE</cord>     </array>   </dict> </array> <!-- Stop of the Google Sign-in Section -->                      

(See the documentation for the package google_sign_in for more details.)

Enable the Google Photos Library API

b2f84ff91b0e1396.png Open the API screen in the Google Developers console and enable the "Google Photos Library API". (You lot may accept to select the Firebase project at the elevation of the screen showtime if the "enable" button is disabled.)

b2f84ff91b0e1396.png Open the OAuth consent screen configuration in the Google Developers console to add the Google Photos Library API scopes and your electronic mail address. (This configuration is required for the OAuth verification review for any scopes used by the Google Photos Library API.) You exercise non take to submit for verification, simply you need to complete the form and save your response. This will enable the scopes for development and testing.

  • Enter the "Application Name", for example Field Trippa Codelab
  • Select a "Back up email address"
  • Select "Add together scope", and then "manually add paste scopes" to enter the post-obit scopes:
https://world wide web.googleapis.com/auth/photoslibrary https://www.googleapis.com/auth/photoslibrary.sharing          
  • Select "Save"
  • There is no need to submit for verification to continue with this codelab. This is only required when launching your application, but not for personal testing.

Run the app and sign in

Google Sign-In has already been implemented using the google_sign_in flutter package. This package requires the google-services.json or GoogleService-Info.plist files that you take already copied into the project.

b2f84ff91b0e1396.png Run the awarding once more and select "Connect to Google Photos". You'll be prompted to select a user business relationship and accept the authentication scopes.

If everything has been fix successfully, you lot'll see an empty list on the next screen.

28747de003d2fa7c.png

Troubleshooting sign in

If you are having trouble signing into the application, hither are a few things y'all can check:

b2f84ff91b0e1396.png Check that the device has Internet connectivity.

b2f84ff91b0e1396.png If you receive the fault PlatformException(sign_in_failed, com.google.android.gms.common.api.ApiException: 10: , cypher), make sure that you have followed all steps in the section Enable the Google Photos Library API. You must add the Google Photos Library API scopes, enter a support electronic mail address and select relieve.

b2f84ff91b0e1396.png If you lot receive the error PlatformException(sign_in_failed, com.google.android.gms.common.api.ApiException: 12500: , null), brand certain that you lot have added a back up email address in the Firebase console. Open up Firebase panel and navigate to the project settings past selecting the gear icon next to your projection championship. Select an email address under back up email on the general settings screen.

b2f84ff91b0e1396.png Check the signing certificate SHA-1 that is configured in the Firebase console. Does information technology match the output from the keytool command from the showtime pace? Does it lucifer the output from the control ./gradlew signingReport when run in the android/ project? You lot may demand to besides include the signing certificate SHA-256 in the console.

b2f84ff91b0e1396.png Check the bundle name and iOS bundle ID that are configured in the Firebase console. This should be prepare to com.google.codelab.photos.sharing

b2f84ff91b0e1396.png Bank check the location of the configuration files you have downloaded from the Firebase console. For Android, the file should be copied to android/app/google-service.json. For iOS it should be added to the Runner module.

b2f84ff91b0e1396.png You may demand to enable Google every bit a sign-in provider for your Firebase project. Open the Firebase panel and navigate to Authentication and Sign-in method. Ensure that Google is enabled.

five. Create an album

Before you implement the offset API telephone call to the Google Photos Library API, let's walk through the data compages that the "Field Trippa" app uses.

App Compages

  • Each screen is implemented as a separate page: 71b9a588fb1bbb41.png
  • The PhotosLibraryApiModel describes the data model of the application and abstracts the Google Photos Library API calls abroad.
  • The HTTPS Residue calls to the Library API are implemented in the PhotosLibraryApiClient. Each call provided by this class takes a *Request object where yous specify parameters and options for a call.
  • The Library API requires user authentication via OAuth2. The admission token required to exist included in all API calls is set directly by the google_sign_in packet on the PhotosLibraryApiClient.

Implement the create albums API phone call

Each trip is stored as an album in Google Photos. When you select the "CREATE A TRIP Anthology" button, you should prompt the user for the name of the trip and create a new album with this name equally its championship.

b2f84ff91b0e1396.png In create_trip_page.dart, write the logic that makes a request to the Library API to create the album. Implement the _createTrip(...) method at the end of the file to call the PhotosLibraryApiModel with the name of the trip the user entered.

lib/pages/create_trip_page.dart

            Future<void> _createTrip(BuildContext context) async {   // Display the loading indicator.   setState(() => _isLoading = true);    await ScopedModel.of<PhotosLibraryApiModel>(context)       .createAlbum(tripNameFormController.text);    // Hibernate the loading indicator.   setState(() => _isLoading = simulated);   Navigator.pop(context); }                      

b2f84ff91b0e1396.png Implement the call to the Library API that creates the album. In the API model, implement the createAlbum(...) method that takes the title of the album as a parameter. It makes a call to the PhotosLibraryApiClient where the actual Residual call is fabricated.

lib/model/photos_library_api_model.dart

            Future<Album?> createAlbum(String title) async {   final anthology =       await client!.createAlbum(CreateAlbumRequest.fromTitle(title));   updateAlbums();   return album; }                      

b2f84ff91b0e1396.png Implement the Rest call to create the album in photos_library_api_client.sprint. Recollect that the CreateAlbumRequest already contains the title belongings- required for this telephone call.

The following encodes it every bit JSON and adds the authentication headers to authorize the request. Finally, render the album created by the API.

lib/photos_library_api/photos_library_api_client.sprint

            Future<Anthology> createAlbum(CreateAlbumRequest request) async {   last response = expect http.post(     Uri.parse('https://photoslibrary.googleapis.com/v1/albums'),     body: jsonEncode(request),     headers: await _authHeaders,   );    printError(response);    return Album.fromJson(jsonDecode(response.body)); }                      

Try it out!

b2f84ff91b0e1396.png Deploy the app and select "+ Create Trip".

2f0bec785bec1710.gif

6. Only show your app'southward albums

You may accept noticed that the trips listing shows other albums from Google Photos that were not created by your app. (If you do not have any other albums in Google Photos and want to see this behaviour, open the Google Photos app and create an album. However, this is not required to continue in this codelab.)

Remember that each trip is stored every bit an album in Google Photos. However, it does not make sense to prove any other albums from Google Photos that were created through other means - Field Trippa should only evidence trips that the app has created.

You can use the API to restrict the list of trips that are displayed to prove merely those created by the app.

b2f84ff91b0e1396.png Change the method listAlbums() method (NOT listSharedAlbums()!) in photos_library_api_client.dart. This method makes the REST call to retrieve a list of albums. Add the parameter excludeNonAppCreatedData=true that restricts the returned data to exclude albums that were not created by this app.

lib/photos_library_api/photos_library_api_client.dart

            Future<ListAlbumsResponse> listAlbums() async {   last response = await http.get(         Uri.parse('https://photoslibrary.googleapis.com/v1/albums?'             'pageSize=fifty&excludeNonAppCreatedData=true'),         headers: look _authHeaders);         ... }                      

Attempt it out!

The first page now only shows trips that were created by the app.

c7c20b76dcbfbfea.png

7. Upload Photos

The next footstep is to upload photos to a trip. The information is stored in your user's Google Photos account, so you lot don't have to worry well-nigh storage or processing the data yourself.

Taking a photo in Palpitate

b2f84ff91b0e1396.png Commencement, implement the method _getImage(...) in the contribute photograph dialog. This method is called when the user clicks the "+ADD PHOTO" push button.

The following code uses the image_picker package to take a photograph, update the UI and telephone call the API model to upload the image. (You lot'll implement this in the next step.) The _getImage(...) call stores an upload token needed later to create the photo in Google Photos.

lib/components/contribute_photo_dialog.dart

            Future _getImage(BuildContext context) async {   // Use the image_picker package to prompt the user for a photo from their   // device.   final pickedImage = await (_imagePicker.getImage(     source: ImageSource.camera,   ));    if (pickedImage == null) {     // No image selected.     return;   }    last pickedFile = File(pickedImage.path);    // Store the image that was selected.   setState(() {     _image = pickedFile;     _isUploading = true;   });    // Brand a asking to upload the image to Google Photos once it was selected.   concluding uploadToken = wait ScopedModel.of<PhotosLibraryApiModel>(context)       .uploadMediaItem(pickedFile);    setState(() {     // Once the upload process has completed, shop the upload token.     // This token is used together with the clarification to create the media     // item afterwards.     _uploadToken = uploadToken;     _isUploading = false;   }); }                      

Implement Library API call to upload the image to become an upload token

Uploading photos and videos to the Library API is done in 2 steps:

  1. Upload the media bytes to receive an upload token
  2. Create a media item in the user's library from the upload token

b2f84ff91b0e1396.png Implement the REST asking to upload media. You lot demand to set some headers to specify the type of upload request and the filename. In the file photos_library_api_client.dart implement the method uploadMediaItem(...) where the file is uploaded, returning the upload token that the HTTP call returns:

lib/photos_library_api/photos_library_api_client.sprint

            Future<String> uploadMediaItem(File image) async {   // Go the filename of the image   final filename = path.basename(epitome.path);    // Set upward the headers required for this request.   final headers = <String, String>{};   headers.addAll(await _authHeaders);   headers['Content-type'] = 'application/octet-stream';   headers['X-Goog-Upload-Protocol'] = 'raw';   headers['X-Goog-Upload-File-Name'] = filename;    // Make the HTTP request to upload the paradigm. The file is sent in the body.   final response = wait http.post(     Uri.parse('https://photoslibrary.googleapis.com/v1/uploads'),     body: image.readAsBytesSync(),     headers: await _authHeaders,   );    printError(response);    return response.body; }                      

Next, implement the creation of a media item in the user's library from the upload token.

Creating a media item requires the upload token, an optional description (for example, the explanation of the photo or video) and the optional identifier of an album. Field Trippa always adds the uploaded photo directly to a trip anthology.

b2f84ff91b0e1396.png Implement the call to the photos_library_api_client that calls mediaItems.batchCreate with the upload token, description, and album ID. In the API model, implement the method createMediaItem(...) that calls the Library API. This method returns a media item.

(The photos_library_client for this phone call is already implemented.)

lib/model/photos_library_api_model.dart

            Future<BatchCreateMediaItemsResponse?> createMediaItem(     String uploadToken, String? albumId, Cord? clarification) async {   // Construct the request with the token, albumId and description.   final request =       BatchCreateMediaItemsRequest.inAlbum(uploadToken, albumId, description);    // Make the API telephone call to create the media item. The response contains a   // media detail.   final response = expect client!.batchCreateMediaItems(request);    // Print and return the response.   print(response.newMediaItemResults?[0].toJson());   return response; }                      

Try it out!

b2f84ff91b0e1396.pngOpen the app and select a trip. Click contribute and select a photo that you have taken previously. Enter a description and select upload. The prototype should appear in the trip after a few seconds.

b2f84ff91b0e1396.png Open up the album in the Google Photos app - yous'll run into the new image in the album of this trip.

526ede994fcd5d8d.gif

viii. Share albums with non-app users

So far you have implemented the functionality to create a trip and upload photos with a description into it. In the backend, each trip is stored as an album in Google Photos.

Next, you volition share a trip with others who are non using your application.

Each trip is backed by an album in Google Photos, therefore you can 'share' an album via a URL and make it available to anyone who has this URL.

Albums are shared from the trip folio when a share button at the peak of the anthology is pressed.

b2f84ff91b0e1396.png Implement the asynchronous phone call _shareAlbum(...) that calls to the model to share the album and then reloads the displayed anthology. By reloading the album, the shareInfo belongings is propagated which contains the shareableUrl that you lot'll show the user in a dialog afterwards.

lib/pages/trip_page.dart

            Hereafter<void> _shareAlbum(BuildContext context) async {   String? id = album.id;    if (id == nada) {     // Anthology is missing an ID.     const snackBar = SnackBar(       duration: Duration(seconds: 3),       content: Text('Could not share album. Try reopening this page.'),     );     ScaffoldMessenger.of(context).showSnackBar(snackBar);     return;   }    // Show the loading indicator   setState(() => _inSharingApiCall = true);    const snackBar = SnackBar(     elapsing: Elapsing(seconds: 3),     content: Text('Sharing Album...'),   );   ScaffoldMessenger.of(context).showSnackBar(snackBar);    // Share the album and update the local model   await ScopedModel.of<PhotosLibraryApiModel>(context).shareAlbum(id);   final updatedAlbum =       await ScopedModel.of<PhotosLibraryApiModel>(context).getAlbum(id);    impress('Album has been shared.');   setState(() {     anthology = updatedAlbum;     // Hide the loading indicator     _inSharingApiCall = false;   }); }                      

b2f84ff91b0e1396.png Implement the method _showShareableUrl(...) that is chosen when the user clicks the "SHARE WITH ANYONE" button at the top of the page. Kickoff, check if the album has already been shared and telephone call the method _showUrlDialog(...) one time it has been shared.

lib/pages/trip_page.dart

            Time to come<void> _showShareableUrl(BuildContext context) async {   if (album.shareInfo == null || album.shareInfo!.shareableUrl == nix) {     print('Not shared, sharing anthology get-go.');     // Album is not shared yet, share it kickoff, then brandish dialog     await _shareAlbum(context);     _showUrlDialog(context);   } else {     // Anthology is already shared, brandish dialog with URL     _showUrlDialog(context);   } }                      

b2f84ff91b0e1396.png Implement the method _showUrlDialog(...) that shows the shareableUrl in a dialog.

lib/pages/trip_page.sprint

            void _showUrlDialog(BuildContext context) {   print('This is the shareableUrl:\due north${album.shareInfo!.shareableUrl}');   _showShareDialog(       context,       'Share this URL with anyone. '       'Anyone with this URL can access all items.',       album.shareInfo!.shareableUrl!); }                      

Endeavor it out!

The app only lists trips that are non shared yet on the main screen. Don't worry, we'll implement that in the next step. For now, you tin can merely create a new trip if you navigate abroad from the screen.

b2f84ff91b0e1396.png Open the app and select a trip. Select "SHARE WITH ANYONE" at the top of the screen and open the returned URL in your browser. (Tip: the URL is too printed to the log, and then you can hands copy it on your reckoner. In Android Studio, the log is displayed in the "Run" tab.)

1d1a40c1078e4221.gif

nine. Share albums inside your app

In Google Photos, albums can exist shared via a URL that anyone with access to the URL tin access. Through the Library API you can likewise share albums via share tokens. A share token is a string that is used inside your application to join users to a shared album via the API.

The process for sharing an album by your application via the Library API looks like this:

  1. User A logs into your application and authorizes the Library API
  2. Create the album
  3. Share the anthology using the identifier of the album
  4. Transfer the share token to some other User

The joining process is similar:

  1. User B logs into your application and authorizes the Library API
  2. Retrive the share token for the album the user should bring together
  3. Join the album using the share token

Shared albums are shown inside Google Photos on the "sharing" tab.

In the previous step you already implemented the method _shareAlbum(...) that shares an anthology. The shareInfo property too contains the "share token" that volition be shown on screen.

b2f84ff91b0e1396.png On the trip page, implement the method _showShareToken(...) that is called when the user presses the "SHARE WITH FIELD TRIPPA" push on screen.

lib/pages/trip_page.sprint

            Future<void> _showShareToken(BuildContext context) async {   if (album.shareInfo == null) {     impress('Not shared, sharing album first.');     // Album is non shared yet, share information technology first, then brandish dialog     await _shareAlbum(context);     _showTokenDialog(context);   } else {     // Anthology is already shared, display dialog with token     _showTokenDialog(context);   } }                      

Next, implement the display of the "share token" in the method _showTokenDialog(...). The token is role of the shareInfo property of an album.

lib/pages/trip_page.sprint

            void _showTokenDialog(BuildContext context) {   print('This is the shareToken:\n${album.shareInfo!.shareToken}');   _showShareDialog(       context, 'Employ this token to share', anthology.shareInfo!.shareToken!); }                      

The application currently only lists albums that are owned by the user, but non shared albums.

Only albums that the user has created or explicitly added to their Google Photos library are shown on the "Albums" screen inside the Google Photos app. Only these albums are returned when calling albums.listing in the Library API. However, in our app the user tin can bring together other user's shared albums, which are merely returned in the call to listing shared albums. You need to change the way the list of trips (albums) are retrieved from the Library API to include both owned and shared albums.

b2f84ff91b0e1396.png Albums are loaded and cached in the API Model. Change the implementation of updateAlbums() in the model to load albums and shared albums, before storing them every bit one list.

This implementation uses multiple Futures to list the albums asynchronously earlier combining them into the list of cached albums. Delete the onetime implementation and comment out the new code.

lib/model/photos_library_api_model.dart

            void updateAlbums() async {   // Reset the flag before loading new albums   hasAlbums = false;   // Clear all albums   _albums.articulate();   // Skip if non signed in   if (!isLoggedIn()) {     return;   }   // Add albums from the user'south Google Photos account   // var ownedAlbums = await _loadAlbums();   // if (ownedAlbums != null) {   //   _albums.addAll(ownedAlbums);   // }    // Load albums from endemic and shared albums   final list = await Futurity.wait([_loadSharedAlbums(), _loadAlbums()]);    _albums.addAll(list.expand((a) => a ?? []));    notifyListeners();   hasAlbums = true; }                      

You tin can join users of your application to an anthology by using the share token. This is done through a simple text dialog in this codelab.

b2f84ff91b0e1396.png Implement the _joinTrip method on the bring together trip page that calls the API model with the share token the user has entered. First, brandish the loading indicator, then make the phone call to join the shared album with the input from the text form, before hiding the loading indicator and returning dorsum to the previous screen.

lib/pages/join_trip_page.dart

            Future<void> _joinTrip(BuildContext context) async {   // Show loading indicator   setState(() => _isLoading = true);    // Call the API to join an album with the entered share token   await ScopedModel.of<PhotosLibraryApiModel>(context)       .joinSharedAlbum(shareTokenFormController.text);    // Hide loading indicator   setState(() => _isLoading = fake);    // Return to the previous screen   Navigator.pop(context); }                      

Try it out!

Y'all demand a 2nd device or emulator with a different user business relationship to try out this role of the codelab.

b2f84ff91b0e1396.png Create and share a trip under one user, then select the "SHARE IN FIELD TRIPPA" option to call up the share token. Copy this share token to the other device or emulator and enter it via the "JOIN A TRIP ALBUM" option on the home page. (Tip: The clipboard between your emulators and your host computer is shared.)

8043086cc00eaa16.gif 55c1e75014d4d2a4.gif

Real world implementation tips

When you implement sharing in a existent world awarding (and not a codelab), yous should think carefully most how you lot can use share tokens to join users to albums. Consider storing them in your secure backend and using your relationships between users to create and join albums.

For example - a soccer club meet upwards awarding could go on track of attendees to item scheduled events and merely join the attendees to the album subsequently prompting them.

Before making any changes in your user's Google Photos account, it is of import to give your users observe and ask for consent. Review the Google Photos Library API UX guidelines for more data.

10. Summary

What you have built

  • Implemented sharing functionality into your application, backed by Google Photos
  • Create your ain photograph and video sharing experiences on top of the Google Photos Library API, without having to worry near infrastructure or storage
  • Using the sharing functionality that is part of the API in interesting and novel ways to share content directly to your users.
  • Used some key parts of the Library API:
  • Created new albums and uploaded new photos
  • Listed shared albums, limited to albums created by your application

Where to go next

See the developer documentation for the Google Photos APIs at https://developers.google.com/photos to observe out more about sharing media and other parts of the Library API. For case smart content filters powered by auto learning to assistance you discover the correct photos and videos.

When you lot are getting gear up to launch your integration, join the Google Photos partner program.

Don't forget to review the UX guidelines and technical all-time practices. To help you get started, client libraries are as well available for some languages.

cruzhisir1958.blogspot.com

Source: https://codelabs.developers.google.com/codelabs/google-photos-sharing/

0 Response to "Ng File Upload to Upload Photo From Camera and Not Gallery in Chrome Mobile Device Type"

Postar um comentário

Iklan Atas Artikel

Iklan Tengah Artikel 1

Iklan Tengah Artikel 2

Iklan Bawah Artikel