06-admob-setup.md
dependencies:
google_mobile_ads: latest
Android (AndroidManifest.xml):
<meta-data
android:name="com.google.android.gms.ads.APPLICATION_ID"
android:value="ca-app-pub-xxxxxxxxxxxxxxxx~yyyyyyyyyy"/>
iOS (Info.plist):
<key>GADApplicationIdentifier</key>
<string>ca-app-pub-xxxxxxxxxxxxxxxx~yyyyyyyyyy</string>
import 'package:google_mobile_ads/google_mobile_ads.dart';
Future<void> main() async {
WidgetsFlutterBinding.ensureInitialized();
await MobileAds.instance.initialize();
// 為測試人員註冊測試裝置
RequestConfiguration configuration = RequestConfiguration(
testDeviceIds: ['YOUR_TEST_DEVICE_ID']
);
MobileAds.instance.updateRequestConfiguration(configuration);
runApp(MyApp());
}
此測驗題庫應用程式實作了根據使用者角色條件渲染廣告的機制:
| 變數 | 說明 |
|---|---|
ADMOB_APP_ID_ANDROID |
Android 的 App ID |
ADMOB_APP_ID_IOS |
iOS 的 App ID |
ADMOB_BANNER_ID |
橫幅廣告的 Unit ID |
ADMOB_REWARDED_ID |
獎勵廣告的 Unit ID |
APPLICATION_ID 中繼資料標籤。07-crashlytics-shake-setup.md
FlutterError.onError 與 PlatformDispatcher.instance.onError,分別用來捕捉框架層與非同步的錯誤。dependencies:
firebase_crashlytics: latest
shake_flutter: latest
為了防止啟動時發生 ANR (應用程式無回應),請透過延遲回呼 (Callback) 來初始化 Shake。
import 'package:shake_flutter/shake_flutter.dart';
import 'package:firebase_crashlytics/firebase_crashlytics.dart';
void initErrorTracking() {
// 捕捉 Flutter UI 錯誤
FlutterError.onError = (errorDetails) {
FirebaseCrashlytics.instance.recordFlutterFatalError(errorDetails);
};
// 捕捉非同步錯誤
PlatformDispatcher.instance.onError = (error, stack) {
FirebaseCrashlytics.instance.recordError(error, stack, fatal: true);
return true;
};
// 延遲初始化 Shake
WidgetsBinding.instance.addPostFrameCallback((_) {
Shake.start(
'YOUR_SHAKE_CLIENT_ID',
'YOUR_SHAKE_CLIENT_SECRET'
);
});
}
建立一個統一的服務來處理自訂的非致命錯誤日誌紀錄,並附加背景資訊 (例如:使用者 ID、測驗連線階段 ID)。若在回答關於 IP 位址或路由器的題目時發生畫面渲染錯誤,可透過此服務記錄狀態。
class ErrorReportService {
Future<void> logError(String message, {String? userId}) async {
await FirebaseCrashlytics.instance.log(message);
if (userId != null) {
await FirebaseCrashlytics.instance.setUserIdentifier(userId);
}
// 若適用,將資訊轉發至 Shake
}
}
| 變數 | 說明 |
|---|---|
SHAKE_CLIENT_ID |
Shake SDK 的 Client ID |
SHAKE_CLIENT_SECRET |
Shake SDK 的 Client Secret |
08-ai-api-setup.md
secrets.json 檔案中。AiTutorService 中設定 REST 端點。使用 FlutterSecureStorage 在裝置上管理金鑰。
class ApiKeyService {
final _storage = const FlutterSecureStorage();
Future<void> saveApiKey(String key) async {
await _storage.write(key: 'ai_api_key', value: key);
}
Future<String?> getApiKey() async {
return await _storage.read(key: 'ai_api_key');
}
}
安全地輪替金鑰,避免服務中斷:
此應用程式使用裝置端 AI 模型作為離線時的備用方案,確保使用者隨時都能存取練習題與認證考試的詳細解析,例如關於子網路劃分或是交換器設定的問題。
gemma-4-E2B-it.litertlm (約 1.7GB)。dependencies:
flutter_gemma: latest
import 'package:flutter_gemma/flutter_gemma.dart';
Future<void> initOnDeviceAi() async {
// 確保本機已有模型檔案
final modelPath = await downloadModelIfNotExists();
await FlutterGemmaPlugin.instance.init(
modelPath: modelPath,
useGpu: true, // 偏好使用 GPU 後端
);
}
| 變數 | 說明 |
|---|---|
CLOUD_AI_API_KEY |
用於雲端 AI 推論的備用 API 金鑰 |
MODEL_DOWNLOAD_URL |
下載 Gemma LiteRT-LM 模型的 URL |