Merge branch 'Logging_firebase' into Logging
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -7,5 +7,6 @@ app/release/app-release.apk
|
|||||||
app/build
|
app/build
|
||||||
app/app.iml
|
app/app.iml
|
||||||
app/release/output-metadata.json
|
app/release/output-metadata.json
|
||||||
|
app/google-services.json
|
||||||
*#
|
*#
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
apply plugin: 'com.android.application'
|
apply plugin: 'com.android.application'
|
||||||
|
apply plugin: 'com.google.gms.google-services'
|
||||||
android {
|
android {
|
||||||
compileSdkVersion 31
|
compileSdkVersion 31
|
||||||
useLibrary 'org.apache.http.legacy'
|
useLibrary 'org.apache.http.legacy'
|
||||||
@@ -37,6 +37,8 @@ dependencies {
|
|||||||
// Unit testing dependencies
|
// Unit testing dependencies
|
||||||
implementation 'androidx.constraintlayout:constraintlayout:2.1.3'
|
implementation 'androidx.constraintlayout:constraintlayout:2.1.3'
|
||||||
implementation 'com.google.android.material:material:1.4.0'
|
implementation 'com.google.android.material:material:1.4.0'
|
||||||
|
implementation 'com.google.firebase:firebase-auth:19.2.0'
|
||||||
|
implementation 'androidx.test:core:1.4.0'
|
||||||
testImplementation 'junit:junit:4.13.2'
|
testImplementation 'junit:junit:4.13.2'
|
||||||
// Set this dependency if you want to use Mockito
|
// Set this dependency if you want to use Mockito
|
||||||
testImplementation 'org.mockito:mockito-core:4.3.1'
|
testImplementation 'org.mockito:mockito-core:4.3.1'
|
||||||
@@ -53,7 +55,10 @@ dependencies {
|
|||||||
//implementation 'com.github.RohitSurwase.UCE-Handler:uce_handler:1.3'
|
//implementation 'com.github.RohitSurwase.UCE-Handler:uce_handler:1.3'
|
||||||
testImplementation 'org.robolectric:robolectric:4.7.3'
|
testImplementation 'org.robolectric:robolectric:4.7.3'
|
||||||
implementation 'com.android.volley:volley:1.2.1'
|
implementation 'com.android.volley:volley:1.2.1'
|
||||||
|
implementation platform('com.google.firebase:firebase-bom:29.2.0')
|
||||||
|
implementation 'com.google.firebase:firebase-analytics'
|
||||||
|
implementation 'com.firebaseui:firebase-ui-auth:7.2.0'
|
||||||
|
implementation 'com.google.firebase:firebase-firestore'
|
||||||
}
|
}
|
||||||
|
|
||||||
repositories {
|
repositories {
|
||||||
|
|||||||
@@ -2,8 +2,8 @@
|
|||||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
package="uk.org.openseizuredetector"
|
package="uk.org.openseizuredetector"
|
||||||
android:versionCode="99"
|
android:versionCode="100"
|
||||||
android:versionName="4.0.2">
|
android:versionName="4.1.1">
|
||||||
<!-- android:allowBackup="false" -->
|
<!-- android:allowBackup="false" -->
|
||||||
<uses-permission android:name="android.permission.BLUETOOTH" />
|
<uses-permission android:name="android.permission.BLUETOOTH" />
|
||||||
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
|
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
|
||||||
|
|||||||
@@ -5,6 +5,9 @@ import android.content.SharedPreferences;
|
|||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
import android.preference.PreferenceManager;
|
import android.preference.PreferenceManager;
|
||||||
|
|
||||||
|
import androidx.activity.result.ActivityResultLauncher;
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
import androidx.appcompat.app.AppCompatActivity;
|
import androidx.appcompat.app.AppCompatActivity;
|
||||||
|
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
@@ -15,19 +18,28 @@ import android.widget.EditText;
|
|||||||
import android.widget.LinearLayout;
|
import android.widget.LinearLayout;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
|
|
||||||
|
import com.firebase.ui.auth.AuthUI;
|
||||||
|
import com.firebase.ui.auth.FirebaseAuthUIActivityResultContract;
|
||||||
|
import com.google.android.gms.tasks.OnCompleteListener;
|
||||||
|
import com.google.android.gms.tasks.Task;
|
||||||
|
import com.google.firebase.auth.FirebaseAuth;
|
||||||
|
|
||||||
import org.json.JSONException;
|
import org.json.JSONException;
|
||||||
import org.json.JSONObject;
|
import org.json.JSONObject;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
|
||||||
public class AuthenticateActivity extends AppCompatActivity {
|
public class AuthenticateActivity extends AppCompatActivity {
|
||||||
private String TAG = "AuthenticateActivity";
|
private String TAG = "AuthenticateActivity";
|
||||||
|
private OsdUtil mUtil;
|
||||||
private EditText mUnameEt;
|
private EditText mUnameEt;
|
||||||
private EditText mPasswdEt;
|
private EditText mPasswdEt;
|
||||||
|
private SdServiceConnection mConnection;
|
||||||
|
final Handler serverStatusHandler = new Handler();
|
||||||
private WebApiConnection mWac;
|
private WebApiConnection mWac;
|
||||||
private LogManager mLm;
|
private LogManager mLm;
|
||||||
private SdServiceConnection mConnection;
|
private static final String TOKEN_ID = "webApiAuthToken";
|
||||||
private OsdUtil mUtil;
|
|
||||||
final Handler serverStatusHandler = new Handler();
|
|
||||||
private String TOKEN_ID = "webApiAuthToken";
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onCreate(Bundle savedInstanceState) {
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
@@ -36,24 +48,28 @@ public class AuthenticateActivity extends AppCompatActivity {
|
|||||||
setContentView(R.layout.activity_authenticate);
|
setContentView(R.layout.activity_authenticate);
|
||||||
|
|
||||||
mUtil = new OsdUtil(getApplicationContext(), serverStatusHandler);
|
mUtil = new OsdUtil(getApplicationContext(), serverStatusHandler);
|
||||||
|
|
||||||
if (!mUtil.isServerRunning()) {
|
if (!mUtil.isServerRunning()) {
|
||||||
mUtil.showToast(getString(R.string.error_server_not_running));
|
mUtil.showToast(getString(R.string.error_server_not_running));
|
||||||
finish();
|
finish();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
mConnection = new SdServiceConnection(getApplicationContext());
|
|
||||||
|
|
||||||
Button cancelBtn =
|
Button cancelBtn =
|
||||||
(Button) findViewById(R.id.cancelBtn);
|
(Button) findViewById(R.id.cancelBtn);
|
||||||
cancelBtn.setOnClickListener(onCancel);
|
cancelBtn.setOnClickListener(onCancel);
|
||||||
Button OKBtn = (Button) findViewById(R.id.OKBtn);
|
Button loginBtn = (Button) findViewById(R.id.loginBtn);
|
||||||
OKBtn.setOnClickListener(onOK);
|
loginBtn.setOnClickListener(onLogin);
|
||||||
Button logoutCancelBtn =
|
Button logoutCancelBtn =
|
||||||
(Button) findViewById(R.id.logoutCancelBtn);
|
(Button) findViewById(R.id.logoutCancelBtn);
|
||||||
logoutCancelBtn.setOnClickListener(onCancel);
|
logoutCancelBtn.setOnClickListener(onCancel);
|
||||||
Button logoutBtn = (Button)findViewById(R.id.logoutBtn);
|
Button logoutBtn = (Button) findViewById(R.id.logoutBtn);
|
||||||
logoutBtn.setOnClickListener(onLogout);
|
logoutBtn.setOnClickListener(onLogout);
|
||||||
|
|
||||||
|
// Components required only for osdapi backend
|
||||||
|
if (LogManager.USE_FIREBASE_BACKEND) { }
|
||||||
|
else {
|
||||||
|
mConnection = new SdServiceConnection(getApplicationContext());
|
||||||
|
|
||||||
Button registerBtn = (Button) findViewById(R.id.RegisterBtn);
|
Button registerBtn = (Button) findViewById(R.id.RegisterBtn);
|
||||||
registerBtn.setOnClickListener(onRegister);
|
registerBtn.setOnClickListener(onRegister);
|
||||||
Button resetPasswordBtn = (Button) findViewById(R.id.ResetPasswordBtn);
|
Button resetPasswordBtn = (Button) findViewById(R.id.ResetPasswordBtn);
|
||||||
@@ -61,25 +77,59 @@ public class AuthenticateActivity extends AppCompatActivity {
|
|||||||
|
|
||||||
mUnameEt = (EditText) findViewById(R.id.username);
|
mUnameEt = (EditText) findViewById(R.id.username);
|
||||||
mPasswdEt = (EditText) findViewById(R.id.password);
|
mPasswdEt = (EditText) findViewById(R.id.password);
|
||||||
//mWac = new WebApiConnection(this, String tokenStr);
|
}
|
||||||
//mLm = new LogManager(this);
|
|
||||||
|
Button aboutDataSharingBtn = (Button) findViewById(R.id.aboutDataSharingBtn);
|
||||||
|
aboutDataSharingBtn.setOnClickListener(
|
||||||
|
new View.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(View view) {
|
||||||
|
Log.v(TAG,"aboutDataSharingBtn.onClick()");
|
||||||
|
String url = OsdUtil.DATA_SHARING_URL;
|
||||||
|
Intent i = new Intent(Intent.ACTION_VIEW);
|
||||||
|
i.setData(Uri.parse(url));
|
||||||
|
startActivity(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
Button privacyPolicyBtn = (Button) findViewById(R.id.privacyPolicyBtn);
|
||||||
|
privacyPolicyBtn.setOnClickListener(
|
||||||
|
new View.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(View view) {
|
||||||
|
Log.v(TAG,"privacyPolicyBtn.onClick()");
|
||||||
|
String url = OsdUtil.PRIVACY_POLICY_URL;
|
||||||
|
Intent i = new Intent(Intent.ACTION_VIEW);
|
||||||
|
i.setData(Uri.parse(url));
|
||||||
|
startActivity(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onStart() {
|
protected void onStart() {
|
||||||
Log.d(TAG, "onStart()");
|
Log.d(TAG, "onStart()");
|
||||||
super.onStart();
|
super.onStart();
|
||||||
|
if (LogManager.USE_FIREBASE_BACKEND) {
|
||||||
|
updateUi();
|
||||||
|
} else {
|
||||||
mUtil.bindToServer(getApplicationContext(), mConnection);
|
mUtil.bindToServer(getApplicationContext(), mConnection);
|
||||||
waitForConnection();
|
waitForConnection();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onStop() {
|
protected void onStop() {
|
||||||
Log.d(TAG, "onStop()");
|
Log.d(TAG, "onStop()");
|
||||||
super.onStop();
|
super.onStop();
|
||||||
|
if (LogManager.USE_FIREBASE_BACKEND) {
|
||||||
|
|
||||||
|
} else {
|
||||||
mUtil.unbindFromServer(getApplicationContext(), mConnection);
|
mUtil.unbindFromServer(getApplicationContext(), mConnection);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void waitForConnection() {
|
private void waitForConnection() {
|
||||||
// We want the UI to update as soon as it is displayed, but it takes a finite time for
|
// We want the UI to update as soon as it is displayed, but it takes a finite time for
|
||||||
@@ -100,40 +150,49 @@ public class AuthenticateActivity extends AppCompatActivity {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void initialiseServiceConnection() {
|
private void initialiseServiceConnection() {
|
||||||
|
Log.v(TAG,"initialiseServiceConnection()");
|
||||||
mLm = mConnection.mSdServer.mLm;
|
mLm = mConnection.mSdServer.mLm;
|
||||||
mWac = mConnection.mSdServer.mLm.mWac;
|
mWac = mConnection.mSdServer.mLm.mWac;
|
||||||
updateUi();
|
updateUi();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updateUi() {
|
|
||||||
SharedPreferences prefs;
|
|
||||||
String storedAuthToken;
|
|
||||||
LinearLayout loginLl = (LinearLayout)findViewById(R.id.login_ui);
|
|
||||||
LinearLayout logoutLl = (LinearLayout)findViewById(R.id.logout_ui);
|
|
||||||
Log.i(TAG, "switchUi()");
|
|
||||||
storedAuthToken = getAuthToken(); //mWac.getStoredToken();
|
|
||||||
//prefs = PreferenceManager.getDefaultSharedPreferences(this);
|
|
||||||
//storedAuthToken = (prefs.getString("webApiAuthToken", null));
|
|
||||||
Log.v(TAG, "storedAuthToken=" + storedAuthToken);
|
|
||||||
|
|
||||||
// Check if we are already logged in
|
|
||||||
if (storedAuthToken == null || storedAuthToken.length() == 0) {
|
// Called after the Firebase Auth UI has completed
|
||||||
Log.v(TAG, "Not Logged in - showing log in UI");
|
private ActivityResultLauncher<Intent> signInLauncher = registerForActivityResult(
|
||||||
loginLl.setVisibility(View.VISIBLE);
|
new FirebaseAuthUIActivityResultContract(),
|
||||||
logoutLl.setVisibility(View.GONE);
|
(result) -> {
|
||||||
} else {
|
Log.i(TAG, "FirebaseAuthUIActivityResult - " + result.toString());
|
||||||
|
updateUi();
|
||||||
|
});
|
||||||
|
|
||||||
|
// ...
|
||||||
|
|
||||||
|
|
||||||
|
private void updateUi() {
|
||||||
|
Log.v(TAG,"updateUi()");
|
||||||
|
LinearLayout loginLl = (LinearLayout) findViewById(R.id.login_ui);
|
||||||
|
LinearLayout osdApiLoginLl = (LinearLayout) findViewById(R.id.login_osdapi_ui);
|
||||||
|
LinearLayout logoutLl = (LinearLayout) findViewById(R.id.logout_ui);
|
||||||
|
|
||||||
|
if (mWac == null) {
|
||||||
|
Log.i(TAG,"mWac is null - not updating UI");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mWac.isLoggedIn()) {
|
||||||
Log.v(TAG, "Already Logged in - showing Log Out prompt");
|
Log.v(TAG, "Already Logged in - showing Log Out prompt");
|
||||||
loginLl.setVisibility(View.GONE);
|
loginLl.setVisibility(View.GONE);
|
||||||
logoutLl.setVisibility(View.VISIBLE);
|
logoutLl.setVisibility(View.VISIBLE);
|
||||||
//TextView tv = (TextView)findViewById(R.id.tokenTv);
|
if (!LogManager.USE_FIREBASE_BACKEND) {
|
||||||
//tv.setText("Logged in with Token: "+storedAuthToken);
|
osdApiLoginLl.setVisibility(View.GONE);
|
||||||
if (mWac != null) {
|
}
|
||||||
mWac.getUserProfile((JSONObject profileObj) -> {
|
mWac.getUserProfile((JSONObject profileObj) -> {
|
||||||
try {
|
try {
|
||||||
Long userId = profileObj.getLong("id");
|
String userId = profileObj.getString("id");
|
||||||
String userName = profileObj.getString("username");
|
String userName = profileObj.getString("username");
|
||||||
TextView tv2 = (TextView) findViewById(R.id.userIdTv);
|
TextView tv2 = (TextView) findViewById(R.id.userIdTv);
|
||||||
tv2.setText(userId.toString());
|
tv2.setText(userId);
|
||||||
tv2 = (TextView) findViewById(R.id.usernameTv);
|
tv2 = (TextView) findViewById(R.id.usernameTv);
|
||||||
tv2.setText(userName);
|
tv2.setText(userName);
|
||||||
} catch (JSONException e) {
|
} catch (JSONException e) {
|
||||||
@@ -142,11 +201,15 @@ public class AuthenticateActivity extends AppCompatActivity {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
Log.i(TAG,"UpdateUI - not retrieving profile because mWac is null");
|
Log.v(TAG,"updateUi() - not logged in..");
|
||||||
}
|
loginLl.setVisibility(View.VISIBLE);
|
||||||
|
logoutLl.setVisibility(View.GONE);
|
||||||
|
if (!LogManager.USE_FIREBASE_BACKEND) {
|
||||||
|
osdApiLoginLl.setVisibility(View.VISIBLE);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
View.OnClickListener onCancel =
|
View.OnClickListener onCancel =
|
||||||
new View.OnClickListener() {
|
new View.OnClickListener() {
|
||||||
@@ -158,12 +221,32 @@ public class AuthenticateActivity extends AppCompatActivity {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
View.OnClickListener onOK =
|
View.OnClickListener onLogin =
|
||||||
new View.OnClickListener() {
|
new View.OnClickListener() {
|
||||||
@Override
|
@Override
|
||||||
public void onClick(View view) {
|
public void onClick(View view) {
|
||||||
//m_status=true;
|
//m_status=true;
|
||||||
Log.v(TAG, "onOK()");
|
if (LogManager.USE_FIREBASE_BACKEND) {
|
||||||
|
Log.v(TAG, "onLogin() - using Firebase Login");
|
||||||
|
Intent signInIntent = AuthUI.getInstance()
|
||||||
|
.createSignInIntentBuilder()
|
||||||
|
.setAvailableProviders(Arrays.asList(
|
||||||
|
new AuthUI.IdpConfig.GoogleBuilder().build(),
|
||||||
|
//new AuthUI.IdpConfig.FacebookBuilder().build(),
|
||||||
|
//new AuthUI.IdpConfig.TwitterBuilder().build(),
|
||||||
|
//new AuthUI.IdpConfig.MicrosoftBuilder().build(),
|
||||||
|
//new AuthUI.IdpConfig.YahooBuilder().build(),
|
||||||
|
//new AuthUI.IdpConfig.AppleBuilder().build(),
|
||||||
|
new AuthUI.IdpConfig.EmailBuilder().build()
|
||||||
|
//new AuthUI.IdpConfig.PhoneBuilder().build()
|
||||||
|
//new AuthUI.IdpConfig.AnonymousBuilder().build()))
|
||||||
|
))
|
||||||
|
// ... options ...
|
||||||
|
.build();
|
||||||
|
signInLauncher.launch(signInIntent);
|
||||||
|
} else {
|
||||||
|
// Use Username and password authentication for OSDAPI.
|
||||||
|
// FIXME - make this work with Google Authentication like we do for Firebase.
|
||||||
String uname = mUnameEt.getText().toString();
|
String uname = mUnameEt.getText().toString();
|
||||||
String passwd = mPasswdEt.getText().toString();
|
String passwd = mPasswdEt.getText().toString();
|
||||||
Log.v(TAG,"onOK() - uname="+uname+", passwd="+passwd);
|
Log.v(TAG,"onOK() - uname="+uname+", passwd="+passwd);
|
||||||
@@ -182,18 +265,31 @@ public class AuthenticateActivity extends AppCompatActivity {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
//finish();
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
View.OnClickListener onLogout =
|
View.OnClickListener onLogout = new View.OnClickListener() {
|
||||||
new View.OnClickListener() {
|
|
||||||
@Override
|
@Override
|
||||||
public void onClick(View view) {
|
public void onClick(View view) {
|
||||||
Log.v(TAG, "onLogout");
|
Log.v(TAG, "onLogout");
|
||||||
//m_status=false;
|
if (LogManager.USE_FIREBASE_BACKEND) {
|
||||||
|
AuthUI.getInstance()
|
||||||
|
.signOut(getApplicationContext())
|
||||||
|
.addOnCompleteListener(new OnCompleteListener<Void>() {
|
||||||
|
public void onComplete(@NonNull Task<Void> task) {
|
||||||
|
// user is now signed out
|
||||||
|
updateUi();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
if (mWac != null) {
|
||||||
mWac.logout();
|
mWac.logout();
|
||||||
saveAuthToken(null);
|
saveAuthToken(null);
|
||||||
|
} else {
|
||||||
|
Log.e(TAG,"logout() - mWac is null - not doing anything");
|
||||||
|
}
|
||||||
|
}
|
||||||
updateUi();
|
updateUi();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -244,5 +340,4 @@ public class AuthenticateActivity extends AppCompatActivity {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -35,7 +35,7 @@ public class EditEventActivity extends AppCompatActivity {
|
|||||||
private HashMap<String, ArrayList<String>> mEventSubTypesHashMap = null;
|
private HashMap<String, ArrayList<String>> mEventSubTypesHashMap = null;
|
||||||
private String mEventTypeStr = null;
|
private String mEventTypeStr = null;
|
||||||
private String mEventSubTypeStr = null;
|
private String mEventSubTypeStr = null;
|
||||||
private Long mEventId;
|
private String mEventId;
|
||||||
private String mEventNotes = "";
|
private String mEventNotes = "";
|
||||||
//private Date mEventDateTime;
|
//private Date mEventDateTime;
|
||||||
private RadioGroup mEventTypeRg;
|
private RadioGroup mEventTypeRg;
|
||||||
@@ -59,7 +59,7 @@ public class EditEventActivity extends AppCompatActivity {
|
|||||||
|
|
||||||
Bundle extras = getIntent().getExtras();
|
Bundle extras = getIntent().getExtras();
|
||||||
if (extras != null) {
|
if (extras != null) {
|
||||||
Long eventId = extras.getLong("eventId");
|
String eventId = extras.getString("eventId");
|
||||||
mEventId = eventId;
|
mEventId = eventId;
|
||||||
Log.v(TAG, "onCreate - mEventId=" + mEventId);
|
Log.v(TAG, "onCreate - mEventId=" + mEventId);
|
||||||
}
|
}
|
||||||
@@ -68,7 +68,7 @@ public class EditEventActivity extends AppCompatActivity {
|
|||||||
Button cancelBtn =
|
Button cancelBtn =
|
||||||
(Button) findViewById(R.id.cancelBtn);
|
(Button) findViewById(R.id.cancelBtn);
|
||||||
cancelBtn.setOnClickListener(onCancel);
|
cancelBtn.setOnClickListener(onCancel);
|
||||||
Button OKBtn = (Button) findViewById(R.id.OKBtn);
|
Button OKBtn = (Button) findViewById(R.id.loginBtn);
|
||||||
OKBtn.setOnClickListener(onOK);
|
OKBtn.setOnClickListener(onOK);
|
||||||
|
|
||||||
mEventTypeRg = findViewById(R.id.eventTypeRg);
|
mEventTypeRg = findViewById(R.id.eventTypeRg);
|
||||||
@@ -159,10 +159,10 @@ public class EditEventActivity extends AppCompatActivity {
|
|||||||
mWac.getEvent(mEventId, new WebApiConnection.JSONObjectCallback() {
|
mWac.getEvent(mEventId, new WebApiConnection.JSONObjectCallback() {
|
||||||
@Override
|
@Override
|
||||||
public void accept(JSONObject eventObj) {
|
public void accept(JSONObject eventObj) {
|
||||||
Log.v(TAG, "onCreate.getEvent");
|
Log.v(TAG, "initialiseServiceConnection.getEvent");
|
||||||
if (eventObj != null) {
|
if (eventObj != null) {
|
||||||
mEventObj = eventObj;
|
mEventObj = eventObj;
|
||||||
Log.v(TAG, "onCreate.getEvent: eventObj=" + eventObj.toString());
|
Log.v(TAG, "initialiseServiceConnection.getEvent: eventObj=" + eventObj.toString());
|
||||||
updateUi();
|
updateUi();
|
||||||
// FIXME: modify updateUi to use mEventObj
|
// FIXME: modify updateUi to use mEventObj
|
||||||
} else {
|
} else {
|
||||||
@@ -198,20 +198,27 @@ public class EditEventActivity extends AppCompatActivity {
|
|||||||
try {
|
try {
|
||||||
if (mEventObj != null) {
|
if (mEventObj != null) {
|
||||||
tv = (TextView) findViewById(R.id.eventIdTv);
|
tv = (TextView) findViewById(R.id.eventIdTv);
|
||||||
tv.setText(String.valueOf(mEventObj.getLong("id")));
|
tv.setText(mEventId);
|
||||||
tv = (TextView) findViewById(R.id.eventAlarmStateTv);
|
tv = (TextView) findViewById(R.id.eventAlarmStateTv);
|
||||||
tv.setText(mEventObj.getString("alarmStateStr"));
|
String alarmStateStr = mEventObj.getString("osdAlarmState");
|
||||||
|
try {
|
||||||
|
int alarmStateVal = Integer.parseInt(alarmStateStr);
|
||||||
|
alarmStateStr = mUtil.alarmStatusToString(alarmStateVal);
|
||||||
|
} catch (Exception e) {
|
||||||
|
Log.v(TAG,"updateUi: alarmState does not parse to int so displaying it as string: " +alarmStateStr);
|
||||||
|
}
|
||||||
|
tv.setText(alarmStateStr);
|
||||||
tv = (TextView) findViewById(R.id.eventNotsTv);
|
tv = (TextView) findViewById(R.id.eventNotsTv);
|
||||||
tv.setText(mEventObj.getString("desc"));
|
tv.setText(mEventObj.getString("desc"));
|
||||||
|
|
||||||
|
|
||||||
tv = (TextView) findViewById(R.id.eventDateTv);
|
tv = (TextView) findViewById(R.id.eventDateTv);
|
||||||
try {
|
try {
|
||||||
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");
|
String dateStr = mEventObj.getString("dataTime");
|
||||||
Date dataTime = dateFormat.parse(mEventObj.getString("dataTime"));
|
Date dataTime = mUtil.string2date(dateStr);
|
||||||
dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
|
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
|
||||||
tv.setText(dateFormat.format(dataTime));
|
tv.setText(dateFormat.format(dataTime));
|
||||||
} catch (ParseException e) {
|
} catch (Exception e) {
|
||||||
Log.e(TAG,"updateUI: Error Parsing dataDate "+e.getLocalizedMessage());
|
Log.e(TAG,"updateUI: Error Parsing dataDate "+e.getLocalizedMessage());
|
||||||
tv.setText("---");
|
tv.setText("---");
|
||||||
}
|
}
|
||||||
@@ -283,12 +290,12 @@ public class EditEventActivity extends AppCompatActivity {
|
|||||||
TextView tv = (TextView)findViewById(R.id.eventNotsTv);
|
TextView tv = (TextView)findViewById(R.id.eventNotsTv);
|
||||||
try {
|
try {
|
||||||
mEventObj.put("desc",tv.getText());
|
mEventObj.put("desc",tv.getText());
|
||||||
|
mEventObj.put("id",mEventId); // Add event Id to event object manually because firestore does not include it by default.
|
||||||
} catch (JSONException e) {
|
} catch (JSONException e) {
|
||||||
Log.e(TAG,"Error writing mEventObj: "+e.getMessage());
|
Log.e(TAG,"Error writing mEventObj: "+e.getMessage());
|
||||||
}
|
}
|
||||||
Log.v(TAG, "onOK() - eventObj="+mEventObj.toString());
|
Log.v(TAG, "onOK() - eventObj="+mEventObj.toString());
|
||||||
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
mWac.updateEvent(mEventObj, new WebApiConnection.JSONObjectCallback() {
|
mWac.updateEvent(mEventObj, new WebApiConnection.JSONObjectCallback() {
|
||||||
@Override
|
@Override
|
||||||
@@ -307,7 +314,7 @@ public class EditEventActivity extends AppCompatActivity {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
Log.e(TAG,"ERROR:"+e.getMessage());
|
Log.e(TAG,"onOK() - ERROR: "+e.getMessage()+" : " +e.toString());
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
mUtil.showToast("Error Updating Event");
|
mUtil.showToast("Error Updating Event");
|
||||||
updateUi();
|
updateUi();
|
||||||
|
|||||||
@@ -68,6 +68,7 @@ public class LogManager {
|
|||||||
static final private String TAG = "LogManager";
|
static final private String TAG = "LogManager";
|
||||||
//private String mDbName = "osdData";
|
//private String mDbName = "osdData";
|
||||||
final static private String mDpTableName = "datapoints";
|
final static private String mDpTableName = "datapoints";
|
||||||
|
final static private String mEventsTableName = "events";
|
||||||
private boolean mLogRemote;
|
private boolean mLogRemote;
|
||||||
private boolean mLogRemoteMobile;
|
private boolean mLogRemoteMobile;
|
||||||
private String mAuthToken;
|
private String mAuthToken;
|
||||||
@@ -76,13 +77,15 @@ public class LogManager {
|
|||||||
private static Context mContext;
|
private static Context mContext;
|
||||||
private OsdUtil mUtil;
|
private OsdUtil mUtil;
|
||||||
public static WebApiConnection mWac;
|
public static WebApiConnection mWac;
|
||||||
|
public static final boolean USE_FIREBASE_BACKEND = false;
|
||||||
|
|
||||||
private boolean mUploadInProgress;
|
private boolean mUploadInProgress;
|
||||||
private long mEventDuration = 120; // event duration in seconds - uploads datapoints that cover this time range centred on the event time.
|
private long mEventDuration = 120; // event duration in seconds - uploads datapoints that cover this time range centred on the event time.
|
||||||
public long mDataRetentionPeriod = 1; // Prunes the local db so it only retains data younger than this duration (in days)
|
public long mDataRetentionPeriod = 1; // Prunes the local db so it only retains data younger than this duration (in days)
|
||||||
private long mRemoteLogPeriod = 60; // Period in seconds between uploads to the remote server.
|
private long mRemoteLogPeriod = 60; // Period in seconds between uploads to the remote server.
|
||||||
private ArrayList<JSONObject> mDatapointsToUploadList;
|
private ArrayList<JSONObject> mDatapointsToUploadList;
|
||||||
private int mCurrentEventId;
|
private String mCurrentEventRemoteId;
|
||||||
|
private long mCurrentEventLocalId = -1;
|
||||||
private int mCurrentDatapointId;
|
private int mCurrentDatapointId;
|
||||||
private long mAutoPrunePeriod = 3600; // Prune the database every hour
|
private long mAutoPrunePeriod = 3600; // Prune the database every hour
|
||||||
private boolean mAutoPruneDb;
|
private boolean mAutoPruneDb;
|
||||||
@@ -121,7 +124,12 @@ public class LogManager {
|
|||||||
mUtil = new OsdUtil(mContext, handler);
|
mUtil = new OsdUtil(mContext, handler);
|
||||||
openDb();
|
openDb();
|
||||||
Log.i(TAG, "Starting Remote Database Interface");
|
Log.i(TAG, "Starting Remote Database Interface");
|
||||||
mWac = new WebApiConnection(mContext);
|
if (USE_FIREBASE_BACKEND) {
|
||||||
|
mWac = new WebApiConnection_firebase(mContext);
|
||||||
|
} else {
|
||||||
|
mWac = new WebApiConnection_osdapi(mContext);
|
||||||
|
}
|
||||||
|
|
||||||
mWac.setStoredToken(mAuthToken);
|
mWac.setStoredToken(mAuthToken);
|
||||||
|
|
||||||
if (mLogRemote) {
|
if (mLogRemote) {
|
||||||
@@ -162,7 +170,7 @@ public class LogManager {
|
|||||||
try {
|
try {
|
||||||
datapoint.put("id", c.getString(c.getColumnIndex("id")));
|
datapoint.put("id", c.getString(c.getColumnIndex("id")));
|
||||||
datapoint.put("dataTime", c.getString(c.getColumnIndex("dataTime")));
|
datapoint.put("dataTime", c.getString(c.getColumnIndex("dataTime")));
|
||||||
datapoint.put("status", c.getString(c.getColumnIndex("Status")));
|
datapoint.put("status", c.getString(c.getColumnIndex("status")));
|
||||||
datapoint.put("dataJSON", c.getString(c.getColumnIndex("dataJSON")));
|
datapoint.put("dataJSON", c.getString(c.getColumnIndex("dataJSON")));
|
||||||
datapoint.put("uploaded", c.getString(c.getColumnIndex("uploaded")));
|
datapoint.put("uploaded", c.getString(c.getColumnIndex("uploaded")));
|
||||||
//Log.v(TAG,"cursor2json() - datapoint="+datapoint.toString());
|
//Log.v(TAG,"cursor2json() - datapoint="+datapoint.toString());
|
||||||
@@ -177,6 +185,41 @@ public class LogManager {
|
|||||||
return dataPointArray.toString();
|
return dataPointArray.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a JSON String representing an array of events that are selected from sqlite cursor c.
|
||||||
|
*
|
||||||
|
* @param c sqlite cursor pointing to events query result.
|
||||||
|
* @return JSON String.
|
||||||
|
* from https://stackoverflow.com/a/20488153/2104584
|
||||||
|
*/
|
||||||
|
private String eventCursor2Json(Cursor c) {
|
||||||
|
StringBuilder cNames = new StringBuilder();
|
||||||
|
for (String n : c.getColumnNames()) {
|
||||||
|
cNames.append(", ").append(n);
|
||||||
|
}
|
||||||
|
c.moveToFirst();
|
||||||
|
Log.v(TAG, "eventCursor2Json: size of cursor=" + c.getCount());
|
||||||
|
JSONArray eventsArray = new JSONArray();
|
||||||
|
int i = 0;
|
||||||
|
while (!c.isAfterLast()) {
|
||||||
|
JSONObject event = new JSONObject();
|
||||||
|
try {
|
||||||
|
event.put("id", c.getString(c.getColumnIndex("id")));
|
||||||
|
event.put("dataTime", c.getString(c.getColumnIndex("dataTime")));
|
||||||
|
event.put("status", c.getString(c.getColumnIndex("status")));
|
||||||
|
event.put("uploaded", c.getString(c.getColumnIndex("uploaded")));
|
||||||
|
c.moveToNext();
|
||||||
|
eventsArray.put(i, event);
|
||||||
|
i++;
|
||||||
|
} catch (JSONException e) {
|
||||||
|
Log.e(TAG, "eventCursor2Json(): error creating JSON Object");
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Log.v(TAG, "eventCursor2JSON(): returning " + eventsArray.toString());
|
||||||
|
return eventsArray.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
private static boolean openDb() {
|
private static boolean openDb() {
|
||||||
Log.d(TAG, "openDb");
|
Log.d(TAG, "openDb");
|
||||||
@@ -187,11 +230,14 @@ public class LogManager {
|
|||||||
} else {
|
} else {
|
||||||
Log.i(TAG, "openDb: mOsdDb has been initialised already so not doing anything");
|
Log.i(TAG, "openDb: mOsdDb has been initialised already so not doing anything");
|
||||||
}
|
}
|
||||||
if (!checkTableExists(mOsdDb, mDpTableName)) {
|
String[] tableNames = new String[]{mDpTableName, mEventsTableName};
|
||||||
Log.e(TAG, "ERROR - Table " + mDpTableName + " does not exist");
|
for (String tableName : tableNames) {
|
||||||
|
if (!checkTableExists(mOsdDb, tableName)) {
|
||||||
|
Log.e(TAG, "ERROR - Table " + tableName + " does not exist");
|
||||||
return false;
|
return false;
|
||||||
} else {
|
} else {
|
||||||
Log.d(TAG, "table " + mDpTableName + " exists ok");
|
Log.d(TAG, "table " + tableName + " exists ok");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
Log.e(TAG, "Failed to open Database: " + e.toString());
|
Log.e(TAG, "Failed to open Database: " + e.toString());
|
||||||
@@ -221,17 +267,19 @@ public class LogManager {
|
|||||||
* FIXME - I am sure we should not be using raw SQL Srings to do this!
|
* FIXME - I am sure we should not be using raw SQL Srings to do this!
|
||||||
*/
|
*/
|
||||||
public void writeDatapointToLocalDb(SdData sdData) {
|
public void writeDatapointToLocalDb(SdData sdData) {
|
||||||
Log.v(TAG, "writeDatapointToLocalDb()");
|
//Log.v(TAG, "writeDatapointToLocalDb()");
|
||||||
Date curDate = new Date();
|
Date curDate = new Date();
|
||||||
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
|
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
|
||||||
|
|
||||||
String dateStr = dateFormat.format(curDate);
|
String dateStr = dateFormat.format(curDate);
|
||||||
String SQLStr = "SQLStr";
|
String SQLStr = "SQLStr";
|
||||||
|
|
||||||
|
if (mOsdDb == null) {
|
||||||
|
Log.e(TAG, "writeDatapointToLocalDb(): mOsdDb is null - doing nothing");
|
||||||
|
return;
|
||||||
|
}
|
||||||
try {
|
try {
|
||||||
//double roiRatio = -1;
|
// Write Datapoint to database
|
||||||
//if (sdData.specPower != 0)
|
|
||||||
// roiRatio = 10. * sdData.roiPower / sdData.specPower;
|
|
||||||
SQLStr = "INSERT INTO " + mDpTableName
|
SQLStr = "INSERT INTO " + mDpTableName
|
||||||
+ "(dataTime, status, dataJSON, uploaded)"
|
+ "(dataTime, status, dataJSON, uploaded)"
|
||||||
+ " VALUES("
|
+ " VALUES("
|
||||||
@@ -240,20 +288,55 @@ public class LogManager {
|
|||||||
+ DatabaseUtils.sqlEscapeString(sdData.toJSON(true)) + ","
|
+ DatabaseUtils.sqlEscapeString(sdData.toJSON(true)) + ","
|
||||||
+ 0
|
+ 0
|
||||||
+ ")";
|
+ ")";
|
||||||
if (mOsdDb != null) {
|
|
||||||
mOsdDb.execSQL(SQLStr);
|
mOsdDb.execSQL(SQLStr);
|
||||||
Log.v(TAG, "writeDatapointToLocalDb(): data written to database");
|
Log.v(TAG, "writeDatapointToLocalDb(): datapoint written to database");
|
||||||
} else {
|
|
||||||
Log.e(TAG,"writeDatapointToLocalDb(): mOsdDb is null");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
if (sdData.alarmState != 0) {
|
||||||
|
Log.i(TAG, "writeDatapointToLocalDb(): adding event to local DB");
|
||||||
|
createLocalEvent(dateStr, sdData.alarmState);
|
||||||
|
}
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
Log.e(TAG, "writeToLocalDb(): Error Writing Data: " + e.toString());
|
Log.e(TAG, "writeToLocalDb(): Error Writing Data: " + e.toString());
|
||||||
Log.e(TAG, "SQLStr was " + SQLStr);
|
Log.e(TAG, "SQLStr was " + SQLStr);
|
||||||
} catch (NullPointerException e) {
|
} catch (NullPointerException e) {
|
||||||
Log.e(TAG, "writeToLocalDb(): Null Pointer Exception: " + e.toString());
|
Log.e(TAG, "writeToLocalDb(): Null Pointer Exception: " + e.toString());
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean createLocalEvent(String dataTime, long status) {
|
||||||
|
// Expects dataTime to be in format: SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
|
||||||
|
Log.d(TAG,"createLocalEvent() - dataTime="+dataTime+", status="+status);
|
||||||
|
// Write Datapoint to database
|
||||||
|
String SQLStr = "INSERT INTO " + mEventsTableName
|
||||||
|
+ "(dataTime, status)"
|
||||||
|
+ " VALUES("
|
||||||
|
+ "'" + dataTime + "',"
|
||||||
|
+ status
|
||||||
|
+ ")";
|
||||||
|
mOsdDb.execSQL(SQLStr);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a json representation of locally stored event 'id'.
|
||||||
|
*
|
||||||
|
* @param id event id to return
|
||||||
|
* @return JSON representation of requested event (single element JSON array)
|
||||||
|
*/
|
||||||
|
public String getLocalEventById(long id) {
|
||||||
|
Log.d(TAG, "getLocalEventById() - id=" + id);
|
||||||
|
Cursor c;
|
||||||
|
String retVal;
|
||||||
|
try {
|
||||||
|
String selectStr = "select * from " + mEventsTableName + " where id=" + id + ";";
|
||||||
|
c = mOsdDb.rawQuery(selectStr, null);
|
||||||
|
retVal = eventCursor2Json(c);
|
||||||
|
} catch (Exception e) {
|
||||||
|
Log.d(TAG, "getLocalEventById(): Error Querying Database: " + e.getLocalizedMessage());
|
||||||
|
retVal = null;
|
||||||
|
}
|
||||||
|
Log.d(TAG, "getLocalEventById() - returning " + retVal);
|
||||||
|
return (retVal);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -269,9 +352,6 @@ public class LogManager {
|
|||||||
String retVal;
|
String retVal;
|
||||||
try {
|
try {
|
||||||
String selectStr = "select * from " + mDpTableName + " where id=" + id + ";";
|
String selectStr = "select * from " + mDpTableName + " where id=" + id + ";";
|
||||||
//String[] selectArgs = new String[]{String.format("%d", id)};
|
|
||||||
//c = mOSDDb.getWritableDatabase().query(mDbTableName, null,
|
|
||||||
// selectStr, selectArgs, null, null, null);
|
|
||||||
c = mOsdDb.rawQuery(selectStr, null);
|
c = mOsdDb.rawQuery(selectStr, null);
|
||||||
retVal = cursor2Json(c);
|
retVal = cursor2Json(c);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
@@ -279,7 +359,6 @@ public class LogManager {
|
|||||||
retVal = null;
|
retVal = null;
|
||||||
}
|
}
|
||||||
return (retVal);
|
return (retVal);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -289,15 +368,17 @@ public class LogManager {
|
|||||||
* @param eventId - the eventId associated with the uploaded datapoint - the 'uploaded' field is set to this value.
|
* @param eventId - the eventId associated with the uploaded datapoint - the 'uploaded' field is set to this value.
|
||||||
* @return True on success or False on failure.
|
* @return True on success or False on failure.
|
||||||
*/
|
*/
|
||||||
public boolean setDatapointToUploaded(int id, int eventId) {
|
public boolean setDatapointToUploaded(int id, String eventId) {
|
||||||
Log.d(TAG, "setDatapointToUploaded() - id=" + id);
|
Log.d(TAG, "setDatapointToUploaded() - id=" + id);
|
||||||
|
if (mOsdDb == null) {
|
||||||
|
Log.e(TAG,"setDatapointToUploaded() - mOsdDb is null - not doing anything");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
ContentValues cv = new ContentValues();
|
ContentValues cv = new ContentValues();
|
||||||
cv.put("uploaded", eventId);
|
cv.put("uploaded", eventId);
|
||||||
int nRowsUpdated = mOsdDb.update(mDpTableName, cv, "id = ?",
|
int nRowsUpdated = mOsdDb.update(mDpTableName, cv, "id = ?",
|
||||||
new String[]{String.format("%d", id)});
|
new String[]{String.format("%d", id)});
|
||||||
|
|
||||||
return (nRowsUpdated == 1);
|
return (nRowsUpdated == 1);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -356,7 +437,7 @@ public class LogManager {
|
|||||||
String whereClause = getEventWhereClause(includeWarnings);
|
String whereClause = getEventWhereClause(includeWarnings);
|
||||||
//sqlStr = "SELECT * from " + mDbTableName + " where Status in (" + statusListStr + ") order by dataTime desc;";
|
//sqlStr = "SELECT * from " + mDbTableName + " where Status in (" + statusListStr + ") order by dataTime desc;";
|
||||||
String[] columns = {"*"};
|
String[] columns = {"*"};
|
||||||
new SelectQueryTask(mDpTableName, columns, whereClause, whereArgs,
|
new SelectQueryTask(mEventsTableName, columns, whereClause, whereArgs,
|
||||||
null, null, "dataTime DESC", (Cursor cursor) -> {
|
null, null, "dataTime DESC", (Cursor cursor) -> {
|
||||||
Log.v(TAG, "getEventsList - returned " + cursor);
|
Log.v(TAG, "getEventsList - returned " + cursor);
|
||||||
if (cursor != null) {
|
if (cursor != null) {
|
||||||
@@ -365,7 +446,7 @@ public class LogManager {
|
|||||||
HashMap<String, String> event = new HashMap<>();
|
HashMap<String, String> event = new HashMap<>();
|
||||||
//event.put("id", cursor.getString(cursor.getColumnIndex("id")));
|
//event.put("id", cursor.getString(cursor.getColumnIndex("id")));
|
||||||
event.put("dataTime", cursor.getString(cursor.getColumnIndex("dataTime")));
|
event.put("dataTime", cursor.getString(cursor.getColumnIndex("dataTime")));
|
||||||
int status = cursor.getInt(cursor.getColumnIndex("Status"));
|
int status = cursor.getInt(cursor.getColumnIndex("status"));
|
||||||
String statusStr = mUtil.alarmStatusToString(status);
|
String statusStr = mUtil.alarmStatusToString(status);
|
||||||
event.put("status", statusStr);
|
event.put("status", statusStr);
|
||||||
event.put("uploaded", cursor.getString(cursor.getColumnIndex("uploaded")));
|
event.put("uploaded", cursor.getString(cursor.getColumnIndex("uploaded")));
|
||||||
@@ -385,25 +466,48 @@ public class LogManager {
|
|||||||
*/
|
*/
|
||||||
public int pruneLocalDb() {
|
public int pruneLocalDb() {
|
||||||
Log.d(TAG, "pruneLocalDb()");
|
Log.d(TAG, "pruneLocalDb()");
|
||||||
int retVal;
|
int retVal = 0;
|
||||||
long currentDateMillis = new Date().getTime();
|
long currentDateMillis = new Date().getTime();
|
||||||
long endDateMillis = currentDateMillis - 24 * 3600 * 1000 * mDataRetentionPeriod;
|
long endDateMillis = currentDateMillis - 24 * 3600 * 1000 * mDataRetentionPeriod;
|
||||||
//long endDateMillis = currentDateMillis - 3600*1000* mDataRetentionPeriod; // Using hours rather than days for testing
|
//long endDateMillis = currentDateMillis - 3600*1000* mDataRetentionPeriod; // Using hours rather than days for testing
|
||||||
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
|
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
|
||||||
|
|
||||||
String endDateStr = dateFormat.format(new Date(endDateMillis));
|
String endDateStr = dateFormat.format(new Date(endDateMillis));
|
||||||
|
String[] tableNames = new String[]{mDpTableName, mEventsTableName};
|
||||||
|
for (String tableName : tableNames) {
|
||||||
|
Log.i(TAG, "pruneLocalDb - pruning table " + tableName);
|
||||||
try {
|
try {
|
||||||
String selectStr = "DataTime<=?";
|
String selectStr = "DataTime<=?";
|
||||||
String[] selectArgs = {endDateStr};
|
String[] selectArgs = {endDateStr};
|
||||||
retVal = mOsdDb.delete(mDpTableName, selectStr, selectArgs);
|
retVal = mOsdDb.delete(tableName, selectStr, selectArgs);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
Log.d(TAG, "Error deleting datapoints" + e.toString());
|
Log.d(TAG, "Error deleting data " + e.toString());
|
||||||
retVal = 0;
|
retVal = 0;
|
||||||
}
|
}
|
||||||
Log.d(TAG, String.format("pruneLocalDb() - deleted %d records", retVal));
|
Log.d(TAG, String.format("pruneLocalDb() - deleted %d records from table %s", retVal, tableName));
|
||||||
|
}
|
||||||
return (retVal);
|
return (retVal);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* setEventToUploaded
|
||||||
|
*
|
||||||
|
* @param localEventId - local Event ID to change
|
||||||
|
* @param remoteEventId - the remote eventId associated with the uploaded datapoint - the 'uploaded' field is set to this value.
|
||||||
|
* @return True on success or False on failure.
|
||||||
|
*/
|
||||||
|
public boolean setEventToUploaded(long localEventId, String remoteEventId) {
|
||||||
|
Log.d(TAG, "setEventToUploaded() - local id=" + localEventId + " remote id="+remoteEventId);
|
||||||
|
if (mOsdDb == null) {
|
||||||
|
Log.e(TAG,"setEventToUploaded() - mOsdDb is null - not doing anything");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
ContentValues cv = new ContentValues();
|
||||||
|
cv.put("uploaded", remoteEventId);
|
||||||
|
int nRowsUpdated = mOsdDb.update(mEventsTableName, cv, "id = ?",
|
||||||
|
new String[]{String.format("%d", localEventId)});
|
||||||
|
return (nRowsUpdated == 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the ID of the next event (alarm, warning, fall etc that needs to be uploaded (alarm or warning condition and has not yet been uploaded.
|
* Return the ID of the next event (alarm, warning, fall etc that needs to be uploaded (alarm or warning condition and has not yet been uploaded.
|
||||||
@@ -423,7 +527,7 @@ public class LogManager {
|
|||||||
long endDateMillis = currentDateMillis - 1000 * mEventDuration;
|
long endDateMillis = currentDateMillis - 1000 * mEventDuration;
|
||||||
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
|
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
|
||||||
String endDateStr = dateFormat.format(new Date(endDateMillis));
|
String endDateStr = dateFormat.format(new Date(endDateMillis));
|
||||||
String whereClauseUploaded = "uploaded = 0";
|
String whereClauseUploaded = "uploaded is null";
|
||||||
String whereClauseDate = "DataTime<?";
|
String whereClauseDate = "DataTime<?";
|
||||||
String whereClause = whereClauseStatus + " AND " + whereClauseUploaded + " AND " + whereClauseDate;
|
String whereClause = whereClauseStatus + " AND " + whereClauseUploaded + " AND " + whereClauseDate;
|
||||||
|
|
||||||
@@ -432,9 +536,8 @@ public class LogManager {
|
|||||||
whereArgs[i] = whereArgsStatus[i];
|
whereArgs[i] = whereArgsStatus[i];
|
||||||
}
|
}
|
||||||
whereArgs[whereArgsStatus.length] = endDateStr;
|
whereArgs[whereArgsStatus.length] = endDateStr;
|
||||||
new SelectQueryTask(mDpTableName, columns, whereClause, whereArgs,
|
new SelectQueryTask(mEventsTableName, columns, whereClause, whereArgs,
|
||||||
null, null, "dataTime DESC", (Cursor cursor) -> {
|
null, null, "dataTime DESC", (Cursor cursor) -> {
|
||||||
Log.v(TAG, "getEventsList - returned " + cursor);
|
|
||||||
Long recordId = new Long(-1);
|
Long recordId = new Long(-1);
|
||||||
if (cursor != null) {
|
if (cursor != null) {
|
||||||
Log.v(TAG, "getNextEventToUpload - returned " + cursor.getCount() + " records");
|
Log.v(TAG, "getNextEventToUpload - returned " + cursor.getCount() + " records");
|
||||||
@@ -443,9 +546,8 @@ public class LogManager {
|
|||||||
Log.v(TAG, "getNextEventToUpload() - no events to Upload - exiting");
|
Log.v(TAG, "getNextEventToUpload() - no events to Upload - exiting");
|
||||||
recordId = new Long(-1);
|
recordId = new Long(-1);
|
||||||
} else {
|
} else {
|
||||||
String recordStr = cursor.getString(3);
|
|
||||||
recordId = cursor.getLong(0);
|
recordId = cursor.getLong(0);
|
||||||
Log.d(TAG, "getNextEventToUpload(): id=" + recordId + ", recordStr=" + recordStr);
|
Log.d(TAG, "getNextEventToUpload(): id=" + recordId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
callback.accept(recordId);
|
callback.accept(recordId);
|
||||||
@@ -494,13 +596,13 @@ public class LogManager {
|
|||||||
* @return True on successful start or false if call fails.
|
* @return True on successful start or false if call fails.
|
||||||
*/
|
*/
|
||||||
public boolean getLocalEventsCount(boolean includeWarnings, WebApiConnection.LongCallback callback) {
|
public boolean getLocalEventsCount(boolean includeWarnings, WebApiConnection.LongCallback callback) {
|
||||||
Log.v(TAG, "getLocalEventsCount- includeWarnings=" + includeWarnings);
|
//Log.v(TAG, "getLocalEventsCount- includeWarnings=" + includeWarnings);
|
||||||
String[] whereArgs = getEventWhereArgs(includeWarnings);
|
String[] whereArgs = getEventWhereArgs(includeWarnings);
|
||||||
String whereClause = getEventWhereClause(includeWarnings);
|
String whereClause = getEventWhereClause(includeWarnings);
|
||||||
String[] columns = {"*"};
|
String[] columns = {"*"};
|
||||||
new SelectQueryTask(mDpTableName, columns, whereClause, whereArgs,
|
new SelectQueryTask(mEventsTableName, columns, whereClause, whereArgs,
|
||||||
null, null, null, (Cursor cursor) -> {
|
null, null, null, (Cursor cursor) -> {
|
||||||
Log.v(TAG, "getLocalEventsCount - returned " + cursor);
|
//Log.v(TAG, "getLocalEventsCount - returned " + cursor);
|
||||||
Long eventCount = Long.valueOf(0);
|
Long eventCount = Long.valueOf(0);
|
||||||
if (cursor != null) {
|
if (cursor != null) {
|
||||||
eventCount = Long.valueOf(cursor.getCount());
|
eventCount = Long.valueOf(cursor.getCount());
|
||||||
@@ -517,13 +619,13 @@ public class LogManager {
|
|||||||
* @return True on successful start or false if call fails.
|
* @return True on successful start or false if call fails.
|
||||||
*/
|
*/
|
||||||
public boolean getLocalDatapointsCount(WebApiConnection.LongCallback callback) {
|
public boolean getLocalDatapointsCount(WebApiConnection.LongCallback callback) {
|
||||||
Log.v(TAG, "getLocalDatapointsCount");
|
//Log.v(TAG, "getLocalDatapointsCount");
|
||||||
String[] whereArgs = null;
|
String[] whereArgs = null;
|
||||||
String whereClause = null;
|
String whereClause = null;
|
||||||
String[] columns = {"*"};
|
String[] columns = {"*"};
|
||||||
new SelectQueryTask(mDpTableName, columns, whereClause, whereArgs,
|
new SelectQueryTask(mDpTableName, columns, whereClause, whereArgs,
|
||||||
null, null, null, (Cursor cursor) -> {
|
null, null, null, (Cursor cursor) -> {
|
||||||
Log.v(TAG, "getLocalDatapointsCount - returned " + cursor);
|
//Log.v(TAG, "getLocalDatapointsCount - returned " + cursor);
|
||||||
Long eventCount = Long.valueOf(0);
|
Long eventCount = Long.valueOf(0);
|
||||||
if (cursor != null) {
|
if (cursor != null) {
|
||||||
eventCount = Long.valueOf(cursor.getCount());
|
eventCount = Long.valueOf(cursor.getCount());
|
||||||
@@ -568,7 +670,7 @@ public class LogManager {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Cursor doInBackground(Void... params) {
|
protected Cursor doInBackground(Void... params) {
|
||||||
Log.v(TAG, "runSelect.doInBackground()");
|
//Log.v(TAG, "runSelect.doInBackground()");
|
||||||
Log.v(TAG, "SelectQueryTask.doInBackground: mTable=" + mTable + ", mColumns=" + Arrays.toString(mColumns)
|
Log.v(TAG, "SelectQueryTask.doInBackground: mTable=" + mTable + ", mColumns=" + Arrays.toString(mColumns)
|
||||||
+ ", mSelection=" + mSelection + ", mSelectionArgs=" + Arrays.toString(mSelectionArgs) + ", mGroupBy=" + mGroupBy
|
+ ", mSelection=" + mSelection + ", mSelectionArgs=" + Arrays.toString(mSelectionArgs) + ", mGroupBy=" + mGroupBy
|
||||||
+ ", mHaving =" + mHaving + ", mOrderBy=" + mOrderBy);
|
+ ", mHaving =" + mHaving + ", mOrderBy=" + mOrderBy);
|
||||||
@@ -659,17 +761,24 @@ public class LogManager {
|
|||||||
*/
|
*/
|
||||||
public void uploadSdData() {
|
public void uploadSdData() {
|
||||||
//int eventId = -1;
|
//int eventId = -1;
|
||||||
Log.v(TAG, "uploadSdData()");
|
//Log.v(TAG, "uploadSdData()");
|
||||||
// First try uploading full alarms, and only if we do not have any of those, upload warnings.
|
// First try uploading full alarms, and only if we do not have any of those, upload warnings.
|
||||||
boolean warningsArr[] = { false, true };
|
//boolean warningsArr[] = {false, true};
|
||||||
for (int n=0; n<warningsArr.length; n++) {
|
// Upload everything - alarms and warnings - we can sort it out in post-processing the data!
|
||||||
|
boolean warningsArr[] = {true};
|
||||||
|
for (int n = 0; n < warningsArr.length; n++) {
|
||||||
boolean warningsVal = warningsArr[n];
|
boolean warningsVal = warningsArr[n];
|
||||||
Log.i(TAG, "uploadSdData(): warningsVal=" + warningsVal);
|
Log.i(TAG, "uploadSdData(): warningsVal=" + warningsVal);
|
||||||
|
if (mUploadInProgress) {
|
||||||
|
Log.d(TAG, "uploadSdData - upload already in progress - not doing anything");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
mUploadInProgress = true;
|
||||||
getNextEventToUpload(warningsVal, (Long eventId) -> {
|
getNextEventToUpload(warningsVal, (Long eventId) -> {
|
||||||
if (eventId != -1) {
|
if (eventId != -1) {
|
||||||
Log.v(TAG, "uploadSdData() - eventId=" + eventId);
|
Log.i(TAG, "uploadSdData() - next Event to Upload eventId=" + eventId);
|
||||||
String eventJsonStr = getDatapointById(eventId);
|
String eventJsonStr = getLocalEventById(eventId);
|
||||||
Log.v(TAG, "uploadSdData() - eventJsonStr=" + eventJsonStr);
|
Log.v(TAG, "uploadSdData() - event to upload eventJsonStr=" + eventJsonStr);
|
||||||
//int eventType;
|
//int eventType;
|
||||||
JSONObject eventObj;
|
JSONObject eventObj;
|
||||||
int eventAlarmStatus;
|
int eventAlarmStatus;
|
||||||
@@ -680,36 +789,42 @@ public class LogManager {
|
|||||||
eventObj = datapointJsonArr.getJSONObject(0); // We only look at the first (and hopefully only) item in the array.
|
eventObj = datapointJsonArr.getJSONObject(0); // We only look at the first (and hopefully only) item in the array.
|
||||||
eventAlarmStatus = Integer.parseInt(eventObj.getString("status"));
|
eventAlarmStatus = Integer.parseInt(eventObj.getString("status"));
|
||||||
eventDateStr = eventObj.getString("dataTime");
|
eventDateStr = eventObj.getString("dataTime");
|
||||||
Log.v(TAG, "uploadSdData - data from local DB is:" + eventJsonStr + ", eventAlarmStatus="
|
Log.d(TAG, "uploadSdData - data from local DB is:" + eventJsonStr + ", eventAlarmStatus="
|
||||||
+ eventAlarmStatus + ", eventDateStr=" + eventDateStr);
|
+ eventAlarmStatus + ", eventDateStr=" + eventDateStr);
|
||||||
} catch (JSONException e) {
|
} catch (JSONException e) {
|
||||||
Log.e(TAG, "ERROR parsing event JSON Data" + eventJsonStr);
|
Log.e(TAG, "uploadSdData(): ERROR parsing event JSON Data" + eventJsonStr);
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
return;
|
return;
|
||||||
} catch (NullPointerException e) {
|
} catch (NullPointerException e) {
|
||||||
Log.e(TAG, "ERROR null pointer exception parsing event JSON Data" + eventJsonStr);
|
Log.e(TAG, "uploadSdData(): ERROR null pointer exception parsing event JSON Data" + eventJsonStr);
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
eventDate = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(eventDateStr);
|
eventDate = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(eventDateStr);
|
||||||
} catch (ParseException e) {
|
} catch (ParseException e) {
|
||||||
Log.e(TAG, "Error parsing date " + eventDateStr);
|
Log.e(TAG, "UploadSdData(): Error parsing date " + eventDateStr);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Log.i(TAG, "uploadSdData - calling mWac.createEvent");
|
||||||
|
mCurrentEventLocalId = eventId;
|
||||||
mWac.createEvent(eventAlarmStatus, eventDate, "", this::createEventCallback);
|
mWac.createEvent(eventAlarmStatus, eventDate, "", this::createEventCallback);
|
||||||
} else {
|
} else {
|
||||||
Log.v(TAG, "UploadSdData - no data to upload");
|
Log.v(TAG, "uploadSdData - no data to upload "); //(warnings="+warningsVal+")");
|
||||||
|
mUploadInProgress = false;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Mark the relevant member variables to show we are not currently doing an upload, so a new one can be
|
// Mark the relevant member variables to show we are not cuurrently doing an upload, so a new one can be
|
||||||
// started if necessary.
|
// started if necessary.
|
||||||
public void finishUpload() {
|
public void finishUpload() {
|
||||||
mCurrentEventId = -1;
|
mCurrentEventRemoteId = null;
|
||||||
|
mCurrentEventLocalId = -1;
|
||||||
|
mCurrentDatapointId = -1;
|
||||||
mDatapointsToUploadList = null;
|
mDatapointsToUploadList = null;
|
||||||
mUploadInProgress = false;
|
mUploadInProgress = false;
|
||||||
}
|
}
|
||||||
@@ -717,82 +832,97 @@ public class LogManager {
|
|||||||
// Called by WebApiConnection when a new event record is created.
|
// Called by WebApiConnection when a new event record is created.
|
||||||
// Once the event is created it queries the local database to find the datapoints associated with the event
|
// Once the event is created it queries the local database to find the datapoints associated with the event
|
||||||
// and uploads those as a batch of data points.
|
// and uploads those as a batch of data points.
|
||||||
public void createEventCallback(String eventStr) {
|
public void createEventCallback(String eventId) {
|
||||||
Log.v(TAG, "eventCallback(): " + eventStr);
|
Log.v(TAG, "createEventCallback(): " + eventId);
|
||||||
|
Log.v(TAG, "createEventCallback(): Retrieving remote event details");
|
||||||
|
mWac.getEvent(eventId, new WebApiConnection.JSONObjectCallback() {
|
||||||
|
@Override
|
||||||
|
public void accept(JSONObject eventObj) {
|
||||||
|
if (eventObj == null) {
|
||||||
|
Log.e(TAG,"createEventCallback() - eventObj is null - failed to create event");
|
||||||
|
mUtil.showToast("Error Creating Remote Event");
|
||||||
|
} else {
|
||||||
|
Log.v(TAG, "createEventCallback() - eventObj=" + eventObj.toString());
|
||||||
Date eventDate;
|
Date eventDate;
|
||||||
String eventDateStr;
|
String eventDateStr = "";
|
||||||
int eventId;
|
|
||||||
try {
|
try {
|
||||||
JSONObject eventObj = new JSONObject(eventStr);
|
String dateStr= eventObj.getString("dataTime");
|
||||||
eventDateStr = eventObj.getString("dataTime");
|
eventDate = mUtil.string2date(dateStr);
|
||||||
eventId = eventObj.getInt("id");
|
|
||||||
} catch (JSONException e) {
|
} catch (JSONException e) {
|
||||||
Log.e(TAG, "eventCallback() - Error parsing eventStr: " + eventStr);
|
Log.e(TAG, "createEventCallback() - Error parsing JSONObject: " + eventObj.toString());
|
||||||
finishUpload();
|
finishUpload();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
|
if (eventDate != null) {
|
||||||
try {
|
Log.v(TAG, "createEventCallback() EventId=" + eventId + ", eventDateStr=" + eventDateStr + ", eventDate=" + eventDate);
|
||||||
eventDate = dateFormat.parse(eventDateStr);
|
mUploadInProgress = true;
|
||||||
} catch (ParseException e) {
|
|
||||||
Log.e(TAG, "eventCallback() - error parsing date string " + eventDateStr);
|
|
||||||
finishUpload();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
Log.v(TAG, "eventCallback() EventId=" + eventId + ", eventDateStr=" + eventDateStr + ", eventDate=" + eventDate);
|
|
||||||
long eventDateMillis = eventDate.getTime();
|
long eventDateMillis = eventDate.getTime();
|
||||||
long startDateMillis = eventDateMillis - 1000 * mEventDuration / 2;
|
long startDateMillis = eventDateMillis - 1000 * mEventDuration / 2;
|
||||||
long endDateMillis = eventDateMillis + 1000 * mEventDuration / 2;
|
long endDateMillis = eventDateMillis + 1000 * mEventDuration / 2;
|
||||||
dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
|
DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
|
||||||
|
|
||||||
getDatapointsByDate(
|
getDatapointsByDate(
|
||||||
dateFormat.format(new Date(startDateMillis)),
|
dateFormat.format(new Date(startDateMillis)),
|
||||||
dateFormat.format(new Date(endDateMillis)), (String datapointsJsonStr) -> {
|
dateFormat.format(new Date(endDateMillis)),
|
||||||
Log.v(TAG, "eventCallback() - datapointsJsonStr=" + datapointsJsonStr);
|
(String datapointsJsonStr) -> {
|
||||||
|
//Log.v(TAG, "createEventCallback() - datapointsJsonStr=" + datapointsJsonStr);
|
||||||
JSONArray dataObj;
|
JSONArray dataObj;
|
||||||
mDatapointsToUploadList = new ArrayList<JSONObject>();
|
mDatapointsToUploadList = new ArrayList<JSONObject>();
|
||||||
try {
|
try {
|
||||||
//DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
|
//DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
|
||||||
dataObj = new JSONArray(datapointsJsonStr);
|
dataObj = new JSONArray(datapointsJsonStr);
|
||||||
|
Log.v(TAG, "createEventCallback() - datapointsObj length=" + dataObj.length());
|
||||||
for (int i = 0; i < dataObj.length(); i++) {
|
for (int i = 0; i < dataObj.length(); i++) {
|
||||||
mDatapointsToUploadList.add(dataObj.getJSONObject(i));
|
mDatapointsToUploadList.add(dataObj.getJSONObject(i));
|
||||||
}
|
}
|
||||||
} catch (JSONException e) {
|
} catch (JSONException e) {
|
||||||
Log.v(TAG, "Error Creating JSON Object from string " + datapointsJsonStr);
|
Log.v(TAG, "createEventCallback(): Error Creating JSON Object from string " + datapointsJsonStr);
|
||||||
dataObj = null;
|
dataObj = null;
|
||||||
finishUpload();
|
finishUpload();
|
||||||
}
|
}
|
||||||
// This starts the process of uploading the datapoints, one at a time.
|
// This starts the process of uploading the datapoints, one at a time.
|
||||||
mCurrentEventId = eventId;
|
mCurrentEventRemoteId = eventId;
|
||||||
mUploadInProgress = true;
|
Log.v(TAG, "createEventCallback() - starting datapoints upload with eventId " + mCurrentEventRemoteId +
|
||||||
Log.v(TAG, "eventCallback() - starting datapoints upload with eventId " + mCurrentEventId);
|
" Uploading " + mDatapointsToUploadList.size() + " datapoints");
|
||||||
uploadNextDatapoint();
|
uploadNextDatapoint();
|
||||||
|
|
||||||
});
|
});
|
||||||
|
} else {
|
||||||
|
Log.e(TAG,"createEventCallback() - Error - event date is null - not doing anything");
|
||||||
|
mUtil.showToast("Error uploading event - date is null");
|
||||||
|
finishUpload();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// takes the next datapoint of the list mDatapointsToUploadList and uploads it to the remote server.
|
// takes the next datapoint of the list mDatapointsToUploadList and uploads it to the remote server.
|
||||||
// datapointCallback is called when the upload is complete.
|
// datapointCallback is called when the upload is complete.
|
||||||
public void uploadNextDatapoint() {
|
public void uploadNextDatapoint() {
|
||||||
Log.v(TAG, "uploadDatapoint()");
|
//Log.v(TAG, "uploadNextDatapoint()");
|
||||||
|
if (mDatapointsToUploadList != null) {
|
||||||
if (mDatapointsToUploadList.size() > 0) {
|
if (mDatapointsToUploadList.size() > 0) {
|
||||||
mUploadInProgress = true;
|
mUploadInProgress = true;
|
||||||
try {
|
try {
|
||||||
mCurrentDatapointId = mDatapointsToUploadList.get(0).getInt("id");
|
mCurrentDatapointId = mDatapointsToUploadList.get(0).getInt("id");
|
||||||
} catch (JSONException e) {
|
} catch (JSONException e) {
|
||||||
Log.e(TAG, "Error reading currentDatapointID from mDatapointsToUploadList[0]" + e.getMessage());
|
Log.e(TAG, "uploadNextDatapoint(): Error reading currentDatapointID from mDatapointsToUploadList[0]" + e.getMessage());
|
||||||
Log.e(TAG, "Removing mDatapointsToUploadList[0] and trying the next datapoint");
|
Log.e(TAG, "uploadNextDatapoint(): Removing mDatapointsToUploadList[0] and trying the next datapoint");
|
||||||
mDatapointsToUploadList.remove(0);
|
mDatapointsToUploadList.remove(0);
|
||||||
uploadNextDatapoint();
|
uploadNextDatapoint();
|
||||||
}
|
}
|
||||||
|
|
||||||
Log.v(TAG, "uploadDatapoint() - uploading datapoint with local id of " + mCurrentDatapointId);
|
Log.v(TAG, "uploadNextDatapoint() - " + mDatapointsToUploadList.size() + " datapoints to upload. Uploading datapoint ID:" + mCurrentDatapointId);
|
||||||
mWac.createDatapoint(mDatapointsToUploadList.get(0), mCurrentEventId, this::datapointCallback);
|
mWac.createDatapoint(mDatapointsToUploadList.get(0), mCurrentEventRemoteId, this::datapointCallback);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
mCurrentEventId = -1;
|
Log.i(TAG, "uploadNextDatapoint() - All datapoints uploaded!");
|
||||||
mCurrentDatapointId = -1;
|
setEventToUploaded(mCurrentEventLocalId, mCurrentEventRemoteId);
|
||||||
mUploadInProgress = false;
|
finishUpload();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Log.w(TAG,"uploadNextDatapoint - mDatapointsToUploadList is null - I don't thin this should have happened!");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -800,11 +930,15 @@ public class LogManager {
|
|||||||
// a datapoint based on mDatapointsToUploadList(0) so removes that from the list and calls UploadDatapoint()
|
// a datapoint based on mDatapointsToUploadList(0) so removes that from the list and calls UploadDatapoint()
|
||||||
// to upload the next one.
|
// to upload the next one.
|
||||||
public void datapointCallback(String datapointStr) {
|
public void datapointCallback(String datapointStr) {
|
||||||
Log.v(TAG, "datapointCallback() " + datapointStr + ", mCurrentEventId=" + mCurrentEventId);
|
Log.v(TAG, "datapointCallback() dataPointId="+mCurrentDatapointId+" remote datapointID=" + datapointStr + ", mCurrentEventId=" + mCurrentEventRemoteId);
|
||||||
|
if (mDatapointsToUploadList != null) {
|
||||||
if (mDatapointsToUploadList.size() > 0) {
|
if (mDatapointsToUploadList.size() > 0) {
|
||||||
mDatapointsToUploadList.remove(0);
|
mDatapointsToUploadList.remove(0);
|
||||||
}
|
}
|
||||||
setDatapointToUploaded(mCurrentDatapointId, mCurrentEventId);
|
} else {
|
||||||
|
Log.w(TAG,"datapointCallback - mDatapointsToUploadList is null - I don't thin this should have happened!");
|
||||||
|
}
|
||||||
|
setDatapointToUploaded(mCurrentDatapointId, mCurrentEventRemoteId);
|
||||||
uploadNextDatapoint();
|
uploadNextDatapoint();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -903,9 +1037,19 @@ public class LogManager {
|
|||||||
String SQLStr = "CREATE TABLE IF NOT EXISTS " + mDpTableName + "("
|
String SQLStr = "CREATE TABLE IF NOT EXISTS " + mDpTableName + "("
|
||||||
+ "id INTEGER PRIMARY KEY,"
|
+ "id INTEGER PRIMARY KEY,"
|
||||||
+ "dataTime DATETIME,"
|
+ "dataTime DATETIME,"
|
||||||
+ "Status INT,"
|
+ "status INT,"
|
||||||
+ "dataJSON TEXT,"
|
+ "dataJSON TEXT,"
|
||||||
+ "uploaded INT"
|
+ "uploaded TEXT" // Stores the ID of the datapoint in the remote database if uploaded, otherwise empty
|
||||||
|
+ ");";
|
||||||
|
db.execSQL(SQLStr);
|
||||||
|
Log.i(TAG, "onCreate - TableName=" + mEventsTableName);
|
||||||
|
SQLStr = "CREATE TABLE IF NOT EXISTS " + mEventsTableName + "("
|
||||||
|
+ "id INTEGER PRIMARY KEY,"
|
||||||
|
+ "dataTime DATETIME,"
|
||||||
|
+ "status INT,"
|
||||||
|
+ "type TEXT,"
|
||||||
|
+ "subType TEXT,"
|
||||||
|
+ "uploaded TEXT" // stores the id of the event in the remote dabase if uploaded, otherwise empty
|
||||||
+ ");";
|
+ ");";
|
||||||
db.execSQL(SQLStr);
|
db.execSQL(SQLStr);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,9 +11,11 @@ import android.os.Bundle;
|
|||||||
import android.os.CountDownTimer;
|
import android.os.CountDownTimer;
|
||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
import android.os.IBinder;
|
import android.os.IBinder;
|
||||||
|
|
||||||
import androidx.core.view.MenuCompat;
|
import androidx.core.view.MenuCompat;
|
||||||
import androidx.appcompat.app.AlertDialog;
|
import androidx.appcompat.app.AlertDialog;
|
||||||
import androidx.appcompat.app.AppCompatActivity;
|
import androidx.appcompat.app.AppCompatActivity;
|
||||||
|
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.view.Menu;
|
import android.view.Menu;
|
||||||
import android.view.MenuItem;
|
import android.view.MenuItem;
|
||||||
@@ -219,14 +221,34 @@ public class LogManagerControlActivity extends AppCompatActivity {
|
|||||||
// A bit of a hack to display in reverse chronological order
|
// A bit of a hack to display in reverse chronological order
|
||||||
for (int i = eventsArray.length() - 1; i >= 0; i--) {
|
for (int i = eventsArray.length() - 1; i >= 0; i--) {
|
||||||
JSONObject eventObj = eventsArray.getJSONObject(i);
|
JSONObject eventObj = eventsArray.getJSONObject(i);
|
||||||
Long id = eventObj.getLong("id");
|
Log.v(TAG, "getRemoteEvents() - " + eventObj.toString());
|
||||||
int osdAlarmState = eventObj.getInt("osdAlarmState");
|
String id = null;
|
||||||
String dataTime = eventObj.getString("dataTime");
|
if (!eventObj.isNull("id")) {
|
||||||
String typeStr = eventObj.getString("type");
|
id = eventObj.getString("id");
|
||||||
String subType = eventObj.getString("subType");
|
}
|
||||||
String desc = eventObj.getString("desc");
|
int osdAlarmState = -1;
|
||||||
|
if (!eventObj.isNull("osdAlarmState")) {
|
||||||
|
osdAlarmState = eventObj.getInt("osdAlarmState");
|
||||||
|
}
|
||||||
|
String dataTime = "null";
|
||||||
|
if (!eventObj.isNull("dataTime")) {
|
||||||
|
dataTime = eventObj.getString("dataTime");
|
||||||
|
Log.v(TAG, "getRemoteEvents() - dataTime=" + dataTime);
|
||||||
|
}
|
||||||
|
String typeStr = "null";
|
||||||
|
if (!eventObj.isNull("type")) {
|
||||||
|
typeStr = eventObj.getString("type");
|
||||||
|
}
|
||||||
|
String subType = "null";
|
||||||
|
if (!eventObj.isNull("subType")) {
|
||||||
|
subType = eventObj.getString("subType");
|
||||||
|
}
|
||||||
|
String desc = "null";
|
||||||
|
if (!eventObj.isNull("desc")) {
|
||||||
|
desc = eventObj.getString("desc");
|
||||||
|
}
|
||||||
HashMap<String, String> eventHashMap = new HashMap<String, String>();
|
HashMap<String, String> eventHashMap = new HashMap<String, String>();
|
||||||
eventHashMap.put("id", String.valueOf(id));
|
eventHashMap.put("id", id);
|
||||||
eventHashMap.put("osdAlarmState", String.valueOf(osdAlarmState));
|
eventHashMap.put("osdAlarmState", String.valueOf(osdAlarmState));
|
||||||
eventHashMap.put("osdAlarmStateStr", mUtil.alarmStatusToString(osdAlarmState));
|
eventHashMap.put("osdAlarmStateStr", mUtil.alarmStatusToString(osdAlarmState));
|
||||||
eventHashMap.put("dataTime", dataTime);
|
eventHashMap.put("dataTime", dataTime);
|
||||||
@@ -249,7 +271,7 @@ public class LogManagerControlActivity extends AppCompatActivity {
|
|||||||
|
|
||||||
|
|
||||||
private void updateUi() {
|
private void updateUi() {
|
||||||
Log.i(TAG,"updateUi()");
|
Log.i(TAG, "updateUi()");
|
||||||
boolean stopUpdating = true;
|
boolean stopUpdating = true;
|
||||||
TextView tv;
|
TextView tv;
|
||||||
Button btn;
|
Button btn;
|
||||||
@@ -291,7 +313,7 @@ public class LogManagerControlActivity extends AppCompatActivity {
|
|||||||
if (mRemoteEventsList != null) {
|
if (mRemoteEventsList != null) {
|
||||||
ListView lv = (ListView) findViewById(R.id.remoteEventsLv);
|
ListView lv = (ListView) findViewById(R.id.remoteEventsLv);
|
||||||
ListAdapter adapter = new RemoteEventsAdapter(LogManagerControlActivity.this, mRemoteEventsList, R.layout.log_entry_layout_remote,
|
ListAdapter adapter = new RemoteEventsAdapter(LogManagerControlActivity.this, mRemoteEventsList, R.layout.log_entry_layout_remote,
|
||||||
new String[]{"id","dataTime", "type", "subType", "osdAlarmStateStr", "desc"},
|
new String[]{"id", "dataTime", "type", "subType", "osdAlarmStateStr", "desc"},
|
||||||
new int[]{R.id.event_id_remote_tv, R.id.event_date_remote_tv, R.id.event_type_remote_tv, R.id.event_subtype_remote_tv,
|
new int[]{R.id.event_id_remote_tv, R.id.event_date_remote_tv, R.id.event_type_remote_tv, R.id.event_subtype_remote_tv,
|
||||||
R.id.event_alarmState_remote_tv, R.id.event_notes_remote_tv});
|
R.id.event_alarmState_remote_tv, R.id.event_notes_remote_tv});
|
||||||
lv.setAdapter(adapter);
|
lv.setAdapter(adapter);
|
||||||
@@ -335,7 +357,7 @@ public class LogManagerControlActivity extends AppCompatActivity {
|
|||||||
boolean checked = ((RadioButton) view).isChecked();
|
boolean checked = ((RadioButton) view).isChecked();
|
||||||
|
|
||||||
// Check which radio button was clicked
|
// Check which radio button was clicked
|
||||||
switch(view.getId()) {
|
switch (view.getId()) {
|
||||||
case R.id.local_data_rb:
|
case R.id.local_data_rb:
|
||||||
if (checked) {
|
if (checked) {
|
||||||
// Switch to the local data view
|
// Switch to the local data view
|
||||||
@@ -411,7 +433,6 @@ public class LogManagerControlActivity extends AppCompatActivity {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
View.OnClickListener onAuth =
|
View.OnClickListener onAuth =
|
||||||
new View.OnClickListener() {
|
new View.OnClickListener() {
|
||||||
@Override
|
@Override
|
||||||
@@ -504,7 +525,7 @@ public class LogManagerControlActivity extends AppCompatActivity {
|
|||||||
public void onItemClick(AdapterView<?> adapter, View v, int position, long id) {
|
public void onItemClick(AdapterView<?> adapter, View v, int position, long id) {
|
||||||
Log.v(TAG, "onRemoteEventList Click() - Position=" + position + ", id=" + id);// Confirmation dialog based on: https://stackoverflow.com/a/12213536/2104584
|
Log.v(TAG, "onRemoteEventList Click() - Position=" + position + ", id=" + id);// Confirmation dialog based on: https://stackoverflow.com/a/12213536/2104584
|
||||||
HashMap<String, String> eventObj = (HashMap<String, String>) adapter.getItemAtPosition(position);
|
HashMap<String, String> eventObj = (HashMap<String, String>) adapter.getItemAtPosition(position);
|
||||||
Long eventId = Long.parseLong(eventObj.get("id"));
|
String eventId = eventObj.get("id");
|
||||||
Log.d(TAG, "onItemClickListener(): eventId=" + eventId + ", eventObj=" + eventObj);
|
Log.d(TAG, "onItemClickListener(): eventId=" + eventId + ", eventObj=" + eventObj);
|
||||||
Intent i = new Intent(getApplicationContext(), EditEventActivity.class);
|
Intent i = new Intent(getApplicationContext(), EditEventActivity.class);
|
||||||
i.putExtra("eventId", eventId);
|
i.putExtra("eventId", eventId);
|
||||||
@@ -588,9 +609,9 @@ public class LogManagerControlActivity extends AppCompatActivity {
|
|||||||
@Override
|
@Override
|
||||||
public View getView(int position, View convertView, ViewGroup parent) {
|
public View getView(int position, View convertView, ViewGroup parent) {
|
||||||
View v = super.getView(position, convertView, parent);
|
View v = super.getView(position, convertView, parent);
|
||||||
Map<String, ?> dataItem = (Map<String,?>)getItem(position);
|
Map<String, ?> dataItem = (Map<String, ?>) getItem(position);
|
||||||
Log.v(TAG,"getView() "+dataItem.toString());
|
Log.v(TAG, "getView() " + dataItem.toString());
|
||||||
switch(dataItem.get("type").toString()) {
|
switch (dataItem.get("type").toString()) {
|
||||||
case "null":
|
case "null":
|
||||||
v.setBackgroundColor(Color.parseColor("#ffaaaa"));
|
v.setBackgroundColor(Color.parseColor("#ffaaaa"));
|
||||||
break;
|
break;
|
||||||
@@ -603,20 +624,17 @@ public class LogManagerControlActivity extends AppCompatActivity {
|
|||||||
|
|
||||||
// Convert date format to something more readable.
|
// Convert date format to something more readable.
|
||||||
TextView tv = (TextView) v.findViewById(R.id.event_date_remote_tv);
|
TextView tv = (TextView) v.findViewById(R.id.event_date_remote_tv);
|
||||||
try {
|
Date dataTime = null;
|
||||||
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");
|
String dateStr = (String) dataItem.get("dataTime");
|
||||||
Date dataTime = dateFormat.parse(dataItem.get("dataTime").toString());
|
dataTime = mUtil.string2date(dateStr);
|
||||||
dateFormat = new SimpleDateFormat("dd-MM-yyyy HH:mm:ss");
|
if (dataTime != null) {
|
||||||
|
SimpleDateFormat dateFormat = new SimpleDateFormat("dd-MM-yyyy HH:mm:ss");
|
||||||
tv.setText(dateFormat.format(dataTime));
|
tv.setText(dateFormat.format(dataTime));
|
||||||
} catch (ParseException e) {
|
} else {
|
||||||
Log.e(TAG,"remoteEventsAdapter.getView: Error Parsing dataDate "+e.getLocalizedMessage());
|
|
||||||
tv.setText("---");
|
tv.setText("---");
|
||||||
}
|
}
|
||||||
|
return (v);
|
||||||
|
}
|
||||||
return(v);
|
|
||||||
}
|
}
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -631,7 +631,7 @@ public class MainActivity extends AppCompatActivity {
|
|||||||
tv.setBackgroundColor(okColour);
|
tv.setBackgroundColor(okColour);
|
||||||
tv.setTextColor(okTextColour);
|
tv.setTextColor(okTextColour);
|
||||||
|
|
||||||
if (!mConnection.mSdServer.mLm.mWac.mServerConnectionOk) {
|
if (!mConnection.mSdServer.mLm.mWac.checkServerConnection()) {
|
||||||
// Problem connecting to server
|
// Problem connecting to server
|
||||||
tv = (TextView) findViewById(R.id.remoteDbTv);
|
tv = (TextView) findViewById(R.id.remoteDbTv);
|
||||||
tv.setText(getString(R.string.data_sharing_status)
|
tv.setText(getString(R.string.data_sharing_status)
|
||||||
|
|||||||
@@ -59,6 +59,7 @@ import java.io.File;
|
|||||||
import java.io.FileWriter;
|
import java.io.FileWriter;
|
||||||
import java.net.InetAddress;
|
import java.net.InetAddress;
|
||||||
import java.net.NetworkInterface;
|
import java.net.NetworkInterface;
|
||||||
|
import java.text.ParseException;
|
||||||
import java.text.SimpleDateFormat;
|
import java.text.SimpleDateFormat;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
@@ -453,6 +454,31 @@ public class OsdUtil {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* string2date - returns a Date object represented by string dateStr
|
||||||
|
* It first attempts to parse it as a long integer, in which case it is assumed to
|
||||||
|
* be a unix timestamp.
|
||||||
|
* If that fails it attempts to parse it as yyyy-MM-dd'T'HH:mm:ss'Z' format.
|
||||||
|
* @param dateStr String reprenting a date
|
||||||
|
* @return Date object or null if parsing fails.
|
||||||
|
*/
|
||||||
|
public Date string2date(String dateStr) {
|
||||||
|
Date dataTime = null;
|
||||||
|
try {
|
||||||
|
Long tstamp = Long.parseLong(dateStr);
|
||||||
|
dataTime = new Date(tstamp);
|
||||||
|
} catch (NumberFormatException e) {
|
||||||
|
Log.v(TAG, "remoteEventsAdapter.getView: Error Parsing dataDate as Long: " + e.getLocalizedMessage()+" trying as string");
|
||||||
|
try {
|
||||||
|
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");
|
||||||
|
dataTime = dateFormat.parse(dateStr);
|
||||||
|
} catch (ParseException e2) {
|
||||||
|
Log.e(TAG, "remoteEventsAdapter.getView: Error Parsing dataDate " + e2.getLocalizedMessage());
|
||||||
|
dataTime = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return(dataTime);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public final int ALARM_STATUS_WARNING = 1;
|
public final int ALARM_STATUS_WARNING = 1;
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ import android.widget.DatePicker;
|
|||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
import android.widget.TimePicker;
|
import android.widget.TimePicker;
|
||||||
|
|
||||||
|
import java.text.SimpleDateFormat;
|
||||||
import java.util.Calendar;
|
import java.util.Calendar;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -40,6 +41,7 @@ public class ReportSeizureActivity extends AppCompatActivity {
|
|||||||
protected void onCreate(Bundle savedInstanceState) {
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
Log.v(TAG, "onCreate()");
|
Log.v(TAG, "onCreate()");
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
|
mContext = this;
|
||||||
mUtil = new OsdUtil(this, serverStatusHandler);
|
mUtil = new OsdUtil(this, serverStatusHandler);
|
||||||
if (!mUtil.isServerRunning()) {
|
if (!mUtil.isServerRunning()) {
|
||||||
mUtil.showToast(getString(R.string.error_server_not_running));
|
mUtil.showToast(getString(R.string.error_server_not_running));
|
||||||
@@ -65,7 +67,7 @@ public class ReportSeizureActivity extends AppCompatActivity {
|
|||||||
//mLm= new LogManager(mContext);
|
//mLm= new LogManager(mContext);
|
||||||
|
|
||||||
Button okBtn =
|
Button okBtn =
|
||||||
(Button) findViewById(R.id.OKBtn);
|
(Button) findViewById(R.id.loginBtn);
|
||||||
okBtn.setOnClickListener(onOk);
|
okBtn.setOnClickListener(onOk);
|
||||||
|
|
||||||
Button cancelBtn =
|
Button cancelBtn =
|
||||||
@@ -142,22 +144,12 @@ public class ReportSeizureActivity extends AppCompatActivity {
|
|||||||
@Override
|
@Override
|
||||||
public void onClick(View view) {
|
public void onClick(View view) {
|
||||||
Log.v(TAG, "onOk");
|
Log.v(TAG, "onOk");
|
||||||
|
//SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
|
||||||
String dateStr=String.format("%4d-%02d-%02d %02d:%02d:30",mYear,mMonth+1,mDay, mHour, mMinute);
|
String dateStr=String.format("%4d-%02d-%02d %02d:%02d:30",mYear,mMonth+1,mDay, mHour, mMinute);
|
||||||
Log.v(TAG, "onOk() - dateSTr="+dateStr);
|
Log.v(TAG, "onOk() - dateSTr="+dateStr);
|
||||||
mMsg = "Finding Nearest Datapoint to Date/Time "+dateStr+"...";
|
mLm.createLocalEvent(dateStr,5);
|
||||||
mLm.getNearestDatapointToDate(dateStr, (Long id) -> {
|
mUtil.showToast("Seizure Event Created");
|
||||||
mMsg = mMsg + "\nNearest Datapoint is "+id;
|
|
||||||
Log.v(TAG, "onOK() - nearest datapoint is "+id);
|
|
||||||
if (id!=-1) {
|
|
||||||
mLm.setDatapointStatus(id,5);
|
|
||||||
mMsg = mMsg + "\nSet Datapoint to Manual Alarm Status";
|
|
||||||
mUtil.showToast(getString(R.string.createdNewEvent));
|
|
||||||
finish();
|
finish();
|
||||||
} else {
|
|
||||||
mMsg = mMsg + "\n*** Datapoint not found - not doing anything ***";
|
|
||||||
mUtil.showToast(getString(R.string.DatapointNotFound));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
View.OnClickListener onCancel =
|
View.OnClickListener onCancel =
|
||||||
|
|||||||
@@ -138,7 +138,7 @@ public class SdServer extends Service implements SdDataReceiver {
|
|||||||
private long mEventsTimerPeriod = 60; // Number of seconds between checks to see if there are unvalidated remote events.
|
private long mEventsTimerPeriod = 60; // Number of seconds between checks to see if there are unvalidated remote events.
|
||||||
private long mEventDuration = 120; // event duration in seconds - uploads datapoints that cover this time range centred on the event time.
|
private long mEventDuration = 120; // event duration in seconds - uploads datapoints that cover this time range centred on the event time.
|
||||||
public long mDataRetentionPeriod = 1; // Prunes the local db so it only retains data younger than this duration (in days)
|
public long mDataRetentionPeriod = 1; // Prunes the local db so it only retains data younger than this duration (in days)
|
||||||
private long mRemoteLogPeriod = 60; // Period in seconds between uploads to the remote server.
|
private long mRemoteLogPeriod = 20; // Period in seconds between uploads to the remote server.
|
||||||
private long mAutoPrunePeriod = 3600; // Prune the database every hour
|
private long mAutoPrunePeriod = 3600; // Prune the database every hour
|
||||||
private boolean mAutoPruneDb;
|
private boolean mAutoPruneDb;
|
||||||
|
|
||||||
@@ -1137,7 +1137,7 @@ public class SdServer extends Service implements SdDataReceiver {
|
|||||||
//writeToSD();
|
//writeToSD();
|
||||||
mLm.writeDatapointToLocalDb(mSdData);
|
mLm.writeDatapointToLocalDb(mSdData);
|
||||||
} else {
|
} else {
|
||||||
Log.e(TAG,"logData() - mLm is null - this should not happen");
|
Log.e(TAG, "logData() - mLm is null - this should not happen");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1241,7 +1241,7 @@ public class SdServer extends Service implements SdDataReceiver {
|
|||||||
|
|
||||||
//prefVal = SP.getString("RemoteLogPeriod", "60");
|
//prefVal = SP.getString("RemoteLogPeriod", "60");
|
||||||
//mRemoteLogPeriod = Integer.parseInt(prefVal);
|
//mRemoteLogPeriod = Integer.parseInt(prefVal);
|
||||||
mRemoteLogPeriod = 60;
|
//mRemoteLogPeriod = 60;
|
||||||
Log.v(TAG, "mRemoteLogPeriod=" + mRemoteLogPeriod);
|
Log.v(TAG, "mRemoteLogPeriod=" + mRemoteLogPeriod);
|
||||||
|
|
||||||
//mOSDUname = SP.getString("OSDUname", "<username>");
|
//mOSDUname = SP.getString("OSDUname", "<username>");
|
||||||
@@ -1300,8 +1300,8 @@ public class SdServer extends Service implements SdDataReceiver {
|
|||||||
Log.i(TAG, "SmsTimer.onFinish() - Last Location is Null so sending first SMS without location.");
|
Log.i(TAG, "SmsTimer.onFinish() - Last Location is Null so sending first SMS without location.");
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
Log.e(TAG,"SmsTImer.onFinish() - mLocationFinder is NULL - this should not happen!");
|
Log.e(TAG,"SmsTimer.onFinish - mLocationFinder is null - this should not happen!");
|
||||||
mUtil.showToast("Error Finding Location - mLocationFinder is null - please report this issue!");
|
mUtil.showToast("SmsTimer.onFinish - mLocationFinder is null - this should not happen! - Please report this issue!");
|
||||||
}
|
}
|
||||||
Log.i(TAG, "SmsTimer.onFinish() - Sending to " + mSMSNumbers.length + " Numbers");
|
Log.i(TAG, "SmsTimer.onFinish() - Sending to " + mSMSNumbers.length + " Numbers");
|
||||||
mUtil.writeToSysLogFile("SdServer.SmsTimer.onFinish()");
|
mUtil.writeToSysLogFile("SdServer.SmsTimer.onFinish()");
|
||||||
@@ -1555,28 +1555,26 @@ public class SdServer extends Service implements SdDataReceiver {
|
|||||||
// Retrieve events from remote database
|
// Retrieve events from remote database
|
||||||
if (mLm.mWac.getEvents((JSONObject remoteEventsObj) -> {
|
if (mLm.mWac.getEvents((JSONObject remoteEventsObj) -> {
|
||||||
Log.v(TAG, "CheckEvents.getEvents.Callback()");
|
Log.v(TAG, "CheckEvents.getEvents.Callback()");
|
||||||
long firstUnvalidatedEvent;
|
Boolean haveUnvalidatedEvent = false;
|
||||||
if (remoteEventsObj == null) {
|
if (remoteEventsObj == null) {
|
||||||
Log.e(TAG, "CheckEvents.Callback: Error Retrieving events");
|
Log.e(TAG, "CheckEvents.Callback: Error Retrieving events");
|
||||||
} else {
|
} else {
|
||||||
try {
|
try {
|
||||||
JSONArray eventsArray = remoteEventsObj.getJSONArray("events");
|
JSONArray eventsArray = remoteEventsObj.getJSONArray("events");
|
||||||
// A bit of a hack to display in reverse chronological order
|
// A bit of a hack to display in reverse chronological order
|
||||||
firstUnvalidatedEvent = -1;
|
|
||||||
for (int i = eventsArray.length() - 1; i >= 0; i--) {
|
for (int i = eventsArray.length() - 1; i >= 0; i--) {
|
||||||
JSONObject eventObj = eventsArray.getJSONObject(i);
|
JSONObject eventObj = eventsArray.getJSONObject(i);
|
||||||
Long id = eventObj.getLong("id");
|
|
||||||
String typeStr = eventObj.getString("type");
|
String typeStr = eventObj.getString("type");
|
||||||
//Log.v(TAG,"CheckEventsTimer: id="+id+", typeStr="+typeStr);
|
//Log.v(TAG,"CheckEventsTimer: id="+id+", typeStr="+typeStr);
|
||||||
if (typeStr.equals("null")) {
|
if (typeStr.equals("null") || typeStr.equals("")) {
|
||||||
firstUnvalidatedEvent = id;
|
haveUnvalidatedEvent = true;
|
||||||
//Log.v(TAG,"CheckEventsTimer:setting firstUnvalidatedEvent to "+firstUnvalidatedEvent);
|
//Log.v(TAG,"CheckEventsTimer:setting firstUnvalidatedEvent to "+firstUnvalidatedEvent);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Log.v(TAG, "CheckEventsTimer.onFinish.callback - firstUnvalidatedEvent = " +
|
Log.v(TAG, "CheckEventsTimer.onFinish.callback - haveUnvalidatedEvent = " +
|
||||||
firstUnvalidatedEvent);
|
haveUnvalidatedEvent);
|
||||||
if (firstUnvalidatedEvent >= 0) {
|
if (haveUnvalidatedEvent) {
|
||||||
showEventNotification(firstUnvalidatedEvent);
|
showEventNotification();
|
||||||
mNM.cancel(DATASHARE_NOTIFICATION_ID);
|
mNM.cancel(DATASHARE_NOTIFICATION_ID);
|
||||||
} else {
|
} else {
|
||||||
mNM.cancel(EVENT_NOTIFICATION_ID);
|
mNM.cancel(EVENT_NOTIFICATION_ID);
|
||||||
@@ -1627,7 +1625,7 @@ public class SdServer extends Service implements SdDataReceiver {
|
|||||||
/**
|
/**
|
||||||
* Show a notification to tell the user that we have unvalidated events.
|
* Show a notification to tell the user that we have unvalidated events.
|
||||||
*/
|
*/
|
||||||
private void showEventNotification(long eventId) {
|
private void showEventNotification() {
|
||||||
Log.v(TAG, "showEventNotification()");
|
Log.v(TAG, "showEventNotification()");
|
||||||
int iconId;
|
int iconId;
|
||||||
String titleStr;
|
String titleStr;
|
||||||
|
|||||||
@@ -4,6 +4,8 @@ import android.content.Context;
|
|||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
|
||||||
import com.android.volley.AuthFailureError;
|
import com.android.volley.AuthFailureError;
|
||||||
import com.android.volley.Request;
|
import com.android.volley.Request;
|
||||||
import com.android.volley.RequestQueue;
|
import com.android.volley.RequestQueue;
|
||||||
@@ -12,6 +14,18 @@ import com.android.volley.VolleyError;
|
|||||||
import com.android.volley.VolleyLog;
|
import com.android.volley.VolleyLog;
|
||||||
import com.android.volley.toolbox.StringRequest;
|
import com.android.volley.toolbox.StringRequest;
|
||||||
import com.android.volley.toolbox.Volley;
|
import com.android.volley.toolbox.Volley;
|
||||||
|
import com.google.android.gms.tasks.OnCompleteListener;
|
||||||
|
import com.google.android.gms.tasks.OnFailureListener;
|
||||||
|
import com.google.android.gms.tasks.OnSuccessListener;
|
||||||
|
import com.google.android.gms.tasks.Task;
|
||||||
|
import com.google.firebase.auth.FirebaseAuth;
|
||||||
|
import com.google.firebase.firestore.DocumentReference;
|
||||||
|
import com.google.firebase.firestore.DocumentSnapshot;
|
||||||
|
import com.google.firebase.firestore.FirebaseFirestore;
|
||||||
|
import com.google.firebase.firestore.Query;
|
||||||
|
import com.google.firebase.firestore.QueryDocumentSnapshot;
|
||||||
|
import com.google.firebase.firestore.QuerySnapshot;
|
||||||
|
import com.google.firebase.firestore.core.OrderBy;
|
||||||
|
|
||||||
import org.json.JSONArray;
|
import org.json.JSONArray;
|
||||||
import org.json.JSONException;
|
import org.json.JSONException;
|
||||||
@@ -22,20 +36,19 @@ import java.text.DateFormat;
|
|||||||
import java.text.SimpleDateFormat;
|
import java.text.SimpleDateFormat;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
|
|
||||||
// This class is intended to handle all interactions with the OSD WebAPI
|
// This class is intended to handle all interactions with the OSD WebAPI
|
||||||
public class WebApiConnection {
|
public abstract class WebApiConnection {
|
||||||
public String retVal;
|
protected Context mContext;
|
||||||
public int retCode;
|
protected OsdUtil mUtil;
|
||||||
public boolean mServerConnectionOk = false;
|
|
||||||
private String mUrlBase = "https://osdApi.ddns.net";
|
|
||||||
private String TAG = "WebApiConnection";
|
private String TAG = "WebApiConnection";
|
||||||
private String mAuthToken;
|
private String mAuthToken;
|
||||||
private Context mContext;
|
|
||||||
private OsdUtil mUtil;
|
|
||||||
RequestQueue mQueue;
|
|
||||||
|
|
||||||
public interface JSONObjectCallback {
|
public interface JSONObjectCallback {
|
||||||
public void accept(JSONObject retValObj);
|
public void accept(JSONObject retValObj);
|
||||||
@@ -51,237 +64,23 @@ public class WebApiConnection {
|
|||||||
|
|
||||||
public WebApiConnection(Context context) {
|
public WebApiConnection(Context context) {
|
||||||
mContext = context;
|
mContext = context;
|
||||||
mQueue = Volley.newRequestQueue(context);
|
|
||||||
mUtil = new OsdUtil(mContext, new Handler());
|
mUtil = new OsdUtil(mContext, new Handler());
|
||||||
}
|
}
|
||||||
|
|
||||||
public void close() {
|
public void close() {
|
||||||
Log.i(TAG,"stop()");
|
Log.i(TAG, "stop()");
|
||||||
mQueue.stop();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public abstract boolean isLoggedIn();
|
||||||
* Attempt to authenticate with the web API using user name uname and password passwd. Calls function callback with either
|
|
||||||
* the authentication token on success or null on failure.
|
|
||||||
*
|
|
||||||
* @param uname - user name
|
|
||||||
* @param passwd - password
|
|
||||||
* @param callback - call back function callback(String retVal)
|
|
||||||
* @return true if request sent, or false if failed to send request.
|
|
||||||
*/
|
|
||||||
public boolean authenticate(final String uname, final String passwd, StringCallback callback) {
|
|
||||||
// NOTE: the 'final' keyword is necessary for uname and passwd to be accessible to getParams below - I don't know why!
|
|
||||||
// We know that this command works, so we just need the Java equivalent:
|
|
||||||
// curl -X POST -d 'login=graham4&password=testpwd1' https://osdapi.ddns.net/api/accounts/login/
|
|
||||||
// sending the credentials as a JSONObject postData did not work, so try the method from:
|
|
||||||
// https://protocoderspoint.com/login-and-registration-form-in-android-using-volley-keeping-user-logged-in/#Login_Registration_form_in_android_using_volley_library
|
|
||||||
String urlStr = mUrlBase + "/api/accounts/login/";
|
|
||||||
Log.v(TAG, "urlStr=" + urlStr);
|
|
||||||
|
|
||||||
StringRequest req = new StringRequest(Request.Method.POST, urlStr,
|
|
||||||
new Response.Listener<String>() {
|
|
||||||
@Override
|
|
||||||
public void onResponse(String response) {
|
|
||||||
String tokenStr = null;
|
|
||||||
Log.v(TAG, "Response is: " + response);
|
|
||||||
try {
|
|
||||||
JSONObject jo = new JSONObject(response);
|
|
||||||
tokenStr = jo.getString("token");
|
|
||||||
mServerConnectionOk = true;
|
|
||||||
} catch (JSONException e) {
|
|
||||||
tokenStr = "Error Parsing Rsponse";
|
|
||||||
}
|
|
||||||
setStoredToken(tokenStr);
|
|
||||||
callback.accept(tokenStr);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
new Response.ErrorListener() {
|
|
||||||
@Override
|
|
||||||
public void onErrorResponse(VolleyError error) {
|
|
||||||
if (error != null) {
|
|
||||||
Log.e(TAG, "Login Error: " + error.toString() + ", message:" + error.getMessage());
|
|
||||||
} else {
|
|
||||||
Log.e(TAG, "Login Error: Returned null response");
|
|
||||||
}
|
|
||||||
mServerConnectionOk = false;
|
|
||||||
setStoredToken(null);
|
|
||||||
callback.accept(null);
|
|
||||||
}
|
|
||||||
}) {
|
|
||||||
// Note, this is overriding part of StringRequest, not one of the sub-classes above!
|
|
||||||
@Override
|
|
||||||
protected Map<String, String> getParams() {
|
|
||||||
Map<String, String> params = new HashMap<>();
|
|
||||||
// params.put("name",sname); // passing parameters to server
|
|
||||||
params.put("login", uname);
|
|
||||||
params.put("password", passwd);
|
|
||||||
return params;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
mQueue.add(req);
|
|
||||||
return (true);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Remove the stored token so future calls are not authenticated.
|
|
||||||
public void logout() {
|
|
||||||
Log.v(TAG, "logout()");
|
|
||||||
setStoredToken(null);
|
|
||||||
//saveStoredToken(null);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setStoredToken(String authToken) {
|
|
||||||
mAuthToken = authToken;
|
|
||||||
}
|
|
||||||
|
|
||||||
private String getStoredToken() {
|
|
||||||
return (mAuthToken);
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isLoggedIn() {
|
|
||||||
String authToken = getStoredToken();
|
|
||||||
//Log.v(TAG, "isLoggedIn(): token=" + authToken);
|
|
||||||
if (authToken == null || authToken.length() == 0) {
|
|
||||||
//Log.v(TAG, "isLogged in - not logged in");
|
|
||||||
return (false);
|
|
||||||
} else {
|
|
||||||
return (true);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Create a new event in the remote database, based on the provided parameters.
|
// Create a new event in the remote database, based on the provided parameters.
|
||||||
public boolean createEvent(final int osdAlarmState, final Date eventDate, final String eventDesc, StringCallback callback) {
|
// passes the newly created documentId to function callback on successful completion, or null on error.
|
||||||
Log.v(TAG, "createEvent()");
|
public abstract boolean createEvent(final int osdAlarmState, final Date eventDate, final String eventDesc, StringCallback callback);
|
||||||
String urlStr = mUrlBase + "/api/events/";
|
|
||||||
Log.v(TAG, "urlStr=" + urlStr);
|
|
||||||
final String authtoken = getStoredToken();
|
|
||||||
|
|
||||||
if (!isLoggedIn()) {
|
// calls function callback with a JSONObject representation of the event with id 'eventId'
|
||||||
Log.v(TAG, "not logged in - doing nothing");
|
public abstract boolean getEvent(String eventId, JSONObjectCallback callback);
|
||||||
return (false);
|
|
||||||
}
|
|
||||||
DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
|
|
||||||
JSONObject jsonObject = new JSONObject();
|
|
||||||
try {
|
|
||||||
jsonObject.put("osdAlarmState", String.valueOf(osdAlarmState));
|
|
||||||
jsonObject.put("dataTime", dateFormat.format(eventDate));
|
|
||||||
jsonObject.put("desc", eventDesc);
|
|
||||||
} catch (JSONException e) {
|
|
||||||
Log.e(TAG, "Error generating event JSON string");
|
|
||||||
}
|
|
||||||
final String dataStr = jsonObject.toString();
|
|
||||||
Log.v(TAG, "createEvent - data=" + dataStr);
|
|
||||||
|
|
||||||
StringRequest req = new StringRequest(Request.Method.POST, urlStr,
|
|
||||||
new Response.Listener<String>() {
|
|
||||||
@Override
|
|
||||||
public void onResponse(String response) {
|
|
||||||
Log.v(TAG, "Response is: " + response);
|
|
||||||
mServerConnectionOk = true;
|
|
||||||
callback.accept(response);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
new Response.ErrorListener() {
|
|
||||||
@Override
|
|
||||||
public void onErrorResponse(VolleyError error) {
|
|
||||||
mServerConnectionOk = false;
|
|
||||||
if (error != null) {
|
|
||||||
Log.e(TAG, "Create Event Error: " + error.toString() + ", message:" + error.getMessage());
|
|
||||||
callback.accept(null);
|
|
||||||
} else {
|
|
||||||
Log.e(TAG, "Create Event Error - null respones");
|
|
||||||
callback.accept(null);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}) {
|
|
||||||
// Note, this is overriding part of StringRequest, not one of the sub-classes above!
|
|
||||||
@Override
|
|
||||||
protected Map<String, String> getParams() {
|
|
||||||
Map<String, String> params = new HashMap<>();
|
|
||||||
// params.put("name",sname); // passing parameters to server
|
|
||||||
String authToken = getStoredToken();
|
|
||||||
params.put("Authorization: Token " + authToken, authToken);
|
|
||||||
Log.v(TAG, "getParams: params=" + params.toString());
|
|
||||||
return params;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Map<String, String> getHeaders() throws AuthFailureError {
|
|
||||||
Map<String, String> params = new HashMap<String, String>();
|
|
||||||
params.put("Content-Type", "application/json; charset=UTF-8");
|
|
||||||
params.put("Authorization", "Token " + getStoredToken());
|
|
||||||
return params;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public byte[] getBody() throws AuthFailureError {
|
|
||||||
try {
|
|
||||||
return dataStr == null ? null : dataStr.getBytes("utf-8");
|
|
||||||
} catch (UnsupportedEncodingException uee) {
|
|
||||||
VolleyLog.wtf("Unsupported Encoding while trying to get the bytes of %s using %s", dataStr, "utf-8");
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
mQueue.add(req);
|
|
||||||
return (true);
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean getEvent(Long eventId, JSONObjectCallback callback) {
|
|
||||||
//Long eventId=Long.valueOf(285);
|
|
||||||
Log.v(TAG, "getEvent()");
|
|
||||||
String urlStr = mUrlBase + "/api/events/" + eventId;
|
|
||||||
Log.v(TAG, "getEvent(): urlStr=" + urlStr);
|
|
||||||
final String authtoken = getStoredToken();
|
|
||||||
|
|
||||||
if (!isLoggedIn()) {
|
|
||||||
Log.v(TAG, "not logged in - doing nothing");
|
|
||||||
return (false);
|
|
||||||
}
|
|
||||||
|
|
||||||
StringRequest req = new StringRequest(Request.Method.GET, urlStr,
|
|
||||||
new Response.Listener<String>() {
|
|
||||||
@Override
|
|
||||||
public void onResponse(String response) {
|
|
||||||
Log.v(TAG, "Response is: " + response);
|
|
||||||
try {
|
|
||||||
JSONObject retObj = new JSONObject(response);
|
|
||||||
retObj.put("alarmStateStr", mUtil.alarmStatusToString(retObj.getInt("osdAlarmState")));
|
|
||||||
callback.accept(retObj);
|
|
||||||
} catch (JSONException e) {
|
|
||||||
Log.e(TAG, "getEventTypes.onRespons(): Error: " + e.getMessage() + "," + e.toString());
|
|
||||||
callback.accept(null);
|
|
||||||
}
|
|
||||||
mServerConnectionOk = true;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
new Response.ErrorListener() {
|
|
||||||
@Override
|
|
||||||
public void onErrorResponse(VolleyError error) {
|
|
||||||
if (error != null) {
|
|
||||||
Log.e(TAG, "Create Event Error: " + error.toString() + ", message:" + error.getMessage());
|
|
||||||
} else {
|
|
||||||
Log.e(TAG, "Create Event Error: returned null response");
|
|
||||||
}
|
|
||||||
mServerConnectionOk = false;
|
|
||||||
callback.accept(null);
|
|
||||||
}
|
|
||||||
}) {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Map<String, String> getHeaders() throws AuthFailureError {
|
|
||||||
Map<String, String> params = new HashMap<String, String>();
|
|
||||||
params.put("Content-Type", "application/json; charset=UTF-8");
|
|
||||||
params.put("Authorization", "Token " + getStoredToken());
|
|
||||||
return params;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
mQueue.add(req);
|
|
||||||
return (true);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieve all events accessible to the logged in user, and pass them to the callback function as a JSONObject
|
* Retrieve all events accessible to the logged in user, and pass them to the callback function as a JSONObject
|
||||||
@@ -289,305 +88,11 @@ public class WebApiConnection {
|
|||||||
* @param callback
|
* @param callback
|
||||||
* @return true on success or false on failure to initiate the request.
|
* @return true on success or false on failure to initiate the request.
|
||||||
*/
|
*/
|
||||||
public boolean getEvents(JSONObjectCallback callback) {
|
public abstract boolean getEvents(JSONObjectCallback callback);
|
||||||
//Long eventId=Long.valueOf(285);
|
|
||||||
Log.v(TAG, "getEvents()");
|
|
||||||
String urlStr = mUrlBase + "/api/events/";
|
|
||||||
Log.v(TAG, "getEvents(): urlStr=" + urlStr);
|
|
||||||
final String authtoken = getStoredToken();
|
|
||||||
|
|
||||||
if (!isLoggedIn()) {
|
|
||||||
Log.v(TAG, "not logged in - doing nothing");
|
|
||||||
return (false);
|
|
||||||
}
|
|
||||||
|
|
||||||
StringRequest req = new StringRequest(Request.Method.GET, urlStr,
|
|
||||||
new Response.Listener<String>() {
|
|
||||||
@Override
|
|
||||||
public void onResponse(String response) {
|
|
||||||
Log.v(TAG, "Response is: " + response);
|
|
||||||
mServerConnectionOk = true;
|
|
||||||
try {
|
|
||||||
JSONObject retObj = new JSONObject();
|
|
||||||
JSONArray eventArray = new JSONArray(response);
|
|
||||||
retObj.put("events", eventArray);
|
|
||||||
callback.accept(retObj);
|
|
||||||
} catch (JSONException e) {
|
|
||||||
Log.e(TAG, "getEventTypes.onRespons(): Error: " + e.getMessage() + "," + e.toString());
|
|
||||||
callback.accept(null);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
new Response.ErrorListener() {
|
|
||||||
@Override
|
|
||||||
public void onErrorResponse(VolleyError error) {
|
|
||||||
//if ((error != null) && (error.networkResponse != null) && (error.networkResponse.data != null)) {#
|
|
||||||
mServerConnectionOk = false;
|
|
||||||
if (error != null) {
|
|
||||||
if (error.networkResponse != null) {
|
|
||||||
Log.e(TAG, "getEvents(): Error: " + error.toString() + ", message:" + error.getMessage());
|
|
||||||
} else {
|
|
||||||
Log.e(TAG, "getEvents(): Error: - request returned null networkResponse");
|
|
||||||
}
|
|
||||||
} else{
|
|
||||||
Log.e(TAG, "getEvents(): Error: - request returned null response");
|
|
||||||
}
|
|
||||||
callback.accept(null);
|
|
||||||
}
|
|
||||||
}) {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Map<String, String> getHeaders() throws AuthFailureError {
|
|
||||||
Map<String, String> params = new HashMap<String, String>();
|
|
||||||
params.put("Content-Type", "application/json; charset=UTF-8");
|
|
||||||
params.put("Authorization", "Token " + getStoredToken());
|
|
||||||
return params;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
mQueue.add(req);
|
|
||||||
return (true);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public boolean updateEvent(final JSONObject eventObj, JSONObjectCallback callback) {
|
|
||||||
Long eventId;
|
|
||||||
Log.v(TAG, "updateEvent()");
|
|
||||||
final String authtoken = getStoredToken();
|
|
||||||
|
|
||||||
if (!isLoggedIn()) {
|
|
||||||
Log.v(TAG, "not logged in - doing nothing");
|
|
||||||
return (false);
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
eventId = eventObj.getLong("id");
|
|
||||||
} catch (JSONException e) {
|
|
||||||
Log.e(TAG, "updateEvent(): Error reading id from eventObj");
|
|
||||||
eventId = Long.valueOf(-1);
|
|
||||||
}
|
|
||||||
final String dataStr = eventObj.toString();
|
|
||||||
Log.v(TAG, "createEvent - data=" + dataStr);
|
|
||||||
|
|
||||||
|
|
||||||
int reqMethod;
|
|
||||||
String urlStr;
|
|
||||||
if (eventId != -1) {
|
|
||||||
Log.v(TAG, "updateEvent() - found eventId " + eventId + ", Updating event record");
|
|
||||||
urlStr = mUrlBase + "/api/events/" + eventId + "/";
|
|
||||||
Log.v(TAG, "urlStr=" + urlStr);
|
|
||||||
reqMethod = Request.Method.PUT;
|
|
||||||
} else {
|
|
||||||
Log.v(TAG, "updateEvent() - eventId not found - creating new event record");
|
|
||||||
urlStr = mUrlBase + "/api/events/";
|
|
||||||
Log.v(TAG, "urlStr=" + urlStr);
|
|
||||||
reqMethod = Request.Method.POST;
|
|
||||||
}
|
|
||||||
|
|
||||||
StringRequest req = new StringRequest(reqMethod, urlStr,
|
|
||||||
new Response.Listener<String>() {
|
|
||||||
@Override
|
|
||||||
public void onResponse(String response) {
|
|
||||||
Log.v(TAG, "Response is: " + response);
|
|
||||||
mServerConnectionOk = true;
|
|
||||||
try {
|
|
||||||
JSONObject retObj = new JSONObject(response);
|
|
||||||
callback.accept(retObj);
|
|
||||||
} catch (JSONException e) {
|
|
||||||
Log.e(TAG, "getEventTypes.onRespons(): Error: " + e.getMessage() + "," + e.toString());
|
|
||||||
callback.accept(null);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
new Response.ErrorListener() {
|
|
||||||
@Override
|
|
||||||
public void onErrorResponse(VolleyError error) {
|
|
||||||
mServerConnectionOk = false;
|
|
||||||
if (error != null) {
|
|
||||||
Log.e(TAG, "Create Event Error: " + error.toString() + ", message:" + error.getMessage());
|
|
||||||
} else {
|
|
||||||
Log.e(TAG, "Create Event Error - returned null response");
|
|
||||||
}
|
|
||||||
callback.accept(null);
|
|
||||||
}
|
|
||||||
}) {
|
|
||||||
// Note, this is overriding part of StringRequest, not one of the sub-classes above!
|
|
||||||
@Override
|
|
||||||
protected Map<String, String> getParams() {
|
|
||||||
Map<String, String> params = new HashMap<>();
|
|
||||||
// params.put("name",sname); // passing parameters to server
|
|
||||||
String authToken = getStoredToken();
|
|
||||||
params.put("Authorization: Token " + authToken, authToken);
|
|
||||||
Log.v(TAG, "getParams: params=" + params.toString());
|
|
||||||
//params.put("eventType", String.valueOf(eventType));
|
|
||||||
//params.put("dataTime", dateFormat.format(eventDate));
|
|
||||||
//params.put("desc", eventDesc);
|
|
||||||
return params;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Map<String, String> getHeaders() throws AuthFailureError {
|
|
||||||
Map<String, String> params = new HashMap<String, String>();
|
|
||||||
params.put("Content-Type", "application/json; charset=UTF-8");
|
|
||||||
params.put("Authorization", "Token " + getStoredToken());
|
|
||||||
return params;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public byte[] getBody() throws AuthFailureError {
|
|
||||||
try {
|
|
||||||
return dataStr == null ? null : dataStr.getBytes("utf-8");
|
|
||||||
} catch (UnsupportedEncodingException uee) {
|
|
||||||
VolleyLog.wtf("Unsupported Encoding while trying to get the bytes of %s using %s", dataStr, "utf-8");
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
mQueue.add(req);
|
|
||||||
return (true);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public boolean createDatapoint(JSONObject dataObj, int eventId, StringCallback callback) {
|
|
||||||
Log.v(TAG, "createDatapoint()");
|
|
||||||
// Create a new event in the remote database, based on the provided parameters.
|
|
||||||
String urlStr = mUrlBase + "/api/datapoints/";
|
|
||||||
Log.v(TAG, "urlStr=" + urlStr);
|
|
||||||
final String authtoken = getStoredToken();
|
|
||||||
|
|
||||||
if (!isLoggedIn()) {
|
|
||||||
Log.v(TAG, "not logged in - doing nothing");
|
|
||||||
return (false);
|
|
||||||
}
|
|
||||||
|
|
||||||
DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
|
|
||||||
JSONObject jsonObject = new JSONObject();
|
|
||||||
try {
|
|
||||||
//jsonObject.put("userId", -1);
|
|
||||||
jsonObject.put("eventId", String.valueOf(eventId));
|
|
||||||
jsonObject.put("dataTime", dataObj.getString("dataTime"));
|
|
||||||
jsonObject.put("dataJSON", dataObj.toString());
|
|
||||||
} catch (JSONException e) {
|
|
||||||
Log.e(TAG, "Error generating event JSON string");
|
|
||||||
}
|
|
||||||
final String dataStr = jsonObject.toString();
|
|
||||||
Log.v(TAG, "createDatapoint - dataStr=" + dataStr);
|
|
||||||
|
|
||||||
|
|
||||||
StringRequest req = new StringRequest(Request.Method.POST, urlStr,
|
|
||||||
new Response.Listener<String>() {
|
|
||||||
@Override
|
|
||||||
public void onResponse(String response) {
|
|
||||||
Log.v(TAG, "Response is: " + response);
|
|
||||||
mServerConnectionOk = true;
|
|
||||||
callback.accept(response);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
new Response.ErrorListener() {
|
|
||||||
@Override
|
|
||||||
public void onErrorResponse(VolleyError error) {
|
|
||||||
mServerConnectionOk = false;
|
|
||||||
if (error != null) {
|
|
||||||
Log.e(TAG, "Create Datapoint Error: " + error.toString() + ", message:" + error.getMessage());
|
|
||||||
callback.accept(null);
|
|
||||||
} else {
|
|
||||||
Log.e(TAG, "Create Datapoint Error - returned null respones");
|
|
||||||
callback.accept(null);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}) {
|
|
||||||
// Note, this is overriding part of StringRequest, not one of the sub-classes above!
|
|
||||||
@Override
|
|
||||||
protected Map<String, String> getParams() {
|
|
||||||
Map<String, String> params = new HashMap<>();
|
|
||||||
// params.put("name",sname); // passing parameters to server
|
|
||||||
String authToken = getStoredToken();
|
|
||||||
params.put("Authorization: Token " + authToken, authToken);
|
|
||||||
Log.v(TAG, "getParams: params=" + params.toString());
|
|
||||||
return params;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Map<String, String> getHeaders() throws AuthFailureError {
|
|
||||||
Map<String, String> params = new HashMap<String, String>();
|
|
||||||
params.put("Content-Type", "application/json; charset=UTF-8");
|
|
||||||
params.put("Authorization", "Token " + getStoredToken());
|
|
||||||
return params;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public byte[] getBody() throws AuthFailureError {
|
|
||||||
try {
|
|
||||||
return dataStr == null ? null : dataStr.getBytes("utf-8");
|
|
||||||
} catch (UnsupportedEncodingException uee) {
|
|
||||||
VolleyLog.wtf("Unsupported Encoding while trying to get the bytes of %s using %s", dataStr, "utf-8");
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
mQueue.add(req);
|
|
||||||
return (true);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Retieve the user profile of the authenticated user from the server, and return it to the callback function.
|
|
||||||
* @param callback - function to be called with a JSONObject as a parameter that contains the user profile data.
|
|
||||||
* @return true if request sent successfully, or else false.
|
|
||||||
*/
|
|
||||||
public boolean getUserProfile(JSONObjectCallback callback) {
|
|
||||||
Log.v(TAG, "getUserProfile()");
|
|
||||||
String urlStr = mUrlBase + "/api/accounts/profile/";
|
|
||||||
Log.v(TAG, "getUserProfile(): urlStr=" + urlStr);
|
|
||||||
final String authtoken = getStoredToken();
|
|
||||||
|
|
||||||
if (!isLoggedIn()) {
|
|
||||||
Log.v(TAG, "not logged in - doing nothing");
|
|
||||||
return (false);
|
|
||||||
}
|
|
||||||
|
|
||||||
StringRequest req = new StringRequest(Request.Method.GET, urlStr,
|
|
||||||
new Response.Listener<String>() {
|
|
||||||
@Override
|
|
||||||
public void onResponse(String response) {
|
|
||||||
Log.v(TAG, "Response is: " + response);
|
|
||||||
try {
|
|
||||||
JSONObject retObj = new JSONObject(response);
|
|
||||||
callback.accept(retObj);
|
|
||||||
} catch (JSONException e) {
|
|
||||||
Log.e(TAG, "getUserProfile.onRespons(): Error: " + e.getMessage() + "," + e.toString());
|
|
||||||
callback.accept(null);
|
|
||||||
}
|
|
||||||
mServerConnectionOk = true;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
new Response.ErrorListener() {
|
|
||||||
@Override
|
|
||||||
public void onErrorResponse(VolleyError error) {
|
|
||||||
if (error != null) {
|
|
||||||
Log.e(TAG, "Create Event Error: " + error.toString() + ", message:" + error.getMessage());
|
|
||||||
} else {
|
|
||||||
Log.e(TAG, "Create Event Error: returned null response");
|
|
||||||
}
|
|
||||||
mServerConnectionOk = false;
|
|
||||||
callback.accept(null);
|
|
||||||
}
|
|
||||||
}) {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Map<String, String> getHeaders() throws AuthFailureError {
|
|
||||||
Map<String, String> params = new HashMap<String, String>();
|
|
||||||
params.put("Content-Type", "application/json; charset=UTF-8");
|
|
||||||
params.put("Authorization", "Token " + getStoredToken());
|
|
||||||
return params;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
mQueue.add(req);
|
|
||||||
return (true);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
public abstract boolean updateEvent(final JSONObject eventObj, JSONObjectCallback callback);
|
||||||
|
|
||||||
|
public abstract boolean createDatapoint(JSONObject dataObj, String eventId, StringCallback callback);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieve the file containing the standard event types from the server.
|
* Retrieve the file containing the standard event types from the server.
|
||||||
@@ -595,88 +100,37 @@ public class WebApiConnection {
|
|||||||
*
|
*
|
||||||
* @return true if request sent successfully or else false.
|
* @return true if request sent successfully or else false.
|
||||||
*/
|
*/
|
||||||
public boolean getEventTypes(JSONObjectCallback callback) {
|
public abstract boolean getEventTypes(JSONObjectCallback callback);
|
||||||
Log.v(TAG, "getEventTypes()");
|
|
||||||
String urlStr = mUrlBase + "/static/eventTypes.json";
|
|
||||||
Log.v(TAG, "urlStr=" + urlStr);
|
|
||||||
final String authtoken = getStoredToken();
|
|
||||||
|
|
||||||
if (!isLoggedIn()) {
|
|
||||||
Log.v(TAG, "not logged in - doing nothing");
|
|
||||||
return (false);
|
|
||||||
}
|
|
||||||
|
|
||||||
StringRequest req = new StringRequest(Request.Method.GET, urlStr,
|
|
||||||
new Response.Listener<String>() {
|
|
||||||
@Override
|
|
||||||
public void onResponse(String response) {
|
|
||||||
Log.v(TAG, "getEventTypes.onResponse(): Response is: " + response);
|
|
||||||
mServerConnectionOk = true;
|
|
||||||
try {
|
|
||||||
JSONObject retObj = new JSONObject(response);
|
|
||||||
callback.accept(retObj);
|
|
||||||
} catch (JSONException e) {
|
|
||||||
Log.e(TAG, "getEventTypes.onRespons(): Error: " + e.getMessage() + "," + e.toString());
|
|
||||||
callback.accept(null);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
new Response.ErrorListener() {
|
|
||||||
@Override
|
|
||||||
public void onErrorResponse(VolleyError error) {
|
|
||||||
mServerConnectionOk = false;
|
|
||||||
if (error != null) {
|
|
||||||
Log.e(TAG, "getEventTypes.onErrorResponse(): " + error.toString() + ", message:" + error.getMessage());
|
|
||||||
} else {
|
|
||||||
Log.e(TAG, "getEventTypes.onErrorResponse() - returned null response");
|
|
||||||
}
|
|
||||||
callback.accept(null);
|
|
||||||
}
|
|
||||||
}) {
|
|
||||||
// Note, this is overriding part of StringRequest, not one of the sub-classes above!
|
|
||||||
@Override
|
|
||||||
public Map<String, String> getHeaders() throws AuthFailureError {
|
|
||||||
Map<String, String> params = new HashMap<String, String>();
|
|
||||||
params.put("Content-Type", "application/json; charset=UTF-8");
|
|
||||||
params.put("Authorization", "Token " + getStoredToken());
|
|
||||||
return params;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
mQueue.add(req);
|
|
||||||
return (true);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieve a trivial file from the server to check we have a good server connection.
|
* Retrieve a trivial file from the server to check we have a good server connection.
|
||||||
* sets mServerConnectionOk.
|
* sets mServerConnectionOk.
|
||||||
|
*
|
||||||
* @return true if request sent successfully or else false.
|
* @return true if request sent successfully or else false.
|
||||||
*/
|
*/
|
||||||
public boolean checkServerConnection() {
|
public abstract boolean checkServerConnection();
|
||||||
Log.v(TAG, "checkServerConnection()");
|
|
||||||
String urlStr = mUrlBase + "/static/test.txt";
|
|
||||||
Log.v(TAG, "urlStr=" + urlStr);
|
|
||||||
|
|
||||||
StringRequest req = new StringRequest(Request.Method.GET, urlStr,
|
public abstract boolean getUserProfile(JSONObjectCallback callback);
|
||||||
new Response.Listener<String>() {
|
|
||||||
@Override
|
|
||||||
public void onResponse(String response) {
|
public boolean authenticate(final String uname, final String passwd, StringCallback callback) {
|
||||||
Log.v(TAG, "checkServerConnection.onResponse(): Response is: " + response);
|
Log.e(TAG,"WebApiConnection.authenticate(username, password, callback) Not Implemented");
|
||||||
mServerConnectionOk = true;
|
return false;
|
||||||
}
|
}
|
||||||
},
|
|
||||||
new Response.ErrorListener() {
|
// Remove the stored token so future calls are not authenticated.
|
||||||
@Override
|
public void logout() {
|
||||||
public void onErrorResponse(VolleyError error) {
|
Log.v(TAG, "logout()");
|
||||||
Log.v(TAG, "checkServerConnection.onErrorResponse");
|
setStoredToken(null);
|
||||||
mServerConnectionOk = false;
|
|
||||||
}
|
}
|
||||||
});
|
|
||||||
|
|
||||||
mQueue.add(req);
|
protected void setStoredToken(String authToken) {
|
||||||
return (true);
|
mAuthToken = authToken;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected String getStoredToken() {
|
||||||
|
return (mAuthToken);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,423 @@
|
|||||||
|
package uk.org.openseizuredetector;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.os.Handler;
|
||||||
|
import android.util.Log;
|
||||||
|
import android.widget.TextView;
|
||||||
|
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
|
||||||
|
import com.android.volley.RequestQueue;
|
||||||
|
import com.android.volley.toolbox.Volley;
|
||||||
|
import com.google.android.gms.tasks.OnCompleteListener;
|
||||||
|
import com.google.android.gms.tasks.OnFailureListener;
|
||||||
|
import com.google.android.gms.tasks.OnSuccessListener;
|
||||||
|
import com.google.android.gms.tasks.Task;
|
||||||
|
import com.google.firebase.auth.FirebaseAuth;
|
||||||
|
import com.google.firebase.firestore.DocumentReference;
|
||||||
|
import com.google.firebase.firestore.DocumentSnapshot;
|
||||||
|
import com.google.firebase.firestore.FirebaseFirestore;
|
||||||
|
import com.google.firebase.firestore.Query;
|
||||||
|
import com.google.firebase.firestore.QueryDocumentSnapshot;
|
||||||
|
import com.google.firebase.firestore.QuerySnapshot;
|
||||||
|
|
||||||
|
import org.json.JSONArray;
|
||||||
|
import org.json.JSONException;
|
||||||
|
import org.json.JSONObject;
|
||||||
|
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
|
||||||
|
// This class is intended to handle all interactions with the OSD WebAPI
|
||||||
|
public class WebApiConnection_firebase extends WebApiConnection {
|
||||||
|
public String retVal;
|
||||||
|
public int retCode;
|
||||||
|
public boolean mServerConnectionOk = false;
|
||||||
|
private String TAG = "WebApiConnection_firebase";
|
||||||
|
private String mAuthToken;
|
||||||
|
private Context mContext;
|
||||||
|
private OsdUtil mUtil;
|
||||||
|
FirebaseFirestore mDb;
|
||||||
|
|
||||||
|
RequestQueue mQueue;
|
||||||
|
|
||||||
|
|
||||||
|
public WebApiConnection_firebase(Context context) {
|
||||||
|
super(context);
|
||||||
|
loginToFirebase();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void loginToFirebase() {
|
||||||
|
// Check if we are already logged in
|
||||||
|
FirebaseAuth auth = FirebaseAuth.getInstance();
|
||||||
|
mDb = FirebaseFirestore.getInstance();
|
||||||
|
if (auth != null) {
|
||||||
|
if (auth.getCurrentUser() != null) {
|
||||||
|
Log.i(TAG, "Firebase Logged in OK -" + auth.getCurrentUser().getDisplayName());
|
||||||
|
} else {
|
||||||
|
Log.e(TAG, "Firebase not logged in - no current user");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Log.e(TAG, "Firebase not logged in");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void close() {
|
||||||
|
Log.i(TAG, "stop()");
|
||||||
|
mQueue.stop();
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isLoggedIn() {
|
||||||
|
FirebaseAuth auth = FirebaseAuth.getInstance();
|
||||||
|
if (auth != null) {
|
||||||
|
if (auth.getCurrentUser() != null) {
|
||||||
|
//Log.v(TAG, "isLoggedIn(): Firebase Logged in OK");
|
||||||
|
return (true);
|
||||||
|
} else {
|
||||||
|
//Log.v(TAG, "isLoggedIn(): Current user is null - Firebase not logged in");
|
||||||
|
return (false);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
//Log.v(TAG, "isLoggedIn(): Firebase not logged in");
|
||||||
|
return (false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean getUserProfile(JSONObjectCallback callback) {
|
||||||
|
Log.v(TAG, "getUserProfile()");
|
||||||
|
FirebaseAuth auth = FirebaseAuth.getInstance();
|
||||||
|
if (!isLoggedIn()) {
|
||||||
|
Log.v(TAG, "not logged in - doing nothing");
|
||||||
|
return (false);
|
||||||
|
} else {
|
||||||
|
try {
|
||||||
|
JSONObject retObj = new JSONObject();
|
||||||
|
retObj.put("id",auth.getCurrentUser().getUid());
|
||||||
|
retObj.put("username", auth.getCurrentUser().getDisplayName());
|
||||||
|
retObj.put("email", auth.getCurrentUser().getEmail());
|
||||||
|
callback.accept(retObj);
|
||||||
|
} catch (JSONException e) {
|
||||||
|
Log.e(TAG, "Error Creating retObjObj: " + e.getMessage());
|
||||||
|
mUtil.showToast("Error Creating retObj - this should not happen!!!");
|
||||||
|
return (false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return (true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getStoredToken() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setStoredToken(String s) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Create a new event in the remote database, based on the provided parameters.
|
||||||
|
// passes the newly created documentId to function callback on successful completion, or null on error.
|
||||||
|
public boolean createEvent(final int osdAlarmState, final Date eventDate, final String eventDesc, StringCallback callback) {
|
||||||
|
Log.v(TAG, "createEvent()");
|
||||||
|
String userId = null;
|
||||||
|
|
||||||
|
if (mDb == null) {
|
||||||
|
Log.w(TAG, "createEvent() - mDb is null - not doing anything");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (FirebaseAuth.getInstance().getCurrentUser() == null) {
|
||||||
|
Log.e(TAG, "ERROR: createEvent() - not logged in");
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
userId = FirebaseAuth.getInstance().getCurrentUser().getUid();
|
||||||
|
}
|
||||||
|
Map<String, Object> event = new HashMap<>();
|
||||||
|
event.put("dataTime", eventDate.getTime());
|
||||||
|
event.put("osdAlarmState", osdAlarmState);
|
||||||
|
event.put("desc", eventDesc);
|
||||||
|
event.put("type", null);
|
||||||
|
event.put("subType", null);
|
||||||
|
event.put("userId", userId);
|
||||||
|
|
||||||
|
mDb.collection("Events")
|
||||||
|
.add(event)
|
||||||
|
.addOnSuccessListener(new OnSuccessListener<DocumentReference>() {
|
||||||
|
@Override
|
||||||
|
public void onSuccess(DocumentReference documentReference) {
|
||||||
|
Log.d(TAG, "createEvent.onSuccess() - DocumentSnapshot added with ID: " + documentReference.getId());
|
||||||
|
mServerConnectionOk = true;
|
||||||
|
callback.accept(documentReference.getId());
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.addOnFailureListener(new OnFailureListener() {
|
||||||
|
@Override
|
||||||
|
public void onFailure(@NonNull Exception e) {
|
||||||
|
Log.w(TAG, "createEvent.onFailure() - Error adding document", e);
|
||||||
|
callback.accept(null);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return (true);
|
||||||
|
}
|
||||||
|
|
||||||
|
// calls function callback with a JSONObject representation of the event with id 'eventId'
|
||||||
|
public boolean getEvent(String eventId, JSONObjectCallback callback) {
|
||||||
|
Log.v(TAG, "getEvent()");
|
||||||
|
if (mDb == null) {
|
||||||
|
Log.w(TAG, "getEvent() - mDb is null - not doing anything");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
DocumentReference docRef = mDb
|
||||||
|
.collection("Events").document(eventId);
|
||||||
|
docRef.get().addOnCompleteListener(new OnCompleteListener<DocumentSnapshot>() {
|
||||||
|
@Override
|
||||||
|
public void onComplete(@NonNull Task<DocumentSnapshot> task) {
|
||||||
|
if (task.isSuccessful()) {
|
||||||
|
DocumentSnapshot document = task.getResult();
|
||||||
|
if (document.exists()) {
|
||||||
|
Log.d(TAG, "getEvent.onComplete(): DocumentSnapshot data: " + document.getData());
|
||||||
|
if (document.getData() == null) {
|
||||||
|
callback.accept(null);
|
||||||
|
} else
|
||||||
|
callback.accept(new JSONObject(document.getData()));
|
||||||
|
} else {
|
||||||
|
Log.d(TAG, "No such document");
|
||||||
|
callback.accept(null);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Log.d(TAG, "get failed with ", task.getException());
|
||||||
|
callback.accept(null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return true;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve all events accessible to the logged in user, and pass them to the callback function as a JSONObject
|
||||||
|
*
|
||||||
|
* @param callback
|
||||||
|
* @return true on success or false on failure to initiate the request.
|
||||||
|
*/
|
||||||
|
public boolean getEvents(JSONObjectCallback callback) {
|
||||||
|
//Long eventId=Long.valueOf(285);
|
||||||
|
Log.v(TAG, "getEvents()");
|
||||||
|
if (mDb == null) {
|
||||||
|
Log.w(TAG, "getEvents() - mDb is null - not doing anything");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!isLoggedIn()) {
|
||||||
|
Log.w(TAG, "getEvents() - not logged in - not doing anything");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
String userId = FirebaseAuth.getInstance().getCurrentUser().getUid();
|
||||||
|
mDb.collection("Events") //.where("userId", "==", userId)
|
||||||
|
.whereEqualTo("userId", userId)
|
||||||
|
.orderBy("dataTime", Query.Direction.ASCENDING)
|
||||||
|
.get()
|
||||||
|
.addOnCompleteListener(new OnCompleteListener<QuerySnapshot>() {
|
||||||
|
@Override
|
||||||
|
public void onComplete(@NonNull Task<QuerySnapshot> task) {
|
||||||
|
if (task.isSuccessful()) {
|
||||||
|
try {
|
||||||
|
JSONObject retObj = new JSONObject();
|
||||||
|
JSONArray eventArray = new JSONArray();
|
||||||
|
Log.d(TAG, "getEvents() - returned " + task.getResult().size());
|
||||||
|
for (QueryDocumentSnapshot document : task.getResult()) {
|
||||||
|
Log.d(TAG, "getEvents() - " + document.getId() + " => " + document.getData());
|
||||||
|
JSONObject eventObj = new JSONObject(document.getData());
|
||||||
|
// Add the event id into the event data because firebase does not include it as part of the document.
|
||||||
|
eventObj.put("id", document.getId());
|
||||||
|
eventArray.put(eventObj);
|
||||||
|
}
|
||||||
|
retObj.put("events", eventArray);
|
||||||
|
callback.accept(retObj);
|
||||||
|
} catch (JSONException e) {
|
||||||
|
Log.e(TAG, "getEvents.onResponse(): Error: " + e.getMessage() + "," + e.toString());
|
||||||
|
callback.accept(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
Log.d(TAG, "Error getting documents: ", task.getException());
|
||||||
|
callback.accept(null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return (true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean updateEvent(final JSONObject eventObj, JSONObjectCallback callback) {
|
||||||
|
String eventId;
|
||||||
|
Log.v(TAG, "updateEvent()");
|
||||||
|
if (mDb == null) {
|
||||||
|
Log.w(TAG, "updateEvent() - mDb is null - not doing anything");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
eventId = eventObj.getString("id");
|
||||||
|
} catch (JSONException e) {
|
||||||
|
Log.e(TAG, "updateEvent(): Error reading id from eventObj");
|
||||||
|
eventId = null;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
final String dataStr = eventObj.toString();
|
||||||
|
Log.v(TAG, "updateEvent - data=" + dataStr);
|
||||||
|
Map<String, Object> eventMap = new HashMap<>();
|
||||||
|
try {
|
||||||
|
eventMap.put("dataTime", eventObj.getLong("dataTime"));
|
||||||
|
eventMap.put("osdAlarmState", eventObj.getInt("osdAlarmState"));
|
||||||
|
eventMap.put("desc", eventObj.getString("desc"));
|
||||||
|
eventMap.put("type", eventObj.getString("type"));
|
||||||
|
eventMap.put("subType", eventObj.getString("subType"));
|
||||||
|
eventMap.put("userId", eventObj.getString("userId"));
|
||||||
|
} catch (JSONException e) {
|
||||||
|
Log.e(TAG, "updateEvent(): Error data from eventObj." + e.toString());
|
||||||
|
e.printStackTrace();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
Log.v(TAG, "updateEvent - map=" + eventMap.toString());
|
||||||
|
|
||||||
|
try {
|
||||||
|
DocumentReference docRef = mDb.collection("Events").document(eventId);
|
||||||
|
docRef.set(eventMap)
|
||||||
|
.addOnSuccessListener(new OnSuccessListener<Void>() {
|
||||||
|
@Override
|
||||||
|
public void onSuccess(Void aVoid) {
|
||||||
|
JSONObject retObj;
|
||||||
|
try {
|
||||||
|
retObj = new JSONObject("{\"status\":\"OK\"}");
|
||||||
|
} catch (Exception e) {
|
||||||
|
retObj = null;
|
||||||
|
}
|
||||||
|
callback.accept(retObj);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.addOnFailureListener(new OnFailureListener() {
|
||||||
|
@Override
|
||||||
|
public void onFailure(@NonNull Exception e) {
|
||||||
|
Log.w(TAG, "Error updating document", e);
|
||||||
|
callback.accept(null);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return (true);
|
||||||
|
} catch (Exception e) {
|
||||||
|
Log.e(TAG, "updateEvent() - ERROR: " + e.toString());
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
return (false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean createDatapoint(JSONObject dataObj, String eventId, StringCallback callback) {
|
||||||
|
Log.v(TAG, "createDatapoint()");
|
||||||
|
// Create a new event in the remote database, based on the provided parameters.
|
||||||
|
String userId = null;
|
||||||
|
if (FirebaseAuth.getInstance().getCurrentUser() == null) {
|
||||||
|
Log.e(TAG, "ERROR: createDatapoint() - not logged in");
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
userId = FirebaseAuth.getInstance().getCurrentUser().getUid();
|
||||||
|
}
|
||||||
|
String dataTime;
|
||||||
|
try {
|
||||||
|
dataTime = dataObj.getString("dataTime");
|
||||||
|
} catch (JSONException e) {
|
||||||
|
dataTime = "";
|
||||||
|
}
|
||||||
|
Map<String, Object> datapoint = new HashMap<>();
|
||||||
|
datapoint.put("dataTime", dataTime);
|
||||||
|
datapoint.put("dataJSON", dataObj.toString());
|
||||||
|
datapoint.put("userId", userId);
|
||||||
|
datapoint.put("eventId", userId);
|
||||||
|
|
||||||
|
mDb.collection("Datapoints")
|
||||||
|
.add(datapoint)
|
||||||
|
.addOnSuccessListener(new OnSuccessListener<DocumentReference>() {
|
||||||
|
@Override
|
||||||
|
public void onSuccess(DocumentReference documentReference) {
|
||||||
|
Log.d(TAG, "createDatapoint.onSuccess() - DocumentSnapshot added with ID: " + documentReference.getId());
|
||||||
|
mServerConnectionOk = true;
|
||||||
|
callback.accept(documentReference.getId());
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.addOnFailureListener(new OnFailureListener() {
|
||||||
|
@Override
|
||||||
|
public void onFailure(@NonNull Exception e) {
|
||||||
|
Log.w(TAG, "createDatapoint.onFailure() - Error adding document", e);
|
||||||
|
callback.accept(null);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return (true);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve the file containing the standard event types from the server.
|
||||||
|
* Calls the specified callback function, passing a JSONObject as a parameter when the data has been received and parsed.
|
||||||
|
*
|
||||||
|
* @return true if request sent successfully or else false.
|
||||||
|
*/
|
||||||
|
public boolean getEventTypes(JSONObjectCallback callback) {
|
||||||
|
Log.v(TAG, "getEventTypes()");
|
||||||
|
if (mDb == null) {
|
||||||
|
Log.w(TAG, "getEventTypes() - mDb is null - not doing anything");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
mDb.collection("EventTypes")
|
||||||
|
.get()
|
||||||
|
.addOnCompleteListener(new OnCompleteListener<QuerySnapshot>() {
|
||||||
|
@Override
|
||||||
|
public void onComplete(@NonNull Task<QuerySnapshot> task) {
|
||||||
|
if (task.isSuccessful()) {
|
||||||
|
try {
|
||||||
|
JSONObject retObj = new JSONObject();
|
||||||
|
for (QueryDocumentSnapshot document : task.getResult()) {
|
||||||
|
Log.d(TAG, "getEventTypes.onComplete(): " + document.getId() + " => " + document.getData());
|
||||||
|
Log.v(TAG, "getEventTypes.onComplete() - subtypes=" + document.getData().get("subTypes"));
|
||||||
|
JSONArray subTypesArray = listToJSONArray((List) document.getData().get("subTypes"));
|
||||||
|
retObj.put(document.getData().get("type").toString(), subTypesArray);
|
||||||
|
}
|
||||||
|
Log.d(TAG, "getEventTypes.onComplete() - retObj=" + retObj.toString());
|
||||||
|
callback.accept(retObj);
|
||||||
|
} catch (JSONException e) {
|
||||||
|
Log.e(TAG, "getEventTypes.onResponse(): Error: " + e.getMessage() + "," + e.toString());
|
||||||
|
callback.accept(null);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Log.d(TAG, "Error getting documents: ", task.getException());
|
||||||
|
callback.accept(null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return (true);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private JSONArray listToJSONArray(List<Object> list) {
|
||||||
|
JSONArray arr = new JSONArray();
|
||||||
|
for (Object obj : list) {
|
||||||
|
arr.put(obj);
|
||||||
|
}
|
||||||
|
return arr;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve a trivial file from the server to check we have a good server connection.
|
||||||
|
* sets mServerConnectionOk.
|
||||||
|
*
|
||||||
|
* @return true if request sent successfully or else false.
|
||||||
|
*/
|
||||||
|
public boolean checkServerConnection() {
|
||||||
|
//FIXME There must be a Firebase function for this?
|
||||||
|
mServerConnectionOk = true;
|
||||||
|
return mServerConnectionOk;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,663 @@
|
|||||||
|
package uk.org.openseizuredetector;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.os.Handler;
|
||||||
|
import android.util.Log;
|
||||||
|
|
||||||
|
import com.android.volley.AuthFailureError;
|
||||||
|
import com.android.volley.Request;
|
||||||
|
import com.android.volley.RequestQueue;
|
||||||
|
import com.android.volley.Response;
|
||||||
|
import com.android.volley.VolleyError;
|
||||||
|
import com.android.volley.VolleyLog;
|
||||||
|
import com.android.volley.toolbox.StringRequest;
|
||||||
|
import com.android.volley.toolbox.Volley;
|
||||||
|
|
||||||
|
import org.json.JSONArray;
|
||||||
|
import org.json.JSONException;
|
||||||
|
import org.json.JSONObject;
|
||||||
|
|
||||||
|
import java.io.UnsupportedEncodingException;
|
||||||
|
import java.text.DateFormat;
|
||||||
|
import java.text.SimpleDateFormat;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
|
||||||
|
// This class is intended to handle all interactions with the OSD WebAPI
|
||||||
|
public class WebApiConnection_osdapi extends WebApiConnection {
|
||||||
|
public String retVal;
|
||||||
|
public int retCode;
|
||||||
|
public boolean mServerConnectionOk = false;
|
||||||
|
private String mUrlBase = "https://osdApi.ddns.net";
|
||||||
|
private String TAG = "WebApiConnection_osdapi";
|
||||||
|
RequestQueue mQueue;
|
||||||
|
|
||||||
|
public WebApiConnection_osdapi(Context context) {
|
||||||
|
super(context);
|
||||||
|
mQueue = Volley.newRequestQueue(context);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void close() {
|
||||||
|
super.close();
|
||||||
|
Log.i(TAG,"stop()");
|
||||||
|
mQueue.stop();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Attempt to authenticate with the web API using user name uname and password passwd. Calls function callback with either
|
||||||
|
* the authentication token on success or null on failure.
|
||||||
|
*
|
||||||
|
* @param uname - user name
|
||||||
|
* @param passwd - password
|
||||||
|
* @param callback - call back function callback(String retVal)
|
||||||
|
* @return true if request sent, or false if failed to send request.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public boolean authenticate(final String uname, final String passwd, StringCallback callback) {
|
||||||
|
// NOTE: the 'final' keyword is necessary for uname and passwd to be accessible to getParams below - I don't know why!
|
||||||
|
// We know that this command works, so we just need the Java equivalent:
|
||||||
|
// curl -X POST -d 'login=graham4&password=testpwd1' https://osdapi.ddns.net/api/accounts/login/
|
||||||
|
// sending the credentials as a JSONObject postData did not work, so try the method from:
|
||||||
|
// https://protocoderspoint.com/login-and-registration-form-in-android-using-volley-keeping-user-logged-in/#Login_Registration_form_in_android_using_volley_library
|
||||||
|
String urlStr = mUrlBase + "/api/accounts/login/";
|
||||||
|
Log.v(TAG, "urlStr=" + urlStr);
|
||||||
|
|
||||||
|
StringRequest req = new StringRequest(Request.Method.POST, urlStr,
|
||||||
|
new Response.Listener<String>() {
|
||||||
|
@Override
|
||||||
|
public void onResponse(String response) {
|
||||||
|
String tokenStr = null;
|
||||||
|
Log.v(TAG, "Response is: " + response);
|
||||||
|
try {
|
||||||
|
JSONObject jo = new JSONObject(response);
|
||||||
|
tokenStr = jo.getString("token");
|
||||||
|
mServerConnectionOk = true;
|
||||||
|
} catch (JSONException e) {
|
||||||
|
tokenStr = "Error Parsing Rsponse";
|
||||||
|
}
|
||||||
|
setStoredToken(tokenStr);
|
||||||
|
callback.accept(tokenStr);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
new Response.ErrorListener() {
|
||||||
|
@Override
|
||||||
|
public void onErrorResponse(VolleyError error) {
|
||||||
|
if (error != null) {
|
||||||
|
Log.e(TAG, "Login Error: " + error.toString() + ", message:" + error.getMessage());
|
||||||
|
} else {
|
||||||
|
Log.e(TAG, "Login Error: Returned null response");
|
||||||
|
}
|
||||||
|
mServerConnectionOk = false;
|
||||||
|
setStoredToken(null);
|
||||||
|
callback.accept(null);
|
||||||
|
}
|
||||||
|
}) {
|
||||||
|
// Note, this is overriding part of StringRequest, not one of the sub-classes above!
|
||||||
|
@Override
|
||||||
|
protected Map<String, String> getParams() {
|
||||||
|
Map<String, String> params = new HashMap<>();
|
||||||
|
// params.put("name",sname); // passing parameters to server
|
||||||
|
params.put("login", uname);
|
||||||
|
params.put("password", passwd);
|
||||||
|
return params;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
mQueue.add(req);
|
||||||
|
return (true);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public boolean isLoggedIn() {
|
||||||
|
String authToken = getStoredToken();
|
||||||
|
Log.v(TAG, "isLoggedIn(): token=" + authToken);
|
||||||
|
if (authToken == null || authToken.length() == 0) {
|
||||||
|
Log.v(TAG, "isLogged in - not logged in");
|
||||||
|
return (false);
|
||||||
|
} else {
|
||||||
|
Log.v(TAG,"isLoggedIn - logged in ok");
|
||||||
|
return (true);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Create a new event in the remote database, based on the provided parameters.
|
||||||
|
public boolean createEvent(final int osdAlarmState, final Date eventDate, final String eventDesc, StringCallback callback) {
|
||||||
|
Log.v(TAG, "createEvent()");
|
||||||
|
String urlStr = mUrlBase + "/api/events/";
|
||||||
|
Log.v(TAG, "urlStr=" + urlStr);
|
||||||
|
final String authtoken = getStoredToken();
|
||||||
|
|
||||||
|
if (!isLoggedIn()) {
|
||||||
|
Log.v(TAG, "not logged in - doing nothing");
|
||||||
|
return (false);
|
||||||
|
}
|
||||||
|
DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
|
||||||
|
JSONObject jsonObject = new JSONObject();
|
||||||
|
try {
|
||||||
|
jsonObject.put("osdAlarmState", String.valueOf(osdAlarmState));
|
||||||
|
jsonObject.put("dataTime", dateFormat.format(eventDate));
|
||||||
|
jsonObject.put("desc", eventDesc);
|
||||||
|
} catch (JSONException e) {
|
||||||
|
Log.e(TAG, "Error generating event JSON string");
|
||||||
|
}
|
||||||
|
final String dataStr = jsonObject.toString();
|
||||||
|
Log.v(TAG, "createEvent - data=" + dataStr);
|
||||||
|
|
||||||
|
StringRequest req = new StringRequest(Request.Method.POST, urlStr,
|
||||||
|
new Response.Listener<String>() {
|
||||||
|
@Override
|
||||||
|
public void onResponse(String response) {
|
||||||
|
Log.v(TAG, "createEvent.onResponse - Response is: " + response);
|
||||||
|
mServerConnectionOk = true;
|
||||||
|
// we return just the eventId to be consistent with the firebase version of WebApiConnection.
|
||||||
|
String retVal = null;
|
||||||
|
try {
|
||||||
|
JSONObject retObj = new JSONObject(response);
|
||||||
|
retVal = retObj.getString("id");
|
||||||
|
} catch (JSONException e) {
|
||||||
|
Log.e(TAG, "createEvent.onResponse(): Error: " + e.getMessage() + "," + e.toString());
|
||||||
|
retVal = null;
|
||||||
|
}
|
||||||
|
callback.accept(retVal);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
new Response.ErrorListener() {
|
||||||
|
@Override
|
||||||
|
public void onErrorResponse(VolleyError error) {
|
||||||
|
mServerConnectionOk = false;
|
||||||
|
if (error != null) {
|
||||||
|
Log.e(TAG, "createEvent Error: " + error.toString() + ", message:" + error.getMessage());
|
||||||
|
callback.accept(null);
|
||||||
|
} else {
|
||||||
|
Log.e(TAG, "createEvent Error - null response");
|
||||||
|
callback.accept(null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}) {
|
||||||
|
// Note, this is overriding part of StringRequest, not one of the sub-classes above!
|
||||||
|
@Override
|
||||||
|
protected Map<String, String> getParams() {
|
||||||
|
Map<String, String> params = new HashMap<>();
|
||||||
|
// params.put("name",sname); // passing parameters to server
|
||||||
|
String authToken = getStoredToken();
|
||||||
|
params.put("Authorization: Token " + authToken, authToken);
|
||||||
|
Log.v(TAG, "getParams: params=" + params.toString());
|
||||||
|
return params;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Map<String, String> getHeaders() throws AuthFailureError {
|
||||||
|
Map<String, String> params = new HashMap<String, String>();
|
||||||
|
params.put("Content-Type", "application/json; charset=UTF-8");
|
||||||
|
params.put("Authorization", "Token " + getStoredToken());
|
||||||
|
return params;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public byte[] getBody() throws AuthFailureError {
|
||||||
|
try {
|
||||||
|
return dataStr == null ? null : dataStr.getBytes("utf-8");
|
||||||
|
} catch (UnsupportedEncodingException uee) {
|
||||||
|
VolleyLog.wtf("Unsupported Encoding while trying to get the bytes of %s using %s", dataStr, "utf-8");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
mQueue.add(req);
|
||||||
|
return (true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean getEvent(String eventId, JSONObjectCallback callback) {
|
||||||
|
Log.v(TAG, "getEvent()");
|
||||||
|
String urlStr = mUrlBase + "/api/events/" + eventId;
|
||||||
|
Log.v(TAG, "getEvent(): urlStr=" + urlStr);
|
||||||
|
final String authtoken = getStoredToken();
|
||||||
|
|
||||||
|
if (!isLoggedIn()) {
|
||||||
|
Log.v(TAG, "not logged in - doing nothing");
|
||||||
|
return (false);
|
||||||
|
}
|
||||||
|
|
||||||
|
StringRequest req = new StringRequest(Request.Method.GET, urlStr,
|
||||||
|
new Response.Listener<String>() {
|
||||||
|
@Override
|
||||||
|
public void onResponse(String response) {
|
||||||
|
Log.v(TAG, "Response is: " + response);
|
||||||
|
try {
|
||||||
|
JSONObject retObj = new JSONObject(response);
|
||||||
|
retObj.put("alarmStateStr", mUtil.alarmStatusToString(retObj.getInt("osdAlarmState")));
|
||||||
|
callback.accept(retObj);
|
||||||
|
} catch (JSONException e) {
|
||||||
|
Log.e(TAG, "getEventTypes.onRespons(): Error: " + e.getMessage() + "," + e.toString());
|
||||||
|
callback.accept(null);
|
||||||
|
}
|
||||||
|
mServerConnectionOk = true;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
new Response.ErrorListener() {
|
||||||
|
@Override
|
||||||
|
public void onErrorResponse(VolleyError error) {
|
||||||
|
if (error != null) {
|
||||||
|
Log.e(TAG, "Create Event Error: " + error.toString() + ", message:" + error.getMessage());
|
||||||
|
} else {
|
||||||
|
Log.e(TAG, "Create Event Error: returned null response");
|
||||||
|
}
|
||||||
|
mServerConnectionOk = false;
|
||||||
|
callback.accept(null);
|
||||||
|
}
|
||||||
|
}) {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Map<String, String> getHeaders() throws AuthFailureError {
|
||||||
|
Map<String, String> params = new HashMap<String, String>();
|
||||||
|
params.put("Content-Type", "application/json; charset=UTF-8");
|
||||||
|
params.put("Authorization", "Token " + getStoredToken());
|
||||||
|
return params;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
mQueue.add(req);
|
||||||
|
return (true);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve all events accessible to the logged in user, and pass them to the callback function as a JSONObject
|
||||||
|
*
|
||||||
|
* @param callback
|
||||||
|
* @return true on success or false on failure to initiate the request.
|
||||||
|
*/
|
||||||
|
public boolean getEvents(JSONObjectCallback callback) {
|
||||||
|
Log.v(TAG, "getEvents()");
|
||||||
|
String urlStr = mUrlBase + "/api/events/";
|
||||||
|
Log.v(TAG, "getEvents(): urlStr=" + urlStr);
|
||||||
|
final String authtoken = getStoredToken();
|
||||||
|
|
||||||
|
if (!isLoggedIn()) {
|
||||||
|
Log.v(TAG, "not logged in - doing nothing");
|
||||||
|
return (false);
|
||||||
|
}
|
||||||
|
|
||||||
|
StringRequest req = new StringRequest(Request.Method.GET, urlStr,
|
||||||
|
new Response.Listener<String>() {
|
||||||
|
@Override
|
||||||
|
public void onResponse(String response) {
|
||||||
|
Log.v(TAG, "Response is: " + response);
|
||||||
|
mServerConnectionOk = true;
|
||||||
|
try {
|
||||||
|
JSONObject retObj = new JSONObject();
|
||||||
|
JSONArray eventArray = new JSONArray(response);
|
||||||
|
retObj.put("events", eventArray);
|
||||||
|
callback.accept(retObj);
|
||||||
|
} catch (JSONException e) {
|
||||||
|
Log.e(TAG, "getEventTypes.onRespons(): Error: " + e.getMessage() + "," + e.toString());
|
||||||
|
callback.accept(null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
new Response.ErrorListener() {
|
||||||
|
@Override
|
||||||
|
public void onErrorResponse(VolleyError error) {
|
||||||
|
//if ((error != null) && (error.networkResponse != null) && (error.networkResponse.data != null)) {#
|
||||||
|
mServerConnectionOk = false;
|
||||||
|
if (error != null) {
|
||||||
|
if (error.networkResponse != null) {
|
||||||
|
Log.e(TAG, "getEvents(): Error: " + error.toString() + ", message:" + error.getMessage());
|
||||||
|
} else {
|
||||||
|
Log.e(TAG, "getEvents(): Error: - request returned null networkResponse");
|
||||||
|
}
|
||||||
|
} else{
|
||||||
|
Log.e(TAG, "getEvents(): Error: - request returned null response");
|
||||||
|
}
|
||||||
|
callback.accept(null);
|
||||||
|
}
|
||||||
|
}) {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Map<String, String> getHeaders() throws AuthFailureError {
|
||||||
|
Map<String, String> params = new HashMap<String, String>();
|
||||||
|
params.put("Content-Type", "application/json; charset=UTF-8");
|
||||||
|
params.put("Authorization", "Token " + getStoredToken());
|
||||||
|
return params;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
mQueue.add(req);
|
||||||
|
return (true);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public boolean updateEvent(final JSONObject eventObj, JSONObjectCallback callback) {
|
||||||
|
String eventId;
|
||||||
|
Log.v(TAG, "updateEvent()");
|
||||||
|
final String authtoken = getStoredToken();
|
||||||
|
|
||||||
|
if (!isLoggedIn()) {
|
||||||
|
Log.v(TAG, "not logged in - doing nothing");
|
||||||
|
return (false);
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
eventId = eventObj.getString("id");
|
||||||
|
} catch (JSONException e) {
|
||||||
|
Log.e(TAG, "updateEvent(): Error reading id from eventObj");
|
||||||
|
eventId = null;
|
||||||
|
}
|
||||||
|
final String dataStr = eventObj.toString();
|
||||||
|
Log.v(TAG, "updateEvent - data=" + dataStr);
|
||||||
|
|
||||||
|
int reqMethod;
|
||||||
|
String urlStr;
|
||||||
|
if (eventId != null) {
|
||||||
|
Log.v(TAG, "updateEvent() - found eventId " + eventId + ", Updating event record");
|
||||||
|
urlStr = mUrlBase + "/api/events/" + eventId + "/";
|
||||||
|
Log.v(TAG, "urlStr=" + urlStr);
|
||||||
|
reqMethod = Request.Method.PUT;
|
||||||
|
} else {
|
||||||
|
Log.v(TAG, "updateEvent() - eventId not found - creating new event record");
|
||||||
|
urlStr = mUrlBase + "/api/events/";
|
||||||
|
Log.v(TAG, "urlStr=" + urlStr);
|
||||||
|
reqMethod = Request.Method.POST;
|
||||||
|
}
|
||||||
|
|
||||||
|
StringRequest req = new StringRequest(reqMethod, urlStr,
|
||||||
|
new Response.Listener<String>() {
|
||||||
|
@Override
|
||||||
|
public void onResponse(String response) {
|
||||||
|
Log.v(TAG, "Response is: " + response);
|
||||||
|
mServerConnectionOk = true;
|
||||||
|
try {
|
||||||
|
JSONObject retObj = new JSONObject(response);
|
||||||
|
callback.accept(retObj);
|
||||||
|
} catch (JSONException e) {
|
||||||
|
Log.e(TAG, "getEventTypes.onRespons(): Error: " + e.getMessage() + "," + e.toString());
|
||||||
|
callback.accept(null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
new Response.ErrorListener() {
|
||||||
|
@Override
|
||||||
|
public void onErrorResponse(VolleyError error) {
|
||||||
|
mServerConnectionOk = false;
|
||||||
|
if (error != null) {
|
||||||
|
Log.e(TAG, "Create Event Error: " + error.toString() + ", message:" + error.getMessage());
|
||||||
|
} else {
|
||||||
|
Log.e(TAG, "Create Event Error - returned null response");
|
||||||
|
}
|
||||||
|
callback.accept(null);
|
||||||
|
}
|
||||||
|
}) {
|
||||||
|
// Note, this is overriding part of StringRequest, not one of the sub-classes above!
|
||||||
|
@Override
|
||||||
|
protected Map<String, String> getParams() {
|
||||||
|
Map<String, String> params = new HashMap<>();
|
||||||
|
// params.put("name",sname); // passing parameters to server
|
||||||
|
String authToken = getStoredToken();
|
||||||
|
params.put("Authorization: Token " + authToken, authToken);
|
||||||
|
Log.v(TAG, "getParams: params=" + params.toString());
|
||||||
|
//params.put("eventType", String.valueOf(eventType));
|
||||||
|
//params.put("dataTime", dateFormat.format(eventDate));
|
||||||
|
//params.put("desc", eventDesc);
|
||||||
|
return params;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Map<String, String> getHeaders() throws AuthFailureError {
|
||||||
|
Map<String, String> params = new HashMap<String, String>();
|
||||||
|
params.put("Content-Type", "application/json; charset=UTF-8");
|
||||||
|
params.put("Authorization", "Token " + getStoredToken());
|
||||||
|
return params;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public byte[] getBody() throws AuthFailureError {
|
||||||
|
try {
|
||||||
|
return dataStr == null ? null : dataStr.getBytes("utf-8");
|
||||||
|
} catch (UnsupportedEncodingException uee) {
|
||||||
|
VolleyLog.wtf("Unsupported Encoding while trying to get the bytes of %s using %s", dataStr, "utf-8");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
mQueue.add(req);
|
||||||
|
return (true);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public boolean createDatapoint(JSONObject dataObj, String eventId, StringCallback callback) {
|
||||||
|
Log.v(TAG, "createDatapoint()");
|
||||||
|
// Create a new event in the remote database, based on the provided parameters.
|
||||||
|
String urlStr = mUrlBase + "/api/datapoints/";
|
||||||
|
Log.v(TAG, "urlStr=" + urlStr);
|
||||||
|
final String authtoken = getStoredToken();
|
||||||
|
|
||||||
|
if (!isLoggedIn()) {
|
||||||
|
Log.v(TAG, "not logged in - doing nothing");
|
||||||
|
return (false);
|
||||||
|
}
|
||||||
|
|
||||||
|
DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
|
||||||
|
JSONObject jsonObject = new JSONObject();
|
||||||
|
try {
|
||||||
|
//jsonObject.put("userId", -1);
|
||||||
|
jsonObject.put("eventId", String.valueOf(eventId));
|
||||||
|
jsonObject.put("dataTime", dataObj.getString("dataTime"));
|
||||||
|
jsonObject.put("dataJSON", dataObj.toString());
|
||||||
|
} catch (JSONException e) {
|
||||||
|
Log.e(TAG, "Error generating event JSON string");
|
||||||
|
}
|
||||||
|
final String dataStr = jsonObject.toString();
|
||||||
|
Log.v(TAG, "createDatapoint - dataStr=" + dataStr);
|
||||||
|
|
||||||
|
|
||||||
|
StringRequest req = new StringRequest(Request.Method.POST, urlStr,
|
||||||
|
new Response.Listener<String>() {
|
||||||
|
@Override
|
||||||
|
public void onResponse(String response) {
|
||||||
|
Log.v(TAG, "Response is: " + response);
|
||||||
|
mServerConnectionOk = true;
|
||||||
|
callback.accept(response);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
new Response.ErrorListener() {
|
||||||
|
@Override
|
||||||
|
public void onErrorResponse(VolleyError error) {
|
||||||
|
mServerConnectionOk = false;
|
||||||
|
if (error != null) {
|
||||||
|
Log.e(TAG, "Create Datapoint Error: " + error.toString() + ", message:" + error.getMessage());
|
||||||
|
callback.accept(null);
|
||||||
|
} else {
|
||||||
|
Log.e(TAG, "Create Datapoint Error - returned null respones");
|
||||||
|
callback.accept(null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}) {
|
||||||
|
// Note, this is overriding part of StringRequest, not one of the sub-classes above!
|
||||||
|
@Override
|
||||||
|
protected Map<String, String> getParams() {
|
||||||
|
Map<String, String> params = new HashMap<>();
|
||||||
|
// params.put("name",sname); // passing parameters to server
|
||||||
|
String authToken = getStoredToken();
|
||||||
|
params.put("Authorization: Token " + authToken, authToken);
|
||||||
|
Log.v(TAG, "getParams: params=" + params.toString());
|
||||||
|
return params;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Map<String, String> getHeaders() throws AuthFailureError {
|
||||||
|
Map<String, String> params = new HashMap<String, String>();
|
||||||
|
params.put("Content-Type", "application/json; charset=UTF-8");
|
||||||
|
params.put("Authorization", "Token " + getStoredToken());
|
||||||
|
return params;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public byte[] getBody() throws AuthFailureError {
|
||||||
|
try {
|
||||||
|
return dataStr == null ? null : dataStr.getBytes("utf-8");
|
||||||
|
} catch (UnsupportedEncodingException uee) {
|
||||||
|
VolleyLog.wtf("Unsupported Encoding while trying to get the bytes of %s using %s", dataStr, "utf-8");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
mQueue.add(req);
|
||||||
|
return (true);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retieve the user profile of the authenticated user from the server, and return it to the callback function.
|
||||||
|
* @param callback - function to be called with a JSONObject as a parameter that contains the user profile data.
|
||||||
|
* @return true if request sent successfully, or else false.
|
||||||
|
*/
|
||||||
|
public boolean getUserProfile(JSONObjectCallback callback) {
|
||||||
|
Log.v(TAG, "getUserProfile()");
|
||||||
|
String urlStr = mUrlBase + "/api/accounts/profile/";
|
||||||
|
Log.v(TAG, "getUserProfile(): urlStr=" + urlStr);
|
||||||
|
final String authtoken = getStoredToken();
|
||||||
|
|
||||||
|
if (!isLoggedIn()) {
|
||||||
|
Log.v(TAG, "not logged in - doing nothing");
|
||||||
|
return (false);
|
||||||
|
}
|
||||||
|
|
||||||
|
StringRequest req = new StringRequest(Request.Method.GET, urlStr,
|
||||||
|
new Response.Listener<String>() {
|
||||||
|
@Override
|
||||||
|
public void onResponse(String response) {
|
||||||
|
Log.v(TAG, "Response is: " + response);
|
||||||
|
try {
|
||||||
|
JSONObject retObj = new JSONObject(response);
|
||||||
|
callback.accept(retObj);
|
||||||
|
} catch (JSONException e) {
|
||||||
|
Log.e(TAG, "getUserProfile.onResponse(): Error: " + e.getMessage() + "," + e.toString());
|
||||||
|
callback.accept(null);
|
||||||
|
}
|
||||||
|
mServerConnectionOk = true;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
new Response.ErrorListener() {
|
||||||
|
@Override
|
||||||
|
public void onErrorResponse(VolleyError error) {
|
||||||
|
if (error != null) {
|
||||||
|
Log.e(TAG, "Create Event Error: " + error.toString() + ", message:" + error.getMessage());
|
||||||
|
} else {
|
||||||
|
Log.e(TAG, "Create Event Error: returned null response");
|
||||||
|
}
|
||||||
|
mServerConnectionOk = false;
|
||||||
|
callback.accept(null);
|
||||||
|
}
|
||||||
|
}) {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Map<String, String> getHeaders() throws AuthFailureError {
|
||||||
|
Map<String, String> params = new HashMap<String, String>();
|
||||||
|
params.put("Content-Type", "application/json; charset=UTF-8");
|
||||||
|
params.put("Authorization", "Token " + getStoredToken());
|
||||||
|
return params;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
mQueue.add(req);
|
||||||
|
return (true);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve the file containing the standard event types from the server.
|
||||||
|
* Calls the specified callback function, passing a JSONObject as a parameter when the data has been received and parsed.
|
||||||
|
*
|
||||||
|
* @return true if request sent successfully or else false.
|
||||||
|
*/
|
||||||
|
public boolean getEventTypes(JSONObjectCallback callback) {
|
||||||
|
Log.v(TAG, "getEventTypes()");
|
||||||
|
String urlStr = mUrlBase + "/static/eventTypes.json";
|
||||||
|
Log.v(TAG, "urlStr=" + urlStr);
|
||||||
|
final String authtoken = getStoredToken();
|
||||||
|
|
||||||
|
if (!isLoggedIn()) {
|
||||||
|
Log.v(TAG, "not logged in - doing nothing");
|
||||||
|
return (false);
|
||||||
|
}
|
||||||
|
|
||||||
|
StringRequest req = new StringRequest(Request.Method.GET, urlStr,
|
||||||
|
new Response.Listener<String>() {
|
||||||
|
@Override
|
||||||
|
public void onResponse(String response) {
|
||||||
|
Log.v(TAG, "getEventTypes.onResponse(): Response is: " + response);
|
||||||
|
mServerConnectionOk = true;
|
||||||
|
try {
|
||||||
|
JSONObject retObj = new JSONObject(response);
|
||||||
|
callback.accept(retObj);
|
||||||
|
} catch (JSONException e) {
|
||||||
|
Log.e(TAG, "getEventTypes.onRespons(): Error: " + e.getMessage() + "," + e.toString());
|
||||||
|
callback.accept(null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
new Response.ErrorListener() {
|
||||||
|
@Override
|
||||||
|
public void onErrorResponse(VolleyError error) {
|
||||||
|
mServerConnectionOk = false;
|
||||||
|
if (error != null) {
|
||||||
|
Log.e(TAG, "getEventTypes.onErrorResponse(): " + error.toString() + ", message:" + error.getMessage());
|
||||||
|
} else {
|
||||||
|
Log.e(TAG, "getEventTypes.onErrorResponse() - returned null response");
|
||||||
|
}
|
||||||
|
callback.accept(null);
|
||||||
|
}
|
||||||
|
}) {
|
||||||
|
// Note, this is overriding part of StringRequest, not one of the sub-classes above!
|
||||||
|
@Override
|
||||||
|
public Map<String, String> getHeaders() throws AuthFailureError {
|
||||||
|
Map<String, String> params = new HashMap<String, String>();
|
||||||
|
params.put("Content-Type", "application/json; charset=UTF-8");
|
||||||
|
params.put("Authorization", "Token " + getStoredToken());
|
||||||
|
return params;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
mQueue.add(req);
|
||||||
|
return (true);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve a trivial file from the server to check we have a good server connection.
|
||||||
|
* sets mServerConnectionOk.
|
||||||
|
* @return true if request sent successfully or else false.
|
||||||
|
*/
|
||||||
|
public boolean checkServerConnection() {
|
||||||
|
Log.v(TAG, "checkServerConnection()");
|
||||||
|
String urlStr = mUrlBase + "/static/test.txt";
|
||||||
|
Log.v(TAG, "urlStr=" + urlStr);
|
||||||
|
|
||||||
|
StringRequest req = new StringRequest(Request.Method.GET, urlStr,
|
||||||
|
new Response.Listener<String>() {
|
||||||
|
@Override
|
||||||
|
public void onResponse(String response) {
|
||||||
|
Log.v(TAG, "checkServerConnection.onResponse(): Response is: " + response);
|
||||||
|
mServerConnectionOk = true;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
new Response.ErrorListener() {
|
||||||
|
@Override
|
||||||
|
public void onErrorResponse(VolleyError error) {
|
||||||
|
Log.v(TAG, "checkServerConnection.onErrorResponse");
|
||||||
|
mServerConnectionOk = false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
mQueue.add(req);
|
||||||
|
return (true);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -31,6 +31,36 @@
|
|||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:orientation="vertical">
|
android:orientation="vertical">
|
||||||
|
|
||||||
|
|
||||||
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:layout_width="fill_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="horizontal">
|
||||||
|
|
||||||
|
<Button
|
||||||
|
android:id="@+id/cancelBtn"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:text="@string/back" />
|
||||||
|
|
||||||
|
<Button
|
||||||
|
android:id="@+id/loginBtn"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:text="@string/authenticate" />
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:id="@+id/login_osdapi_ui"
|
||||||
|
android:layout_width="fill_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="vertical">
|
||||||
|
|
||||||
<EditText
|
<EditText
|
||||||
android:id="@+id/username"
|
android:id="@+id/username"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
@@ -53,30 +83,12 @@
|
|||||||
android:hint="password"
|
android:hint="password"
|
||||||
android:inputType="textPassword" />
|
android:inputType="textPassword" />
|
||||||
|
|
||||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
android:layout_width="fill_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:orientation="horizontal">
|
|
||||||
|
|
||||||
<Button
|
|
||||||
android:id="@+id/cancelBtn"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_weight="1"
|
|
||||||
android:text="@string/back" />
|
|
||||||
|
|
||||||
<Button
|
|
||||||
android:id="@+id/OKBtn"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_weight="1"
|
|
||||||
android:text="@string/authenticate" />
|
|
||||||
</LinearLayout>
|
|
||||||
|
|
||||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
android:layout_width="fill_parent"
|
android:layout_width="fill_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:orientation="horizontal">
|
android:orientation="horizontal"
|
||||||
|
>
|
||||||
|
|
||||||
<Button
|
<Button
|
||||||
android:id="@+id/RegisterBtn"
|
android:id="@+id/RegisterBtn"
|
||||||
@@ -94,6 +106,8 @@
|
|||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:id="@+id/logout_ui"
|
android:id="@+id/logout_ui"
|
||||||
android:layout_width="fill_parent"
|
android:layout_width="fill_parent"
|
||||||
@@ -117,6 +131,12 @@
|
|||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:textAppearance="?android:attr/textAppearanceLarge"
|
android:textAppearance="?android:attr/textAppearanceLarge"
|
||||||
android:text="userId" />
|
android:text="userId" />
|
||||||
|
</LinearLayout>
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="horizontal">
|
||||||
|
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
@@ -139,12 +159,6 @@
|
|||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
<!--<TextView
|
|
||||||
android:id="@+id/tokenTv"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:text="@string/logged_in_with_token" />
|
|
||||||
-->
|
|
||||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
android:layout_width="fill_parent"
|
android:layout_width="fill_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
@@ -164,25 +178,6 @@
|
|||||||
android:layout_weight="1"
|
android:layout_weight="1"
|
||||||
android:text="@string/logout" />
|
android:text="@string/logout" />
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
<!--
|
|
||||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
android:layout_width="fill_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:orientation="horizontal">
|
|
||||||
|
|
||||||
<Button
|
|
||||||
android:id="@+id/createEventBtn"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_weight="1"
|
|
||||||
android:text="Create Event" />
|
|
||||||
|
|
||||||
<Button
|
|
||||||
android:id="@+id/createDatapointBtn"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_weight="1"
|
|
||||||
android:text="Prune Database" />
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
android:layout_width="fill_parent"
|
android:layout_width="fill_parent"
|
||||||
@@ -190,14 +185,22 @@
|
|||||||
android:orientation="horizontal">
|
android:orientation="horizontal">
|
||||||
|
|
||||||
<Button
|
<Button
|
||||||
android:id="@+id/getLocalEventsBtn"
|
android:id="@+id/aboutDataSharingBtn"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_weight="1"
|
android:layout_weight="1"
|
||||||
android:text="getLocalEvents" />
|
android:text="@string/about_data_sharing" />
|
||||||
|
|
||||||
|
<Button
|
||||||
|
android:id="@+id/privacyPolicyBtn"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:text="@string/privacy_policy" />
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
-->
|
|
||||||
</LinearLayout>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
@@ -17,7 +17,7 @@
|
|||||||
android:text="@string/cancel" />
|
android:text="@string/cancel" />
|
||||||
|
|
||||||
<Button
|
<Button
|
||||||
android:id="@+id/OKBtn"
|
android:id="@+id/loginBtn"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_weight="1"
|
android:layout_weight="1"
|
||||||
|
|||||||
@@ -96,7 +96,7 @@
|
|||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:orientation="horizontal">
|
android:orientation="horizontal">
|
||||||
<Button
|
<Button
|
||||||
android:id="@+id/OKBtn"
|
android:id="@+id/loginBtn"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:text="@string/okBtnTxt" />
|
android:text="@string/okBtnTxt" />
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
android:orientation="vertical" android:layout_width="match_parent"
|
android:orientation="vertical" android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent">
|
android:layout_height="match_parent">
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:layout_width="fill_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:orientation="horizontal">
|
android:orientation="horizontal">
|
||||||
<TextView
|
<TextView
|
||||||
|
|||||||
@@ -5,19 +5,12 @@
|
|||||||
android:orientation="vertical">
|
android:orientation="vertical">
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:layout_width="fill_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:orientation="horizontal">
|
android:orientation="horizontal">
|
||||||
<TextView
|
|
||||||
android:id="@+id/event_id_remote_tv"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginRight="10dp"
|
|
||||||
android:textAppearance="?android:attr/textAppearanceLarge" />
|
|
||||||
android:text="eventId" />
|
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:layout_width="fill_parent"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:orientation="vertical">
|
android:orientation="vertical">
|
||||||
|
|
||||||
@@ -25,8 +18,8 @@
|
|||||||
android:id="@+id/event_date_remote_tv"
|
android:id="@+id/event_date_remote_tv"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:textStyle="bold"
|
android:text="date"
|
||||||
android:text="date" />
|
android:textStyle="bold" />
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:layout_width="fill_parent"
|
android:layout_width="fill_parent"
|
||||||
@@ -37,8 +30,8 @@
|
|||||||
android:id="@+id/event_type_remote_tv"
|
android:id="@+id/event_type_remote_tv"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:textStyle="bold"
|
android:text="---"
|
||||||
android:text="---" />
|
android:textStyle="bold" />
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
@@ -52,24 +45,27 @@
|
|||||||
android:text="---" />
|
android:text="---" />
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/event_alarmState_remote_tv"
|
android:id="@+id/event_alarmState_remote_tv"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:text="alarm" />
|
android:text="alarm" />
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
|
android:id="@+id/event_notes_remote_tv"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:text="notes"
|
android:text="notes"
|
||||||
android:textStyle="italic"
|
android:textStyle="italic" />
|
||||||
android:id="@+id/event_notes_remote_tv" />
|
|
||||||
|
|
||||||
<!-- <TextView
|
<TextView
|
||||||
|
android:id="@+id/event_id_remote_tv"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:text="dataJSON"
|
android:layout_marginRight="10dp"
|
||||||
android:id="@+id/event_dataJSON" />
|
android:textAppearance="?android:attr/textAppearanceSmall" />
|
||||||
-->
|
android:text="eventId" />
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
@@ -3,6 +3,8 @@
|
|||||||
<string name="app_name">OpenSeizureDetector</string>
|
<string name="app_name">OpenSeizureDetector</string>
|
||||||
<string name="changelog">
|
<string name="changelog">
|
||||||
"\n
|
"\n
|
||||||
|
\nV4.1.1 - Changed remote database to be compatible with either OSD webAPI or future Firebase database.<br/>
|
||||||
|
- Performance improvement by having separate events and datapoints tables in local database
|
||||||
\nV4.0.1 - fixed crash in Report Seizure function
|
\nV4.0.1 - fixed crash in Report Seizure function
|
||||||
\nV4.0.0
|
\nV4.0.0
|
||||||
- Introduced the <b>Data Sharing</b> feature to allow users to share their seizure and false alarm data
|
- Introduced the <b>Data Sharing</b> feature to allow users to share their seizure and false alarm data
|
||||||
@@ -370,7 +372,7 @@
|
|||||||
<string name="check_seizures_message">Please select the events highlighted in pink to say if they are real seizures or false alarms</string>
|
<string name="check_seizures_message">Please select the events highlighted in pink to say if they are real seizures or false alarms</string>
|
||||||
<string name="error_server_not_running">ERROR: OpenSeizureDetector Server is not running - please re-start it</string>
|
<string name="error_server_not_running">ERROR: OpenSeizureDetector Server is not running - please re-start it</string>
|
||||||
<string name="system_logs">System Logs</string>
|
<string name="system_logs">System Logs</string>
|
||||||
<string name="logged_in_as_user_id">Logged in as User Id:</string>
|
<string name="logged_in_as_user_id">Logged in as: </string>
|
||||||
<string name="datasharing_notification_text">Select for more information</string>
|
<string name="datasharing_notification_text">Select for more information</string>
|
||||||
<string name="datasharing_notification_title">OpenSeizureDetector Data Sharing Problem</string>
|
<string name="datasharing_notification_title">OpenSeizureDetector Data Sharing Problem</string>
|
||||||
<string name="datasharing_about_title">OpenSeizureDetector Data Sharing</string>
|
<string name="datasharing_about_title">OpenSeizureDetector Data Sharing</string>
|
||||||
@@ -430,4 +432,6 @@
|
|||||||
and selecting <b>Apps->OpenSeizureDetector->Permissions</b>.
|
and selecting <b>Apps->OpenSeizureDetector->Permissions</b>.
|
||||||
</string>
|
</string>
|
||||||
<string name="permissions_required">Permissions Disclosure</string>
|
<string name="permissions_required">Permissions Disclosure</string>
|
||||||
|
<string name="about_data_sharing">About Data Sharing</string>
|
||||||
|
<string name="privacy_policy">Privacy Policy</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|||||||
@@ -15,20 +15,14 @@ import java.util.TimeZone;
|
|||||||
@RunWith(RobolectricTestRunner.class)
|
@RunWith(RobolectricTestRunner.class)
|
||||||
@Config(sdk = {Build.VERSION_CODES.O_MR1}, packageName = "uk.org.openseizuredetector")
|
@Config(sdk = {Build.VERSION_CODES.O_MR1}, packageName = "uk.org.openseizuredetector")
|
||||||
public class LogManagerTest extends TestCase {
|
public class LogManagerTest extends TestCase {
|
||||||
LogManager mLm;
|
|
||||||
public void setUp() throws Exception {
|
|
||||||
super.setUp();
|
|
||||||
TimeZone.setDefault(TimeZone.getTimeZone("America/Los_Angeles"));
|
|
||||||
mLm = new LogManager(RuntimeEnvironment.systemContext);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void tearDown() throws Exception {
|
public void tearDown() throws Exception {
|
||||||
mLm.close();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SdData getFakeSdData() {
|
SdData getFakeSdData() {
|
||||||
SdData sdData = new SdData();
|
return null;
|
||||||
return sdData;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,62 @@
|
|||||||
|
package uk.org.openseizuredetector;
|
||||||
|
|
||||||
|
import static org.junit.Assert.*;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
|
||||||
|
import androidx.test.core.app.ApplicationProvider;
|
||||||
|
import androidx.test.platform.app.InstrumentationRegistry;
|
||||||
|
|
||||||
|
import com.google.firebase.FirebaseApp;
|
||||||
|
|
||||||
|
import org.junit.After;
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
import org.robolectric.RobolectricTestRunner;
|
||||||
|
|
||||||
|
|
||||||
|
@RunWith(RobolectricTestRunner.class)
|
||||||
|
public class WebApiConnectionTest {
|
||||||
|
WebApiConnection mWac;
|
||||||
|
@Before
|
||||||
|
public void setUp() throws Exception {
|
||||||
|
Context context = ApplicationProvider.getApplicationContext();
|
||||||
|
FirebaseApp.initializeApp(context);
|
||||||
|
mWac = new WebApiConnection(context);
|
||||||
|
}
|
||||||
|
|
||||||
|
@After
|
||||||
|
public void tearDown() throws Exception {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void isLoggedIn() {
|
||||||
|
assertTrue(mWac.isLoggedIn());
|
||||||
|
assertFalse(mWac.isLoggedIn());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void createEvent() {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void getEvent() {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void getEvents() {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void updateEvent() {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void createDatapoint() {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void getUserProfile() {
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -10,6 +10,7 @@ buildscript {
|
|||||||
}
|
}
|
||||||
dependencies {
|
dependencies {
|
||||||
classpath 'com.android.tools.build:gradle:7.1.0'
|
classpath 'com.android.tools.build:gradle:7.1.0'
|
||||||
|
classpath 'com.google.gms:google-services:4.3.10'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
allprojects {
|
allprojects {
|
||||||
@@ -19,6 +20,7 @@ allprojects {
|
|||||||
url 'https://maven.google.com/'
|
url 'https://maven.google.com/'
|
||||||
name 'Google'
|
name 'Google'
|
||||||
}
|
}
|
||||||
|
google()
|
||||||
//maven { url 'https://jitpack.io' }
|
//maven { url 'https://jitpack.io' }
|
||||||
}
|
}
|
||||||
tasks.withType(JavaCompile) {
|
tasks.withType(JavaCompile) {
|
||||||
|
|||||||
Reference in New Issue
Block a user