<p>Flutterã«éãã¾ãããã<strong>Google Driveã使ç¨ãã¦ã¢ããªã±ã¼ã·ã§ã³é åã«ããã¯ã¢ããããªã¹ãã¢ãããã</strong>å ´åãè²ã ã¨è¨å®ããããããã¦è©°ã¾ãã®ã§ãèªåç¨ã®åå¿é²ã¨ãã¦ç¢ºèªãã¹ãé ç®ããªã¹ãåãã¦ããã¾ãã</p>



<p>ä»ã®äººã«ãå½¹ç«ã¦ã°å¹¸ãã§ãã</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading">èªåã®PC</h2>



<ul class="wp-block-list">
<li>keytoolã使ç¨ã§ããäºï¼èªåã®å ´åããã¹ãéã£ã¦ããªãã®ã§[Java >; jdk-xxx >; bin](keytool.exeããããã©ã«ã)ã¾ã§ç§»åï¼</li>



<li>ã³ãã³ãã§ãããã°ãã¼ã¹ãã¢ã®åå¾</li>
</ul>



<pre class="wp-block-code has-background" style="border-style:none;border-width:0px;background-color:#ececec"><code>keytool -list -v -alias androiddebugkey -keystore C:\Users\YOUR_USERNAME\.android\debug.keystore

* &#91;YOUR_USERNAME] èªåã®ã¦ã¼ã¶ã¼å
* &#91;ãã¼ã¹ãã¢ã®ãã¹ã¯ã¼ã] é常ã¯ãandroidã</code></pre>



<ul class="wp-block-list">
<li>表示ããããSHA-1ã(<em><mark style="background-color:#9DFF20" class="has-inline-color">key1</mark></em>)ã¨ãSHA-256ã(<em><mark style="background-color:#9DFF20" class="has-inline-color">key2</mark></em>)ãã³ãããã¦ãã</li>



<li>ã³ãã³ãã§ãªãªã¼ã¹ãã¼ã¹ãã¢ã®ä½æã¨åå¾</li>
</ul>



<pre class="wp-block-code has-background" style="background-color:#ececec"><code>keytool -genkey -v -keystore my-release-key.keystore -alias my-key-alias -keyalg RSA -keysize 2048 -validity 10000

* &#91;my-release-key.keystore] çæããããã¼ã¹ãã¢ã®åå
* &#91;my-key-alias] ãã¼ã¨ã¤ãªã¢ã¹ã®åå</code></pre>



<ul class="wp-block-list">
<li>ãã¼ã¹ãã¢ã®ãã¹ã¯ã¼ãã¨ãã¼ã¨ã¤ãªã¢ã¹ã®ãã¹ã¯ã¼ããè¨å®å¾ãååãçµç¹é¨ç½²ãçµç¹å(ä¼ç¤¾å)ãé½å¸å(å¸)ãå·(ç)ãå½ã³ã¼ã(JP)ãå ¥åãã¦ã[ã¯ã]ã§ãã¼ã¹ãã¢ã®ä½æ</li>



<li>ã³ãã³ãã§ä½æãããã¼ã¹ãã¢ã®ãã£ã³ã¬ã¼ããªã³ããåå¾</li>
</ul>



<pre class="wp-block-code has-background" style="background-color:#ececec"><code>keytool -list -v -alias my-key-alias -keystore my-release-key.keystore

* &#91;my-key-alias] å ç¨ã®ä½æãããã¼ã¨ã¤ãªã¢ã¹ã®åå
* &#91;my-release-key.keystore] å ç¨ã®ä½æãããã¼ã¹ãã¢ã®åå</code></pre>



<ul class="wp-block-list">
<li>ãã¼ã¹ãã¢ã®ãã¹ã¯ã¼ãã¨ãã¼ã¨ã¤ãªã¢ã¹ã®ãã¹ã¯ã¼ããå ¥åãã¦ã表示ããããSHA-1ã(<em><mark style="background-color:#9DFF20" class="has-inline-color">key3</mark></em>)ã¨ãSHA-256ã(<em><mark style="background-color:#9DFF20" class="has-inline-color">key4</mark></em>)ãã³ãããã¦ãã</li>
</ul>



<h2 class="wp-block-heading">Google Play</h2>



<ul class="wp-block-list">
<li>ã¢ããªã®ç»é²ï¼å¤§åæï¼ï¼ãã¹ãå ¬éã§OK)</li>



<li>[è¨å® >; ã¢ããªã®ç½²å]ãããSHA-1 è¨¼ææ¸ã®ãã£ã³ã¬ã¼ããªã³ãã(<em><mark style="background-color:#9DFF20" class="has-inline-color">key5</mark></em>)ãSHA-256 è¨¼ææ¸ã®ãã£ã³ã¬ã¼ããªã³ãã(<em><mark style="background-color:#9DFF20" class="has-inline-color">key6</mark></em>)ãåå¾</li>
</ul>



<h2 class="wp-block-heading">Firebase</h2>



<ul class="wp-block-list">
<li>ããã¸ã§ã¯ãã®ä½æï¼å¤§åæï¼</li>



<li>ã¢ããªã®è¿½å (Android)</li>



<li>[Authentication >; Sign-in method(ãã°ã¤ã³æ¹æ³)]ã®ãã°ã¤ã³ãããã¤ãã§ãGoogleããæå¹ã«ãã</li>



<li>[ããã¸ã§ã¯ãã®æ¦è¦ >; ããã¸ã§ã¯ãã®è¨å®]ãããã¯[ããã¸ã§ã¯ã >; ã¢ããª]ã鏿</li>



<li>[ãã¤ã¢ããª]ã®ã¢ããªã鏿ãã¦ããã£ã³ã¬ã¼ããªã³ãã追å ããã(<em><mark style="background-color:#9DFF20" class="has-inline-color">key1</mark>, <mark style="background-color:#9DFF20" class="has-inline-color">key2</mark>, <mark style="background-color:#9DFF20" class="has-inline-color">key3</mark>, <mark style="background-color:#9DFF20" class="has-inline-color">key4</mark>, <mark style="background-color:#9DFF20" class="has-inline-color">key5</mark>, <mark style="background-color:#9DFF20" class="has-inline-color">key6</mark></em>)</li>



<li>google-services.jsonããã¦ã³ãã¼ããã¦ãã</li>
</ul>



<h2 class="wp-block-heading">Google Cloud</h2>



<ul class="wp-block-list">
<li>ããã¸ã§ã¯ãã®ä½æï¼å¤§åæï¼</li>



<li>[ããã²ã¼ã·ã§ã³ã¡ãã¥ã¼ >; APIã¨ãµã¼ãã¹ >; ã©ã¤ãã©ãª]ã«ç§»å</li>



<li>ãGoogle Driveããæ¤ç´¢ãã¦ããGoogle Drive APIããæå¹ã«ãã</li>



<li>[APIã¨ãµã¼ãã¹ >; OAuth åæç»é¢]ã«ç§»å</li>



<li>[å ¬éã¹ãã¼ã¿ã¹]ã¯ããã¹ãã(å ¬éãããæ¬çªç°å¢ã¸ï¼</li>



<li>[ã¦ã¼ã¶ã¼ã®ç¨®é¡]ã¯ãå¤é¨ã</li>



<li>[ã¹ã³ã¼ãã®è¨å®]ã¯ãGoogle Driveãã§æ¤ç´¢ãã¦ã&#8230;/auth/drive.fileãã¨ã&#8230;/auth/drive.appdataãã追å </li>
</ul>



<h2 class="wp-block-heading">Flutter</h2>



<ul class="wp-block-list">
<li>ï¼ããããã«ã¼ãã¯ã¢ããªã®ããããã£ã¬ã¯ããªï¼</li>



<li>[android/app]ã«google-services.jsonã追å </li>



<li>[android/build.gradle]ã«ä»¥ä¸ã追å </li>
</ul>



<pre class="wp-block-code"><code> dependencies {
 ...

 // versionã¯ãã®é½åº¦åããã
 classpath 'com.google.gms:google-services:4.3.15'
 }
</code></pre>



<ul class="wp-block-list">
<li>[android/app/build.gradle]ã«ä»¥ä¸ã追å </li>
</ul>



<pre class="wp-block-code"><code>plugins {
 ...
 id 'com.google.gms.google-services'
}
dependencies {
 ...
 implementation(platform("com.google.firebase:firebase-bom:32.7.0"))
 implementation("com.google.firebase:firebase-analytics")
 implementation("com.google.firebase:firebase-auth")
 implementation("com.google.firebase:firebase-firestore")
}
</code></pre>



<ul class="wp-block-list">
<li>ãflutter pub addãã³ãã³ãã§å¿ è¦ãªããã±ã¼ã¸ãåå¾</li>



<li> ; google_sign_in</li>



<li> firebase_core</li>



<li> firebase_auth</li>



<li> ; flutter_secure_storage</li>



<li> ; googleapis</li>



<li> ; googleapis_auth</li>



<li> http</li>
</ul>



<h2 class="wp-block-heading">Flutterã§ã®æ¥ç¶ã«ã¤ãã¦</h2>



<p>è¨å®ã¯Google Play, Firebase, Google Cloudãã¡ããã¨ãã¦ããã°å¤§ä¸å¤«ã®ã¯ãã§ããä¸ã¯ããã¯ã¢ããããªã¹ãã¢ãåé¤ã®ã¯ã©ã¹(google_drive_api.dart)ã§ãã</p>



<p>*åèãµã¤ãã<a href="https://qiita.com/YuKiO-OO/items/67b471e6be6c4c4c26e9" target="_blank" rel="noreferrer noopener">ãFlutterãGoogleDriveã¸ã®ããã¯ã¢ããã»ãªã¹ãã¢æ©è½ãå®è£ ããã¾ã§ã®éã®ã</a>ã</p>



<pre class="wp-block-code has-border-color has-cyan-bluish-gray-border-color has-background has-small-font-size" style="border-width:1px;background-color:#e4e4e4;padding-top:var(--wp--preset--spacing--30);padding-right:var(--wp--preset--spacing--30);padding-bottom:var(--wp--preset--spacing--30);padding-left:var(--wp--preset--spacing--30)"><code>import 'dart:async'; 
import 'package:google_sign_in/google_sign_in.dart'; 
import 'package:googleapis/drive/v3.dart' as ga; 
import 'package:http/io_client.dart'; 
import 'package:http/http.dart' as http; 
import 'package:path/path.dart' as path; 
import 'dart:io' as io; 
 
class GoogleApi { 
 Future<;bool> uploadFileToGoogleDrive() async { 
 bool isUpload = false; 
 final completer = Completer<;bool>(); 
 
 try { 
 GoogleSignIn googleSignIn = GoogleSignIn( 
 scopes: &#91; 
 'https://www.googleapis.com/auth/drive.file', 
 'https://www.googleapis.com/auth/drive.appdata', 
 ], 
 ); 
 GoogleSignInAccount? googleSignInAccount = await googleSignIn.signIn(); 
 
 if (googleSignInAccount != null) { 
 var client = GoogleHttpClient(await googleSignInAccount.authHeaders); 
 var drive = ga.DriveApi(client); 
 ga.FileList list = await drive.files.list(spaces: 'appDataFolder', $fields: 'files(id, name, modifiedTime)'); 
 
 // Google Driveã«æ®ã£ã¦ããã¢ããªãã©ã«ãå ã®ãã¼ã¿ãåé¤ãã¦ãã 
 if (list.files != null &;&; list.files!.isNotEmpty) { 
 for (var i = 0; i <; list.files!.length; i++) { 
 String? gdId = list.files!&#91;i].id; 
 if (gdId != null) { 
 await drive.files.delete(gdId); 
 } 
 } 
 } 
 
 ga.File fileToUpload = ga.File(); 
 
 String dbPath = "ãã¡ã¤ã«ã®ãã«ãã¹"; 
 if (io.File(dbPath).existsSync()) { 
 io.File dbFile = io.File(dbPath); 
 
 fileToUpload.parents = &#91;"appDataFolder"]; 
 fileToUpload.modifiedTime = DateTime.now(); 
 fileToUpload.name = path.basename(dbFile.path); 
 await drive.files.create( 
 fileToUpload, 
 uploadMedia: ga.Media(dbFile.openRead(), await dbFile.length()), 
 ); 
 isUpload = true; 
 completer.complete(isUpload); 
 } else { 
 // ããã¯ã¢ãããããã¡ã¤ã«ãè¦ã¤ããã¾ãã 
 completer.complete(isUpload); 
 } 
 } else { 
 // Googleã®ãµã¤ã³ã¤ã³ã«å¤±æãã¾ãã 
 completer.complete(isUpload); 
 } 
 } catch (e) { 
 // ã¨ã©ã¼ 
 completer.completeError(e); 
 } 
 
 return completer.future; 
 } 
 
 Future<;bool> downloadGoogleDriveFile() async { 
 bool isDownload = false; 
 final completer = Completer<;bool>(); 
 
 try { 
 GoogleSignIn googleSignIn = GoogleSignIn( 
 scopes: &#91; 
 'https://www.googleapis.com/auth/drive.file', 
 'https://www.googleapis.com/auth/drive.appdata', 
 ], 
 ); 
 GoogleSignInAccount? googleSignInAccount = await googleSignIn.signIn(); 
 
 if (googleSignInAccount != null) { 
 var client = GoogleHttpClient(await googleSignInAccount.authHeaders); 
 var drive = ga.DriveApi(client); 
 
 // Google Driveã®ã¢ããªãã©ã«ãã«ä¿åããã¦ããä¸ã¤ç®ã®ãã¼ã¿ãåå¾ 
 ga.FileList list = await drive.files.list(spaces: 'appDataFolder', $fields: 'files(id, name, modifiedTime)'); 
 String? gdID = (list.files != null &;&; list.files!.isNotEmpty) ? list.files!.first.id : ""; 
 
 if (gdID != null &;&; gdID.isNotEmpty) { 
 ga.Media file = await drive.files.get(gdID, downloadOptions: ga.DownloadOptions.fullMedia) as ga.Media; 
 
 String dbPath = "ãã¡ã¤ã«ã®ãã«ãã¹"; 
 io.File dbFile = io.File(dbPath); 
 
 List<;int> dataStore = &#91;]; 
 file.stream.listen((data) { 
 dataStore.insertAll(dataStore.length, data); 
 }, onDone: () { 
 dbFile.writeAsBytes(dataStore); 
 isDownload = true; 
 completer.complete(isDownload); 
 }, onError: (error) { 
 // ã¨ã©ã¼ 
 completer.completeError(error); 
 }); 
 
 } else { 
 // ãã¦ã³ãã¼ããããã¼ã¿ãè¦ã¤ããã¾ããã§ãã 
 completer.complete(isDownload); 
 } 
 } else { 
 // Googleã®ãµã¤ã³ã¤ã³ã«å¤±æãã¾ãã 
 completer.complete(isDownload); 
 } 
 } catch (e) { 
 // ã¨ã©ã¼ 
 completer.completeError(e); 
 } 
 
 return completer.future; 
 } 
 
 // ããã¯ã¢ãããã¼ã¿ã®åé¤ 
 Future<;bool> deletedGoogleDriveFile() async { 
 bool isDelete = false; 
 final completer = Completer<;bool>(); 
 
 try { 
 GoogleSignIn googleSignIn = GoogleSignIn( 
 scopes: &#91; 
 'https://www.googleapis.com/auth/drive.file', 
 'https://www.googleapis.com/auth/drive.appdata', 
 ], 
 ); 
 GoogleSignInAccount? googleSignInAccount = await googleSignIn.signIn(); 
 
 if (googleSignInAccount != null) { 
 var client = GoogleHttpClient(await googleSignInAccount.authHeaders); 
 var drive = ga.DriveApi(client); 
 ga.FileList list = await drive.files.list(spaces: 'appDataFolder', $fields: 'files(id, name, modifiedTime)'); 
 
 // Google Driveã«æ®ã£ã¦ããã¢ããªãã©ã«ãå ã®ãã¼ã¿ãåé¤ãã¦ãã 
 if (list.files != null &;&; list.files!.isNotEmpty) { 
 for (var i = 0; i <; list.files!.length; i++) { 
 String? gdId = list.files!&#91;i].id; 
 if (gdId != null) { 
 await drive.files.delete(gdId); 
 } 
 } 
 } 
 isDelete = true; 
 completer.complete(isDelete); 
 } else { 
 // Googleã®ãµã¤ã³ã¤ã³ã«å¤±æãã¾ãã 
 completer.complete(isDelete); 
 } 
 } catch (e) { 
 // ã¨ã©ã¼ 
 completer.completeError(e); 
 } 
 
 return completer.future; 
 } 
} 
 
class GoogleHttpClient extends IOClient { 
 final Map<;String, String> _headers; 
 GoogleHttpClient(this._headers) : super(); 
 @override 
 Future<;IOStreamedResponse> send(http.BaseRequest request) => super.send(request..headers.addAll(_headers)); 
 @override 
 Future<;http.Response> head(Uri url, {Map<;String, String>? headers}) { 
 headers = headers ?? {}; 
 headers.addAll(_headers); 
 return super.head(url, headers: headers); 
 } 
} </code></pre>



<p>使ãå ´åã¯ä¸ã¿ãããªæãã§ã</p>



<pre class="wp-block-code has-border-color has-cyan-bluish-gray-border-color has-background has-small-font-size" style="border-width:1px;background-color:#e4e4e4;padding-top:var(--wp--preset--spacing--30);padding-right:var(--wp--preset--spacing--30);padding-bottom:var(--wp--preset--spacing--30);padding-left:var(--wp--preset--spacing--30)"><code>import 'package:notebook/google_drive_api.dart';

// ãããªæãã§ä½¿ãã
bool isUpload= await GoogleApi().uploadFileToGoogleDrive();
message = (isUpload) ? "ããã¯ã¢ããæå" : "ããã¯ã¢ãã失æ";

// ãããªæãã§ä½¿ã
GoogleApi().uploadFileToGoogleDrive().then((bool isUpload) {
 var message = (isUpload) ? "ããã¯ã¢ããæå" : "ããã¯ã¢ãã失æ";
});
</code></pre>



<p>ããã§ä¸æãããã¾ããã<br>ã¡ãªã¿ã«ããã¾ã§Bingã¨äºäººä¸èã§ããã¾ãããBingããã¡ããã¡ãåªç§ã§ãã</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<p>ããã¾ã§ãã£ã¦æ¥ç¶ã§ããªããã¨ã©ã¼ãåºã人ã¯ç§ã«ã¨ã£ã¦ãåå¼·ã«ãªãã®ã§æãã¦ãã ããã</p>

FlutterでGoogle Driveを使ったバックアップ
