Indoor Location new module (#287)

* Adding icons and text for manage location

* Adding manage location to main menu

* Adding class to manage location

* Adding view layout to manage location

* Share location switch created

* Basic listener added to switch

* Moving manage location to users menu

* Adding icons and text for manage location

* Adding manage location to main menu

* Adding class to manage location

* Adding view layout to manage location

* Share location switch created

* Basic listener added to switch

* Moving manage location to users menu

* Adding elements to indoor_location view

* Improving indoor_location with default text

* Logic to calculate distance

* Trying to connect to the API.

* Adding model to location distance

* Changing textview to listview

* Making request to MacStore API to get location of Mac

* Search user menu

* New designs manage location activity

* Connecting to swad api

* Connection to swad api working

* Location history showing up in activity

* Adding button and user code to find user

* Sorting locations and saving only one

* Implementing GetLastLocation API method

* Adding location preferences translations

* Adding translations to location menu toast

* Return without error from searching user

* Removing warning

* Adding translations

* Changing permissions

* Changing module name

* Making location serializable

* Changing deprecated implementation

* Cleaning code and refactoring deprecated classes

* Changing location name in menu

* Scanning all wifi networks

* Hiding white activities

* Showing more information in each location

* Fixing bug when searching user

* Fixing available networks sort

* Using roomCode instead of institutionCode

* Changes scheduling tasks

* Deleting dependencies

* Deleting useless import

* Getting correct mac

* Requesting permissions to user

* LocationTimeStamp inherits from Location

* Using new variable to soap object

* Setting const defaultValue

* Extracting common lines on update location click

* Extracting common lines on activity result

* Update SWADroid/src/main/res/values/strings.xml

Co-authored-by: Juan Miguel Boyero Corral <juanmi1982@gmail.com>

* Update SWADroid/src/main/res/values/strings.xml

Co-authored-by: Juan Miguel Boyero Corral <juanmi1982@gmail.com>

* Update SWADroid/src/main/res/values-es/strings.xml

Co-authored-by: Juan Miguel Boyero Corral <juanmi1982@gmail.com>

* Using functions to reduce code

* Update SWADroid/src/main/res/values/strings.xml

Co-authored-by: Juan Miguel Boyero Corral <juanmi1982@gmail.com>

* Update SWADroid/src/main/java/es/ugr/swad/swadroid/modules/indoorlocation/GetLastLocation.java

Co-authored-by: Juan Miguel Boyero Corral <juanmi1982@gmail.com>

* Update SWADroid/src/main/java/es/ugr/swad/swadroid/model/UserFilter.java

Co-authored-by: Juan Miguel Boyero Corral <juanmi1982@gmail.com>

* Update SWADroid/src/main/java/es/ugr/swad/swadroid/modules/indoorlocation/GetLocation.java

Co-authored-by: Juan Miguel Boyero Corral <juanmi1982@gmail.com>

* Update SWADroid/src/main/java/es/ugr/swad/swadroid/modules/indoorlocation/GetLocation.java

Co-authored-by: Juan Miguel Boyero Corral <juanmi1982@gmail.com>

* Update SWADroid/src/main/java/es/ugr/swad/swadroid/modules/indoorlocation/GetLocation.java

Co-authored-by: Juan Miguel Boyero Corral <juanmi1982@gmail.com>

* Update SWADroid/src/main/java/es/ugr/swad/swadroid/modules/indoorlocation/IndoorLocation.java

Co-authored-by: Juan Miguel Boyero Corral <juanmi1982@gmail.com>

* Update SWADroid/src/main/java/es/ugr/swad/swadroid/modules/indoorlocation/IndoorLocation.java

Co-authored-by: Juan Miguel Boyero Corral <juanmi1982@gmail.com>

* Update SWADroid/src/main/java/es/ugr/swad/swadroid/modules/indoorlocation/IndoorLocation.java

Co-authored-by: Juan Miguel Boyero Corral <juanmi1982@gmail.com>

* Update SWADroid/src/main/java/es/ugr/swad/swadroid/modules/indoorlocation/IndoorLocation.java

Co-authored-by: Juan Miguel Boyero Corral <juanmi1982@gmail.com>

* Update SWADroid/src/main/java/es/ugr/swad/swadroid/modules/indoorlocation/IndoorLocation.java

Co-authored-by: Juan Miguel Boyero Corral <juanmi1982@gmail.com>

* Update SWADroid/src/main/java/es/ugr/swad/swadroid/modules/indoorlocation/IndoorLocation.java

Co-authored-by: Juan Miguel Boyero Corral <juanmi1982@gmail.com>

* Update SWADroid/src/main/java/es/ugr/swad/swadroid/modules/indoorlocation/IndoorLocation.java

Co-authored-by: Juan Miguel Boyero Corral <juanmi1982@gmail.com>

* Update SWADroid/src/main/java/es/ugr/swad/swadroid/modules/indoorlocation/IndoorLocation.java

Co-authored-by: Juan Miguel Boyero Corral <juanmi1982@gmail.com>

* Update SWADroid/src/main/java/es/ugr/swad/swadroid/modules/indoorlocation/IndoorLocation.java

Co-authored-by: Juan Miguel Boyero Corral <juanmi1982@gmail.com>

* Constant moved to class level

* Update SWADroid/src/main/java/es/ugr/swad/swadroid/modules/indoorlocation/SendCurrentLocation.java

Co-authored-by: Juan Miguel Boyero Corral <juanmi1982@gmail.com>

* Update SWADroid/src/main/java/es/ugr/swad/swadroid/modules/indoorlocation/SendCurrentLocation.java

Co-authored-by: Juan Miguel Boyero Corral <juanmi1982@gmail.com>

* Update SWADroid/src/main/java/es/ugr/swad/swadroid/modules/indoorlocation/SendCurrentLocation.java

Co-authored-by: Juan Miguel Boyero Corral <juanmi1982@gmail.com>

* Update SWADroid/src/main/java/es/ugr/swad/swadroid/modules/messages/SearchUsers.java

Co-authored-by: Juan Miguel Boyero Corral <juanmi1982@gmail.com>

* Update SWADroid/src/main/res/values-es/strings.xml

Co-authored-by: Juan Miguel Boyero Corral <juanmi1982@gmail.com>

* Update SWADroid/src/main/res/values-es/strings.xml

Co-authored-by: Juan Miguel Boyero Corral <juanmi1982@gmail.com>

* Update SWADroid/src/main/res/values-es/strings.xml

Co-authored-by: Juan Miguel Boyero Corral <juanmi1982@gmail.com>

* Update SWADroid/src/main/res/values-es/strings.xml

Co-authored-by: Juan Miguel Boyero Corral <juanmi1982@gmail.com>

* Update SWADroid/src/main/res/values-es/strings.xml

Co-authored-by: Juan Miguel Boyero Corral <juanmi1982@gmail.com>

* Update SWADroid/src/main/res/values-es/strings.xml

Co-authored-by: Juan Miguel Boyero Corral <juanmi1982@gmail.com>

* Update SWADroid/src/main/res/values-es/strings.xml

Co-authored-by: Juan Miguel Boyero Corral <juanmi1982@gmail.com>

* Update SWADroid/src/main/res/values/strings.xml

Co-authored-by: Juan Miguel Boyero Corral <juanmi1982@gmail.com>

* Update SWADroid/src/main/res/values/strings.xml

Co-authored-by: Juan Miguel Boyero Corral <juanmi1982@gmail.com>

* Update SWADroid/src/main/res/values/strings.xml

Co-authored-by: Juan Miguel Boyero Corral <juanmi1982@gmail.com>

* Update SWADroid/src/main/res/values/strings.xml

Co-authored-by: Juan Miguel Boyero Corral <juanmi1982@gmail.com>

* Update SWADroid/src/main/res/values/strings.xml

Co-authored-by: Juan Miguel Boyero Corral <juanmi1982@gmail.com>

* Adding dependency to preferences

* Changing indoor location title text

* Showing text when no location is found

* Allow always location option

* Adding new button to show mac

* Find mac button added and working

* Stopping scheduler when user can't be located

* Update SWADroid/src/main/java/es/ugr/swad/swadroid/model/LocationTimeStamp.java

Co-authored-by: Juan Miguel Boyero Corral <juanmi1982@gmail.com>

* Update SWADroid/src/main/java/es/ugr/swad/swadroid/model/LocationTimeStamp.java

Co-authored-by: Juan Miguel Boyero Corral <juanmi1982@gmail.com>

* Update SWADroid/src/main/java/es/ugr/swad/swadroid/model/LocationTimeStamp.java

Co-authored-by: Juan Miguel Boyero Corral <juanmi1982@gmail.com>

* Update SWADroid/src/main/res/xml/preferences.xml

Co-authored-by: Juan Miguel Boyero Corral <juanmi1982@gmail.com>

* Update material version to 1.2.1

* Updating plugin

* Fixing API permissions

* Update gradle/wrapper/gradle-wrapper.properties

* Minor code style improvements

* Fix IndexOutOfBoundsException

* Add default locale to SimpleDateFormat

* Use complete Gradle distribution

* Update authors

* Update CHANGELOG

* Remove unused import

* Minor code style improvements

Co-authored-by: javibl8@correo.ugr.es <javier.bueno@jitkey.com>
Co-authored-by: Juan Miguel Boyero Corral <juanmi1982@gmail.com>
This commit is contained in:
Javier Bueno López 2020-10-14 19:50:20 +02:00 committed by GitHub
parent df40491a2f
commit ab0898c571
106 changed files with 1733 additions and 21 deletions

View File

@ -93,4 +93,5 @@ dependencies {
implementation 'com.google.zxing:core:3.4.1'
implementation 'com.google.code.gson:gson:2.8.6'
implementation 'com.google.firebase:firebase-core:17.5.1'
implementation 'com.google.android.material:material:1.2.1'
}

View File

@ -3,6 +3,9 @@
package="es.ugr.swad.swadroid"
android:installLocation="auto" >
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.GET_ACCOUNTS" android:maxSdkVersion="22"/>
@ -14,6 +17,7 @@
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-feature
android:name="android.hardware.touchscreen"
@ -239,6 +243,46 @@
android:name="android.support.PARENT_ACTIVITY"
android:value="es.ugr.swad.swadroid.SWADMain" />
</activity>
<activity
android:name=".modules.indoorlocation.IndoorLocation"
android:theme="@style/Theme.AppCompat.Light"
android:parentActivityName="es.ugr.swad.swadroid.SWADMain" >
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value="es.ugr.swad.swadroid.SWADMain" />
</activity>
<activity
android:name=".modules.indoorlocation.GetLocation"
android:theme="@style/Theme.AppCompat.Translucent"
android:parentActivityName="es.ugr.swad.swadroid.SWADMain" >
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value="es.ugr.swad.swadroid.SWADMain" />
</activity>
<activity
android:name=".modules.indoorlocation.GetLastLocation"
android:theme="@style/Theme.AppCompat.Translucent"
android:parentActivityName="es.ugr.swad.swadroid.SWADMain" >
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value="es.ugr.swad.swadroid.SWADMain" />
</activity>
<activity
android:name=".modules.indoorlocation.SendCurrentLocation"
android:theme="@style/Theme.AppCompat.Translucent"
android:parentActivityName="es.ugr.swad.swadroid.SWADMain" >
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value="es.ugr.swad.swadroid.SWADMain" />
</activity>
<activity
android:name=".modules.indoorlocation.GetAvailableRoles"
android:theme="@style/Theme.AppCompat.Translucent"
android:parentActivityName="es.ugr.swad.swadroid.SWADMain" >
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value="es.ugr.swad.swadroid.SWADMain" />
</activity>
<activity
android:name="es.ugr.swad.swadroid.modules.information.Information"
android:configChanges="orientation|screenSize"

View File

@ -231,6 +231,30 @@ public class Constants {
* Request code for search users
*/
public static final int SEARCH_USERS_REQUEST_CODE = 40;
/**
* Request code for Manage Location
*/
public static final int MANAGE_LOCATION = 41;
/**
* Request code for Find User
*/
public static final int FIND_USER = 42;
/**
* Request code for Get Location
*/
public static final int GET_LOCATION = 43;
/**
* Request code for Get Last Location
*/
public static final int GET_LAST_LOCATION = 44;
/**
* Request code for Send Current Location
*/
public static final int SEND_CURRENT_LOCATION = 45;
/**
* Request code for Get Available Roles
*/
public static final int GET_AVAILABLE_ROLES = 46;
/**
* Request code for CAMERA permission
*/
@ -239,6 +263,10 @@ public class Constants {
* Request code for WRITE_EXTERNAL_STORAGE permission
*/
public static final int PERMISSIONS_REQUEST_WRITE_EXTERNAL_STORAGE = 101;
/**
* Request code for PERMISSION_MULTIPLE permissions
*/
public static final int PERMISSION_MULTIPLE = 102;
/**
* Prefix tag name for Logcat
*/

View File

@ -60,6 +60,7 @@ import es.ugr.swad.swadroid.modules.courses.Courses;
import es.ugr.swad.swadroid.modules.downloads.DownloadsManager;
import es.ugr.swad.swadroid.modules.groups.MyGroupsManager;
import es.ugr.swad.swadroid.modules.information.Information;
import es.ugr.swad.swadroid.modules.indoorlocation.IndoorLocation;
import es.ugr.swad.swadroid.modules.login.Login;
import es.ugr.swad.swadroid.modules.login.LoginActivity;
import es.ugr.swad.swadroid.modules.messages.Messages;
@ -580,6 +581,8 @@ public class SWADMain extends MenuExpandableListActivity {
mUsersData.add(getMenuItem(R.string.myGroupsModuleLabel, R.string.fa_sitemap));
//Generate QR code
mUsersData.add(getMenuItem(R.string.generateQRModuleLabel, R.string.fa_qrcode));
//Manage location
mUsersData.add(getMenuItem(R.string.manageLocation, R.string.fa_map_marker));
//Messages category
//Notifications
@ -685,6 +688,9 @@ public class SWADMain extends MenuExpandableListActivity {
} else if (keyword.equals(getString(R.string.generateQRModuleLabel))) {
activity = new Intent(ctx, GenerateQR.class);
startActivityForResult(activity, Constants.GENERATE_QR_REQUEST_CODE);
} else if (keyword.equals(getString(R.string.manageLocation))) {
activity = new Intent(ctx, IndoorLocation.class);
startActivityForResult(activity, Constants.MANAGE_LOCATION);
} else if (keyword.equals(getString(R.string.documentsDownloadModuleLabel))) {
activity = new Intent(ctx, DownloadsManager.class);
activity.putExtra("downloadsAreaCode", Constants.DOCUMENTS_AREA_CODE);

View File

@ -465,6 +465,7 @@ public class DataBaseHelper {
crypto.decrypt(ent.getString("surname2Recipient")),
crypto.decrypt(ent.getString("firstnameRecipient")),
crypto.decrypt(ent.getString("photoRecipient")),
ent.getInt("userCode"),
false,
ent.getDouble("score"));
break;

View File

@ -54,6 +54,10 @@ public class FrequentUser extends Model implements Serializable{
* Full path where user's picture is stored.
*/
private String userPhoto;
/**
* Unique identifier for each user.
*/
private int userCode;
/**
* Is a receiver?.
*/
@ -72,16 +76,18 @@ public class FrequentUser extends Model implements Serializable{
* @param userSurname2 User last surname.
* @param userFirstname User name.
* @param userPhoto Full path where user's picture is stored.
* @param userCode User code.
* @param selectedCheckbox Is a receiver?.
* @param score Score of frequent recipient
*/
public FrequentUser(String idUser, String userNickname, String userSurname1, String userSurname2, String userFirstname, String userPhoto, boolean selectedCheckbox, double score) {
public FrequentUser(String idUser, String userNickname, String userSurname1, String userSurname2, String userFirstname, String userPhoto, int userCode, boolean selectedCheckbox, double score) {
this.idUser = idUser;
this.userNickname = userNickname;
this.userSurname1 = userSurname1;
this.userSurname2 = userSurname2;
this.userFirstname = userFirstname;
this.userPhoto = userPhoto;
this.userCode = userCode;
this.selectedCheckbox = selectedCheckbox;
this.score = score;
}
@ -194,6 +200,24 @@ public class FrequentUser extends Model implements Serializable{
this.userPhoto = userPhoto;
}
/**
* Gets userCode.
*
* @return the userPhoto
*/
public int getUserCode() {
return userCode;
}
/**
* Sets userCode.
*
* @param userCode
*/
public void setUserCode(int userCode) {
this.userCode = userCode;
}
/**
* Get if checkbox is selected.
*

View File

@ -0,0 +1,371 @@
package es.ugr.swad.swadroid.model;
import org.ksoap2.serialization.PropertyInfo;
import java.io.Serializable;
import java.util.Hashtable;
public class Location extends Model implements Serializable {
protected int institutionCode;
protected String institutionShortName;
protected String institutionFullName;
protected int centerCode;
protected String centerShortName;
protected String centerFullName;
protected int buildingCode;
protected String buildingShortName;
protected String buildingFullName;
protected int floor;
protected int roomCode;
protected String roomShortName;
protected String roomFullName;
protected static final PropertyInfo PI_id = new PropertyInfo();
protected static final PropertyInfo PI_institutionCode = new PropertyInfo();
protected static final PropertyInfo PI_institutionShortName = new PropertyInfo();
protected static final PropertyInfo PI_institutionFullName = new PropertyInfo();
protected static final PropertyInfo PI_centerCode = new PropertyInfo();
protected static final PropertyInfo PI_centerShortName = new PropertyInfo();
protected static final PropertyInfo PI_centerFullName = new PropertyInfo();
protected static final PropertyInfo PI_buildingCode = new PropertyInfo();
protected static final PropertyInfo PI_buildingShortName = new PropertyInfo();
protected static final PropertyInfo PI_buildingFullName = new PropertyInfo();
protected static final PropertyInfo PI_floor = new PropertyInfo();
protected static final PropertyInfo PI_roomCode = new PropertyInfo();
protected static final PropertyInfo PI_roomShortName = new PropertyInfo();
protected static final PropertyInfo PI_roomFullName = new PropertyInfo();
protected static PropertyInfo[] PI_PROP_ARRAY =
{
PI_id,
PI_institutionCode,
PI_institutionShortName,
PI_institutionFullName,
PI_centerCode,
PI_centerShortName,
PI_centerFullName,
PI_buildingCode,
PI_buildingShortName,
PI_buildingFullName,
PI_floor,
PI_roomCode,
PI_roomShortName,
PI_roomFullName
};
public Location(int institutionCode, String institutionShortName, String institutionFullName, int centerCode, String centerShortName, String centerFullName, int buildingCode, String buildingShortName, String buildingFullName, int floor, int roomCode, String roomShortName, String roomFullName) {
this.institutionCode = institutionCode;
this.institutionShortName = institutionShortName;
this.institutionFullName = institutionFullName;
this.centerCode = centerCode;
this.centerShortName = centerShortName;
this.centerFullName = centerFullName;
this.buildingCode = buildingCode;
this.buildingShortName = buildingShortName;
this.buildingFullName = buildingFullName;
this.floor = floor;
this.roomCode = roomCode;
this.roomShortName = roomShortName;
this.roomFullName = roomFullName;
}
public int getInstitutionCode() {
return institutionCode;
}
public void setInstitutionCode(int institutionCode) {
this.institutionCode = institutionCode;
}
public String getInstitutionShortName() {
return institutionShortName;
}
public void setInstitutionShortName(String institutionShortName) {
this.institutionShortName = institutionShortName;
}
public String getInstitutionFullName() {
return institutionFullName;
}
public void setInstitutionFullName(String institutionFullName) {
this.institutionFullName = institutionFullName;
}
public int getCenterCode() {
return centerCode;
}
public void setCenterCode(int centerCode) {
this.centerCode = centerCode;
}
public String getCenterShortName() {
return centerShortName;
}
public void setCenterShortName(String centerShortName) {
this.centerShortName = centerShortName;
}
public String getCenterFullName() {
return centerFullName;
}
public void setCenterFullName(String centerFullName) {
this.centerFullName = centerFullName;
}
public int getBuildingCode() {
return buildingCode;
}
public void setBuildingCode(int buildingCode) {
this.buildingCode = buildingCode;
}
public String getBuildingShortName() {
return buildingShortName;
}
public void setBuildingShortName(String buildingShortName) {
this.buildingShortName = buildingShortName;
}
public String getBuildingFullName() {
return buildingFullName;
}
public void setBuildingFullName(String buildingFullName) {
this.buildingFullName = buildingFullName;
}
public int getFloor() {
return floor;
}
public void setFloor(int floor) {
this.floor = floor;
}
public int getRoomCode() {
return roomCode;
}
public void setRoomCode(int roomCode) {
this.roomCode = roomCode;
}
public String getRoomShortName() {
return roomShortName;
}
public void setRoomShortName(String roomShortName) {
this.roomShortName = roomShortName;
}
public String getRoomFullName() {
return roomFullName;
}
public void setRoomFullName(String roomFullName) {
this.roomFullName = roomFullName;
}
@Override
public Object getProperty(int param) {
Object object = null;
switch (param) {
case 0:
object = this.getId();
break;
case 1:
object = institutionCode;
break;
case 2:
object = institutionShortName;
break;
case 3:
object = institutionFullName;
break;
case 4:
object = centerCode;
break;
case 5:
object = centerShortName;
break;
case 6:
object = centerFullName;
break;
case 7:
object = buildingCode;
break;
case 8:
object = buildingShortName;
break;
case 9:
object = buildingFullName;
break;
case 10:
object = floor;
break;
case 11:
object = roomCode;
break;
case 12:
object = roomShortName;
break;
case 13:
object = roomFullName;
break;
}
return object;
}
@Override
public int getPropertyCount() {
return PI_PROP_ARRAY.length;
}
@Override
public void setProperty(int param, Object obj) {
switch (param) {
case 0:
this.setId((Long) obj);
break;
case 1:
institutionCode = (Integer) obj;
break;
case 2:
institutionShortName = (String) obj;
break;
case 3:
institutionFullName = (String) obj;
break;
case 4:
centerCode = (Integer) obj;
break;
case 5:
centerShortName = (String) obj;
break;
case 6:
centerFullName = (String) obj;
break;
case 7:
buildingCode = (Integer) obj;
break;
case 8:
buildingShortName = (String) obj;
break;
case 9:
buildingFullName = (String) obj;
break;
case 10:
floor = (Integer) obj;
break;
case 11:
roomCode = (Integer) obj;
break;
case 12:
roomShortName = (String) obj;
break;
case 13:
roomFullName = (String) obj;
break;
}
}
@Override
public void getPropertyInfo(int param, Hashtable properties, PropertyInfo propertyInfo) {
switch (param) {
case 0:
propertyInfo.type = PropertyInfo.LONG_CLASS;
propertyInfo.name = "id";
break;
case 1:
propertyInfo.type = PropertyInfo.INTEGER_CLASS;
propertyInfo.name = "institutionCode";
break;
case 2:
propertyInfo.type = PropertyInfo.STRING_CLASS;
propertyInfo.name = "institutionShortName";
break;
case 3:
propertyInfo.type = PropertyInfo.STRING_CLASS;
propertyInfo.name = "institutionFullName";
break;
case 4:
propertyInfo.type = PropertyInfo.INTEGER_CLASS;
propertyInfo.name = "centerCode";
break;
case 5:
propertyInfo.type = PropertyInfo.STRING_CLASS;
propertyInfo.name = "centerShortName";
break;
case 6:
propertyInfo.type = PropertyInfo.STRING_CLASS;
propertyInfo.name = "centerFullName";
break;
case 7:
propertyInfo.type = PropertyInfo.INTEGER_CLASS;
propertyInfo.name = "buildingCode";
break;
case 8:
propertyInfo.type = PropertyInfo.STRING_CLASS;
propertyInfo.name = "buildingShortName";
break;
case 9:
propertyInfo.type = PropertyInfo.STRING_CLASS;
propertyInfo.name = "buildingFullName";
break;
case 10:
propertyInfo.type = PropertyInfo.INTEGER_CLASS;
propertyInfo.name = "floor";
break;
case 11:
propertyInfo.type = PropertyInfo.INTEGER_CLASS;
propertyInfo.name = "roomCode";
break;
case 12:
propertyInfo.type = PropertyInfo.STRING_CLASS;
propertyInfo.name = "roomShortName";
break;
case 13:
propertyInfo.type = PropertyInfo.STRING_CLASS;
propertyInfo.name = "roomFullName";
break;
}
}
@Override
public String toString() {
return "Location{" +
"institutionCode=" + institutionCode +
", institutionShortName='" + institutionShortName + '\'' +
", institutionFullName='" + institutionFullName + '\'' +
", centerCode=" + centerCode +
", centerShortName='" + centerShortName + '\'' +
", centerFullName='" + centerFullName + '\'' +
", buildingCode=" + buildingCode +
", buildingShortName='" + buildingShortName + '\'' +
", buildingFullName='" + buildingFullName + '\'' +
", floor=" + floor +
", roomCode=" + roomCode +
", roomShortName='" + roomShortName + '\'' +
", roomFullName='" + roomFullName + '\'' +
'}';
}
}

View File

@ -0,0 +1,79 @@
package es.ugr.swad.swadroid.model;
import org.ksoap2.serialization.PropertyInfo;
import java.io.Serializable;
import java.util.Hashtable;
public class LocationTimeStamp extends Location implements Serializable {
private int checkInTime;
public LocationTimeStamp(int institutionCode, String institutionShortName, String institutionFullName, int centerCode, String centerShortName, String centerFullName, int buildingCode, String buildingShortName, String buildingFullName, int floor, int roomCode, String roomShortName, String roomFullName, int checkInTime) {
super(institutionCode, institutionShortName, institutionFullName, centerCode, centerShortName, centerFullName, buildingCode, buildingShortName, buildingFullName, floor, roomCode, roomShortName, roomFullName);
this.checkInTime = checkInTime;
}
public int getCheckInTime() {
return checkInTime;
}
public void setCheckInTime(int checkInTime) {
this.checkInTime = checkInTime;
}
@Override
public Object getProperty(int param) {
Object object;
if (param == 14) {
object = checkInTime;
} else {
object = super.getProperty(param);
}
return object;
}
@Override
public int getPropertyCount() {
return PI_PROP_ARRAY.length;
}
@Override
public void setProperty(int param, Object obj) {
if (param == 14) {
checkInTime = (int) obj;
} else {
super.setProperty(param, obj);
}
}
@Override
public void getPropertyInfo(int param, Hashtable properties, PropertyInfo propertyInfo) {
if (param == 14) {
propertyInfo.type = PropertyInfo.INTEGER_CLASS;
propertyInfo.name = "checkInTime";
} else {
super.getPropertyInfo(param, properties, propertyInfo);
}
}
@Override
public String toString() {
return "LocationTimeStamp{" +
"institutionCode=" + institutionCode +
", institutionShortName='" + institutionShortName + '\'' +
", institutionFullName='" + institutionFullName + '\'' +
", centerCode=" + centerCode +
", centerShortName='" + centerShortName + '\'' +
", centerFullName='" + centerFullName + '\'' +
", buildingCode=" + buildingCode +
", buildingShortName='" + buildingShortName + '\'' +
", buildingFullName='" + buildingFullName + '\'' +
", floor=" + floor +
", roomCode=" + roomCode +
", roomShortName='" + roomShortName + '\'' +
", roomFullName='" + roomFullName + '\'' +
", checkInTime'" + checkInTime + '\'' +
'}';
}
}

View File

@ -0,0 +1,76 @@
package es.ugr.swad.swadroid.model;
import org.ksoap2.serialization.PropertyInfo;
import java.io.Serializable;
import java.util.Hashtable;
public class Roles extends Model implements Serializable {
private int rol;
protected static final PropertyInfo PI_id = new PropertyInfo();
protected static final PropertyInfo PI_roles = new PropertyInfo();
protected static PropertyInfo[] PI_PROP_ARRAY =
{
PI_id,
PI_roles
};
public Roles(int rol) {
this.rol = rol;
}
public int getRol() {
return rol;
}
public void setRol(int rol) {
this.rol = rol;
}
@Override
public Object getProperty(int param) {
Object object = null;
switch (param) {
case 0:
object = this.getId();
break;
case 1:
object = rol;
break;
}
return object;
}
@Override
public int getPropertyCount() {
return PI_PROP_ARRAY.length;
}
@Override
public void setProperty(int param, Object obj) {
switch (param) {
case 0:
this.setId((Long) obj);
break;
case 1:
rol = (int) obj;
break;
}
}
@Override
public void getPropertyInfo(int param, Hashtable properties, PropertyInfo propertyInfo) {
switch (param) {
case 0:
propertyInfo.type = PropertyInfo.LONG_CLASS;
propertyInfo.name = "id";
break;
case 1:
propertyInfo.type = PropertyInfo.INTEGER_CLASS;
propertyInfo.name = "roles";
break;
}
}
}

View File

@ -50,6 +50,10 @@ public class UserFilter extends Model implements Serializable{
* Full path where user's picture is stored.
*/
private String userPhoto;
/**
* Unique identifier for each user
*/
private int userCode;
/**
* Is a receiver?.
*/
@ -57,20 +61,21 @@ public class UserFilter extends Model implements Serializable{
/**
* Constructor.
*
* @param userNickname User identifier.
* @param userSurname1 User first surname.
* @param userSurname2 User last surname.
* @param userFirstname User name.
* @param userPhoto Full path where user's picture is stored.
* @param userCode Unique identifier for each user
* @param selectedCheckbox Is a receiver?.
*/
public UserFilter(String userNickname, String userSurname1, String userSurname2, String userFirstname, String userPhoto, boolean selectedCheckbox){
public UserFilter(String userNickname, String userSurname1, String userSurname2, String userFirstname, String userPhoto, int userCode, boolean selectedCheckbox){
this.userNickname = userNickname;
this.userSurname1 = userSurname1;
this.userSurname2 = userSurname2;
this.userFirstname = userFirstname;
this.userPhoto = userPhoto;
this.userCode = userCode;
this.selectedCheckbox = selectedCheckbox;
}
@ -164,6 +169,24 @@ public class UserFilter extends Model implements Serializable{
this.userPhoto = userPhoto;
}
/**
* Gets users code.
*
* @return the userCode
*/
public int getUserCode() {
return userCode;
}
/**
* Sets user code.
*
* @param userCode the userCode to set
*/
public void setUserCode(int userCode) {
this.userCode = userCode;
}
/**
* Get if checkbox is selected.
*

View File

@ -0,0 +1,82 @@
package es.ugr.swad.swadroid.modules.indoorlocation;
import android.content.Intent;
import android.os.Bundle;
import org.ksoap2.serialization.SoapObject;
import es.ugr.swad.swadroid.Constants;
import es.ugr.swad.swadroid.model.Roles;
import es.ugr.swad.swadroid.modules.Module;
import es.ugr.swad.swadroid.modules.courses.Courses;
import es.ugr.swad.swadroid.modules.login.Login;
import es.ugr.swad.swadroid.webservices.SOAPClient;
public class GetAvailableRoles extends Module {
private Roles roles;
/**
* Messages tag name for Logcat
*/
private static final String TAG = Constants.APP_TAG + " GetAvailableRoles";
@Override
protected void runConnection() {
super.runConnection();
if (!isConnected) {
setResult(RESULT_CANCELED);
finish();
}
}
/* (non-Javadoc)
* @see android.app.Activity#onCreate()
*/
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setMETHOD_NAME("getAvailableRoles");
getSupportActionBar().hide();
}
/* (non-Javadoc)
* @see android.app.Activity#onStart()
*/
@Override
protected void onStart() {
super.onStart();
connect();
}
@Override
protected void requestService() throws Exception {
createRequest(SOAPClient.CLIENT_TYPE);
addParam("wsKey", Login.getLoggedUser().getWsKey());
addParam("courseCode", Courses.getSelectedCourseCode());
sendRequest(Roles.class, true);
if (result!=null) {
int rol = Integer.parseInt(((SoapObject) result).getProperty("roles").toString());
roles = new Roles(rol);
}
Intent intent = new Intent();
intent.putExtra("roles", roles);
setResult(RESULT_OK, intent);
}
@Override
protected void connect() {
startConnection();
}
@Override
protected void postConnect() {
finish();
}
@Override
protected void onError() {
}
}

View File

@ -0,0 +1,103 @@
package es.ugr.swad.swadroid.modules.indoorlocation;
import android.content.Intent;
import android.os.Bundle;
import org.ksoap2.serialization.SoapObject;
import es.ugr.swad.swadroid.Constants;
import es.ugr.swad.swadroid.model.LocationTimeStamp;
import es.ugr.swad.swadroid.modules.Module;
import es.ugr.swad.swadroid.modules.login.Login;
import es.ugr.swad.swadroid.webservices.SOAPClient;
public class GetLastLocation extends Module {
private int userCode;
private LocationTimeStamp locationTimeStamp;
/**
* Messages tag name for Logcat
*/
private static final String TAG = Constants.APP_TAG + " GetLastLocation";
@Override
protected void runConnection() {
super.runConnection();
if (!isConnected) {
setResult(RESULT_CANCELED);
finish();
}
}
/* (non-Javadoc)
* @see android.app.Activity#onCreate()
*/
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setMETHOD_NAME("getLastLocation");
getSupportActionBar().hide();
}
/* (non-Javadoc)
* @see android.app.Activity#onStart()
*/
@Override
protected void onStart() {
super.onStart();
userCode = getIntent().getIntExtra("userCode", -1);
connect();
}
@Override
protected void requestService() throws Exception {
createRequest(SOAPClient.CLIENT_TYPE);
addParam("wsKey", Login.getLoggedUser().getWsKey());
addParam("userCode", userCode);
sendRequest(LocationTimeStamp.class, true);
if (result!=null) {
SoapObject soap = (SoapObject) result;
SoapObject properties = (SoapObject)soap.getProperty(0);
int institutionCode = Integer.parseInt(properties.getProperty("institutionCode").toString());
String institutionShortName = properties.getProperty("institutionShortName").toString();
String institutionFullName = properties.getProperty("institutionFullName").toString();
int centerCode = Integer.parseInt(properties.getProperty("centerCode").toString());
String centerShortName = properties.getProperty("centerShortName").toString();
String centerFullName = properties.getProperty("centerFullName").toString();
int buildingCode = Integer.parseInt(properties.getProperty("buildingCode").toString());
String buildingShortName = properties.getProperty("buildingShortName").toString();
String buildingFullName = properties.getProperty("buildingFullName").toString();
int floor = Integer.parseInt(properties.getProperty("floor").toString());
int roomCode = Integer.parseInt(properties.getProperty("roomCode").toString());
String roomShortName = properties.getProperty("roomShortName").toString();
String roomFullName = properties.getProperty("roomFullName").toString();
int checkInTime = Integer.parseInt(soap.getProperty(1).toString());
locationTimeStamp = new LocationTimeStamp(institutionCode, institutionShortName, institutionFullName,
centerCode, centerShortName, centerFullName, buildingCode, buildingShortName, buildingFullName,
floor, roomCode, roomShortName, roomFullName, checkInTime);
}
Intent intent = new Intent();
intent.putExtra("locationTimeStamp", locationTimeStamp);
setResult(RESULT_OK, intent);
}
@Override
protected void connect() {
startConnection();
}
@Override
protected void postConnect() {
finish();
}
@Override
protected void onError() {
}
}

View File

@ -0,0 +1,120 @@
package es.ugr.swad.swadroid.modules.indoorlocation;
import android.content.Intent;
import android.os.Bundle;
import org.ksoap2.serialization.SoapObject;
import es.ugr.swad.swadroid.Constants;
import es.ugr.swad.swadroid.model.Location;
import es.ugr.swad.swadroid.modules.Module;
import es.ugr.swad.swadroid.modules.login.Login;
import es.ugr.swad.swadroid.webservices.SOAPClient;
public class GetLocation extends Module {
/**
* Physical address of AP
*/
private String mac;
/**
* Distance to AP
*/
private double distance;
/**
* Default distance
*/
private final double defaultDistance = 500;
/**
* Location related to mac
*/
private Location location;
/**
* Messages tag name for Logcat
*/
private static final String TAG = Constants.APP_TAG + " GetLocation";
@Override
protected void runConnection() {
super.runConnection();
if (!isConnected) {
setResult(RESULT_CANCELED);
finish();
}
}
/* (non-Javadoc)
* @see android.app.Activity#onCreate()
*/
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setMETHOD_NAME("getLocation");
getSupportActionBar().hide();
}
/* (non-Javadoc)
* @see android.app.Activity#onStart()
*/
@Override
protected void onStart() {
super.onStart();
mac = getIntent().getStringExtra("mac");
distance = getIntent().getDoubleExtra("distance", defaultDistance);
connect();
}
@Override
protected void requestService() throws Exception {
createRequest(SOAPClient.CLIENT_TYPE);
addParam("wsKey", Login.getLoggedUser().getWsKey());
addParam("MAC", mac);
sendRequest(Location.class, true);
if (result != null) {
SoapObject soap = (SoapObject) result;
soap = (SoapObject)soap.getProperty(0);
int roomCode = Integer.parseInt(soap.getProperty("roomCode").toString());
if (roomCode != -1) {
int institutionCode = Integer.parseInt(soap.getProperty("institutionCode").toString());
String institutionShortName = soap.getProperty("institutionShortName").toString();
String institutionFullName = soap.getProperty("institutionShortName").toString();
int centerCode = Integer.parseInt(soap.getProperty("centerCode").toString());
String centerShortName = soap.getProperty("centerShortName").toString();
String centerFullName = soap.getProperty("centerFullName").toString();
int buildingCode = Integer.parseInt(soap.getProperty("buildingCode").toString());
String buildingShortName = soap.getProperty("buildingShortName").toString();
String buildingFullName = soap.getProperty("buildingFullName").toString();
int floor = Integer.parseInt(soap.getProperty("floor").toString());
String roomShortName = soap.getProperty("roomShortName").toString();
String roomFullName = soap.getProperty("roomFullName").toString();
location = new Location(institutionCode, institutionShortName, institutionFullName,
centerCode, centerShortName, centerFullName, buildingCode, buildingShortName, buildingFullName,
floor, roomCode, roomShortName, roomFullName);
} else {
location = null;
}
}
Intent intent = new Intent();
intent.putExtra("location", location);
intent.putExtra("distance", distance);
setResult(RESULT_OK, intent);
}
@Override
protected void connect() {
startConnection();
}
@Override
protected void postConnect() {
finish();
}
@Override
protected void onError() {
}
}

View File

@ -0,0 +1,354 @@
package es.ugr.swad.swadroid.modules.indoorlocation;
import android.Manifest;
import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.ClipData;
import android.content.ClipboardManager;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.PackageManager;
import android.net.wifi.ScanResult;
import android.net.wifi.WifiManager;
import android.os.Build;
import android.os.Bundle;
import android.os.Parcelable;
import android.util.Log;
import android.util.Pair;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.annotation.RequiresApi;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import com.google.android.material.floatingactionbutton.FloatingActionButton;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Locale;
import java.util.Objects;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import es.ugr.swad.swadroid.Constants;
import es.ugr.swad.swadroid.R;
import es.ugr.swad.swadroid.gui.MenuActivity;
import es.ugr.swad.swadroid.model.Location;
import es.ugr.swad.swadroid.model.LocationTimeStamp;
import es.ugr.swad.swadroid.model.Roles;
import es.ugr.swad.swadroid.model.UserFilter;
import es.ugr.swad.swadroid.modules.messages.SearchUsers;
import es.ugr.swad.swadroid.preferences.Preferences;
public class IndoorLocation extends MenuActivity {
private static final String TAG = Constants.APP_TAG + " IndoorLocation";
private final List<String> locationHistory = new ArrayList<>();
private final List<Pair<ScanResult, Integer>> availableNetworks = new ArrayList<>();
private final double FREE_SPACE_PATH_LOSS_CONSTANT = 27.55;
private ListView history;
private ArrayAdapter<String> locationHistoryAdapter;
private WifiManager wifiManager;
private ArrayList<Parcelable> arrayReceivers = new ArrayList<>();
private ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
private TextView textView;
private boolean showMac = false;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.indoor_location);
setTitle(R.string.manageLocation);
Objects.requireNonNull(getSupportActionBar()).setDisplayHomeAsUpEnabled(true);
textView = findViewById(R.id.location_history);
history = findViewById(R.id.location_history_data);
wifiManager = (WifiManager) getApplicationContext().getSystemService(Context.WIFI_SERVICE);
assert wifiManager != null;
if (!wifiManager.isWifiEnabled()) {
Toast.makeText(this, "Wifi is disabled ... You need to enable it", Toast.LENGTH_LONG).show();
}
locationHistory.add(getResources().getString(R.string.lostLocation));
locationHistoryAdapter = new ArrayAdapter<>(this, android.R.layout.simple_list_item_1, locationHistory);
history.setAdapter(locationHistoryAdapter);
history.setOnItemClickListener((adapterView, view, i, l) -> {
ClipboardManager clipboard = (ClipboardManager)
getSystemService(Context.CLIPBOARD_SERVICE);
ClipData clip = ClipData.newPlainText("macAddress", availableNetworks.get(0).first.BSSID);
clipboard.setPrimaryClip(clip);
});
}
private void init() {
Intent getAvailableRoles = new Intent(getApplicationContext(), GetAvailableRoles.class);
startActivityForResult(getAvailableRoles, Constants.GET_AVAILABLE_ROLES);
FloatingActionButton findUser = findViewById(R.id.find_user);
findUser.setOnClickListener(view -> {
stopScheduler();
Intent intent = new Intent(getApplicationContext(), SearchUsers.class);
intent.putExtra("receivers", arrayReceivers);
startActivityForResult(intent, Constants.SEARCH_USERS_REQUEST_CODE);
});
history = findViewById(R.id.location_history_data);
FloatingActionButton updateLocation = findViewById(R.id.user_location);
updateLocation.setOnClickListener(v -> {
stopScheduler();
if(Preferences.getShareLocation()) {
textView.setText(getString(R.string.lastLocation));
int syncTime = Integer.parseInt(Preferences.getSyncLocationTime());
Runnable wifiScanner = this::scanWifi;
try {
scheduler.scheduleAtFixedRate(wifiScanner,0, syncTime, TimeUnit.MINUTES);
} catch (IllegalArgumentException e) {
Log.e(TAG, e.getMessage(), e);
}
} else {
Toast.makeText(getApplicationContext(), getResources().getString(R.string.locationDisabled), Toast.LENGTH_LONG).show();
}
});
FloatingActionButton findMac = findViewById(R.id.find_mac);
findMac.setOnClickListener(v -> {
showMac = true;
scanWifi();
});
}
private void stopScheduler() {
scheduler.shutdownNow();
scheduler = Executors.newScheduledThreadPool(1);
}
@Override
protected void onStart() {
super.onStart();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
requestMarshmallowPermissions();
} else {
requestSimplePermissions();
}
}
private void requestSimplePermissions() {
if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION)
!= PackageManager.PERMISSION_GRANTED ||
ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_WIFI_STATE)
!= PackageManager.PERMISSION_GRANTED ||
ContextCompat.checkSelfPermission(this, Manifest.permission.CHANGE_WIFI_STATE)
!= PackageManager.PERMISSION_GRANTED){
ActivityCompat.requestPermissions(this,
new String[]{Manifest.permission.ACCESS_FINE_LOCATION,
Manifest.permission.ACCESS_WIFI_STATE,
Manifest.permission.CHANGE_WIFI_STATE}, Constants.PERMISSION_MULTIPLE);
} else {
init();
}
}
@RequiresApi(api = Build.VERSION_CODES.Q)
private void requestMarshmallowPermissions() {
if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION)
!= PackageManager.PERMISSION_GRANTED ||
ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_WIFI_STATE)
!= PackageManager.PERMISSION_GRANTED ||
ContextCompat.checkSelfPermission(this, Manifest.permission.CHANGE_WIFI_STATE)
!= PackageManager.PERMISSION_GRANTED ||
ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_BACKGROUND_LOCATION)
!= PackageManager.PERMISSION_GRANTED){
ActivityCompat.requestPermissions(this,
new String[]{Manifest.permission.ACCESS_FINE_LOCATION,
Manifest.permission.ACCESS_WIFI_STATE,
Manifest.permission.CHANGE_WIFI_STATE,
Manifest.permission.ACCESS_BACKGROUND_LOCATION}, Constants.PERMISSION_MULTIPLE);
} else {
init();
}
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (data != null) {
switch (requestCode) {
case Constants.SEARCH_USERS_REQUEST_CODE:
arrayReceivers = data.getParcelableArrayListExtra("receivers");
if (arrayReceivers != null && !arrayReceivers.isEmpty()) {
locationHistory.clear();
locationHistoryAdapter.notifyDataSetChanged();
UserFilter user = ((UserFilter)arrayReceivers.get(0));
String userText = getResources().getString(R.string.userLocation) + " " + user.getUserFirstname() + " "
+ user.getUserSurname1();
textView.setText(userText);
Intent getLastLocation = new Intent(getApplicationContext(), GetLastLocation.class);
getLastLocation.putExtra("userCode", user.getUserCode());
startActivityForResult(getLastLocation, Constants.GET_LAST_LOCATION);
}
break;
case Constants.GET_LOCATION:
Location location = (Location) data.getSerializableExtra("location");
if (location != null) {
double distance = (double) data.getSerializableExtra("distance");
locationHistory.add(
getBasicInformation(location) +
getResources().getString(R.string.distance) + ": " + distance + " m");
locationHistoryAdapter.notifyDataSetChanged();
Intent sendCurrentLocation = new Intent(getApplicationContext(), SendCurrentLocation.class);
sendCurrentLocation.putExtra("roomCode", location.getRoomCode());
startActivityForResult(sendCurrentLocation, Constants.SEND_CURRENT_LOCATION);
} else {
if (availableNetworks.isEmpty()) {
stopScheduler();
Log.d(TAG, "No more available networks");
} else {
Intent getLocation = new Intent(this.getApplicationContext(), GetLocation.class);
getLocation.putExtra("mac", availableNetworks.get(0).first.BSSID.replace(":",""));
availableNetworks.remove(0);
startActivityForResult(getLocation, Constants.GET_LOCATION);
}
}
break;
case Constants.GET_LAST_LOCATION:
LocationTimeStamp locationTimeStamp = (LocationTimeStamp) data.getSerializableExtra("locationTimeStamp");
if (locationTimeStamp != null && locationTimeStamp.getRoomCode() != -1) {
Date checkIn = new Date((long)locationTimeStamp.getCheckInTime()*1000);
SimpleDateFormat ft = new SimpleDateFormat ("hh:mm a", Locale.getDefault());
locationHistory.clear();
locationHistory.add(
getBasicInformation(locationTimeStamp) +
getResources().getString(R.string.checkIn) + ": "+ ft.format(checkIn));
locationHistoryAdapter.notifyDataSetChanged();
} else {
if (locationHistory.isEmpty()) {
locationHistory.add(getResources().getString(R.string.lostLocation));
locationHistoryAdapter.notifyDataSetChanged();
}
}
break;
case Constants.SEND_CURRENT_LOCATION:
if ((boolean) data.getSerializableExtra("success"))
Log.d(TAG, "Current location sent");
break;
case Constants.GET_AVAILABLE_ROLES:
int rol = ((Roles) Objects.requireNonNull(data.getSerializableExtra("roles"))).getRol();
int bitEnabled = Integer.toBinaryString(rol).length();
FloatingActionButton findMac = findViewById(R.id.find_mac);
if (bitEnabled >= 7 ){
findMac.setVisibility(View.VISIBLE);
}else{
findMac.setVisibility(View.INVISIBLE);
}
}
}
super.onActivityResult(requestCode, resultCode, data);
}
private void scanWifi() {
Log.i(TAG, "SCANNING WIFI");
registerReceiver(wifiReceiver, new IntentFilter(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION));
wifiManager.startScan();
}
private final BroadcastReceiver wifiReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
List<ScanResult> results = wifiManager.getScanResults();
unregisterReceiver(this);
if (!results.isEmpty()) {
for (ScanResult scanResult : results) {
int distance = (int) calculateDistance(scanResult.level, scanResult.frequency);
availableNetworks.add(new Pair<>(scanResult, distance));
}
availableNetworks.sort((n1, n2) -> n1.second - n2.second);
scanFinished();
}
}
private void scanFinished() {
if (!showMac){
Intent getLocation = new Intent(getApplicationContext(), GetLocation.class);
getLocation.putExtra("mac", availableNetworks.get(0).first.BSSID.replace(":",""));
getLocation.putExtra("distance", availableNetworks.get(0).second.doubleValue());
startActivityForResult(getLocation, Constants.GET_LOCATION);
} else {
showMac = false;
locationHistory.clear();
locationHistory.add(availableNetworks.get(0).first.SSID + " - " + availableNetworks.get(0).first.BSSID + " - " + availableNetworks.get(0).second + "m" );
locationHistoryAdapter.notifyDataSetChanged();
textView.setText(getString(R.string.nearestLocation));
}
}
private double calculateDistance(double levelInDb, double freqInMHz) {
double exp = (FREE_SPACE_PATH_LOSS_CONSTANT - (20 * Math.log10(freqInMHz)) + Math.abs(levelInDb)) / 20.0;
return Math.pow(10.0, exp);
}
};
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
switch (requestCode) {
case Constants.PERMISSION_MULTIPLE: {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED
&& grantResults[1] == PackageManager.PERMISSION_GRANTED
&& grantResults[2] == PackageManager.PERMISSION_GRANTED
&& grantResults[3] == PackageManager.PERMISSION_GRANTED) {
init();
} else {
setResult(Activity.RESULT_CANCELED);
finish();
}
} else {
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED
&& grantResults[1] == PackageManager.PERMISSION_GRANTED
&& grantResults[2] == PackageManager.PERMISSION_GRANTED) {
init();
} else {
setResult(Activity.RESULT_CANCELED);
finish();
}
}
}
}
}
private String getBasicInformation(Location location) {
return getResources().getString(R.string.institution) + ": " + location.getInstitutionShortName() + "\n" +
getResources().getString(R.string.center) + ": " + location.getCenterFullName() + "\n" +
getResources().getString(R.string.building) + ": " + location.getBuildingFullName() + "\n" +
getResources().getString(R.string.floor) + ": " + location.getFloor() + "\n" +
getResources().getString(R.string.room) + ": " + location.getFloor() + "\n";
}
}

View File

@ -0,0 +1,86 @@
package es.ugr.swad.swadroid.modules.indoorlocation;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import org.ksoap2.serialization.SoapObject;
import es.ugr.swad.swadroid.Constants;
import es.ugr.swad.swadroid.modules.Module;
import es.ugr.swad.swadroid.modules.login.Login;
import es.ugr.swad.swadroid.webservices.SOAPClient;
public class SendCurrentLocation extends Module {
/**
* Messages tag name for Logcat
*/
private static final String TAG = Constants.APP_TAG + " SendCurrentLocation";
/**
* Room code
*/
private Integer roomCode;
@Override
protected void runConnection() {
super.runConnection();
if (!isConnected) {
setResult(RESULT_CANCELED);
finish();
}
}
/* (non-Javadoc)
* @see android.app.Activity#onCreate()
*/
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setMETHOD_NAME("sendMyLocation");
getSupportActionBar().hide();
}
/* (non-Javadoc)
* @see android.app.Activity#onStart()
*/
@Override
protected void onStart() {
super.onStart();
roomCode = getIntent().getIntExtra("roomCode", -1);
connect();
}
@Override
protected void requestService() throws Exception {
boolean success = false;
createRequest(SOAPClient.CLIENT_TYPE);
addParam("wsKey", Login.getLoggedUser().getWsKey());
addParam("roomCode", roomCode);
sendRequest(Boolean.class, true);
if (result != null) {
SoapObject soap = (SoapObject) result;
success = Integer.parseInt(soap.getProperty("success").toString()) != 0;
}
Intent intent = new Intent();
intent.putExtra("success", success);
setResult(Activity.RESULT_OK, intent);
}
@Override
protected void connect() {
startConnection();
}
@Override
protected void postConnect() {
finish();
}
@Override
protected void onError() {
}
}

View File

@ -353,7 +353,7 @@ public class Messages extends Module {
}
for(int i=0; i < arrayReceivers.size(); i++){
frequentsList.add(new FrequentUser(userLogged, arrayReceivers.get(i).getUserNickname(), arrayReceivers.get(i).getUserSurname1(), arrayReceivers.get(i).getUserSurname2(), arrayReceivers.get(i).getUserFirstname(), arrayReceivers.get(i).getUserPhoto(), false, INITIAL_SCORE));
frequentsList.add(new FrequentUser(userLogged, arrayReceivers.get(i).getUserNickname(), arrayReceivers.get(i).getUserSurname1(), arrayReceivers.get(i).getUserSurname2(), arrayReceivers.get(i).getUserFirstname(), arrayReceivers.get(i).getUserPhoto(), arrayReceivers.get(i).getUserCode(), false, INITIAL_SCORE));
Log.d(TAG, "frequent user '" + arrayReceivers.get(i).getUserNickname() + "' added = " + INITIAL_SCORE + " (sender = '" + userLogged + "')");
}

View File

@ -142,7 +142,9 @@ public class SearchUsers extends Module implements SearchView.OnQueryTextListene
frequentUsers = new FrequentUsersList();
arrayReceivers = (ArrayList) getIntent().getSerializableExtra("receivers");
//save the old receivers
oldReceivers = (ArrayList) arrayReceivers.clone();
if (arrayReceivers != null) {
oldReceivers = (ArrayList) arrayReceivers.clone();
}
search = "";
@ -181,9 +183,10 @@ public class SearchUsers extends Module implements SearchView.OnQueryTextListene
String surname2 = frequentsList.get(i).getUserSurname2();
String firstname = frequentsList.get(i).getUserFirstname();
String userPhoto = frequentsList.get(i).getUserPhoto();
int userCode = frequentsList.get(i).getUserCode();
boolean selected = frequentsList.get(i).getCheckbox();
Double score = frequentsList.get(i).getScore();
frequentUsers.saveUser(new FrequentUser(idUser, nickname, surname1, surname2, firstname, userPhoto, selected, score));
frequentUsers.saveUser(new FrequentUser(idUser, nickname, surname1, surname2, firstname, userPhoto, userCode, selected, score));
}
updateCheckboxesFrequentUsers();
@ -360,6 +363,7 @@ public class SearchUsers extends Module implements SearchView.OnQueryTextListene
String surname2 = pii.getPrimitiveProperty("userSurname2").toString();
String firstname = pii.getPrimitiveProperty("userFirstname").toString();
String userPhoto = pii.getPrimitiveProperty("userPhoto").toString();
int userCode = Integer.parseInt(pii.getPrimitiveProperty("userCode").toString());
boolean selected = false;
for(int j=0; j<arrayReceivers.size(); j++){
@ -369,7 +373,7 @@ public class SearchUsers extends Module implements SearchView.OnQueryTextListene
}
}
usersFilter.saveUser(new UserFilter(nickname, surname1, surname2, firstname, userPhoto, selected));
usersFilter.saveUser(new UserFilter(nickname, surname1, surname2, firstname, userPhoto, userCode, selected));
}
}
numUsers = usersFilter.getUsers().size();
@ -451,7 +455,7 @@ public class SearchUsers extends Module implements SearchView.OnQueryTextListene
else{
checkbox.setChecked(true);
FrequentUser currentFrequent = frequentUsers.getUsers().get(position);
arrayReceivers.add(new UserFilter(currentFrequent.getUserNickname(), currentFrequent.getUserSurname1(), currentFrequent.getUserSurname2(), currentFrequent.getUserFirstname(), currentFrequent.getUserPhoto(), currentFrequent.getCheckbox()));
arrayReceivers.add(new UserFilter(currentFrequent.getUserNickname(), currentFrequent.getUserSurname1(), currentFrequent.getUserSurname2(), currentFrequent.getUserFirstname(), currentFrequent.getUserPhoto(), currentFrequent.getUserCode(), currentFrequent.getCheckbox()));
}
}
});
@ -540,4 +544,4 @@ public class SearchUsers extends Module implements SearchView.OnQueryTextListene
AlertDialog alert = builder.create();
alert.show();
}
}
}

View File

@ -157,7 +157,14 @@ public class Preferences {
* Indicates if there are changes on preferences
*/
private static boolean preferencesChanged = false;
/**
* Synchronization time preference for location
*/
public static final String SYNCLOCATIONTIMEPREF = "prefSyncLocationTime";
/*
* Sharing location preference
*/
public static String SHARELOCATION = "prefShareLocation";
/**
* Gets application preferences
* @param ctx Application context
@ -465,4 +472,43 @@ public class Preferences {
public static void setPreferencesChanged(boolean newState) {
preferencesChanged = newState;
}
/**
* Gets the synchronization time
*
* @return The synchronization time
*/
public static String getSyncLocationTime() {
return prefs.getString(SYNCLOCATIONTIMEPREF, "1");
}
/**
* Sets the synchronization time for location
*
* @param syncLocationTime The synchronization time for location
*/
public static void setSyncLocationTime(String syncLocationTime) {
editor = editor.putString(SYNCLOCATIONTIMEPREF, syncLocationTime);
editor.commit();
}
/**
* Gets sharing location preference
*
* @return share location preference
*/
public static boolean getShareLocation() {
return prefs.getBoolean(SHARELOCATION, false);
}
/**
* Sets the SHARELOCATION preference
*
* @param shareLocation The preference for sharing location
*/
public static void setShareLocation(boolean shareLocation) {
editor = editor.putBoolean(SHARELOCATION, shareLocation);
editor.commit();
}
}

View File

@ -136,7 +136,11 @@ public class PreferencesActivity extends PreferenceActivity implements OnPrefere
* User password preference changed flag
*/
private boolean userPasswordPrefChanged = false;
/**
* Synchronization time preference for location
*/
private static Preference syncTimeLocationPref;
/**
* Shows an error message.
*
@ -189,6 +193,7 @@ public class PreferencesActivity extends PreferenceActivity implements OnPrefere
privacyPolicyPref = findPreference(Preferences.PRIVACYPOLICYPREF);
syncTimePref = findPreference(Preferences.SYNCTIMEPREF);
syncEnablePref = (CheckBoxPreference) findPreference(Preferences.SYNCENABLEPREF);
syncTimeLocationPref = findPreference(Preferences.SYNCLOCATIONTIMEPREF);
ratePref.setOnPreferenceChangeListener(this);
twitterPref.setOnPreferenceChangeListener(this);
@ -200,7 +205,8 @@ public class PreferencesActivity extends PreferenceActivity implements OnPrefere
privacyPolicyPref.setOnPreferenceChangeListener(this);
syncEnablePref.setOnPreferenceChangeListener(this);
syncTimePref.setOnPreferenceChangeListener(this);
syncTimeLocationPref.setOnPreferenceChangeListener(this);
logOutPref.setOnPreferenceClickListener(new OnPreferenceClickListener() {
@Override
@ -378,7 +384,7 @@ public class PreferencesActivity extends PreferenceActivity implements OnPrefere
Preferences.setSyncEnabled(syncEnabled);
syncEnablePref.setChecked(syncEnabled);
syncPrefsChanged = true;
} else if(Preferences.SYNCTIMEPREF.equals(key)) {
} else if(Preferences.SYNCTIMEPREF.equals(key)) {
String syncTime = (String) newValue;
long lastSyncTime = Preferences.getLastSyncTime();
@ -404,6 +410,16 @@ public class PreferencesActivity extends PreferenceActivity implements OnPrefere
syncTimePref.setSummary(prefSyncTimeEntry);
syncPrefsChanged = true;
} else if(Preferences.SYNCLOCATIONTIMEPREF.equals(key)) {
String syncLocationTime = (String) newValue;
List<String> prefSyncTimeValues = Arrays.asList(getResources().getStringArray(R.array.prefSyncLocationTimeValues));
List<String> prefSyncTimeEntries = Arrays.asList(getResources().getStringArray(R.array.prefSyncLocationTimeEntries));
int prefSyncTimeIndex = prefSyncTimeValues.indexOf(syncLocationTime);
String prefSyncTimeEntry = prefSyncTimeEntries.get(prefSyncTimeIndex);
Preferences.setSyncLocationTime(syncLocationTime);
syncTimeLocationPref.setSummary(prefSyncTimeEntry);
syncPrefsChanged = true;
}
return returnValue;

Binary file not shown.

After

Width:  |  Height:  |  Size: 801 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 901 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 835 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 935 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 711 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 770 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 985 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1002 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 716 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 781 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 901 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 935 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 770 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 933 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 781 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 946 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 985 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

View File

@ -0,0 +1,8 @@
<!-- drawable/account-search-outline.xml -->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:height="24dp"
android:width="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path android:fillColor="#000" android:pathData="M10,13C9.65,13.59 9.36,14.24 9.19,14.93C6.5,15.16 3.9,16.42 3.9,17V18.1H9.2C9.37,18.78 9.65,19.42 10,20H2V17C2,14.34 7.33,13 10,13M10,4A4,4 0 0,1 14,8C14,8.91 13.69,9.75 13.18,10.43C12.32,10.75 11.55,11.26 10.91,11.9L10,12A4,4 0 0,1 6,8A4,4 0 0,1 10,4M10,5.9A2.1,2.1 0 0,0 7.9,8A2.1,2.1 0 0,0 10,10.1A2.1,2.1 0 0,0 12.1,8A2.1,2.1 0 0,0 10,5.9M15.5,12C18,12 20,14 20,16.5C20,17.38 19.75,18.21 19.31,18.9L22.39,22L21,23.39L17.88,20.32C17.19,20.75 16.37,21 15.5,21C13,21 11,19 11,16.5C11,14 13,12 15.5,12M15.5,14A2.5,2.5 0 0,0 13,16.5A2.5,2.5 0 0,0 15.5,19A2.5,2.5 0 0,0 18,16.5A2.5,2.5 0 0,0 15.5,14Z" />
</vector>

View File

@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path
android:fillColor="#FF000000"
android:pathData="M12,2C8.14,2 5,5.14 5,9c0,5.25 7,13 7,13s7,-7.75 7,-13c0,-3.86 -3.14,-7 -7,-7zM12,4c1.1,0 2,0.9 2,2 0,1.11 -0.9,2 -2,2s-2,-0.89 -2,-2c0,-1.1 0.9,-2 2,-2zM12,14c-1.67,0 -3.14,-0.85 -4,-2.15 0.02,-1.32 2.67,-2.05 4,-2.05s3.98,0.73 4,2.05c-0.86,1.3 -2.33,2.15 -4,2.15z"/>
</vector>

View File

@ -0,0 +1,8 @@
<!-- drawable/sync.xml -->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:height="24dp"
android:width="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path android:fillColor="#000" android:pathData="M12,18A6,6 0 0,1 6,12C6,11 6.25,10.03 6.7,9.2L5.24,7.74C4.46,8.97 4,10.43 4,12A8,8 0 0,0 12,20V23L16,19L12,15M12,4V1L8,5L12,9V6A6,6 0 0,1 18,12C18,13 17.75,13.97 17.3,14.8L18.76,16.26C19.54,15.03 20,13.57 20,12A8,8 0 0,0 12,4Z" />
</vector>

View File

@ -0,0 +1,107 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:focusable="auto"
android:focusableInTouchMode="false"
android:orientation="vertical">
<TextView
android:id="@+id/location_history"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginStart="10dp"
android:layout_marginTop="20dp"
android:layout_marginEnd="10dp"
android:gravity="center_horizontal"
android:text="@string/lastLocation"
android:textColor="#000000"
android:textSize="18sp"
android:textStyle="bold" />
<ListView
android:id="@+id/location_history_data"
android:layout_width="match_parent"
android:layout_height="455dp"
android:layout_marginStart="10dp"
android:layout_marginTop="20dp"
android:layout_marginEnd="10dp"
android:gravity="center|top"
android:textSize="18sp"/>
<LinearLayout
android:id="@+id/location_buttons"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal">
<View
android:id="@+id/divider"
android:layout_width="62dp"
android:layout_height="match_parent"
android:layout_weight="1.0"
android:backgroundTint="#FFFFFF"
android:background="?android:attr/listDivider" />
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="@+id/user_location"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_weight="1.0"
android:src="@drawable/ic_person_pin_circle_black_24dp"
app:backgroundTint="#00BFA5"
app:fabCustomSize="60dp" />
<View
android:id="@+id/divider2"
android:layout_width="50dp"
android:layout_height="match_parent"
android:layout_weight="1.0"
android:backgroundTint="#FFFFFF"
android:background="?android:attr/listDivider" />
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="@+id/find_mac"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_weight="1.0"
android:src="@android:drawable/ic_menu_mylocation"
android:tint="#FFFFFF"
android:visibility="invisible"
app:backgroundTint="@color/design_default_color_primary"
app:fabCustomSize="60dp" />
<View
android:id="@+id/divider3"
android:layout_width="50dp"
android:layout_height="match_parent"
android:layout_weight="1.0"
android:backgroundTint="#FFFFFF"
android:background="?android:attr/listDivider" />
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="@+id/find_user"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1.0"
android:layout_gravity="center_vertical"
android:src="@drawable/account_search_outline"
app:backgroundTint="#304FFE"
app:fabCustomSize="60dp" />
<View
android:id="@+id/divider5"
android:layout_width="62dp"
android:layout_height="match_parent"
android:layout_weight="1.0"
android:backgroundTint="#FFFFFF"
android:background="?android:attr/listDivider" />
</LinearLayout>
</LinearLayout>

View File

@ -44,5 +44,10 @@
<li>Mensajes&#58; B&uacute;squeda de destinatarios</li>
</ul>
</li>
<li style="list-style-type: none;"><a href="https://github.com/JaviBL8">Javier Bueno L&oacute;pez</a>
<ul>
<li>M&oacute;dulo para localizaci&oacute;n en interiores</li>
</ul>
</li>
</ul>
</body>

View File

@ -14,6 +14,13 @@
</style>
</head>
<body bgcolor="white">
<h4>1.6.0 (upcoming)</h4>
<ul>
<li type="disc">Corregida descarga de archivos en Android R</li>
<li type="disc">Añadido módulo para localización en interiores</li>
</ul>
<body bgcolor="white">
<h4>1.5.6 (2019-11-05)</h4>
<ul>

View File

@ -44,5 +44,10 @@
<li>Messages&#58; Search of recipients</li>
</ul>
</li>
<li style="list-style-type: none;"><a href="https://github.com/JaviBL8">Javier Bueno L&oacute;pez</a>
<ul>
<li>Module for indoor location</li>
</ul>
</li>
</ul>
</body>

View File

@ -14,6 +14,13 @@
</style>
</head>
<body bgcolor="white">
<h4>1.6.0 (upcoming)</h4>
<ul>
<li type="disc">Fixed file downloads on Android R</li>
<li type="disc">Added indoor location module</li>
</ul>
<body bgcolor="white">
<h4>1.5.6 (2019-11-05)</h4>
<ul>

View File

@ -24,5 +24,21 @@
<item>12 horas</item>
<item>24 horas</item>
</string-array>
<string-array name="prefSyncLocationTimeEntries">
<item>1 minuto</item>
<item>2 minutos</item>
<item>5 minutos</item>
<item>15 minutos</item>
<item>30 minutos</item>
<item>1 hora</item>
</string-array>
<string-array name="prefSyncLocationTimeValues">
<item>1</item>
<item>2</item>
<item>5</item>
<item>15</item>
<item>30</item>
<item>60</item>
</string-array>
</resources>

Some files were not shown because too many files have changed in this diff Show More