User discovery is show activity
fabiola29 opened this issue · 0 comments
fabiola29 commented
Hi I'm making an application that manages the user's activities in particular I give a path and the robot must find the person and notify him of the activity. I did it by implementing the service as shown in the following code using the sdk methods and it seems correct to me but I don't know which permissions to activate on the robot I have robot themes with OS 16400 launcher and Robox OS 128.12.
`public class SearchingUserService extends Service implements OnDetectionStateChangedListener,
OnUserInteractionChangedListener,
OnDetectionDataChangedListener,
OnGoToLocationStatusChangedListener
{
private Robot robot;
SharedPreferences savedPath;
private int pathIndex= 0;
private List<String> path = new ArrayList<>();
private volatile int detectionState = 0; //Changed from stateDetection to detectionState
private volatile int detectionAngle;
private List<String> locations;
private int interactionCounter = 0;
private String taskInfo;
private static final int REQUEST_CODE_START_DETECTION_WITH_DISTANCE = 6;
@Override
public void onCreate() {
super.onCreate();
//--------------Robot Instance--------------
robot = Robot.getInstance();
locations = robot.getLocations();
//locationListSize = locations.lastIndexOf(locations);
//--------------Path--------------
// Recupero del percorso salvato dalle SharedPreferences
savedPath = getSharedPreferences("savedPath_file", Context.MODE_PRIVATE);
path = new Gson().fromJson(savedPath.getString("savedPath_file", null), new TypeToken<List<String>>() {}.getType());
Log.d("SearchingTaskService", "Saved Path:" + path);
//--------------Robot Listeners--------------
robot.addOnDetectionDataChangedListener(this);
robot.addOnUserInteractionChangedListener(this);
robot.addOnDetectionStateChangedListener(this);
robot.addOnGoToLocationStatusChangedListener(this);
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.d("SearchingTaskService", "Service starting ");
Log.d("SearchingTaskService", "TASK_INFO: "+intent.getStringExtra(TASK_INFO));
taskInfo = intent.getStringExtra(TASK_INFO);
//robot.setDetectionModeOn(true);
startDetection();
return super.onStartCommand(intent, flags, startId);
}
@Override
public void onDestroy() {
super.onDestroy();
robot.removeOnDetectionDataChangedListener(this);
robot.removeOnUserInteractionChangedListener(this);
robot.removeOnDetectionStateChangedListener(this);
robot.removeOnGoToLocationStatusChangedListener(this);
try{
Intent intentService = new Intent(getApplicationContext(), TemiTask.class);
getApplicationContext().stopService(intentService);
} catch (Exception e){
Log.e("NotificationActivity", "Exception: "+e);
}
}
@Nullable
@Override
public IBinder onBind(Intent intent) { return null; }
/*-------------------------------------- User Quest functions --------------------------------------*/
/*Questo metodo avvia il processo di rilevamento, che sembra coinvolgere un percorso
predefinito che il robot deve seguire. Usa anche il metodo goTo() per spostarsi
tra le posizioni specificate.
*/
private void startDetection() {
if (requestPermissionIfNeeded(Permission.SETTINGS, REQUEST_CODE_START_DETECTION_WITH_DISTANCE)) {
return;
}
pathIndex = 0;
goTo(pathIndex);
Log.d("StartDetection", "detectionMode: "+robot.isDetectionModeOn());
//detecting(); TODO: erase if the process works
}
/* Questo metodo sembra gestire il rilevamento effettivo. Imposta il robot in modalità di
rilevamento e quindi fa ruotare il robot in incrementi di 45 gradi fino a quando non
rileva un utente o compie una rotazione completa di 360 gradi. Quando un utente viene
rilevato o il robot completa la rotazione, vengono intraprese azioni di conseguenza.*/
private void detecting(){
if (!robot.isDetectionModeOn()){
robot.setDetectionModeOn(true);
Log.d("Detecting", "Mode: "+robot.isDetectionModeOn());
}
detectionAngle = 0;
ScheduledExecutorService scheduleTaskExecutor = Executors.newScheduledThreadPool(1);
scheduleTaskExecutor.scheduleAtFixedRate(new Runnable() {
@Override
public void run() {
try{
if (detectionState != OnDetectionStateChangedListener.DETECTED && detectionAngle<360) {
turnBy();
detectionAngle = detectionAngle + 45;
} else if (detectionState == OnDetectionStateChangedListener.DETECTED){
detectionAngle = 360;
}
} catch (Exception e){
Log.d("Robot", "Exception: "+ e);
}finally {
}
if (detectionAngle == 360) {
if(detectionState != OnDetectionStateChangedListener.DETECTED) {
Log.d("Detecting...", "No user detected, going to the next position in the path");
pathIndex = pathIndex + 1;
goTo(pathIndex);
//TODO: Check if it does work, if not move if-statement outside of scheduleTaskExecutor!
}
Log.d("detectingProces", "Stop turning around, ScheduleTaskExecutor stopped");
scheduleTaskExecutor.shutdown();
}
}
},0,5000, TimeUnit.MILLISECONDS);
}
/* Questo metodo fa ruotare il robot di 45 gradi. Sembrerebbe essere utilizzato all'interno
di detecting() per far girare il robot in modo incrementale.*/
private void turnBy(){
if (detectionState != OnDetectionStateChangedListener.DETECTED) {
robot.turnBy(45);
Log.d("TurnBy", "Robot turning around");
}
}
/*Questo metodo muove il robot verso una posizione specifica nell'elenco delle posizioni.
L'indice specificato corrisponde all'elemento nell'elenco delle posizioni da raggiungere.*/
private void goTo(int index){
if (path != null && index < path.size()){
Log.d("goTo", "going to:"+path.get(index));
robot.goTo(path.get(index));
} else { robot.goTo("home base");}
}
@CheckResult
private boolean requestPermissionIfNeeded(Permission permission, int requestCode) {
if (robot.checkSelfPermission(permission) == Permission.GRANTED) {
return false;
}
robot.requestPermissions(Collections.singletonList(permission), requestCode);
return true;
}
/*Questo metodo gestisce le interazioni dell'utente con il robot. In particolare,
sembra arrestare il movimento del robot e disattiva la modalità di rilevamento
quando un utente sta interagendo.*/
private void interacting(){
Log.d("Interaction", "Temi is interacting with a user");
if ( detectionState == OnDetectionStateChangedListener.DETECTED){
robot.stopMovement();
robot.setDetectionModeOn(false);
}
}
//--------------------------------------Temi Listeners--------------------------------------
@Override
public void onUserInteraction(boolean isInteracting) {
if (isInteracting && interactionCounter<1){
interactionCounter++;
interacting();
}
}
@Override
public void onDetectionDataChanged(@NotNull DetectionData detectionData) {
}
@Override
public void onDetectionStateChanged(int state) {
Log.d("DetectionActivity", "onDetectionStateChanged - State:"+state);
if(state == OnDetectionStateChangedListener.DETECTED){
//robot.stopMovement();
//TODO: Restrict to once detectionStateChange to trigger NotificationActivity and the Speak request
Log.d("onDetectionStateChanged", "User detected");
detectionState = state;
robot.speak(TtsRequest.create("Hello, you have a saved event", true));
robot.beWithMe();
Intent notificationIntent = new Intent(this, NotificationActivity.class);
notificationIntent.putExtra(TASK_INFO, taskInfo);
notificationIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
String toastText = String.format("Starting NotificationsActivity");
Toast.makeText(this, toastText, Toast.LENGTH_SHORT).show();
startActivity(notificationIntent);
//Stop Service
Intent intentService = new Intent(getApplicationContext(),TemiTask.class);
getApplicationContext().stopService(intentService);
} else if (state == IDLE){
detectionState = state;
Log.d("onDetectionStateChanged", "Nobody detected");
//robot.turnBy(45);
} else if(state == OnDetectionStateChangedListener.LOST){
detectionState = state;
robot.turnBy(45);
robot.turnBy(-90);
}
}
@Override
public void onGoToLocationStatusChanged(@NotNull String location, String status, int descriptionId, @NotNull String description) {
try{
if (pathIndex < path.size()) {
Log.d("onGoToLocationStatus", "Location: " + location);
Log.d("onGoToLocationStatus", "PathLocation: " + path.get(pathIndex));
}
} catch (Exception e){
Log.e("onGoToLocationStatus", "Exception: "+e);
}
switch (status) {
case OnGoToLocationStatusChangedListener.START:
break;
case OnGoToLocationStatusChangedListener.CALCULATING:
break;
case OnGoToLocationStatusChangedListener.GOING:
break;
case OnGoToLocationStatusChangedListener.COMPLETE:
try{//if the Location is the same as the location in the path(index) then detecting() will star
if (pathIndex < path.size()) {
Log.d("onGoToLocationStatus", "COMPLETE");
Log.d("onGoToLocationStatus", "Location: "+location+" PathLocation: "+path.get(pathIndex));
if(location.equals(path.get(pathIndex))){
Log.d("onGoToLocationStatus", "Detecting...");
detecting();
} else {
Log.d("onGoToLocationStatus", "Location doesn't match...");
//TODO: See if condition is met, if not then place detecting() outside, and see why the condition won't be fulfilled
}
if (location.equals("home base") && detectionState==0){
rescheduleTask();
}
}
} catch (Exception e){
Log.e("onGoToLocationStatus", "Exception: "+e);
}
if (location.equals("home base") && detectionState==0){
rescheduleTask();
}
break;
case OnGoToLocationStatusChangedListener.ABORT:
break;
}
}
private void rescheduleTask() {
}
}
`
In the Manifest:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.temi1">
<uses-permission android:name="android.permission.SCHEDULE_EXACT_ALARM" />
<uses-feature android:name="android.hardware.camera" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/Theme.Temi1">
<meta-data
android:name="com.robotemi.sdk.metadata.SKILL"
android:value="@string/app_name" />
<meta-data
android:name="com.robotemi.sdk.metadata.ACTIONS"
android:value="home.welcome, home.dance, home.sleep" />
<meta-data
android:name="com.robotemi.sdk.metadata.KIOSK"
android:value="TRUE" />
<meta-data
android:name="@string/metadata_permissions"
android:value="com.robotemi.permission.face_recognition, com.robotemi.permission.map, com.robotemi.permission.settings, com.robotemi.permission.sequence" />
<activity
android:name=".views.activity.MainActivity"
android:exported="true"
android:screenOrientation="landscape"
android:windowSoftInputMode="adjustPan">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<receiver android:name=".TaskBroadcastReceiver.TaskBroadcastReceiver"
android:enabled="true"
android:exported="false">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
<service android:name=".Services.SearchingUserService"/>
<activity android:name=".views.activity.NotificationActivity" />
</application>
</manifest>