表題の件、やってみた。
テスト環境の整備
- 基本は公式を見て設定すればOK
- 公式の設定だけではエラーが出たので追加(見逃しただけかも)
Android の場合
kotlin_version が最新じゃないといけないっぽい
Kotlin_version : 1.9.0
コード
エミュレーターを起動して、"距離を計算する!"をクリックすればデバッグコンソールに計算結果が出てくる。
main
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:location_sample/location.dart';
void main() {
runApp(
const ProviderScope(
child: MaterialApp(home: MyApp(),)
),
);
}
class MyApp extends ConsumerStatefulWidget {
const MyApp({super.key});
@override
ConsumerState<ConsumerStatefulWidget> createState() => _MyAppState();
}
class _MyAppState extends ConsumerState<MyApp> {
@override
Widget build(BuildContext context) {
bool isGetLocate = ref.watch( isGetLocateProvider );
if ( isGetLocate ) {
return Center(
child: TextButton(
child : const Text( "距離を計算する!!" ),
onPressed : () {
final myLocateData = ref.watch( isLocateProvider )!;
double lon1 = myLocateData.longitude!;
double lat1 = myLocateData.latitude!;
double lon2 = 130.0;
double lat2 = 45.0;
double dist = calcDistance( lon1, lat1, lon2, lat2 );
debugPrint( "x1 : $lon1 y2 : $lat1" );
debugPrint( "x2 : $lon2 y2 : $lat2" );
debugPrint( "dist : $dist" );
},
)
);
} else { return const Placeholder(); }
}
}
location.dart
// flutter pub run build_runner build --delete-conflicting-outputs
import 'dart:math';
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:freezed_annotation/freezed_annotation.dart';
import 'package:riverpod_annotation/riverpod_annotation.dart';
import 'package:location/location.dart';
part 'location.freezed.dart';
//
// State
//
@freezed
class LocateState with _$LocateState {
factory LocateState({
required Location location,
@Default(null) LocationData? locateData,
@Default(false) bool isGetLocation
}) = _LocateState;
}
//
// Notifier
//
class LocationCnrl extends AsyncNotifier<LocateState> {
// 初期化
@override
Future<LocateState> build() async {
Location location = Location();
location.enableBackgroundMode( enable: true );
bool serviceEnabled;
PermissionStatus permissionGranted;
// 位置情報使える?
serviceEnabled = await location.serviceEnabled();
if ( !serviceEnabled ) {
serviceEnabled = await location.requestService();
if ( !serviceEnabled ) {
debugPrint( "位置情報が利用できません。。。" );
return LocateState(
location : location,
locateData : null,
isGetLocation : false
);
}
}
// アプリに許可してる?
permissionGranted = await location.hasPermission();
if ( permissionGranted == PermissionStatus.denied ) {
permissionGranted = await location.requestPermission();
if ( permissionGranted != PermissionStatus.granted ) {
debugPrint( "このアプリに対して位置情報の利用許可がおりていません。。。" );
return LocateState(
location : location,
locateData : null,
isGetLocation : false
);
}
}
debugPrint( "正常に位置情報を取得しました!" );
return LocateState(
location : location,
locateData : await location.getLocation(),
isGetLocation : true
);
}
// =============================================================================
// ログイン関係
// =============================================================================
// 変数の更新
void updateState() async
{
state.when(
error : (e,s) => state = AsyncValue.error(e,s),
loading : () => state = const AsyncValue.loading(),
data : (tmp) {
tmp.location.onLocationChanged.listen( ( LocationData currentLocation ) {
tmp = tmp.copyWith( locateData: currentLocation );
});
}
);
}
}
//
// Provider
//
final userProvider = AsyncNotifierProvider<LocationCnrl, LocateState>(() {
return LocationCnrl();
});
// 位置情報データ
final isLocateProvider = Provider<LocationData?>( ( ref ) =>
ref.watch( userProvider ).when(
error : (e,s) => null,
loading : () => null,
data : (data) => data.locateData
)
);
// 位置情報はとれてる?
final isGetLocateProvider = Provider<bool>( ( ref ) =>
ref.watch( userProvider ).when(
error : (e,s) => false,
loading : () => false,
data : (data) => true
)
);
//
// function
//
double calcDistance( double lon1, double lat1, double lon2, double lat2 ) {
double x1 = lon1 / 180 * 3.14;
double y1 = lat1 / 180 * 3.14;
double x2 = lon2 / 180 * 3.14;
double y2 = lat2 / 180 * 3.14;
return 6378.137 * acos(
( sin( y1 ) * sin( y2 ) ) + ( cos( y1 ) * cos( y2 ) * cos( x2 - x1 ) )
);
}