huawei_remote_config 1.0.0
huawei_remote_config: ^1.0.0 copied to clipboard
Flutter plugin for Huawei AppGallery Connect Remote Config (AGConnectConfig). Android-only.
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:huawei_remote_config/huawei_remote_config.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'huawei_remote_config example',
theme: ThemeData(colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple)),
home: const RemoteConfigPage(),
);
}
}
/// Demonstrates the `huawei_remote_config` API: seeding local defaults,
/// fetching and activating remote values, and inspecting where each value
/// came from ([HuaweiRemoteConfigSource]).
///
/// This app is Android-only, matching the plugin itself — running it on any
/// other platform surfaces the `unsupported_platform`
/// [HuaweiRemoteConfigException] that every method throws there.
class RemoteConfigPage extends StatefulWidget {
const RemoteConfigPage({super.key});
@override
State<RemoteConfigPage> createState() => _RemoteConfigPageState();
}
class _RemoteConfigPageState extends State<RemoteConfigPage> {
static const _greetingKey = 'greeting';
final _remoteConfig = HuaweiRemoteConfig.instance;
bool _isLoading = false;
String? _error;
HuaweiRemoteConfigValues? _values;
HuaweiRemoteConfigSource? _greetingSource;
@override
void initState() {
super.initState();
// Seed a default so there is always something to show, even before the
// first successful fetch.
unawaited(_remoteConfig.applyDefaults({_greetingKey: 'Hello from local defaults!'}));
}
Future<void> _fetchAndApply() async {
setState(() {
_isLoading = true;
_error = null;
});
try {
// `Duration.zero` bypasses the SDK's ~12h fetch cache — useful here,
// but avoid it in production where the cache is what keeps the app off
// the network on every cold start.
final values = await _remoteConfig.fetchAndApply(interval: Duration.zero);
final source = await _remoteConfig.getSource(_greetingKey);
setState(() {
_values = values;
_greetingSource = source;
});
} on HuaweiRemoteConfigException catch (e) {
// e.code is one of: fetch_failed, no_pending_fetch,
// unsupported_platform, native_error. This example has no fallback of
// its own — deciding what to do next is the host app's job.
setState(() => _error = '${e.code}: ${e.message ?? 'no message'}');
} finally {
setState(() => _isLoading = false);
}
}
Future<void> _showDiagnostics() async {
final diagnostics = await _remoteConfig.diagnostics();
if (!mounted) return;
await showDialog<void>(
context: context,
builder: (context) => AlertDialog(
title: const Text('Diagnostics'),
content: SingleChildScrollView(
child: Text(diagnostics.entries.map((e) => '${e.key}: ${e.value}').join('\n')),
),
actions: [TextButton(onPressed: () => Navigator.pop(context), child: const Text('Close'))],
),
);
}
@override
Widget build(BuildContext context) {
final greeting = _values?.getString(_greetingKey);
return Scaffold(
appBar: AppBar(title: const Text('huawei_remote_config example')),
body: Center(
child: Padding(
padding: const EdgeInsets.all(24),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
if (_error != null)
Text(_error!, style: TextStyle(color: Theme.of(context).colorScheme.error))
else if (greeting != null) ...[
Text(greeting, style: Theme.of(context).textTheme.headlineSmall),
const SizedBox(height: 8),
Text('Source: ${_greetingSource?.name ?? 'unknown'}'),
] else
const Text('Fetch remote config to see the "greeting" value.'),
const SizedBox(height: 24),
FilledButton(
onPressed: _isLoading ? null : _fetchAndApply,
child: _isLoading
? const SizedBox(height: 16, width: 16, child: CircularProgressIndicator(strokeWidth: 2))
: const Text('Fetch and apply'),
),
const SizedBox(height: 8),
OutlinedButton(onPressed: _showDiagnostics, child: const Text('Show diagnostics')),
],
),
),
),
);
}
}