I am trying to capture X, Y coordinates for touch event but the output in the CSV is not capturing. I am running this in Android 11 version mobile, but this needs to work Android 9 and above all versions. Here is the code –
package com.example.kb_keylog;
import android.content.ContentValues;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.provider.MediaStore;
import android.text.Editable;
import android.text.TextWatcher;
import android.view.MotionEvent;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
import androidx.appcompat.app.AppCompatActivity;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;
public class MainActivity extends AppCompatActivity {
private Button startButton, stopButton, submitButton;
private EditText sentenceEditText;
private boolean logging = false;
private int seconds = 0;
private Handler handler = new Handler();
private List<String> coordinatesList = new ArrayList<>();
private StringBuilder typedCharacters = new StringBuilder();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
startButton = findViewById(R.id.startButton);
stopButton = findViewById(R.id.stopButton);
submitButton = findViewById(R.id.submitButton);
sentenceEditText = findViewById(R.id.sentenceEditText);
startButton.setOnClickListener(v -> startLogging());
stopButton.setOnClickListener(v -> stopLogging());
submitButton.setOnClickListener(v -> exportToCSV());
// Add touch listener to capture touch events
sentenceEditText.setOnTouchListener((v, event) -> {
if (event.getAction() == MotionEvent.ACTION_DOWN) {
// Touch down event
String touchCoordinates = event.getX() + "," + event.getY();
String timestamp = String.valueOf(System.currentTimeMillis());
coordinatesList.add(timestamp + "," + touchCoordinates + ",TAP");
}
return false;
});
// Add text change listener to capture typed characters
sentenceEditText.addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
// Add typed character information
String timestamp = String.valueOf(System.currentTimeMillis());
int endIndex = start + count; // Calculate the end index
if (count > 0) {
// Append typed characters
typedCharacters.append(s.subSequence(start, endIndex));
coordinatesList.add(timestamp + ",-,-," + s.charAt(endIndex - 1) + "," + typedCharacters.toString() + ",TAP");
} else {
// Backspace/delete key pressed
if (start > 0 && typedCharacters.length() > 0) {
// Remove the last character from typedCharacters
typedCharacters.deleteCharAt(typedCharacters.length() - 1);
}
coordinatesList.add(timestamp + ",-,-,Backspace," + typedCharacters.toString() + ",Backspace");
}
}
@Override
public void afterTextChanged(Editable s) {}
});
}
private void startLogging() {
logging = true;
handler.postDelayed(new Runnable() {
@Override
public void run() {
seconds++;
startButton.setText("Start (" + seconds + "s)");
if (logging) {
handler.postDelayed(this, 1000);
}
}
}, 1000);
}
private void stopLogging() {
logging = false;
seconds = 0;
startButton.setText("Start");
}
private void exportToCSV() {
// Define the content values for the new media file
ContentValues values = new ContentValues();
values.put(MediaStore.MediaColumns.DISPLAY_NAME, "captured_data.csv");
values.put(MediaStore.MediaColumns.MIME_TYPE, "text/csv");
// Prepare the CSV file content
StringBuilder csvContent = new StringBuilder();
csvContent.append("id,xCoordinate,yCoordinate,timestamp,character,charSq,typen"); // CSV header
int id = 1;
for (String entry : coordinatesList) {
String[] parts = entry.split(",");
if (parts.length >= 6) { // Ensure array has at least 6 elements
String timestamp = parts[0];
String coordinates = parts[1] + "," + parts[2]; // Combine x and y coordinates
String character = parts[3];
String charSq = parts[4];
String type = parts[5];
csvContent.append(id++).append(",").append(coordinates).append(",").append(timestamp)
.append(",").append(character).append(",").append(charSq).append(",").append(type).append("n");
} else {
// Handle invalid entry (missing data)
// Log a warning or skip this entry
// You can also consider adding error handling based on your app's requirements
}
}
// Insert the content values into the MediaStore
Uri uri = getContentResolver().insert(MediaStore.Files.getContentUri("external"), values);
try {
// Open an OutputStream to the MediaStore URI
OutputStream outputStream = getContentResolver().openOutputStream(uri);
if (outputStream != null) {
// Write data to the OutputStream
outputStream.write(csvContent.toString().getBytes());
outputStream.close();
// Show a success message to the user
Toast.makeText(this, "Data exported to CSV: " + uri.toString(), Toast.LENGTH_LONG).show();
}
} catch (Exception e) {
// Handle any errors that occur during file operations
e.printStackTrace();
Toast.makeText(this, "Error exporting data to CSV", Toast.LENGTH_SHORT).show();
}
}
}
I believe on text change or somewhere it is missing to capture the coordinates.