|
@@ -1,16 +1,31 @@
|
|
|
package de.tudarmstadt.informatik.hostage.ui;
|
|
|
|
|
|
+import java.io.File;
|
|
|
+import java.io.FileOutputStream;
|
|
|
import java.text.SimpleDateFormat;
|
|
|
import java.util.ArrayList;
|
|
|
import java.util.Arrays;
|
|
|
import java.util.Calendar;
|
|
|
import java.util.Date;
|
|
|
+import java.util.Locale;
|
|
|
|
|
|
+import org.apache.http.HttpResponse;
|
|
|
+import org.apache.http.client.HttpClient;
|
|
|
+import org.apache.http.client.methods.HttpPost;
|
|
|
+import org.apache.http.entity.StringEntity;
|
|
|
+
|
|
|
+import de.tudarmstadt.informatik.hostage.R;
|
|
|
+import de.tudarmstadt.informatik.hostage.commons.HelperUtils;
|
|
|
+import de.tudarmstadt.informatik.hostage.logging.Logger;
|
|
|
+import de.tudarmstadt.informatik.hostage.logging.Record;
|
|
|
+import de.tudarmstadt.informatik.hostage.logging.SQLLogger;
|
|
|
import android.annotation.SuppressLint;
|
|
|
import android.app.Activity;
|
|
|
import android.app.AlertDialog;
|
|
|
import android.app.DatePickerDialog;
|
|
|
import android.app.Dialog;
|
|
|
+import android.app.NotificationManager;
|
|
|
+import android.app.PendingIntent;
|
|
|
import android.content.Context;
|
|
|
import android.content.DialogInterface;
|
|
|
import android.content.Intent;
|
|
@@ -18,7 +33,11 @@ import android.content.SharedPreferences;
|
|
|
import android.content.SharedPreferences.Editor;
|
|
|
import android.os.Build;
|
|
|
import android.os.Bundle;
|
|
|
+import android.os.Environment;
|
|
|
import android.preference.PreferenceManager;
|
|
|
+import android.support.v4.app.NotificationCompat;
|
|
|
+import android.support.v4.app.TaskStackBuilder;
|
|
|
+import android.util.Log;
|
|
|
import android.view.Gravity;
|
|
|
import android.view.Menu;
|
|
|
import android.view.MenuItem;
|
|
@@ -29,22 +48,33 @@ import android.widget.TableRow;
|
|
|
import android.widget.TextView;
|
|
|
import android.widget.TimePicker;
|
|
|
import android.widget.Toast;
|
|
|
-import de.tudarmstadt.informatik.hostage.R;
|
|
|
-import de.tudarmstadt.informatik.hostage.logging.DatabaseHandler;
|
|
|
-import de.tudarmstadt.informatik.hostage.logging.Record;
|
|
|
-import de.tudarmstadt.informatik.hostage.logging.SQLLogger;
|
|
|
-
|
|
|
+/**
|
|
|
+ * ViewLog shows Statistics about the recorded Attacks.
|
|
|
+ * It also offers the user several options to perform actions with the database.
|
|
|
+ * This includes:<br>
|
|
|
+ * - show records,<br>
|
|
|
+ * - export records,<br>
|
|
|
+ * - upload records,<br>
|
|
|
+ * - and delete records.
|
|
|
+ * @author Lars Pandikow
|
|
|
+ */
|
|
|
public class ViewLog extends Activity {
|
|
|
+
|
|
|
+ public static final int JSON = 0x01;
|
|
|
+
|
|
|
+ private final SimpleDateFormat sdf = new SimpleDateFormat("MMM dd,yyyy HH:mm", Locale.US);
|
|
|
|
|
|
- DatabaseHandler dbh;
|
|
|
- private final Context context = this;
|
|
|
- private final SimpleDateFormat sdf = new SimpleDateFormat("MMM dd,yyyy HH:mm");
|
|
|
+ private Logger logger;
|
|
|
+ private SharedPreferences pref;
|
|
|
+ private Editor editor;
|
|
|
|
|
|
@Override
|
|
|
protected void onCreate(Bundle savedInstanceState) {
|
|
|
super.onCreate(savedInstanceState);
|
|
|
setContentView(R.layout.activity_viewlog);
|
|
|
- dbh = new DatabaseHandler(getApplicationContext());
|
|
|
+ logger = new SQLLogger(this);
|
|
|
+ pref = PreferenceManager.getDefaultSharedPreferences(this);
|
|
|
+ editor = pref.edit();
|
|
|
initStatistic();
|
|
|
}
|
|
|
|
|
@@ -69,37 +99,171 @@ public class ViewLog extends Activity {
|
|
|
return super.onOptionsItemSelected(item);
|
|
|
}
|
|
|
|
|
|
+ /**
|
|
|
+ * Creates a Dialog to choose export format.
|
|
|
+ * Then calls {@link ViewLog#exportDatabase(int)}
|
|
|
+ * @param view View elements which triggers the method call.
|
|
|
+ */
|
|
|
public void exportDatabase(View view) {
|
|
|
AlertDialog.Builder builder = new AlertDialog.Builder(this);
|
|
|
builder.setTitle(R.string.export_dialog_title);
|
|
|
builder.setItems(R.array.format, new DialogInterface.OnClickListener() {
|
|
|
- @Override
|
|
|
public void onClick(DialogInterface dialog, int position) {
|
|
|
- SQLLogger logger = new SQLLogger(context);
|
|
|
- logger.exportDatabase(position);
|
|
|
+ exportDatabase(position);
|
|
|
}
|
|
|
});
|
|
|
builder.create();
|
|
|
builder.show();
|
|
|
}
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Exports all records in a given format. Before exporting checks export location from preferences.
|
|
|
+ * @param format Integer coded export format
|
|
|
+ * @see Record#toString(int)
|
|
|
+ */
|
|
|
+ private void exportDatabase(int format){
|
|
|
+ try {
|
|
|
+ FileOutputStream log;
|
|
|
+ String filename = "hostage_" + format + "_" + System.currentTimeMillis() + ".log";
|
|
|
+ boolean externalStorage = pref.getBoolean("pref_external_storage", false);
|
|
|
+ String externalLocation = pref.getString("pref_external_location", "");
|
|
|
+ if(externalStorage){
|
|
|
+ String root = Environment.getExternalStorageDirectory().toString();
|
|
|
+ if(root != null && HelperUtils.isExternalStorageWritable()){
|
|
|
+ File dir = new File(root + externalLocation);
|
|
|
+ dir.mkdirs();
|
|
|
+ File file = new File(dir, filename);
|
|
|
+ log = new FileOutputStream(file);
|
|
|
+ }else {
|
|
|
+ Toast.makeText(this, "Could not write to SD Card", Toast.LENGTH_SHORT).show();
|
|
|
+ return;
|
|
|
+ }
|
|
|
|
|
|
- public void uploadDatabase(View view) {
|
|
|
- SQLLogger log = new SQLLogger(this);
|
|
|
- log.uploadDatabase();
|
|
|
+ } else{
|
|
|
+ log = this.openFileOutput("hostage_" + format + "_" + System.currentTimeMillis() + ".log", Context.MODE_PRIVATE);
|
|
|
+ }
|
|
|
+
|
|
|
+ ArrayList<Record> records = logger.getAllRecords();
|
|
|
+ for(Record record : records){
|
|
|
+ log.write((record.toString(format) + "\n").getBytes());
|
|
|
+ }
|
|
|
+ log.flush();
|
|
|
+ log.close();
|
|
|
+ Toast.makeText(this, externalStorage ? filename + " saved on external memory! " + externalLocation : filename + " saved on internal memory!", Toast.LENGTH_LONG).show();
|
|
|
+ } catch (Exception e) {
|
|
|
+ Toast.makeText(this, "Could not write to SD Card", Toast.LENGTH_SHORT).show();
|
|
|
+ e.printStackTrace();
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Uploads a JSON Representation of each attack to a server, specified in the preferences.<br>
|
|
|
+ * The method only uploads information about attacks that have net been uploaded yet.
|
|
|
+ * For the Upload it uses a HttpPost with a HttpsClient, which does not validate any certificates.<br>
|
|
|
+ * The Upload runs in its own Thread.<br>
|
|
|
+ * While uploading the method also creates a notification to inform the user about the status of the upload.
|
|
|
+ * @param view View elements which triggers the method call.
|
|
|
+ * @see de.tudarmstadt.informatik.hostage.net.MySSLSocketFactory
|
|
|
+ */
|
|
|
+ public void uploadDatabase(View view){
|
|
|
+ //Create a Notification
|
|
|
+ final NotificationCompat.Builder builder;
|
|
|
+ final NotificationManager mNotifyManager;
|
|
|
+ final int lastUploadedAttackId = pref.getInt("LAST_UPLOADED_ATTACK_ID", -1);
|
|
|
+ int currentAttackId = pref.getInt("ATTACK_ID_COUNTER", 0);
|
|
|
+ // Check if there are new records to upload
|
|
|
+ if(lastUploadedAttackId == currentAttackId -1){
|
|
|
+ // Inform user that no upload is necessary
|
|
|
+ Toast.makeText(this, "All data have already been uploaded.", Toast.LENGTH_SHORT).show();
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ // Build and show Upload Notification in notification bar
|
|
|
+ builder = new NotificationCompat.Builder(this)
|
|
|
+ .setContentTitle(this.getString(R.string.app_name))
|
|
|
+ .setContentText("Upload in progress...")
|
|
|
+ .setTicker("Uploading Data...")
|
|
|
+ .setSmallIcon(R.drawable.ic_launcher)
|
|
|
+ .setWhen(System.currentTimeMillis());
|
|
|
+ TaskStackBuilder stackBuilder = TaskStackBuilder.create(this);
|
|
|
+ stackBuilder.addParentStack(MainActivity.class);
|
|
|
+ stackBuilder.addNextIntent(new Intent());
|
|
|
+ PendingIntent resultPendingIntent = stackBuilder.getPendingIntent(0,
|
|
|
+ PendingIntent.FLAG_UPDATE_CURRENT);
|
|
|
+ builder.setContentIntent(resultPendingIntent);
|
|
|
+ builder.setAutoCancel(true);
|
|
|
+ builder.setOnlyAlertOnce(false);
|
|
|
+ mNotifyManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
|
|
|
+ mNotifyManager.notify(2, builder.build());
|
|
|
+ // Create a new Thread for upload
|
|
|
+ new Thread(new Runnable() {
|
|
|
+ public void run() {
|
|
|
+ // Create a https client. Uses MySSLSocketFactory to accept all certificates
|
|
|
+ HttpClient httpclient = HelperUtils.createHttpClient();
|
|
|
+ // get RecordList
|
|
|
+ ArrayList<Record> recordList = logger.getRecordOfEachAttack(lastUploadedAttackId);
|
|
|
+ final int progressMax = recordList.size();
|
|
|
+ Log.i("SQLLogger", "Logs to upload: " + progressMax);
|
|
|
+ HttpPost httppost;
|
|
|
+ int progressBarStatus = 0;
|
|
|
+ for(Record record: recordList){
|
|
|
+ Log.i("SQLLogger", "Uploading log: " + progressBarStatus);
|
|
|
+ try {
|
|
|
+ // Create HttpPost
|
|
|
+ httppost = new HttpPost(pref.getString("pref_upload", "https://ssi.cased.de"));
|
|
|
+ // Create JSON String of Record
|
|
|
+ StringEntity se = new StringEntity(record.toString(JSON));
|
|
|
+ httppost.setEntity(se);
|
|
|
+ // Execute HttpPost
|
|
|
+ HttpResponse response = httpclient.execute(httppost);
|
|
|
+ Log.i("SQLLogger", "Statuscode of log " + progressBarStatus + ": " + " " + response.getStatusLine().getReasonPhrase());
|
|
|
+ Log.i("SQLLogger", "Statuscode of log " + progressBarStatus + ": " + " " + response.getStatusLine().getStatusCode());
|
|
|
+ // Update Notification progress bar
|
|
|
+ progressBarStatus++;
|
|
|
+ builder.setProgress(progressMax, progressBarStatus, false);
|
|
|
+ // Update the progress bar
|
|
|
+ mNotifyManager.notify(2, builder.build());
|
|
|
+ } catch (Exception e) {
|
|
|
+ Log.i("SQLLogger", "Failed");
|
|
|
+ e.printStackTrace();
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if(progressBarStatus == progressMax){
|
|
|
+ // When the loop is finished, updates the notification
|
|
|
+ builder.setContentText("Upload complete")
|
|
|
+ .setTicker("Upload complete")
|
|
|
+ // Removes the progress bar
|
|
|
+ .setProgress(0,0,false);
|
|
|
+ mNotifyManager.notify(2, builder.build());
|
|
|
+ }
|
|
|
+ }}).start();
|
|
|
+ editor.putInt("LAST_UPLOADED_ATTACK_ID",currentAttackId - 1);
|
|
|
+ editor.commit();
|
|
|
}
|
|
|
|
|
|
+ /**
|
|
|
+ * Starts a ViewLogTable Activity.
|
|
|
+ * @param view View elements which triggers the method call.
|
|
|
+ * @see ViewLogTable
|
|
|
+ */
|
|
|
public void showLog(View view) {
|
|
|
startActivity(new Intent(this, ViewLogTable.class));
|
|
|
}
|
|
|
|
|
|
- @SuppressLint("NewApi")
|
|
|
+ /**
|
|
|
+ * Creates a Dialog that lets the user decide which criteria he want to use to delete records.
|
|
|
+ * Then calls the corresponding method.
|
|
|
+ * @param view View elements which triggers the method call.
|
|
|
+ * @see ViewLog#deleteByBSSID()
|
|
|
+ * @see ViewLog#deleteByDate()
|
|
|
+ * @see ViewLog#deleteAll()
|
|
|
+ */
|
|
|
public void deleteLog(View view) {
|
|
|
AlertDialog.Builder builder = new AlertDialog.Builder(this);
|
|
|
|
|
|
builder.setTitle(R.string.delete_dialog_title);
|
|
|
builder.setItems(R.array.delete_criteria,
|
|
|
new DialogInterface.OnClickListener() {
|
|
|
- @Override
|
|
|
public void onClick(DialogInterface dialog, int position) {
|
|
|
switch (position) {
|
|
|
case 0:
|
|
@@ -116,19 +280,47 @@ public class ViewLog extends Activity {
|
|
|
builder.create();
|
|
|
builder.show();
|
|
|
}
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Shows a List with all recorded BSSIDs.
|
|
|
+ * If a BSSID is selected the method calls {@link Logger#deleteByBSSID(String)} to delete all records with the chosen BSSID
|
|
|
+ * @see Logger#deleteByBSSID
|
|
|
+ */
|
|
|
+ private void deleteByBSSID() {
|
|
|
+ AlertDialog.Builder builder = new AlertDialog.Builder(this);
|
|
|
+ final String[] bssidArray = logger.getAllBSSIDS();
|
|
|
+ for(int i = 0; i < bssidArray.length; i++){
|
|
|
+ bssidArray[i] = bssidArray[i] + " (" + logger.getSSID(bssidArray[i]) +")";
|
|
|
+ }
|
|
|
+ builder.setTitle(R.string.delete_dialog_title);
|
|
|
+ builder.setItems(bssidArray, new DialogInterface.OnClickListener() {
|
|
|
+ @SuppressLint("NewApi")
|
|
|
+ public void onClick(DialogInterface dialog, int position) {
|
|
|
+ logger.deleteByBSSID(bssidArray[position]);
|
|
|
+ Toast.makeText(
|
|
|
+ getApplicationContext(),
|
|
|
+ "All entries with bssid '" + bssidArray[position]
|
|
|
+ + "' deleted.", Toast.LENGTH_SHORT).show();
|
|
|
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
|
|
|
+ recreate();
|
|
|
+ } else {
|
|
|
+ Intent intent = getIntent();
|
|
|
+ finish();
|
|
|
+ startActivity(intent);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ });
|
|
|
+ builder.create();
|
|
|
+ builder.show();
|
|
|
+ }
|
|
|
|
|
|
+ /**
|
|
|
+ * Creates a DatePicking Dialog where the user can choose a date. Afterwards {@link ViewLog#deleteByDate(int, int, int)} is called.
|
|
|
+ */
|
|
|
private void deleteByDate() {
|
|
|
showDialog(0);
|
|
|
}
|
|
|
|
|
|
- private DatePickerDialog.OnDateSetListener pDateSetListener = new DatePickerDialog.OnDateSetListener() {
|
|
|
-
|
|
|
- @Override
|
|
|
- public void onDateSet(DatePicker view, int year, int monthOfYear,
|
|
|
- int dayOfMonth) {
|
|
|
- deleteByDate(year, monthOfYear, dayOfMonth);
|
|
|
- }
|
|
|
- };
|
|
|
|
|
|
@Override
|
|
|
protected Dialog onCreateDialog(int id) {
|
|
@@ -138,14 +330,24 @@ public class ViewLog extends Activity {
|
|
|
int pYear = cal.get(Calendar.YEAR);
|
|
|
int pMonth = cal.get(Calendar.MONTH);
|
|
|
int pDay = cal.get(Calendar.DAY_OF_MONTH);
|
|
|
- return new DatePickerDialog(this, pDateSetListener, pYear, pMonth,
|
|
|
- pDay);
|
|
|
+ return new DatePickerDialog(this, new DatePickerDialog.OnDateSetListener() {
|
|
|
+ public void onDateSet(DatePicker view, int year, int monthOfYear,
|
|
|
+ int dayOfMonth) {deleteByDate(year, monthOfYear, dayOfMonth);}}
|
|
|
+ , pYear, pMonth, pDay);
|
|
|
}
|
|
|
return null;
|
|
|
}
|
|
|
|
|
|
+ /**
|
|
|
+ * Shows a Dialog with the given date and ask him to confirm deleting records that are older than the shown date.
|
|
|
+ * When the user confirms {@link Logger#deleteByDate(long)} is called with a long representation of the Date.
|
|
|
+ * If the user cancels the Dialog nothing happens and the dialog disappears.
|
|
|
+ * @param year
|
|
|
+ * @param monthOfYear
|
|
|
+ * @param dayOfMonth
|
|
|
+ */
|
|
|
private void deleteByDate(int year, int monthOfYear, int dayOfMonth) {
|
|
|
- TimePicker timePicker = new TimePicker(context);
|
|
|
+ TimePicker timePicker = new TimePicker(this);
|
|
|
final Calendar calendar = Calendar.getInstance();
|
|
|
calendar.set(year, monthOfYear, dayOfMonth,
|
|
|
timePicker.getCurrentHour(), timePicker.getCurrentMinute(), 0);
|
|
@@ -154,12 +356,11 @@ public class ViewLog extends Activity {
|
|
|
.setMessage(sdf.format(calendar.getTime()))
|
|
|
.setPositiveButton(R.string.delete,
|
|
|
new DialogInterface.OnClickListener() {
|
|
|
- @Override
|
|
|
@SuppressLint("NewApi")
|
|
|
public void onClick(DialogInterface dialog, int id) {
|
|
|
long time = calendar.getTimeInMillis();
|
|
|
// Delete Data
|
|
|
- dbh.deleteByDate(time);
|
|
|
+ logger.deleteByDate(time);
|
|
|
Toast.makeText(getApplicationContext(),
|
|
|
"Data sets deleted!",
|
|
|
Toast.LENGTH_SHORT).show();
|
|
@@ -175,7 +376,6 @@ public class ViewLog extends Activity {
|
|
|
})
|
|
|
.setNegativeButton(R.string.cancel,
|
|
|
new DialogInterface.OnClickListener() {
|
|
|
- @Override
|
|
|
public void onClick(DialogInterface dialog, int id) {
|
|
|
// User cancelled the dialog
|
|
|
}
|
|
@@ -185,47 +385,20 @@ public class ViewLog extends Activity {
|
|
|
builder.show();
|
|
|
}
|
|
|
|
|
|
- private void deleteByBSSID() {
|
|
|
- AlertDialog.Builder builder = new AlertDialog.Builder(this);
|
|
|
- final String[] bssidArray = dbh.getAllBSSIDS();
|
|
|
- for(int i = 0; i < bssidArray.length; i++){
|
|
|
- bssidArray[i] = bssidArray[i] + " (" + dbh.getSSID(bssidArray[i]) +")";
|
|
|
- }
|
|
|
- builder.setTitle(R.string.delete_dialog_title);
|
|
|
- builder.setItems(bssidArray, new DialogInterface.OnClickListener() {
|
|
|
- @Override
|
|
|
- @SuppressLint("NewApi")
|
|
|
- public void onClick(DialogInterface dialog, int position) {
|
|
|
- dbh.deleteByBSSID(bssidArray[position]);
|
|
|
- Toast.makeText(
|
|
|
- getApplicationContext(),
|
|
|
- "All entries with bssid '" + bssidArray[position]
|
|
|
- + "' deleted.", Toast.LENGTH_SHORT).show();
|
|
|
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
|
|
|
- recreate();
|
|
|
- } else {
|
|
|
- Intent intent = getIntent();
|
|
|
- finish();
|
|
|
- startActivity(intent);
|
|
|
- }
|
|
|
- }
|
|
|
- });
|
|
|
- builder.create();
|
|
|
- builder.show();
|
|
|
- }
|
|
|
-
|
|
|
+ /**
|
|
|
+ * Shows a Dialog to confirm that the database should be cleared.
|
|
|
+ * If confirmed {@link SQLLogger#clearData()} is called.
|
|
|
+ * @see Logger#clearData()
|
|
|
+ */
|
|
|
private void deleteAll() {
|
|
|
AlertDialog.Builder builder = new AlertDialog.Builder(this);
|
|
|
builder.setMessage(R.string.dialog_clear_database)
|
|
|
.setPositiveButton(R.string.clear,
|
|
|
new DialogInterface.OnClickListener() {
|
|
|
- @Override
|
|
|
@SuppressLint("NewApi")
|
|
|
public void onClick(DialogInterface dialog, int id) {
|
|
|
// Clear all Data
|
|
|
- dbh.clearData();
|
|
|
- SharedPreferences pref = PreferenceManager.getDefaultSharedPreferences(context);
|
|
|
- Editor editor = pref.edit();
|
|
|
+ logger.clearData();
|
|
|
editor.putInt("ATTACK_ID_COUNTER", 0);
|
|
|
editor.putInt("LAST_UPLOADED_ATTACK_ID", -1);
|
|
|
editor.commit();
|
|
@@ -244,7 +417,6 @@ public class ViewLog extends Activity {
|
|
|
})
|
|
|
.setNegativeButton(R.string.cancel,
|
|
|
new DialogInterface.OnClickListener() {
|
|
|
- @Override
|
|
|
public void onClick(DialogInterface dialog, int id) {
|
|
|
// User cancelled the dialog
|
|
|
}
|
|
@@ -254,6 +426,12 @@ public class ViewLog extends Activity {
|
|
|
builder.show();
|
|
|
}
|
|
|
|
|
|
+ /**
|
|
|
+ * Initializes the Statistics. Creates a table row for every protocol and checks the dabase for the attack count.
|
|
|
+ * Calls {@link ViewLog#setFirstAndLastAttack()} to set the TextViews.
|
|
|
+ * @see Logger#getAttackCount()
|
|
|
+ * @see Logger#getAttackPerProtokolCount(String)
|
|
|
+ */
|
|
|
private void initStatistic() {
|
|
|
TableLayout table = (TableLayout) findViewById(R.id.layoutContainer);
|
|
|
|
|
@@ -278,18 +456,24 @@ public class ViewLog extends Activity {
|
|
|
value.setPadding(3, 0, 3, 0);
|
|
|
row.addView(value);
|
|
|
if (protocol.equals("Total")) {
|
|
|
- value.setText("" + dbh.getAttackCount());
|
|
|
+ value.setText("" + logger.getAttackCount());
|
|
|
} else {
|
|
|
- value.setText("" + dbh.getAttackPerProtokolCount(protocol));
|
|
|
+ value.setText("" + logger.getAttackPerProtokolCount(protocol));
|
|
|
}
|
|
|
table.addView(row);
|
|
|
}
|
|
|
setFirstAndLastAttack();
|
|
|
}
|
|
|
|
|
|
+ /**
|
|
|
+ * Sets the TextViews for first and last attack.
|
|
|
+ * @see Logger#getSmallestAttackId()
|
|
|
+ * @see Logger#getHighestAttackId()
|
|
|
+ * @see Logger#getRecordOfAttackId(long)
|
|
|
+ */
|
|
|
private void setFirstAndLastAttack() {
|
|
|
- Record firstAttack = dbh.getRecordOfAttackId(dbh.getSmallestAttackId());
|
|
|
- Record lastAttack = dbh.getRecordOfAttackId(dbh.getHighestAttackId());
|
|
|
+ Record firstAttack = logger.getRecordOfAttackId(logger.getSmallestAttackId());
|
|
|
+ Record lastAttack = logger.getRecordOfAttackId(logger.getHighestAttackId());
|
|
|
if (firstAttack != null) {
|
|
|
Date resultdate = new Date(firstAttack.getTimestamp());
|
|
|
TextView text = (TextView) findViewById(R.id.textFirstAttackValue);
|