首页 > 解决方案 > Google Drive ApI V3 Migration for Xamrin.Android

问题描述

Please let me know how to migrate to Google Drive API v2 or V3. I found all the answers for the migration related to java.I could't find the equivalent xamarin nuget package for the Google Drive API v2 or V3.

I have tried with this Xamarin.GooglePlayServices.Drive nuget package but in this all the drive api's are depricated.

Can anyone tried google drive integration in xamarin.Please help me.This is my try

    GoogleSignInOptions gso = new GoogleSignInOptions.Builder(GoogleSignInOptions.DefaultSignIn)
                .RequestEmail()
                .Build();

    var mGoogleApiClient = new GoogleApiClient.Builder(this)
                .EnableAutoManage(this /* FragmentActivity */, this /* OnConnectionFailedListener */)
                .AddApi(Auth.GOOGLE_SIGN_IN_API, gso)
                .Build();


     MetadataChangeSet changeSet = new MetadataChangeSet.Builder()
            .SetTitle(_backupFolderName)
            .Build();
        IDriveFolderDriveFolderResult result;
        try
        {
            result = await DriveClass.DriveApi.GetRootFolder(_googleApiClient)
                .CreateFolderAsync(_googleApiClient, changeSet);
        }
        catch (Exception)
        {
            return null;
        }

标签: c#xamarin.android

解决方案


我找不到任何支持 Xamarin 和 OAuth 身份验证的谷歌驱动器的 nuget 包。所以我找到了使用 Http Client Rest API 的方法

请按照以下步骤

  1. 使用 Google Developer Console 创建 OAuth 客户端 ID
  2. 使用客户端 ID 以及重定向等其他信息

    public class GoogleAuthenticator : OAuth2Authenticator
    {
    public static OAuth2Authenticator Auth;
    
    public GoogleAuthenticator(string clientId, string scope, Uri authorizeUrl, Uri redirectUrl,
        GetUsernameAsyncFunc getUsernameAsync = null, bool isUsingNativeUi = false) : base(clientId, scope,
        authorizeUrl, redirectUrl, getUsernameAsync, isUsingNativeUi)
    {
        Auth = new OAuth2Authenticator(clientId, string.Empty, scope,
            authorizeUrl,
            redirectUrl,
            new Uri(GoogleDriveConfig.AccessTokenUri),
            null, true);
    
        Auth.Completed += OnAuthenticationCompleted;
        Auth.Error += OnAuthenticationFailed;
    }
    
    public void OnAuthenticationCompleted(object sender,AuthenticatorCompletedEventArgs e)
    {
        if (e.IsAuthenticated)
        {
            AuthenticationCompleted?.Invoke(e.Account.Properties["access_token"],
                e.Account.Properties["refresh_token"], e.Account.Properties["expires_in"]);
        }
    
    }
    
    public void OnAuthenticationFailed(object sender, AuthenticatorErrorEventArgs e)
    {
    
    }
    
  3. 启动浏览器

    public void SignInToDrive(Activity context)
      {
        Intent loginUi = Auth.GetUI(context);
    
        CustomTabsConfiguration.IsShowTitleUsed = false;
        CustomTabsConfiguration.IsActionButtonUsed = false;
        context.StartActivity(loginUi);
      }
    
  4. 创建 GoogleAuthInterceptor 活动

      [Activity(Label = "GoogleAuthInterceptor")] 
      [  IntentFilter ( actions: new[] 
      {Intent.ActionView}, 
       Categories = new[] { Intent.CategoryDefault, 
      Intent.CategoryBrowsable }, 
      DataSchemes = new[] {"YOUR PACKAGE NAME"}, DataPaths = new[] { "/oauth2redirect" 
       } ) ]
    
      public class GoogleAuthInterceptor : Activity
     {
       protected override void OnCreate(Bundle savedInstanceState)
      {
        base.OnCreate(savedInstanceState);
        Uri uriAndroid = Intent.Data;
    
        System.Uri uri = new System.Uri(uriAndroid.ToString());
    
            var intent = new Intent(ApplicationContext, typeof(MainActivity));
            intent.SetFlags(ActivityFlags.ClearTop | ActivityFlags.SingleTop);
            StartActivity(intent);
    
        GoogleAuthenticator.Auth.OnPageLoading(uri);
    
        Finish();
        return;
    }
    }
    
  5. 将文件上传到 Google 云端硬盘

    此基地址适用于以下所有 google drive API

      HttpClient _httpClient = httpClient ?? new HttpClient
        {
            BaseAddress = new Uri(),
    
        };
    
    private async Task<HttpResponseMessage> CreateResumableSession(string accessToken, string fileName, long fileSize, string folderId)
    {
    
        var sessionRequest = new 
        HttpRequestMessage(HttpMethod.Post,"upload/drive/v3/files?uploadType=resumable");
        sessionRequest.Headers.Add("Authorization", "Bearer " + accessToken);
        sessionRequest.Headers.Add("X-Upload-Content-Type", "*/*");
        sessionRequest.Headers.Add("X-Upload-Content-Length", fileSize.ToString());
    
        string body = "{\"name\": \"" + fileName + "\", \"parents\": [\"" + folderId + "\"]}";
        sessionRequest.Content = new StringContent(body);
        sessionRequest.Content.Headers.ContentType = new MediaTypeHeaderValue("application/json");
      using (var sessionResponse = await _httpClient.SendAsync(sessionRequest) )
        {
            return sessionResponse;
        };
    
  6. 更新 Google 云端硬盘中的文件

    private async Task<bool> UpdateFile(string accessToken,string fileId,long fileSize,Stream stream)
    {
       HttpRequestMessage sessionRequest = new HttpRequestMessage(new HttpMethod("PATCH"), "upload/drive/v3/files/" + $"{fileId}");
        sessionRequest.Headers.Add("Authorization", "Bearer " + accessToken);
        sessionRequest.Headers.Add("X-Upload-Content-Type", "*/*");
        sessionRequest.Headers.Add("X-Upload-Content-Length", fileSize.ToString());
        sessionRequest.Content = new StreamContent(stream);
        sessionRequest.Content.Headers.ContentType = new MediaTypeHeaderValue("*/*");
    
        using (var response = await _httpClient.SendAsync(sessionRequest))
        {
            return response.IsSuccessStatusCode;
        }
    }
    
  7. 下载文件

      public async Task<Stream> DownloadFile(string accessToken, string fileId)
    {
        var request = new HttpRequestMessage(HttpMethod.Get,"drive/v3/files"+ $"/{fileId}" + "?fields=*&alt=media");
        request.Headers.Add("Authorization", "Bearer " + accessToken);
    
        var response = await _httpClient.SendAsync(request);
    
        if (response.IsSuccessStatusCode)
        {
            var contents = await response.Content.ReadAsStreamAsync();
            return contents;
        }
    
        return null; 
    }
    
  8. 获取所有文件

    public  async Task<GoogleDriveItem> GetFiles(string folderId, string accessToken)
    {  
        var request = new HttpRequestMessage(HttpMethod.Get,
            "drive/v3/files" +"?q=parents%20%3D%20'" +
            $"{folderId}" +
            "'%20and%20trashed%20%3D%20false&fields=files(id%2Cname%2Ctrashed%2CmodifiedTime%2Cparents)");
        request.Headers.Add("Authorization", "Bearer " + accessToken);
        request.Headers.Add("Accept", "application/json");
        request.Headers.CacheControl = new CacheControlHeaderValue() { NoCache = true 
        };
    
        using (var response = await _httpClient.SendAsync(request))
        {
            var content = await response.Content.ReadAsStringAsync();
            return (JsonConvert.DeserializeObject<GoogleDriveItem>(content));
        }
    }
    

推荐阅读