Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

march 29 18:44 #8

Merged
merged 2 commits into from
Mar 29, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions android/app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -132,8 +132,8 @@ android {
minSdkVersion rootProject.ext.minSdkVersion
targetSdkVersion rootProject.ext.targetSdkVersion
multiDexEnabled true
versionCode 14
versionName "0.5.9"
versionCode 15
versionName "0.5.10"
}
splits {
abi {
Expand Down
14 changes: 8 additions & 6 deletions app/locales/es/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,14 @@ import importFile from './import.json';
import exportFile from './exportscreen.json';
import licensesFile from './licensesscreen.json';
import overlapFile from './overlap.json';
import notificationFile from './notification.json';

export default {
...intro,
...locationTracking,
...importFile,
...exportFile,
...overlapFile,
...licensesFile,
...intro,
...locationTracking,
...importFile,
...exportFile,
...overlapFile,
...licensesFile,
...notificationFile,
};
8 changes: 8 additions & 0 deletions app/locales/es/notification.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"notification_main_text": "Comprueba tus posibles puntos de encuentro a diario",
"notification_title": "Analizar tus puntos de encuentro",
"notification_data_not_available": "\n\nNo tienes información pública de posibles puntos de encuentro descargada!\n\n",
"notification_warning_text": "Pues hacer click en el siguiente botón para generar una simulación de puntos de encuentro. \nAVISO: Estos puntos de encuentro no son casos reales, sino simulaciones",
"notification_random_data_button": "Haz click en este botón para generar una simulación",
"notifications":"Notificaciones"
}
4 changes: 2 additions & 2 deletions app/locales/es/overlap.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"overlap_title": "Comprobar posibles puntos de encuentro",
"overlap_para_1": "Los círculos verdes indican las ubicaciones en las que te has registrado más veces. Amplia el mapa para ver los marcadores rojos, que indican tus ubicaciones exactas guardadas en cada momento. \n\nHaz click en el botón para descargar la información pública sobre casos confirmados, que se muestra con los círculos de color púrpura claro.",
"show_overlap": "Incorporar información pública",
"overlap_para_1": "El registro de color verde representa tu historial de localizaciones\n\nLos círculos de color púrpura claro representan la información pública actual",
"show_overlap": "Haz click para ver la información pública disponible",
"loading_public_data": "cargando datos...",
"overlap_no_results_button_label": "Información pública incorporada",
"overlap_found_button_label": "Información pública incorporada",
Expand Down
256 changes: 197 additions & 59 deletions app/services/BroadcastingService.js
Original file line number Diff line number Diff line change
@@ -1,127 +1,265 @@
import { GetStoreData, SetStoreData } from '../helpers/General';

import { Alert, Platform } from 'react-native';
import BackgroundTimer from 'react-native-background-timer';
import UUIDGenerator from 'react-native-uuid-generator';
import Moment from 'moment';

import AndroidBLEAdvertiserModule from 'react-native-ble-advertiser';
import { NativeEventEmitter, NativeModules } from 'react-native';

var currentUUID = null;
var onDeviceFound = null;
var onBTStatusChange = null;
var lastSeen = {};

function saveContact(contact) {
// Persist this contact data in our local storage of time/lat/lon values
const c5_MINS = 1000 * 60 * 5;
const c28_DAYS = 1000 * 60 * 60 * 24 * 28;
const c1_HOUR = 1000 * 60;

GetStoreData('CONTACT_DATA').then(contactArrayString => {
var contactArray;
if (contactArrayString !== null) {
contactArray = JSON.parse(contactArrayString);
} else {
contactArray = [];
const MANUFACTURER_ID = 0xff;
const MANUFACTURER_DATA = [12, 23, 56];

function nowStr() {
return Moment(new Date()).format('H:mm')
}

/*
* Check if the contact is new in the last 5 mins.
*/
function isNewContact(contact) {
var nowLocal = new Date().getTime();
if (lastSeen[contact['uuid']] && lastSeen[contact['uuid']] > nowLocal - c5_MINS) {
//console.log('[Bluetooth]', nowStr(), currentUUID, 'Ignoring UUID for 5 mins:', contact['uuid']);
return false; // needs a space of 5 mins to log again.
}

lastSeen[contact['uuid']] = nowLocal;
return true;
}

/*
* Select only the last 28 days of data.
*/
function filterAfter(arrayIncludingTime, time) {
let curated = [];
for (let i = 0; i < arrayIncludingTime.length; i++) {
if (arrayIncludingTime[i]['time'] > time) {
curated.push(arrayIncludingTime[i]);
}
}
return curated;
}

// Always work in UTC, not the local time in the contactData
var nowUTC = new Date().toISOString();
var unixtimeUTC = Date.parse(nowUTC);
var unixtimeUTC_28daysAgo = unixtimeUTC - 60 * 60 * 24 * 1000 * 28;

// Save the contact using the current lat-lon and the
// calculated UTC time (maybe a few milliseconds off from
// when the GPS data was collected, but that's unimportant
// for what we are doing.)
console.log('[GPS] Saving point:', contactArray.length);
var lat_lon_time = {
uuid: contact['uuid'],
time: unixtimeUTC,
};
contactArray.push(lat_lon_time);
function saveContact(contact) {
// Persist this contact data in our local storage of time/uuid values
//console.log('[Bluetooth]', nowStr(), currentUUID, 'New Device Found', contact['uuid']);
if (isNewContact(contact)) {
GetStoreData('CONTACT_DATA', false).then(contactArray => {
if (!contactArray) {
contactArray = [];
}

SetStoreData('CONTACT_DATA', contactArray);
});
// Always work in UTC, not the local time in the contactData
var nowUTC = new Date().toISOString();
var unixtimeUTC = Date.parse(nowUTC);

// Curate the list of contacts, only keep the last 28 days
let curated = filterAfter(contactArray, unixtimeUTC - c28_DAYS);

var uuid_time = {
uuid: contact['uuid'],
time: unixtimeUTC,
};
curated.push(uuid_time);
console.log('[Bluetooth]', nowStr(), currentUUID,
'Saving contact:', contact['uuid'], curated.length);

SetStoreData('CONTACT_DATA', curated);
});
}
}

function saveMyUUID(me) {
// Persist this contact data in our local storage of time/lat/lon values

GetStoreData('MY_UUIDs').then(myUUIDArrayString => {
var myUUIDArray;
if (myUUIDArrayString !== null) {
myUUIDArray = JSON.parse(myUUIDArrayString);
} else {
GetStoreData('MY_UUIDs', false).then(myUUIDArray => {
if (!myUUIDArray) {
myUUIDArray = [];
}

// Always work in UTC, not the local time in the contactData
var nowUTC = new Date().toISOString();
var unixtimeUTC = Date.parse(nowUTC);
var unixtimeUTC_28daysAgo = unixtimeUTC - 60 * 60 * 24 * 1000 * 28;

// Curate the list of points, only keep the last 28 days
let curated = filterAfter(myUUIDArray, unixtimeUTC - c28_DAYS);

var uuid_time = {
uuid: me['uuid'],
time: unixtimeUTC,
};

console.log(
'[GPS] Saving myUUID:',
Moment(unixtimeUTC).format('MMM Do, H:mma'),
me['uuid'],
myUUIDArray.length,
'[Bluetooth]', nowStr(), me['uuid'],
'Saving myUUID:', me['uuid'], curated.length,
);
myUUIDArray.push(uuid_time);
curated.push(uuid_time);

SetStoreData('MY_UUIDs', myUUIDArray);
SetStoreData('MY_UUIDs', curated);
});
}

function loadLastUUIDAndBroadcast() {
GetStoreData('MY_UUIDs').then(myUUIDArrayString => {
var myUUIDArray;
if (myUUIDArrayString !== null) {
myUUIDArray = JSON.parse(myUUIDArrayString);
GetStoreData('MY_UUIDs', false).then(myUUIDArray => {
if (!myUUIDArray) {
console.log(
'Loading last uuid ',
'[Bluetooth]', nowStr(),
myUUIDArray[myUUIDArray.length - 1].uuid,
'Loading last uuid'
);
currentUUID = myUUIDArray[myUUIDArray.length - 1].uuid;
broadcast();
var lastUUID = myUUIDArray[myUUIDArray.length - 1].uuid;
broadcast(lastUUID);
} else {
generateNewUUIDAndBroadcast();
}
});
}

function broadcast() {
function broadcast(currentUUID) {
if (!currentUUID) return; // does not allow to start without UUID

// Do not run on iOS for now.
if (Platform.OS === 'android') {
console.log('Broadcasting: ', currentUUID);
AndroidBLEAdvertiserModule.setCompanyId(0xff);
AndroidBLEAdvertiserModule.broadcast(currentUUID, [12, 23, 56])
.then(sucess => {
console.log('Broadcasting Sucessful', sucess);
})
.catch(error => console.log('Broadcasting Error', error));
//console.log('[Bluetooth]', nowStr(), currentUUID, 'Broadcasting');
AndroidBLEAdvertiserModule.setCompanyId(MANUFACTURER_ID);
AndroidBLEAdvertiserModule.broadcast(currentUUID, MANUFACTURER_DATA)
.then(success => console.log('[Bluetooth]', nowStr(), currentUUID, 'Broadcasting Sucessful', success))
.catch(error => console.log('[Bluetooth]', nowStr(), currentUUID, 'Broadcasting Error', error));

//console.log('[Bluetooth]', nowStr(), currentUUID, "Starting Scanner");
AndroidBLEAdvertiserModule.scan(MANUFACTURER_DATA, {})
.then(success => console.log('[Bluetooth]', nowStr(), currentUUID, "Scan Successful", success))
.catch(error => console.log('[Bluetooth]', nowStr(), currentUUID, "Scan Error", error));
}
}

function stopBroadcast(currentUUID) {
if (!currentUUID) return; // does not allow to start without UUID

// Do not run on iOS for now.
if (Platform.OS === 'android') {
//console.log('[Bluetooth]', nowStr(), currentUUID, 'Stopping Broadcast');
AndroidBLEAdvertiserModule.stopBroadcast()
.then(success => console.log('[Bluetooth]', nowStr(), currentUUID, "Stop Broadcast Successful", success))
.catch(error => console.log('[Bluetooth]', nowStr(), currentUUID, "Stop Broadcast Error", error));

//console.log('[Bluetooth]', nowStr(), currentUUID, "Stopping Scanning");
AndroidBLEAdvertiserModule.stopScan()
.then(success => console.log('[Bluetooth]', nowStr(), currentUUID, "Stop Scan Successful", success))
.catch(error => console.log('[Bluetooth]', nowStr(), currentUUID, "Stop Scan Error", error));
}
}

function generateNewUUIDAndBroadcast() {
UUIDGenerator.getRandomUUID(uuid => {
console.log('[Bluetooth]', nowStr(), currentUUID, 'Renewing this UUID');
stopBroadcast(currentUUID);

currentUUID = uuid;
saveMyUUID({ uuid: uuid });
broadcast();

broadcast(currentUUID);
});
}

export default class BroadcastingServices {
static isBTActive() {
AndroidBLEAdvertiserModule.getAdapterState().then(result => {
console.log('[Bluetooth]', nowStr(), currentUUID, 'Bluetooth State', result);
if (result != 12) {
setTimeout(() =>
Alert.alert(
'Private Kit requires bluetooth to be enabled',
'Would you like to enable Bluetooth?',
[
{
text: 'Yes',
onPress: () => AndroidBLEAdvertiserModule.enableAdapter(),
},
{
text: 'No',
onPress: () => console.log('No Pressed'),
style: 'cancel',
},
],
),
1000);
return false;
} else {
return true;
}
}).catch(error => {
return false;
console.log('[Bluetooth]', nowStr(), currentUUID, "BT Not Enabled")
});
}

static start() {
const eventEmitter = new NativeEventEmitter(NativeModules.AndroidBLEAdvertiserModule);
onBTStatusChange = eventEmitter.addListener('onBTStatusChange', (status) => {
if (status.enabled)
BroadcastingServices.startAndSetCallbacks();
else
BroadcastingServices.stopAndClearCallbacks();
});

if (!BroadcastingServices.isBTActive()) return;

BroadcastingServices.startAndSetCallbacks();
}

static stop() {
if (onBTStatusChange) {
onBTStatusChange.remove();
onBTStatusChange = null;
}

if (!BroadcastingServices.isBTActive()) return;

BroadcastingServices.stopAndClearCallbacks();
}

static startAndSetCallbacks() {
// if it was already active
if (onDeviceFound) {
BroadcastingServices.stopAndClearCallbacks();
}

// listening event.
const eventEmitter = new NativeEventEmitter(NativeModules.AndroidBLEAdvertiserModule);
onDeviceFound = eventEmitter.addListener('onDeviceFound', (event) => {
//console.log('[Bluetooth]', nowStr(), currentUUID, 'New Device', event);
if (event.serviceUuids && event.serviceUuids.length > 0)
saveContact({ uuid: event.serviceUuids[0]});
});

// Get a Valid UUID and start broadcasting and scanning.
loadLastUUIDAndBroadcast();

BackgroundTimer.runBackgroundTimer(() => {
generateNewUUIDAndBroadcast();
}, 1000 * 60 * 60); // Every hour, change UUID

console.log('Starting Bluetooth');
}, c1_HOUR); // Every hour, change UUID
}

static stop(nav) {
console.log('Stopping Bluetooth');
static stopAndClearCallbacks() {
//console.log('[Bluetooth]', nowStr(), currentUUID, 'Stopping Bluetooth');
stopBroadcast(currentUUID);

if (onDeviceFound) {
onDeviceFound.remove();
onDeviceFound = null;
}

BackgroundTimer.stopBackgroundTimer();
}
}
4 changes: 2 additions & 2 deletions ios/PrivateKit/Info.plist
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,11 @@
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>0.5.9</string>
<string>0.5.10</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>14</string>
<string>15</string>
<key>LSRequiresIPhoneOS</key>
<true />
<key>NSAppTransportSecurity</key>
Expand Down
Loading