Skip to content
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
8 changes: 6 additions & 2 deletions CHANGES.txt
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
Change log for AWARE-Light

4.2.1.beta

- New feature to export the aware-light database files to the device's storage.

4.1.6.beta

- Fixed a crash that occurred when enabling accessibility before starting a study.
Expand All@@ -9,11 +13,11 @@ Change log for AWARE-Light
- Logging if the application is terminated by user actions or system actions to aware_log table

4.1.4.beta
- Screen reader function improved preformance
- Screen reader function improved performance

4.1.3.light.bundle
- Fixed bug for random EMA triggered condition
- Screen reader function improved preformance
- Screen reader function improved performance

4.1.2.light.bundle
- Screen reader table allows longer text to be stored
Expand Down
4 changes: 2 additions & 2 deletions aware-core/aware.gradle
Original file line numberDiff line numberDiff line change
Expand Up@@ -4,8 +4,8 @@ buildscript {
mqtt_libs = '1.2.1'
ion_libs = "2.+"
google_libs = "17.0.0"
version_code = 6
version_readable = "4.1." + version_code + "." + "beta"
version_code = 1
version_readable = "4.2." + version_code + "." + "beta"
compile_sdk = 28
target_sdk = 28
minimum_sdk = 24
Expand Down
63 changes: 40 additions & 23 deletions aware-core/src/main/java/com/aware/Applications.java
Original file line numberDiff line numberDiff line change
Expand Up@@ -41,8 +41,11 @@
import org.json.JSONException;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

import android.graphics.Rect;

/**
Expand DownExpand Up@@ -95,7 +98,7 @@ public class Applications extends AccessibilityService {

ArrayList<ContentValues> contentBuffer = new ArrayList<ContentValues>();

ArrayList<Integer> textBuffer = new ArrayList<Integer>();
Set<Integer> textBuffer = new HashSet<>();

int TEXT_BUFFER_LIMIT = 100;

Expand DownExpand Up@@ -170,12 +173,9 @@ private String getApplicationName(String package_name) {
public void onAccessibilityEvent(AccessibilityEvent event) {
if (event.getPackageName() == null) return;




// if text buffer is full then send all contents in the content buffer
if (textBuffer.size() == TEXT_BUFFER_LIMIT){

// if content buffer is full then send all contents in the content buffer
if (contentBuffer.size() == TEXT_BUFFER_LIMIT){
// Log.d("Screen_Text", "==========LIMIT REACH============");

for (ContentValues content: contentBuffer){
getContentResolver().insert(ScreenText_Provider.ScreenTextData.CONTENT_URI, content);
Expand All@@ -186,6 +186,8 @@ public void onAccessibilityEvent(AccessibilityEvent event) {
}
textBuffer.clear();
contentBuffer.clear();

// Log.d("Screen_Text", "==========CLEAN BUFFER============");
}


Expand DownExpand Up@@ -225,15 +227,6 @@ else if (criteria == 1 && app_names.contains(curr_app)) { // package in exclusiv
// Get the current foreground app
String currentForegroundApp = event.getPackageName().toString();

// Check if the foreground app has changed
if (!currentForegroundApp.equals(previousForegroundApp)) {
// Clear the text buffer
textBuffer.clear();

// Update the previous foreground app
previousForegroundApp = currentForegroundApp;
}

// Get text tree
AccessibilityNodeInfo mNodeInfo = event.getSource();
textTree(mNodeInfo);
Expand DownExpand Up@@ -261,14 +254,38 @@ else if (criteria == 1 && app_names.contains(curr_app)) { // package in exclusiv

int hashedText = currScreenText.hashCode();

// Add to content: get rid of the duplicate text
if (!textBuffer.contains(hashedText)) {
textBuffer.add(hashedText);
contentBuffer.add(screenText);
// Check if the foreground app has changed
if (!currentForegroundApp.equals(previousForegroundApp)) {
// // Log.d("Screen_Text", "==========App Switch============");
if (!textBuffer.contains(hashedText)) {
textBuffer.add(hashedText);
contentBuffer.add(screenText);
// // Log.d("Screen_Text", "Add ContentText: " + currScreenText);
}


// Log.d("Screen_Text", "Current ContentBuffer Size: " + contentBuffer.size());

for (ContentValues content: contentBuffer){
getContentResolver().insert(ScreenText_Provider.ScreenTextData.CONTENT_URI, content);

// Log the current screen text for debugging
if (Aware.DEBUG){
Log.d("AWARE::ScreenText", "Current Screen Text: " + currScreenText);
if (awareSensor != null) awareSensor.onScreentext(content);
Intent screen_text_data = new Intent(ScreenText.ACTION_SCREENTEXT_DETECT);
sendBroadcast(screen_text_data);
}

textBuffer.clear();
contentBuffer.clear();
// Log.d("Screen_Text", "==========CLEAN BUFFER============");
// Update the previous foreground app
previousForegroundApp = currentForegroundApp;

} else {
// Add to content: get rid of the duplicate text
if (!textBuffer.contains(hashedText)) {
textBuffer.add(hashedText);
contentBuffer.add(screenText);
// Log.d("Screen_Text", "Add ContentText: " + currScreenText);
}
}

Expand Down
1 change: 1 addition & 0 deletions aware-core/src/main/res/values/strings.xml
Original file line numberDiff line numberDiff line change
Expand Up@@ -33,6 +33,7 @@
<string name="sensors_required">Sensors needed</string>
<string name="sync_study_config">Check for study updates</string>
<string name="sync_study_data">Sync data</string>
<string name="export_study_data">Export data</string>
<string name="join_study">Join a study</string>
<string name="quit_study">Quit study</string>
<string name="sign_up">Sign Up!</string>
Expand Down
1 change: 1 addition & 0 deletions aware-phone/build.gradle
Original file line numberDiff line numberDiff line change
Expand Up@@ -134,6 +134,7 @@ dependencies {
api(project(":com.aware.plugin.sensortag"))
api(project(":com.aware.plugin.sentimental"))
implementation 'com.android.support:support-v4:28.0.0'
implementation 'androidx.annotation:annotation:1.2.0'
}

repositories {
Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -35,6 +35,10 @@
import android.view.ViewGroup;
import android.widget.ListAdapter;
import android.widget.Toast;
import android.view.View;
import android.widget.ListView;
import androidx.annotation.NonNull;
import androidx.core.app.ActivityCompat;

import com.aware.Applications;
import com.aware.Aware;
Expand DownExpand Up@@ -63,6 +67,27 @@
import static com.aware.Aware.TAG;
import static com.aware.Aware.setNotificationProperties;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

import android.Manifest;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import androidx.documentfile.provider.DocumentFile;

/**
*
*/
Expand All@@ -71,7 +96,8 @@ public class Aware_Light_Client extends Aware_Activity {
public static boolean permissions_ok;
private static Hashtable<Integer, Boolean> listSensorType;
private static SharedPreferences prefs;

public static final int REQUEST_CODE_OPEN_DIRECTORY = 1000;
public static final int REQUEST_CODE_STORAGE_PERMISSION = 1001;
private static final ArrayList<String> REQUIRED_PERMISSIONS = new ArrayList<>();
private static final Hashtable<String, Integer> optionalSensors = new Hashtable<>();

Expand DownExpand Up@@ -334,6 +360,129 @@ protected void onProgressUpdate(Preference... values) {
}
}

/**
* Checks if the application is running on an emulator.
*
* @return true if the application is running on an emulator, false otherwise.
*/
public static boolean isEmulator() {
// Check various properties to determine if the current environment is an emulator.
return Build.FINGERPRINT.startsWith("generic")
|| Build.FINGERPRINT.startsWith("unknown")
|| Build.MODEL.contains("google_sdk")
|| Build.MODEL.contains("Emulator")
|| Build.MODEL.contains("Android SDK built for x86")
|| Build.MANUFACTURER.contains("Genymotion")
|| (Build.BRAND.startsWith("generic") && Build.DEVICE.startsWith("generic"))
|| "google_sdk".equals(Build.PRODUCT);
}

/**
* Retrieves the appropriate directory for the application's database file storage based on
* several conditions such as running environment (emulator or real device) and configuration settings.
*
* @return The File object pointing to the appropriate directory for database storage.
*/
protected File getDatabaseFileFolder(){
Context context = this; // Use the current instance to access the context methods.

File dataDirectory;

if (context.getResources().getBoolean(com.aware.R.bool.internalstorage)) {
// Use the internal storage directory assigned to the app which is private.
dataDirectory = context.getFilesDir();
} else if (!context.getResources().getBoolean(com.aware.R.bool.standalone)) {
// Use a directory on the external storage that remains after the app is uninstalled.
dataDirectory = new File(Environment.getExternalStoragePublicDirectory("AWARE").toString());
} else {
// Decide the storage location based on whether the environment is an emulator.
if (isEmulator()) {
// Use internal storage for emulators for simplicity.
dataDirectory = context.getFilesDir();
} else {
// Use the external app-specific directory that is removed when the app is uninstalled.
dataDirectory = new File(ContextCompat.getExternalFilesDirs(context, null)[0] + "/AWARE");
}
}

return dataDirectory;
}

/**
* This method checks if the result corresponds to the REQUEST_CODE_OPEN_DIRECTORY and if
* the result code indicates success. If so, it proceeds to export files from a specified
* internal directory to the selected external directory.
*/
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);

// Check if the result comes from the correct request and has a successful result code
if (requestCode == REQUEST_CODE_OPEN_DIRECTORY && resultCode == RESULT_OK) {
Uri treeUri = data.getData();
DocumentFile pickedDir = DocumentFile.fromTreeUri(this, treeUri);

// Retrieve the directory for storing database files
File externalAppDirectory = getDatabaseFileFolder();


// Log.d("export_data", "External AWARE directory path: " + externalAppDirectory.getAbsolutePath());

File[] files = externalAppDirectory.listFiles();

if (files != null && files.length > 0) {
for (final File file : files) {
// Log.d("export_data", "Processing file: " + file.getAbsolutePath());
try {
DocumentFile newFile = pickedDir.createFile("application/octet-stream", file.getName());
if (newFile != null) {
try (InputStream in = new FileInputStream(file);
OutputStream out = getContentResolver().openOutputStream(newFile.getUri())) {
byte[] buffer = new byte[1024];
int length;
while ((length = in.read(buffer)) > 0) {
out.write(buffer, 0, length);
}
out.flush();
}
runOnUiThread(new Runnable() {
@Override
public void run() {
Toast.makeText(Aware_Light_Client.this, "Exported: " + file.getName(), Toast.LENGTH_SHORT).show();
}
});
} else {
throw new IOException("Failed to create document file for: " + file.getName());
}
} catch (final IOException e) {
// Log.e("export_data", "Failed to export: " + file.getName(), e);
runOnUiThread(new Runnable() {
@Override
public void run() {
Toast.makeText(Aware_Light_Client.this, "Failed to export: " + file.getName(), Toast.LENGTH_SHORT).show();
}
});
}
}
runOnUiThread(new Runnable() {
@Override
public void run() {
Toast.makeText(Aware_Light_Client.this, "All files exported successfully", Toast.LENGTH_LONG).show();
}
});
} else {
// Log.d("export_data", "No files found to export.");
runOnUiThread(new Runnable() {
@Override
public void run() {
Toast.makeText(Aware_Light_Client.this, "No files available to export.", Toast.LENGTH_SHORT).show();
}
});
}
// Log.d("export_data", "Output folder URI: " + pickedDir.getUri().toString());
}
}


@Override
protected void onResume() {
Expand Down
Loading