File name
Commit message
Commit date
File name
Commit message
Commit date
File name
Commit message
Commit date
import React, { useState, useEffect } from 'react';
import { View, Text, StyleSheet, Alert, TouchableOpacity, PermissionsAndroid } from 'react-native';
import AsyncStorage from '@react-native-async-storage/async-storage';
import crypto from 'crypto-js';
import Api from '../api/ApiUtils';
import { useNavigation } from '@react-navigation/native';
import Icon from 'react-native-vector-icons/FontAwesome';
import Geolocation from 'react-native-geolocation-service';
const GpsScreen = () => {
const [isMeasuring, setIsMeasuring] = useState(false);
const [elapsedTime, setElapsedTime] = useState(0);
const [tripId, setTripId] = useState('');
const [userId, setUserId] = useState('');
const [locationData, setLocationData] = useState({
latitude: [],
longitude: [],
timestamp: []
}); // 위치 데이터 상태 수정
const [watchId, setWatchId] = useState(null);
const navigation = useNavigation();
useEffect(() => {
let timer;
if (isMeasuring) {
timer = setInterval(() => {
setElapsedTime(prevElapsedTime => prevElapsedTime + 1);
}, 1000);
} else {
clearInterval(timer);
}
return () => {
clearInterval(timer);
};
}, [isMeasuring]);
useEffect(() => {
const fetchUserId = async () => {
try {
const storedUserId = await AsyncStorage.getItem('user_id');
if (storedUserId !== null) {
setUserId(storedUserId);
}
} catch (error) {
console.error('Error fetching user_id from AsyncStorage:', error);
}
};
fetchUserId();
}, []);
const generateTripId = () => {
const rand = Math.random().toString();
const date = new Date();
const sha256Hash = crypto.SHA256(rand + ',' + date.toString()).toString(crypto.enc.Hex);
return sha256Hash;
};
const requestLocationPermission = async () => {
try {
const granted = await PermissionsAndroid.request(
PermissionsAndroid.PERMISSIONS.ACCESS_FINE_LOCATION
);
return granted === PermissionsAndroid.RESULTS.GRANTED;
} catch (err) {
console.warn(err);
return false;
}
};
const handleStart = async () => {
const permissionGranted = await requestLocationPermission();
if (!permissionGranted) {
Alert.alert('위치 권한 오류', '위치 권한을 허용해야 합니다.');
return;
}
try {
const newTripId = generateTripId();
setTripId(newTripId);
setIsMeasuring(true);
startLocationTracking();
} catch (error) {
console.error('Error starting location tracking:', error);
Alert.alert('오류', '위치 추적을 시작할 수 없습니다.');
setIsMeasuring(false);
}
};
const handleStop = async () => {
setIsMeasuring(false);
setElapsedTime(0);
if (watchId !== null) {
Geolocation.clearWatch(watchId);
setWatchId(null);
}
try {
const dataToSend = {
user_id: userId,
trip_id: tripId,
trip_log: locationData,
};
console.log('Data to send:', dataToSend);
try {
const response = await Api.sendTripLog(dataToSend, navigation);
console.log("Response:", response);
} catch (error) {
Alert.alert('로그인 실패', error.message);
}
} catch (error) {
console.error('Error stopping location tracking:', error);
}
};
const handleLogout = () => {
AsyncStorage.removeItem('token');
navigation.navigate('Login');
Alert.alert('로그아웃', '로그아웃되었습니다.');
};
const handleHistory = () => {
navigation.navigate('Analysis');
Alert.alert('히스토리', '히스토리 화면으로 이동합니다.');
};
const startLocationTracking = () => {
const id = Geolocation.watchPosition(
(position) => {
const { latitude, longitude } = position.coords;
const time = new Date().toISOString();
const timestamp = formatDate(time);
setLocationData(prevData => ({
latitude: [...prevData.latitude, latitude],
longitude: [...prevData.longitude, longitude],
timestamp: [...prevData.timestamp, timestamp]
}));
console.log('위치 업데이트:', { latitude, longitude, timestamp: timestamp });
},
(error) => {
console.error('위치 감시 중 오류:', error);
},
{ enableHighAccuracy: true, distanceFilter: 0, interval: 1000, fastestInterval: 1000, forceRequestLocation: true }
);
setWatchId(id);
};
const formatTime = (seconds) => {
const hours = Math.floor(seconds / 3600);
const minutes = Math.floor((seconds % 3600) / 60);
const secs = seconds % 60;
return `${String(hours).padStart(2, '0')}:${String(minutes).padStart(2, '0')}:${String(secs).padStart(2, '0')}`;
};
// 한국 시간으로 변환하는 함수
const formatDate = (time) => {
const date = new Date(time);
const year = date.getFullYear();
const month = `0${date.getMonth() + 1}`.slice(-2);
const day = `0${date.getDate()}`.slice(-2);
const hours = `0${date.getHours()}`.slice(-2);
const minutes = `0${date.getMinutes()}`.slice(-2);
const seconds = `0${date.getSeconds()}`.slice(-2);
const milliseconds = `00${date.getMilliseconds()}`.slice(-3);
return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}.${milliseconds}`;
};
return (
<View style={styles.container}>
<View style={styles.timerContainer}>
<Text style={styles.time}>{formatTime(elapsedTime)}</Text>
</View>
<View style={styles.buttonRowContainer}>
<TouchableOpacity
style={[styles.button, styles.startButton, isMeasuring && styles.buttonDisabled]}
onPress={handleStart}
disabled={isMeasuring}
>
<Icon name="play" size={20} color="#FFFFFF" />
<Text style={styles.buttonText}>측정 시작</Text>
</TouchableOpacity>
<TouchableOpacity
style={[styles.button, styles.stopButton, !isMeasuring && styles.buttonDisabled]}
onPress={handleStop}
disabled={!isMeasuring}
>
<Icon name="stop" size={20} color="#FFFFFF" />
<Text style={styles.buttonText}>측정 종료</Text>
</TouchableOpacity>
</View>
<View style={styles.fullWidthButtonContainer}>
<TouchableOpacity
style={[styles.fullWidthButton, styles.historyButton]}
onPress={handleHistory}
>
<Text style={styles.fullWidthButtonText}>분석결과</Text>
</TouchableOpacity>
<TouchableOpacity
style={[styles.fullWidthButton, styles.logoutButton]}
onPress={handleLogout}
>
<Text style={styles.blackbuttonText}>로그아웃</Text>
</TouchableOpacity>
</View>
</View>
);
};
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
padding: 20,
backgroundColor: '#F7F7F7', // 배경색
},
timerContainer: {
marginVertical: 30,
padding: 20,
borderRadius: 10,
width: '100%',
alignItems: 'center',
},
time: {
fontSize: 68,
fontWeight: 'bold',
color: '#007AFF', // 타이머 색상
},
buttonRowContainer: {
flexDirection: 'row',
width: '100%',
justifyContent: 'space-between',
paddingHorizontal: 20,
marginBottom: 20,
},
button: {
flex: 1,
paddingVertical: 15,
borderRadius: 10,
marginHorizontal: 5,
alignItems: 'center',
justifyContent: 'center', // 중앙 정렬
},
startButton: {
backgroundColor: '#007AFF', // 시작 버튼 색상
},
stopButton: {
backgroundColor: '#FF3B30', // 종료 버튼 색상
},
fullWidthButtonContainer: {
width: '100%',
paddingHorizontal: 20,
},
fullWidthButton: {
paddingVertical: 15,
borderRadius: 10,
marginVertical: 5,
alignItems: 'center',
},
logoutButton: {
backgroundColor: '#eeeeee', // 로그아웃 버튼 색상 (연한 무채색)
},
historyButton: {
backgroundColor: '#CAF4FF', // 분석결과 버튼 색상 (연한 파란색)
},
buttonText: {
color: '#FFFFFF',
fontWeight: 'bold',
fontSize: 16,
},
blackbuttonText: {
fontWeight: 'bold',
fontSize: 16,
},
fullWidthButtonText: {
color: '#007AFF',
fontWeight: 'bold',
fontSize: 16,
},
buttonDisabled: {
opacity: 0.5,
},
});
export default GpsScreen;