Фоновый процесс не отменяется, когда я нажимаю кнопку (Bluetooth -> выключен), чтобы сканировать близлежащие устройства Bluetooth.
Библиотеки иИспользуемые языки: реакции-нативный, реагировать-нативный-ble-plx, / реагировать-нативный-bluetooth-state-manager
Я довольно новичок в реакции-нативный и в программировании в целом.В настоящее время я занимаюсь разработкой приложения, которое использует некоторые библиотеки для управления и сканирования устройств Bluetooth.
Функциональность сканирования ближайших устройств Bluetooth может быть выполнена только при включенном Bluetooth.
ЕслиBluetooth не включен, пользователь все еще может нажать кнопку (touchableopacity) и получить уведомление о том, что он должен активировать Bluetooth.
В этот момент пользователь активирует Bluetooth, а затем, в некоторых случаях,приложение начинает обнаруживать устройства Bluetooth.Это реальная проблема.
Я хотел бы отменить первый OnPress, который остается в фоновом режиме?и заставьте пользователя нажать кнопку еще раз для сканирования устройств.
Когда появляется эта «ошибка», я получаю это предупреждение через React Native Debugger.
Предупреждение: Невозможно выполнить обновление состояния React для отключенного компонента.Это не работает, но это указывает на утечку памяти в вашем приложении.Чтобы исправить, отмените все подписки и асинхронные задачи в методе componentWillUnmount
Примечание: я должен смешать оба компонента componentWillUnmount ()?
Я застрял с этим на день, я бы действительноценю любую помощь.Заранее спасибо.
import React, { Component } from 'react';
import { NavigationActions, StackActions } from "react-navigation";
import {
Platform,
Text,
View,
Alert,
Button,
TouchableOpacity,
ActivityIndicator,
StyleSheet
} from 'react-native';
import {Agenda} from 'react-native-calendars';
import { BleManager, Device, BleError, LogLevel } from "react-native-ble-plx";
import axios from 'axios';
import {LocaleConfig} from 'react-native-calendars';
import SInfo from "react-native-sensitive-info";
import Icon from "react-native-vector-icons/Ionicons";
import BottomToolbar from 'react-native-bottom-toolbar';
import { BluetoothStatus } from 'react-native-bluetooth-status';
import Spinner from 'react-native-loading-spinner-overlay';
import BluetoothStateManager from 'react-native-bluetooth-state-manager';
LocaleConfig.locales['es'] = {
monthNames: ['Enero','Febrero','Marzo','Abril','Mayo','Junio','Julio','Agosto','Septiembre','Octubre','Noviembre','Diciembre'],
monthNamesShort: ['Ene.','Febr.','Mar.','Abr.','May.','Jun.','Jul.','Ago.','Sept.','Oct.','Nov.','Dic.'],
dayNames: ['Domingo','Lunes','Martes','Miercoles','Jueves','Viernes','Sabádo'],
dayNamesShort: ['Dom.','Lun.','Mar.','Mie.','Jue.','Vie.','Sáb.']
};
LocaleConfig.defaultLocale = 'es';
type Props = {};
type State = {
text: Array<string>
};
export default class Calendar extends Component {
static navigationOptions = ({ navigation }) => {
return {
title: /* navigation.getParam('user', '') + ' | */'Calendario de ponencias',
headerRight: (
<TouchableOpacity onPress={() => null}>
<View style={styles.buttonInfo}>
<Text style={styles.text}>INFO</Text>
</View>
</TouchableOpacity>
),headerLeft: null
};
};
_isMounted = false;
constructor(props) {
super(props);
this.state = {
items: {},
bluetoothState: null,
requesting: null,
ponencias: [],
counter: false,
btStatus: false,
ver: false,
spinner: false,
isLoading: true,
actualDay: '',
buttonColor: 'red' // default button color goes here
};
}
async componentDidMount(){
//this.checkInitialBluetoothState();
this.bluetoothStateChangeSubscription = await BluetoothStateManager.onStateChange(
this.onBluetoothStateChange,
true /*=emitCurrentState*/
);
this.setState({ isLoading: true });
this.loadPresentations();
}
componentWillUnmount() {
if (this.bluetoothStateChangeSubscription) {
this.bluetoothStateChangeSubscription.remove();
}
}
onBluetoothStateChange = bluetoothState => {
this.setState({ bluetoothState });
console.log(this.state.bluetoothState);
};
loadPresentations(){
SInfo.getItem('idToken',{}).then(idToken => {
console.log("idTOKEN4 " + idToken);
axios.get(`http://**.**.183.***:8080/api/lessons/` + idToken)
.then(response => {
console.log(response.data);
this.setState({ponencias: response.data})
this.setState({isLoading: false });
})
});
}
render() {
if (this.state.isLoading) {
return null;
}
const { navigation } = this.props;
return (
<View style={styles.container2}>
<Spinner
visible={this.state.ver}
textContent={'Confirmando asistencia...'}
textStyle={styles.spinnerTextStyle}
/>
<Agenda
items={this.state.items}
loadItemsForMonth={this.loadItems.bind(this)}
onDayPress={(day)=>{console.log('day pressed')}}
onDayChange={(day)=>{console.log('day changed')}}
selected={this.state.actualDay}
renderItem={this.renderItem.bind(this)}
renderEmptyDate={this.renderEmptyDate.bind(this)}
rowHasChanged={this.rowHasChanged.bind(this)}
theme={{calendarBackground: 'white', agendaKnobColor: 'grey'}}
/>
</View>
);
}
loadItems(day) {
const myObj = {
"ponencias": this.state.ponencias
};
setTimeout(() => {
for (let i = -15; i < 80; i++) {
const time = day.timestamp + i * 24 * 60 * 60 * 1000;
const strTime = this.timeToString(time);
if (!this.state.items[strTime]) {
this.state.items[strTime] = [];
let self = this;
myObj.ponencias.forEach(function(item,index){
if (strTime === item.day.date.substring(0, 10)) {
self.state.items[item.day.date.substring(0, 10)].push({
name: 'Ponencia ' + item.subject,
id: item.id,
height: Math.max(50, Math.floor(Math.random() * 150)),
date: item.day.date.substring(0, 10),
attendance: item.attendance,
});
}
});
}
}
const newItems = {};
Object.keys(this.state.items).forEach(key => {newItems[key] = this.state.items[key];});
this._isMounted = true;
if (this._isMounted) {
this.setState({
items: newItems
});
}
}, 1000);
}
renderItem(item) {
const manager = new BleManager();
return (
<View style={[styles.item, { width: "100%", backgroundColor: "white" }]}>
<TouchableOpacity onPress={()=> {this.presentation(item.id);}}><Text style={{color: "black", textDecorationLine: 'underline', marginLeft: 6, fontSize: Platform.OS === 'ios' ? 12 : 12}}>{item.name}</Text></TouchableOpacity>
<TouchableOpacity onPress={() => {
if(this.state.bluetoothState === 'PoweredOn'){
this.setState({counter: false})
}
if(this.state.bluetoothState === 'PoweredOff'){
manager.stopDeviceScan();
Alert.alert(
'Bluetooth desactivado',
'Debe activar el bluetooth para confirmar su asistencia a la ponencia.',
[
//{text: 'Ask me later', onPress: () => console.log('Ask me later pressed')},
//{text: 'Cancel', onPress: () => console.log('Cancel Pressed'), style: 'cancel'},
{text: 'OK', onPress: () => console.log('OK Pressed')},
],
{ cancelable: false }
)
return null;
}
if (this.state.counter) {
return null;
}
if (item.attendance === true) {
Alert.alert(
'Asistencia previamente confirmada',
'Su asistencia a la ponencia ya había sido confirmada con anterioridad.',
[
//{text: 'Ask me later', onPress: () => console.log('Ask me later pressed')},
//{text: 'Cancel', onPress: () => console.log('Cancel Pressed'), style: 'cancel'},
{text: 'OK', onPress: () => console.log('OK Pressed')},
],
{ cancelable: false }
)
return null;
}
if(this.state.bluetoothState === 'PoweredOff'){
this.setState({counter: true})
Alert.alert(
'Bluetooth desactivado',
'Debe activar el bluetooth para confirmar su asistencia a la ponencia.',
[
//{text: 'Ask me later', onPress: () => console.log('Ask me later pressed')},
//{text: 'Cancel', onPress: () => console.log('Cancel Pressed'), style: 'cancel'},
{text: 'OK', onPress: () => console.log('OK Pressed')},
],
{ cancelable: false }
)
return null;
}else if(this.state.bluetoothState === 'PoweredOn'){
if (this.checkDay(item)) {
if(item.attendance !== true){
console.log("entra");
this.setState({ ver: true });
var beacon1_detect = false;
var beacon2_detect = false;
var beacon3_detect = false;
var beacon1_detect_ios = false;
var beacon2_detect_ios = false;
var beacon3_detect_ios = false;
//this.setState({ ver: true });
if(this.state.bluetoothState === 'PoweredOff'){
manager.stopDeviceScan();
}else{
manager.onStateChange(newState => {
if (newState != "PoweredOn") return;
if(this.state.counter === false){
manager.startDeviceScan(
null,
{
allowDuplicates: false
},
(error, device) => {
if (error) {
return;
}
//this._log("Device: " + device.id, device);
if (device.id == 'D7:E7:89:5A:7A:49' || device.id == '47E488CF-1160-5FB6-E429-C3DEE737538E'){
beacon1_detect = true;
beacon1_detect_ios = true;
}
if (device.id == 'C9:6A:6E:07:6D:72' || device.id == '5D6D2889-ED22-940B-236C-EA882A2346D3'){
beacon2_detect = true;
beacon2_detect_ios = true;
}
if (device.id == 'D2:2B:25:30:D7:F8' || device.id == '32DD3745-C65A-850A-97FF-DA593FCDA2BB'){
beacon3_detect = true;
beacon3_detect_ios = true;
}
if((beacon1_detect && beacon2_detect && beacon3_detect) || beacon1_detect_ios && beacon2_detect_ios && beacon3_detect_ios){
// Ingresar que el alumno 'a' en cuestión ha asistido a la ponencia 'x' a la hora 'h'
this.registerAttendance(item);
item.attendance = true;
this.setState({ ver: false });
console.log("Alumno en clase");
manager.stopDeviceScan()
Alert.alert(
'Asistencia confirmada',
'Se ha confirmado tu asistencia a la ponencia.',
[
//{text: 'Ask me later', onPress: () => console.log('Ask me later pressed')},
//{text: 'Cancel', onPress: () => console.log('Cancel Pressed'), style: 'cancel'},
{text: 'OK', onPress: () => console.log('OK Pressed')},
],
{ cancelable: false }
)
}else{
console.log("Alumno no en clase. Detectando beacons.");
}
console.log("DEVICE " + device.name + " WITH MAC = " + device.id);
console.log("DEVICE " + device.name + " POWER = " + device.rssi + "dB");
//manager.stopDeviceScan()
}
);
}
}, true);
}
}
}else if(!this.checkDay(item)) {
Alert.alert(
'Asistencia no confirmada',
'Sólo puede confirmar la asistencia en el día correspondiente a la ponencia.',
[
//{text: 'Ask me later', onPress: () => console.log('Ask me later pressed')},
//{text: 'Cancel', onPress: () => console.log('Cancel Pressed'), style: 'cancel'},
{text: 'OK', onPress: () => console.log('OK Pressed')},
],
{ cancelable: false }
)
}
}
}}>
<View style={this.checkDay(item) ? styles.button : styles.buttonNo}>
<Text style={styles.text}>Confirmar asistencia</Text>
</View>
</TouchableOpacity>
<TouchableOpacity onPress={()=> {
if (item.attendance) {
this.poll(item.id);
}else{
Alert.alert(
'Asistencia no confirmada.',
'Su asistencia a la ponencia debe ser confirmada antes de realizar la encuesta.',
[
//{text: 'Ask me later', onPress: () => console.log('Ask me later pressed')},
//{text: 'Cancel', onPress: () => console.log('Cancel Pressed'), style: 'cancel'},
{text: 'OK', onPress: () => console.log('OK Pressed')},
],
{ cancelable: false }
)
return null;
}
}}>
<View style={this.checkAttendance(item) ? styles.buttonPoll : styles.buttonPollNo}>
<Text style={styles.text}>Realizar encuesta</Text>
</View>
</TouchableOpacity>
</View>
);
}
checkDay(item){
console.log(item);
var today = new Date();
var month = parseInt(today.getMonth()+1);
var hoy = today.getDate();
if (hoy < 10) {
hoy = '0' + hoy
}
if (month < 10) {
month = '0' + month
}
date = today.getFullYear() + "-" + month + "-" + hoy;
this.setState({ actualDay: date });
if (item.date === date && item.attendance === false) {
return true;
}
else{
return false;
}
}
checkAttendance (item){
if (item.attendance == false) {
return false;
}
else{
return true;
}
}
beacon = (item) => {
};
registerAttendance = (item) => {
SInfo.getItem('idToken',{}).then(idToken => {
console.log(idToken);
console.log(item.id);
axios.post('http://**.**.183.***:8080/api/attendance/' + item.id + '/' + idToken).then((response ) => {
console.log(response);
this.loadPresentations();
this.forceUpdate();
})
.catch((error) => {
console.log("axios error:",error);
})
});
}
poll = (idSurvey) => {
const resetAction = StackActions.reset({
index: 0,
actions: [
NavigationActions.navigate({
routeName: "Poll",
params: {
idSurvey: idSurvey
}
})
]
});
this.props.navigation.dispatch(resetAction);
};
presentation = (idPresentation) => {
const resetAction = StackActions.reset({
index: 0,
actions: [
NavigationActions.navigate({
routeName: "Presentation",
params: {
idPresentation: idPresentation
}
})
]
});
this.props.navigation.dispatch(resetAction);
};
renderEmptyDate() {
return (
<View style={styles.emptyDate}><Text>No hay ninguna ponencia</Text></View>
);
}
rowHasChanged(r1, r2) {
return r1.name !== r2.name;
}
timeToString(time) {
const date = new Date(time);
return date.toISOString().split('T')[0];
}
componentWillUnmount() {
this._isMounted = false;
}
}
const styles = StyleSheet.create({
item: {
backgroundColor: 'white',
flex: 1,
borderRadius: 5,
padding: 20,
alignItems: 'center',
flexDirection: 'row',
justifyContent: 'center',
marginTop: 17
},
container2: {
flex: 1,
backgroundColor: '#F5FCFF'
},
emptyDate: {
height: 15,
marginRight: 10,
flex:1,
paddingTop: 30
},
button: {
margin: 5,
paddingHorizontal: 6,
paddingVertical: 5,
borderRadius: 5,
backgroundColor: "red"
},
buttonNo: {
margin: 5,
paddingHorizontal: 6,
paddingVertical: 5,
borderRadius: 5,
backgroundColor: "#ffb2b2"
},
buttonPoll: {
marginRight: 20,
paddingHorizontal: 6,
paddingVertical: 5,
borderRadius: 5,
backgroundColor: Platform.OS === 'ios' ? "green" : "green"
},
buttonPollNo: {
marginRight: 20,
paddingHorizontal: 6,
paddingVertical: 5,
borderRadius: 5,
backgroundColor: "#76a076"
},
spinnerTextStyle: {
color: '#FFF'
},
buttonInfo: {
margin: 5,
paddingHorizontal: 8,
paddingVertical: 7,
backgroundColor: "blue"
},
text: {
color: '#fff',
fontWeight: "bold",
fontSize: Platform.OS === 'ios' ? 10 : 10
}
});