diff --git a/.idea/android.iml b/.idea/android.iml
deleted file mode 100644
index d6ebd48..0000000
--- a/.idea/android.iml
+++ /dev/null
@@ -1,9 +0,0 @@
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/.idea/workspace.xml b/.idea/workspace.xml
index 7d09cf7..937cf1d 100644
--- a/.idea/workspace.xml
+++ b/.idea/workspace.xml
@@ -1,11 +1,22 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
+
-
+
@@ -26,106 +37,127 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
-
+
+
+
+
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
-
+
+
+
+
+
+
-
-
+
+
-
-
+
+
@@ -133,13 +165,22 @@
+
+
+
+
+
+
+
+
-
-
-
@@ -171,31 +212,60 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
+
-
+
-
+
-
-
+
+
+
+
+
@@ -248,6 +318,10 @@
+
+
+
+
@@ -269,6 +343,10 @@
+
+
+
+
@@ -303,6 +381,11 @@
+
+
+
+
+
@@ -335,6 +418,11 @@
+
+
+
+
+
@@ -343,6 +431,11 @@
+
+
+
+
+
@@ -359,6 +452,11 @@
+
+
+
+
+
@@ -388,10 +486,24 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -414,13 +526,13 @@
+
-
+
-
-
+
@@ -476,9 +588,9 @@
-
+
-
+
@@ -508,10 +620,20 @@
+
+
+
+
+
+
+
+
+
+
@@ -545,6 +667,16 @@
+
+
+
+
+
+
+
+
+
+
@@ -558,6 +690,10 @@
+
+
+
+
@@ -590,10 +726,20 @@
+
+
+
+
+
+
+
+
+
+
@@ -655,11 +801,6 @@
-
-
-
-
-
@@ -707,11 +848,6 @@
-
-
-
-
-
@@ -730,11 +866,6 @@
-
-
-
-
-
@@ -751,6 +882,16 @@
+
+
+
+
+
+
+
+
+
+
@@ -760,6 +901,14 @@
+
+
+
+
+
+
+
+
@@ -799,6 +948,11 @@
+
+
+
+
+
@@ -830,46 +984,94 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
+
-
+
-
+
-
-
+
+
+
+
+
@@ -912,6 +1114,10 @@
+
+
+
+
@@ -938,6 +1144,10 @@
+
+
+
+
@@ -972,6 +1182,11 @@
+
+
+
+
+
@@ -1004,6 +1219,11 @@
+
+
+
+
+
@@ -1012,6 +1232,11 @@
+
+
+
+
+
@@ -1028,6 +1253,11 @@
+
+
+
+
+
@@ -1057,10 +1287,24 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -1083,13 +1327,13 @@
+
-
+
-
-
+
@@ -1145,9 +1389,9 @@
-
+
-
+
@@ -1177,10 +1421,20 @@
+
+
+
+
+
+
+
+
+
+
@@ -1209,6 +1463,16 @@
+
+
+
+
+
+
+
+
+
+
@@ -1222,6 +1486,10 @@
+
+
+
+
@@ -1254,10 +1522,20 @@
+
+
+
+
+
+
+
+
+
+
@@ -1319,11 +1597,6 @@
-
-
-
-
-
@@ -1371,11 +1644,6 @@
-
-
-
-
-
@@ -1394,11 +1662,6 @@
-
-
-
-
-
@@ -1415,6 +1678,16 @@
+
+
+
+
+
+
+
+
+
+
@@ -1424,6 +1697,14 @@
+
+
+
+
+
+
+
+
@@ -1464,6 +1745,11 @@
+
+
+
+
+
@@ -1495,15 +1781,34 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -1511,7 +1816,8 @@
@@ -1526,13 +1832,15 @@
-
-
-
-
+
+
+
+
+
+
-
-
+
+
@@ -1541,18 +1849,18 @@
-
-
-
-
-
-
-
+
+
+
+
+
+
+
-
-
-
+
+
+
@@ -1560,22 +1868,22 @@
-
+
-
+
-
+
-
-
-
+
+
+
@@ -1586,7 +1894,7 @@
-
+
@@ -1599,7 +1907,7 @@
-
+
@@ -1611,13 +1919,15 @@
-
-
-
-
+
+
+
+
+
+
-
-
+
+
@@ -1626,18 +1936,18 @@
-
-
-
-
-
-
-
+
+
+
+
+
+
+
-
-
-
+
+
+
@@ -1645,22 +1955,22 @@
-
+
-
+
-
+
-
-
-
+
+
+
@@ -1671,7 +1981,7 @@
-
+
@@ -1684,7 +1994,7 @@
-
+
@@ -1777,20 +2087,67 @@
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
+
+
+
+
-
+
@@ -1801,7 +2158,7 @@
-
+
@@ -1815,6 +2172,7 @@
+
@@ -1868,46 +2226,132 @@
+
+
+
+
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
+
+
+
-
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
@@ -2028,6 +2472,15 @@
+
+
+
+
+
+
+
+
+
@@ -2137,7 +2590,7 @@
-
+
@@ -2206,63 +2659,158 @@
-
- 1478436208764
+
+ 1478857506196
- 1478436208764
+ 1478857506196
-
- 1478450570408
+
+ 1479058296259
- 1478450570408
+ 1479058296259
-
- 1478470490779
+
+ 1479561125630
- 1478470490779
+ 1479561125630
+
+
+ 1479580057441
+
+
+
+ 1479580057442
+
+
+ 1479584021963
+
+
+
+ 1479584021963
+
+
+ 1479585131399
+
+
+
+ 1479585131399
+
+
+ 1479586559351
+
+
+
+ 1479586559351
+
+
+ 1479637025663
+
+
+
+ 1479637025665
+
+
+ 1479639477068
+
+
+
+ 1479639477068
+
+
+ 1480808724226
+
+
+
+ 1480808724226
+
+
+ 1480879770763
+
+
+
+ 1480879770765
+
+
+ 1484405033944
+
+
+
+ 1484405033944
+
+
+ 1485345647383
+
+
+
+ 1485345647383
-
+
+ 1485345979437
+
+
+
+ 1485345979437
+
+
+ 1485361440392
+
+
+
+ 1485361440392
+
+
+
+
+
+
+
+
+
+
+
-
+
-
+
-
-
+
+
-
-
-
-
+
+
+
+
-
+
-
-
+
+
-
+
+
+
@@ -2278,64 +2826,164 @@
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
+
+
-
+
-
-
-
+
+
-
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
+
-
+
+
+
-
+
+
-
-
-
+
+
-
+
-
-
-
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -2343,170 +2991,253 @@
-
+
-
-
+
+
+
+
+
-
+
-
-
+
+
+
+
+
-
+
-
+
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
+
-
+
-
-
-
+
+
-
+
-
-
-
+
+
-
+
-
-
-
+
+
-
+
+
-
-
+
+
-
+
-
-
+
+
-
+
-
-
+
+
-
+
-
-
+
+
+
+
+
-
+
-
-
+
+
-
+
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
+
+
-
-
+
+
-
+
-
-
+
+
-
+
-
-
+
+
-
+
-
-
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
+
+
-
+
-
-
+
+
diff --git a/.travis.yml b/.travis.yml
index 56905d3..72ec26c 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -3,15 +3,16 @@ jdk: oraclejdk8
sudo: false
env:
global:
- - ANDROID_TARGET=android-11
+ - ANDROID_TARGET=android-12
- ANDROID_ABI=armeabi-v7a
android:
components:
- platform-tools
- tools
- - build-tools-25.0.0
- - android-23
+ - build-tools-25.0.1
+ - android-25
- extra-android-m2repository
+ - extra-google-m2repository
- sys-img-${ANDROID_ABI}-${ANDROID_TARGET}
licenses:
- android-sdk-preview-license-52d11cd2
diff --git a/app/build.gradle b/app/build.gradle
index 557e46c..de55f54 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -1,12 +1,12 @@
apply plugin: 'com.android.application'
android {
- compileSdkVersion 23
- buildToolsVersion "25.0.0"
+ compileSdkVersion 25
+ buildToolsVersion "25.0.1"
defaultConfig {
applicationId "ovh.exception.watchdogzz"
- minSdkVersion 11
- targetSdkVersion 23
+ minSdkVersion 12
+ targetSdkVersion 25
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
@@ -21,6 +21,9 @@ android {
lintOptions {
abortOnError false
}
+ dataBinding {
+ enabled = true
+ }
}
dependencies {
@@ -28,7 +31,18 @@ dependencies {
androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
exclude group: 'com.android.support', module: 'support-annotations'
})
- compile 'com.android.support:appcompat-v7:23.4.0'
- compile 'com.android.support:design:23.4.0'
+ compile 'com.android.support:appcompat-v7:25.0.1'
+ compile 'com.android.support:design:25.0.1'
+
+ // Dependency for Google Sign-In
+ compile 'com.google.android.gms:play-services-auth:10.0.0'
+ compile 'com.google.firebase:firebase-appindexing:10.0.0'
+
+ // Dependency for web services
+ compile 'com.android.volley:volley:1.0.0'
+ compile 'com.google.code.gson:gson:2.8.0'
+
testCompile 'junit:junit:4.12'
}
+
+apply plugin: 'com.google.gms.google-services'
\ No newline at end of file
diff --git a/app/google-services.json b/app/google-services.json
new file mode 100644
index 0000000..5058253
--- /dev/null
+++ b/app/google-services.json
@@ -0,0 +1,48 @@
+{
+ "project_info": {
+ "project_number": "933756986924",
+ "project_id": "watchdogzz-debug"
+ },
+ "client": [
+ {
+ "client_info": {
+ "mobilesdk_app_id": "1:933756986924:android:c7a71a2bd981b9eb",
+ "android_client_info": {
+ "package_name": "ovh.exception.watchdogzz"
+ }
+ },
+ "oauth_client": [
+ {
+ "client_id": "933756986924-v52rhof4skjmj9kprdm13tst684l5756.apps.googleusercontent.com",
+ "client_type": 1,
+ "android_info": {
+ "package_name": "ovh.exception.watchdogzz",
+ "certificate_hash": "9D649B1CBD804239FDAF0E24FB14742B7BDECC6A"
+ }
+ },
+ {
+ "client_id": "933756986924-ont7s5iohrb9rm3nch8momvatsr4qp47.apps.googleusercontent.com",
+ "client_type": 3
+ }
+ ],
+ "api_key": [
+ {
+ "current_key": "AIzaSyBKpQ3mgWWvT14QfFqIHKNLyzCu4uRDRfE"
+ }
+ ],
+ "services": {
+ "analytics_service": {
+ "status": 1
+ },
+ "appinvite_service": {
+ "status": 1,
+ "other_platform_oauth_client": []
+ },
+ "ads_service": {
+ "status": 1
+ }
+ }
+ }
+ ],
+ "configuration_version": "1"
+}
\ No newline at end of file
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 91231ba..09263b2 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -6,22 +6,38 @@
+
+
+
+
+
+
+
+ android:name=".activities.LoginActivity"
+ android:label="@string/app_name"
+ android:theme="@style/AppTheme.NoActionBar">
+
+
\ No newline at end of file
diff --git a/app/src/main/java/ovh/exception/watchdogzz/LoginActivity.java b/app/src/main/java/ovh/exception/watchdogzz/LoginActivity.java
deleted file mode 100644
index 095e9d8..0000000
--- a/app/src/main/java/ovh/exception/watchdogzz/LoginActivity.java
+++ /dev/null
@@ -1,385 +0,0 @@
-package ovh.exception.watchdogzz;
-
-import android.animation.Animator;
-import android.animation.AnimatorListenerAdapter;
-import android.annotation.TargetApi;
-import android.content.pm.PackageManager;
-import android.support.annotation.NonNull;
-import android.support.design.widget.Snackbar;
-import android.support.v7.app.AppCompatActivity;
-import android.app.LoaderManager.LoaderCallbacks;
-import android.content.ContentResolver;
-import android.content.CursorLoader;
-import android.content.Loader;
-import android.database.Cursor;
-import android.net.Uri;
-import android.os.AsyncTask;
-import android.os.Build.VERSION;
-import android.os.Build;
-import android.os.Bundle;
-import android.provider.ContactsContract;
-import android.text.TextUtils;
-import android.view.KeyEvent;
-import android.view.View;
-import android.view.View.OnClickListener;
-import android.view.inputmethod.EditorInfo;
-import android.widget.ArrayAdapter;
-import android.widget.AutoCompleteTextView;
-import android.widget.Button;
-import android.widget.EditText;
-import android.widget.TextView;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import static android.Manifest.permission.READ_CONTACTS;
-
-/**
- * A login screen that offers login via email/password.
- */
-public class LoginActivity extends AppCompatActivity implements LoaderCallbacks {
-
- /**
- * Id to identity READ_CONTACTS permission request.
- */
- private static final int REQUEST_READ_CONTACTS = 0;
-
- /**
- * A dummy authentication store containing known user names and passwords.
- * TODO: remove after connecting to a real authentication system.
- */
- private static final String[] DUMMY_CREDENTIALS = new String[]{
- "foo@example.com:hello", "bar@example.com:world"
- };
- /**
- * Keep track of the login task to ensure we can cancel it if requested.
- */
- private UserLoginTask mAuthTask = null;
-
- // UI references.
- private AutoCompleteTextView mEmailView;
- private EditText mPasswordView;
- private View mProgressView;
- private View mLoginFormView;
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_login);
- // Set up the login form.
- mEmailView = (AutoCompleteTextView) findViewById(R.id.email);
- populateAutoComplete();
-
- mPasswordView = (EditText) findViewById(R.id.password);
- mPasswordView.setOnEditorActionListener(new TextView.OnEditorActionListener() {
- @Override
- public boolean onEditorAction(TextView textView, int id, KeyEvent keyEvent) {
- if (id == R.id.login || id == EditorInfo.IME_NULL) {
- attemptLogin();
- return true;
- }
- return false;
- }
- });
-
- Button mEmailSignInButton = (Button) findViewById(R.id.email_sign_in_button);
- mEmailSignInButton.setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(View view) {
- attemptLogin();
- }
- });
-
- mLoginFormView = findViewById(R.id.login_form);
- mProgressView = findViewById(R.id.login_progress);
- }
-
- private void populateAutoComplete() {
- if (!mayRequestContacts()) {
- return;
- }
-
- if (VERSION.SDK_INT >= 14) {
- // Use ContactsContract.Profile (API 14+)
- getLoaderManager().initLoader(0, null, this);
- } else if (VERSION.SDK_INT >= 8) {
- // Use AccountManager (API 8+)
- new SetupEmailAutoCompleteTask().execute(null, null);
- }
- }
-
- private boolean mayRequestContacts() {
- if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
- return true;
- }
- if (checkSelfPermission(READ_CONTACTS) == PackageManager.PERMISSION_GRANTED) {
- return true;
- }
- if (shouldShowRequestPermissionRationale(READ_CONTACTS)) {
- Snackbar.make(mEmailView, R.string.permission_rationale, Snackbar.LENGTH_INDEFINITE)
- .setAction(android.R.string.ok, new View.OnClickListener() {
- @Override
- @TargetApi(Build.VERSION_CODES.M)
- public void onClick(View v) {
- requestPermissions(new String[]{READ_CONTACTS}, REQUEST_READ_CONTACTS);
- }
- });
- } else {
- requestPermissions(new String[]{READ_CONTACTS}, REQUEST_READ_CONTACTS);
- }
- return false;
- }
-
- /**
- * Callback received when a permissions request has been completed.
- */
- @Override
- public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions,
- @NonNull int[] grantResults) {
- if (requestCode == REQUEST_READ_CONTACTS) {
- if (grantResults.length == 1 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
- populateAutoComplete();
- }
- }
- }
-
-
- /**
- * Attempts to sign in or register the account specified by the login form.
- * If there are form errors (invalid email, missing fields, etc.), the
- * errors are presented and no actual login attempt is made.
- */
- private void attemptLogin() {
- if (mAuthTask != null) {
- return;
- }
-
- // Reset errors.
- mEmailView.setError(null);
- mPasswordView.setError(null);
-
- // Store values at the time of the login attempt.
- String email = mEmailView.getText().toString();
- String password = mPasswordView.getText().toString();
-
- boolean cancel = false;
- View focusView = null;
-
- // Check for a valid password, if the user entered one.
- if (!TextUtils.isEmpty(password) && !isPasswordValid(password)) {
- mPasswordView.setError(getString(R.string.error_invalid_password));
- focusView = mPasswordView;
- cancel = true;
- }
-
- // Check for a valid email address.
- if (TextUtils.isEmpty(email)) {
- mEmailView.setError(getString(R.string.error_field_required));
- focusView = mEmailView;
- cancel = true;
- } else if (!isEmailValid(email)) {
- mEmailView.setError(getString(R.string.error_invalid_email));
- focusView = mEmailView;
- cancel = true;
- }
-
- if (cancel) {
- // There was an error; don't attempt login and focus the first
- // form field with an error.
- focusView.requestFocus();
- } else {
- // Show a progress spinner, and kick off a background task to
- // perform the user login attempt.
- showProgress(true);
- mAuthTask = new UserLoginTask(email, password);
- mAuthTask.execute((Void) null);
- }
- }
-
- private boolean isEmailValid(String email) {
- //TODO: Replace this with your own logic
- return email.contains("@");
- }
-
- private boolean isPasswordValid(String password) {
- //TODO: Replace this with your own logic
- return password.length() > 4;
- }
-
- /**
- * Shows the progress UI and hides the login form.
- */
- @TargetApi(Build.VERSION_CODES.HONEYCOMB_MR2)
- private void showProgress(final boolean show) {
- // On Honeycomb MR2 we have the ViewPropertyAnimator APIs, which allow
- // for very easy animations. If available, use these APIs to fade-in
- // the progress spinner.
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB_MR2) {
- int shortAnimTime = getResources().getInteger(android.R.integer.config_shortAnimTime);
-
- mLoginFormView.setVisibility(show ? View.GONE : View.VISIBLE);
- mLoginFormView.animate().setDuration(shortAnimTime).alpha(
- show ? 0 : 1).setListener(new AnimatorListenerAdapter() {
- @Override
- public void onAnimationEnd(Animator animation) {
- mLoginFormView.setVisibility(show ? View.GONE : View.VISIBLE);
- }
- });
-
- mProgressView.setVisibility(show ? View.VISIBLE : View.GONE);
- mProgressView.animate().setDuration(shortAnimTime).alpha(
- show ? 1 : 0).setListener(new AnimatorListenerAdapter() {
- @Override
- public void onAnimationEnd(Animator animation) {
- mProgressView.setVisibility(show ? View.VISIBLE : View.GONE);
- }
- });
- } else {
- // The ViewPropertyAnimator APIs are not available, so simply show
- // and hide the relevant UI components.
- mProgressView.setVisibility(show ? View.VISIBLE : View.GONE);
- mLoginFormView.setVisibility(show ? View.GONE : View.VISIBLE);
- }
- }
-
- @Override
- public Loader onCreateLoader(int i, Bundle bundle) {
- return new CursorLoader(this,
- // Retrieve data rows for the device user's 'profile' contact.
- Uri.withAppendedPath(ContactsContract.Profile.CONTENT_URI,
- ContactsContract.Contacts.Data.CONTENT_DIRECTORY), ProfileQuery.PROJECTION,
-
- // Select only email addresses.
- ContactsContract.Contacts.Data.MIMETYPE +
- " = ?", new String[]{ContactsContract.CommonDataKinds.Email
- .CONTENT_ITEM_TYPE},
-
- // Show primary email addresses first. Note that there won't be
- // a primary email address if the user hasn't specified one.
- ContactsContract.Contacts.Data.IS_PRIMARY + " DESC");
- }
-
- @Override
- public void onLoadFinished(Loader cursorLoader, Cursor cursor) {
- List emails = new ArrayList<>();
- cursor.moveToFirst();
- while (!cursor.isAfterLast()) {
- emails.add(cursor.getString(ProfileQuery.ADDRESS));
- cursor.moveToNext();
- }
-
- addEmailsToAutoComplete(emails);
- }
-
- @Override
- public void onLoaderReset(Loader cursorLoader) {
-
- }
-
- private void addEmailsToAutoComplete(List emailAddressCollection) {
- //Create adapter to tell the AutoCompleteTextView what to show in its dropdown list.
- ArrayAdapter adapter =
- new ArrayAdapter<>(LoginActivity.this,
- android.R.layout.simple_dropdown_item_1line, emailAddressCollection);
-
- mEmailView.setAdapter(adapter);
- }
-
- private interface ProfileQuery {
- String[] PROJECTION = {
- ContactsContract.CommonDataKinds.Email.ADDRESS,
- ContactsContract.CommonDataKinds.Email.IS_PRIMARY,
- };
-
- int ADDRESS = 0;
- int IS_PRIMARY = 1;
- }
-
- /**
- * Use an AsyncTask to fetch the user's email addresses on a background thread, and update
- * the email text field with results on the main UI thread.
- */
- class SetupEmailAutoCompleteTask extends AsyncTask> {
-
- @Override
- protected List doInBackground(Void... voids) {
- ArrayList emailAddressCollection = new ArrayList<>();
-
- // Get all emails from the user's contacts and copy them to a list.
- ContentResolver cr = getContentResolver();
- Cursor emailCur = cr.query(ContactsContract.CommonDataKinds.Email.CONTENT_URI, null,
- null, null, null);
- while (emailCur.moveToNext()) {
- String email = emailCur.getString(emailCur.getColumnIndex(ContactsContract
- .CommonDataKinds.Email.DATA));
- emailAddressCollection.add(email);
- }
- emailCur.close();
-
- return emailAddressCollection;
- }
-
- @Override
- protected void onPostExecute(List emailAddressCollection) {
- addEmailsToAutoComplete(emailAddressCollection);
- }
- }
-
- /**
- * Represents an asynchronous login/registration task used to authenticate
- * the user.
- */
- public class UserLoginTask extends AsyncTask {
-
- private final String mEmail;
- private final String mPassword;
-
- UserLoginTask(String email, String password) {
- mEmail = email;
- mPassword = password;
- }
-
- @Override
- protected Boolean doInBackground(Void... params) {
- // TODO: attempt authentication against a network service.
-
- try {
- // Simulate network access.
- Thread.sleep(2000);
- } catch (InterruptedException e) {
- return false;
- }
-
- for (String credential : DUMMY_CREDENTIALS) {
- String[] pieces = credential.split(":");
- if (pieces[0].equals(mEmail)) {
- // Account exists, return true if the password matches.
- return pieces[1].equals(mPassword);
- }
- }
-
- // TODO: register the new account here.
- return true;
- }
-
- @Override
- protected void onPostExecute(final Boolean success) {
- mAuthTask = null;
- showProgress(false);
-
- if (success) {
- finish();
- } else {
- mPasswordView.setError(getString(R.string.error_incorrect_password));
- mPasswordView.requestFocus();
- }
- }
-
- @Override
- protected void onCancelled() {
- mAuthTask = null;
- showProgress(false);
- }
- }
-}
-
diff --git a/app/src/main/java/ovh/exception/watchdogzz/activities/LoginActivity.java b/app/src/main/java/ovh/exception/watchdogzz/activities/LoginActivity.java
new file mode 100644
index 0000000..116e8cd
--- /dev/null
+++ b/app/src/main/java/ovh/exception/watchdogzz/activities/LoginActivity.java
@@ -0,0 +1,343 @@
+package ovh.exception.watchdogzz.activities;
+
+import android.Manifest;
+import android.animation.Animator;
+import android.animation.AnimatorListenerAdapter;
+import android.annotation.TargetApi;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.net.Uri;
+import android.os.AsyncTask;
+import android.os.Build;
+import android.os.Build.VERSION;
+import android.os.Bundle;
+import android.os.Parcelable;
+import android.support.annotation.NonNull;
+import android.support.v4.app.ActivityCompat;
+import android.support.v4.content.ContextCompat;
+import android.support.v7.app.AppCompatActivity;
+import android.util.Log;
+import android.view.View;
+import android.widget.AutoCompleteTextView;
+import android.widget.EditText;
+
+import com.google.android.gms.auth.api.Auth;
+import com.google.android.gms.auth.api.signin.GoogleSignInAccount;
+import com.google.android.gms.auth.api.signin.GoogleSignInOptions;
+import com.google.android.gms.auth.api.signin.GoogleSignInResult;
+import com.google.android.gms.common.ConnectionResult;
+import com.google.android.gms.common.api.GoogleApiClient;
+
+import java.io.BufferedInputStream;
+import java.io.BufferedOutputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.HttpURLConnection;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.nio.charset.StandardCharsets;
+import java.util.ArrayList;
+import java.util.List;
+
+import ovh.exception.watchdogzz.R;
+import ovh.exception.watchdogzz.data.GPSPosition;
+import ovh.exception.watchdogzz.data.User;
+
+/**
+ * A login screen that offers login via email/password.
+ */
+public class LoginActivity extends AppCompatActivity implements GoogleApiClient.OnConnectionFailedListener, View.OnClickListener {
+
+ private enum Permissions {
+ REQUEST_GET_ACCOUNTS,
+ REQUEST_READ_PROFILE,
+ REQUEST_READ_CONTACTS,
+ REQUEST_ACCESS_FINE_LOCATION,
+ REQUEST_ACCESS_COARSE_LOCATION,
+ REQUEST_ACCESS_NETWORK_STATE,
+ REQUEST_VIBRATE,
+ REQUEST_INTERNET
+ }
+
+ /**
+ * Keep track of the login task to ensure we can cancel it if requested.
+ */
+ private UserLoginTask mAuthTask = null;
+
+ // Sign in information
+ private GoogleSignInOptions mGoogleSignInOptions;
+ private GoogleApiClient mGoogleApiClient;
+ private final int RC_SIGN_IN = 10;
+ private User mUser;
+
+ // UI references.
+ private AutoCompleteTextView mEmailView;
+ private EditText mPasswordView;
+ private View mProgressView;
+ private View mLoginFormView;
+ private Context that;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_login);
+ that = this;
+ mUser = new User("","","","",null,true,new GPSPosition(0,0,0));
+ mProgressView = findViewById(R.id.login_progress);
+ mLoginFormView = findViewById(R.id.sign_in_button);
+
+ // Check READ_CONTACTS
+ if (ContextCompat.checkSelfPermission(this,
+ Manifest.permission.READ_CONTACTS)
+ != PackageManager.PERMISSION_GRANTED) {
+ ActivityCompat.requestPermissions(this,
+ new String[]{Manifest.permission.READ_CONTACTS},
+ Permissions.REQUEST_READ_CONTACTS.ordinal());
+ }
+
+ // Check ACCESS_FINE_LOCATION
+ if (ContextCompat.checkSelfPermission(this,
+ Manifest.permission.ACCESS_FINE_LOCATION)
+ != PackageManager.PERMISSION_GRANTED) {
+ ActivityCompat.requestPermissions(this,
+ new String[]{Manifest.permission.ACCESS_FINE_LOCATION},
+ Permissions.REQUEST_ACCESS_FINE_LOCATION.ordinal());
+ }
+
+ // Check GET_ACCOUNTS
+ if (ContextCompat.checkSelfPermission(this,
+ Manifest.permission.GET_ACCOUNTS)
+ != PackageManager.PERMISSION_GRANTED) {
+ ActivityCompat.requestPermissions(this,
+ new String[]{Manifest.permission.GET_ACCOUNTS},
+ Permissions.REQUEST_GET_ACCOUNTS.ordinal());
+ }
+
+ // Check ACCESS_COARSE_LOCATION
+ if (ContextCompat.checkSelfPermission(this,
+ Manifest.permission.ACCESS_COARSE_LOCATION)
+ != PackageManager.PERMISSION_GRANTED) {
+ ActivityCompat.requestPermissions(this,
+ new String[]{Manifest.permission.ACCESS_COARSE_LOCATION},
+ Permissions.REQUEST_ACCESS_COARSE_LOCATION.ordinal());
+ }
+
+ // Check VIBRATE
+ if (ContextCompat.checkSelfPermission(this,
+ Manifest.permission.VIBRATE)
+ != PackageManager.PERMISSION_GRANTED) {
+ ActivityCompat.requestPermissions(this,
+ new String[]{Manifest.permission.VIBRATE},
+ Permissions.REQUEST_VIBRATE.ordinal());
+ }
+
+ // Check INTERNET
+ if (ContextCompat.checkSelfPermission(this,
+ Manifest.permission.INTERNET)
+ != PackageManager.PERMISSION_GRANTED) {
+ ActivityCompat.requestPermissions(this,
+ new String[]{Manifest.permission.INTERNET},
+ Permissions.REQUEST_INTERNET.ordinal());
+ }
+
+ // Configure sign-in to request the user's ID, email address, and basic profile.
+ mGoogleSignInOptions = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
+ .requestEmail()
+ .requestId()
+ .requestProfile()
+ .requestIdToken(getString(R.string.server_client_id))
+ .build();
+
+ // Build a GoogleApiClient with access to the Google Sign-In API and the
+// options specified by gso.
+ mGoogleApiClient = new GoogleApiClient.Builder(this)
+ .enableAutoManage(this /* FragmentActivity */, this /* OnConnectionFailedListener */)
+ .addApi(Auth.GOOGLE_SIGN_IN_API, mGoogleSignInOptions)
+ .build();
+
+ findViewById(R.id.sign_in_button).setOnClickListener(this);
+ }
+
+ protected void connect(View v) {
+ showProgress(true);
+ Intent signInIntent = Auth.GoogleSignInApi.getSignInIntent(mGoogleApiClient);
+ startActivityForResult(signInIntent, RC_SIGN_IN);
+ }
+
+ /**
+ * Shows the progress UI and hides the login form.
+ */
+ @TargetApi(Build.VERSION_CODES.HONEYCOMB_MR2)
+ private void showProgress(final boolean show) {
+ // On Honeycomb MR2 we have the ViewPropertyAnimator APIs, which allow
+ // for very easy animations. If available, use these APIs to fade-in
+ // the progress spinner.
+ if (VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB_MR2) {
+ int shortAnimTime = getResources().getInteger(android.R.integer.config_shortAnimTime);
+
+ mLoginFormView.setVisibility(show ? View.GONE : View.VISIBLE);
+ mLoginFormView.animate().setDuration(shortAnimTime).alpha(
+ show ? 0 : 1).setListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ mLoginFormView.setVisibility(show ? View.GONE : View.VISIBLE);
+ }
+ });
+
+ mProgressView.setVisibility(show ? View.VISIBLE : View.GONE);
+ mProgressView.animate().setDuration(shortAnimTime).alpha(
+ show ? 1 : 0).setListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ mProgressView.setVisibility(show ? View.VISIBLE : View.GONE);
+ }
+ });
+ } else {
+ // The ViewPropertyAnimator APIs are not available, so simply show
+ // and hide the relevant UI components.
+ mProgressView.setVisibility(show ? View.VISIBLE : View.GONE);
+ mLoginFormView.setVisibility(show ? View.GONE : View.VISIBLE);
+ }
+ }
+
+ @Override
+ public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
+
+ if (grantResults.length > 0 && grantResults[0] != PackageManager.PERMISSION_GRANTED) {
+ finish();
+ }
+
+ }
+
+ @Override
+ public void onConnectionFailed(@NonNull ConnectionResult connectionResult) {
+
+ }
+
+ @Override
+ public void onClick(View view) {
+ switch (view.getId()) {
+ case R.id.sign_in_button:
+ connect(view);
+ break;
+ default:
+ break;
+ }
+ }
+
+ @Override
+ public void onActivityResult(int requestCode, int resultCode, Intent data) {
+ super.onActivityResult(requestCode, resultCode, data);
+
+ // Result returned from launching the Intent from GoogleSignInApi.getSignInIntent(...);
+ if (requestCode == RC_SIGN_IN) {
+ GoogleSignInResult result = Auth.GoogleSignInApi.getSignInResultFromIntent(data);
+ handleSignInResult(result);
+ }
+ }
+
+ private void handleSignInResult(GoogleSignInResult result) {
+ if (result.isSuccess()) {
+ // Signed in successfully, show authenticated UI.
+ GoogleSignInAccount acct = result.getSignInAccount();
+ mUser.setEmail(acct.getEmail());
+ mUser.setName(acct.getDisplayName());
+ mUser.setId(acct.getId());
+ mUser.setPhotoUrl(acct.getPhotoUrl());
+ mUser.setIdToken(acct.getIdToken());
+
+ mAuthTask = new UserLoginTask(mUser.getEmail(), mUser.getName());
+ mAuthTask.execute((Void) null);
+ } else {
+ // Signed out, show unauthenticated UI.
+ Log.d("SIGN IN", "Sign in failed.");
+ }
+ }
+
+ /**
+ * Represents an asynchronous login/registration task used to authenticate
+ * the user.
+ */
+ public class UserLoginTask extends AsyncTask {
+
+ private final String mEmail;
+ private final String mPassword;
+
+ UserLoginTask(String email, String password) {
+ mEmail = email;
+ mPassword = password;
+ }
+
+ @Override
+ protected Boolean doInBackground(Void... params) {
+ // attempt authentication against a network service.
+
+ try {
+
+ HttpURLConnection urlConnection = (HttpURLConnection) (new URL("https://wd.exception.ovh/tokensignin")).openConnection();
+ try {
+ String urlParameters = "idToken="+mUser.getIdToken()+"&name="+mUser.getName();
+ byte[] postData = new byte[0];
+ if (VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
+ postData = urlParameters.getBytes( StandardCharsets.UTF_8 );
+ } else {
+ postData = urlParameters.getBytes();
+ }
+ int postDataLength = postData.length;
+ urlConnection.setDoOutput( true );
+ urlConnection.setInstanceFollowRedirects( false );
+ urlConnection.setRequestMethod( "POST" );
+ urlConnection.setRequestProperty( "Content-Type", "application/x-www-form-urlencoded");
+ urlConnection.setRequestProperty( "charset", "utf-8");
+ urlConnection.setRequestProperty( "Content-Length", Integer.toString( postDataLength ));
+ urlConnection.setUseCaches( false );
+ try {
+ DataOutputStream wr = new DataOutputStream( urlConnection.getOutputStream() );
+ wr.write( postData );
+ } catch (Exception e) {
+ Log.w("Backend sign in", e.getMessage());
+ }
+
+ InputStream in = new BufferedInputStream(urlConnection.getInputStream());
+ Log.d("Backend sign in", in.toString());
+ } finally {
+ urlConnection.disconnect();
+ }
+ } catch (MalformedURLException e) {
+ e.printStackTrace();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+
+ return true;
+ }
+
+ @Override
+ protected void onPostExecute(final Boolean success) {
+ mAuthTask = null;
+ showProgress(false);
+
+ if (success) {
+ Intent intent;
+ intent = new Intent(that, MainActivity.class);
+ intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
+ intent.putExtra("user", mUser);
+ startActivity(intent);
+ finish();
+ } else {
+ mPasswordView.setError(getString(R.string.error_incorrect_password));
+ mPasswordView.requestFocus();
+ }
+ }
+
+ @Override
+ protected void onCancelled() {
+ mAuthTask = null;
+ showProgress(false);
+ }
+ }
+}
+
diff --git a/app/src/main/java/ovh/exception/watchdogzz/activities/MainActivity.java b/app/src/main/java/ovh/exception/watchdogzz/activities/MainActivity.java
new file mode 100644
index 0000000..0f651dd
--- /dev/null
+++ b/app/src/main/java/ovh/exception/watchdogzz/activities/MainActivity.java
@@ -0,0 +1,283 @@
+package ovh.exception.watchdogzz.activities;
+
+import android.content.Intent;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.os.AsyncTask;
+import android.os.Bundle;
+import android.support.design.widget.CoordinatorLayout;
+import android.support.design.widget.FloatingActionButton;
+import android.support.design.widget.Snackbar;
+import android.util.Log;
+import android.view.View;
+import android.support.design.widget.NavigationView;
+import android.support.v4.view.GravityCompat;
+import android.support.v4.widget.DrawerLayout;
+import android.support.v7.app.ActionBarDrawerToggle;
+import android.support.v7.app.AppCompatActivity;
+import android.support.v7.widget.Toolbar;
+import android.view.Menu;
+import android.view.MenuItem;
+import android.widget.ImageView;
+import android.widget.TextView;
+
+import com.google.gson.Gson;
+
+import org.json.JSONException;
+import org.json.JSONObject;
+
+import java.io.InputStream;
+import java.net.URL;
+import java.util.ArrayList;
+
+import ovh.exception.watchdogzz.R;
+import ovh.exception.watchdogzz.data.GPSPosition;
+import ovh.exception.watchdogzz.data.JUser;
+import ovh.exception.watchdogzz.data.User;
+import ovh.exception.watchdogzz.data.UserManager;
+import ovh.exception.watchdogzz.network.DownloadImageTask;
+import ovh.exception.watchdogzz.network.IWSConsumer;
+import ovh.exception.watchdogzz.network.NetworkManager;
+import ovh.exception.watchdogzz.network.PostWebServiceTask;
+import ovh.exception.watchdogzz.network.PostitionManager;
+import ovh.exception.watchdogzz.network.WebServiceTask;
+import ovh.exception.watchdogzz.view.WDRenderer;
+import ovh.exception.watchdogzz.view.WDSurfaceView;
+
+public class MainActivity extends AppCompatActivity implements NavigationView.OnNavigationItemSelectedListener, IWSConsumer {
+
+ private WDSurfaceView glView;
+ private UserManager users;
+ private PostitionManager postitionManager;
+ private NetworkManager networkManager;
+
+ @Override
+ public void consume(JSONObject json) {
+ if(json!=null) {
+ Snackbar.make(findViewById(R.id.content_main), json.toString(), Snackbar.LENGTH_LONG).setAction("Action", null).show();
+ Gson gson = new Gson();
+ JUser[] serverUsers = new JUser[1];
+ try {
+ serverUsers = gson.fromJson(json.getJSONArray("list").toString(), JUser[].class);
+ } catch (JSONException e) {
+ e.printStackTrace();
+ }
+
+/**
+ for (String s : serverUsernames) {
+ try {
+ User tmpU = new User(Integer.toString(s.length()),s,"","",null,false,new GPSPosition(0f,0f,0f));
+ new WebServiceTask(MainActivity.this, new IWSConsumer() {
+ @Override
+ public void consume(JSONObject json) {
+ Gson gson = new Gson();
+ JUser u = gson.fromJson(json.toString(), JUser.class);
+ User nouv = new User(Integer.toString(u.name.length()),u.name,"","",null,false, new GPSPosition(
+ u.location.length > 2 ? u.location[0] : 0.0f,
+ u.location.length > 2 ? u.location[1] : 0.0f,
+ u.location.length > 2 ? u.location[2] : 0.0f)); // necessaire apres serialisation
+ if(u.name != users.getMe().getName()) { // on ne s'update pas sois meme
+ if (users.contains(nouv)) { // faire l'update
+ users.updateUser(nouv.getName(), nouv);
+ } else { // faire l'ajout
+ users.addUser(nouv);
+ }
+ }
+ }
+ }).execute("http://ec2-35-157-1-159.eu-central-1.compute.amazonaws.com/where");
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }**/
+
+ for (JUser u : serverUsers) { // on traite les nouveaux utilisateurs
+ User nouv = new User(Integer.toString(u.name.length()),u.name,"","",null,false, new GPSPosition(
+ u.location.length > 2 ? u.location[0] : 0.0f,
+ u.location.length > 2 ? u.location[1] : 0.0f,
+ u.location.length > 2 ? u.location[2] : 0.0f)); // necessaire apres serialisation
+ if(u.name != users.getMe().getName()) { // on ne s'update pas sois meme
+ if (users.contains(nouv)) { // faire l'update
+ users.updateUser(nouv.getName(), nouv);
+ } else { // faire l'ajout
+ users.addUser(nouv);
+ }
+ }
+ }
+
+ }
+ else
+ Log.w("COUCOU", "JSON is null");
+ }
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_main); // doit etre avant tout appel au layout
+ glView = (WDSurfaceView) findViewById(R.id.main_map);
+ WDRenderer renderer = new WDRenderer(this);
+ glView.setRenderer(renderer); // Use a custom renderer
+ Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
+ setSupportActionBar(toolbar);
+
+ FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
+ fab.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View view) {
+ Snackbar.make(view, "Position: " + users.getMe().getPosition(), Snackbar.LENGTH_LONG)
+ .setAction("Action", null).show();
+ new PostWebServiceTask(MainActivity.this, MainActivity.this, users.getMe()).execute("http://ec2-35-157-1-159.eu-central-1.compute.amazonaws.com/where");
+ new WebServiceTask(MainActivity.this, MainActivity.this).execute("http://ec2-35-157-1-159.eu-central-1.compute.amazonaws.com/where");
+ }
+ });
+
+
+
+
+ NavigationView navigationView = (NavigationView) findViewById(R.id.nav_view);
+ navigationView.setNavigationItemSelectedListener(this);
+
+ this.postitionManager = new PostitionManager(this);
+ this.networkManager = NetworkManager.getInstance(this.getApplicationContext());
+ setUsers(new UserManager());
+ User futurMe = (User) getIntent().getParcelableExtra("user");
+ this.users.setMe(futurMe);
+ getUsers().addObserver(renderer.getMap());
+
+
+ // login sur le serveur
+ new PostWebServiceTask(MainActivity.this, new IWSConsumer() {
+ @Override
+ public void consume(JSONObject json) {
+ if(json==null) {
+ new PostWebServiceTask(MainActivity.this, new IWSConsumer() {
+ @Override
+ public void consume(JSONObject json) {
+ if(json==null) {
+
+ }
+ }
+ }, users.getMe()).execute("http://ec2-35-157-1-159.eu-central-1.compute.amazonaws.com/login");
+ }
+ }
+ }, users.getMe()).execute("http://ec2-35-157-1-159.eu-central-1.compute.amazonaws.com/login");
+
+ DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
+ ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
+ this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close) {
+ public void onDrawerOpened(View drawerView) {
+ super.onDrawerOpened(drawerView);
+ TextView t = (TextView) findViewById(R.id.complete_name);
+ t.setText(users.getMe().getName());
+ t = (TextView) findViewById(R.id.email_adresse);
+ t.setText(users.getMe().getEmail());
+ ImageView im = (ImageView) findViewById(R.id.photo_profil);
+ new DownloadImageTask(im).execute(users.getMe().getPhotoUrl().toString());
+ invalidateOptionsMenu(); // creates call to onPrepareOptionsMenu()
+ }
+ };
+
+ drawer.setDrawerListener(toggle);
+ toggle.syncState();
+ }
+
+ @Override
+ public void onBackPressed() {
+ DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
+ if (drawer.isDrawerOpen(GravityCompat.START)) {
+ drawer.closeDrawer(GravityCompat.START);
+ } else {
+ super.onBackPressed();
+ }
+ }
+
+ @Override
+ public boolean onCreateOptionsMenu(Menu menu) {
+ // Inflate the menu; this adds items to the action bar if it is present.
+ getMenuInflater().inflate(R.menu.main, menu);
+ TextView t = (TextView) findViewById(R.id.complete_name);
+ t.setText(this.users.getMe().getName());
+ t = (TextView) findViewById(R.id.email_adresse);
+ t.setText(this.users.getMe().getEmail());
+ ImageView im = (ImageView) findViewById(R.id.photo_profil);
+ im.setImageURI(this.getUsers().getMe().getPhotoUrl());
+ return true;
+ }
+
+ @Override
+ public boolean onOptionsItemSelected(MenuItem item) {
+ // Handle action bar item clicks here. The action bar will
+ // automatically handle clicks on the Home/Up button, so long
+ // as you specify a parent activity in AndroidManifest.xml.
+ int id = item.getItemId();
+
+ //noinspection SimplifiableIfStatement
+ if (id == R.id.action_settings) {
+ return true;
+ }
+
+ return super.onOptionsItemSelected(item);
+ }
+
+ @SuppressWarnings("StatementWithEmptyBody")
+ @Override
+ public boolean onNavigationItemSelected(MenuItem item) {
+ // Handle navigation view item clicks here.
+ int id = item.getItemId();
+
+ if (id == R.id.rv_mode) {
+ // Handle the camera action
+ } else if (id == R.id.normal_mode) {
+
+ } else if (id == R.id.configuration) {
+
+ } else if (id == R.id.share_position) {
+ Intent sendIntent = new Intent();
+ sendIntent.setAction(Intent.ACTION_SEND);
+ sendIntent.putExtra(Intent.EXTRA_TEXT, getResources().getText(R.string.default_share_message) + users.getMe().getPosition().toString());
+ sendIntent.setType("text/plain");
+ startActivity(Intent.createChooser(sendIntent, getResources().getText(R.string.send_to)));
+ } else if (id == R.id.send_message) {
+
+ }
+
+ DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
+ drawer.closeDrawer(GravityCompat.START);
+ return true;
+ }
+
+ @Override
+ protected void onPause() {
+ super.onPause();
+ glView.onPause();
+ }
+
+ @Override
+ protected void onResume() {
+ super.onResume();
+ glView.onResume();
+ }
+
+ @Override
+ public void onStart() {
+ super.onStart();
+ }
+
+ @Override
+ public void onStop() {
+ super.onStop();
+ new WebServiceTask(MainActivity.this, new IWSConsumer() {
+ @Override
+ public void consume(JSONObject json) {
+
+ }
+ }).execute("http://ec2-35-157-1-159.eu-central-1.compute.amazonaws.com/logout/");
+ }
+
+ public UserManager getUsers() {
+ return users;
+ }
+
+ public void setUsers(UserManager users) {
+ this.users = users;
+ }
+}
diff --git a/app/src/main/java/ovh/exception/watchdogzz/data/GPSPosition.java b/app/src/main/java/ovh/exception/watchdogzz/data/GPSPosition.java
new file mode 100644
index 0000000..9f34f94
--- /dev/null
+++ b/app/src/main/java/ovh/exception/watchdogzz/data/GPSPosition.java
@@ -0,0 +1,52 @@
+package ovh.exception.watchdogzz.data;
+
+/**
+ * Created by begarco on 19/11/2016.
+ */
+
+public class GPSPosition {
+ private float latitude;
+ private float longitude;
+ private float altitude;
+
+ public GPSPosition(float latitude, float longitude, float altitude) {
+ this.setAltitude(altitude);
+ this.setLatitude(latitude);
+ this.setLongitude(longitude);
+ }
+
+ public float[] getForMap(float[] origin, float scale) {
+ float[] res = { (getLatitude() -origin[1])*scale, (getLongitude() -origin[0])*scale, (getAltitude() -origin[2])*scale };
+
+ return res;
+ }
+
+ @Override
+ public String toString() {
+ return getLatitude() + " " + getLongitude() + " " + getAltitude();
+ }
+
+ public float getLatitude() {
+ return latitude;
+ }
+
+ public void setLatitude(float latitude) {
+ this.latitude = latitude;
+ }
+
+ public float getLongitude() {
+ return longitude;
+ }
+
+ public void setLongitude(float longitude) {
+ this.longitude = longitude;
+ }
+
+ public float getAltitude() {
+ return altitude;
+ }
+
+ public void setAltitude(float altitude) {
+ this.altitude = altitude;
+ }
+}
diff --git a/app/src/main/java/ovh/exception/watchdogzz/data/JUser.java b/app/src/main/java/ovh/exception/watchdogzz/data/JUser.java
new file mode 100644
index 0000000..c05f35e
--- /dev/null
+++ b/app/src/main/java/ovh/exception/watchdogzz/data/JUser.java
@@ -0,0 +1,19 @@
+package ovh.exception.watchdogzz.data;
+
+import com.google.gson.annotations.SerializedName;
+
+import java.io.Serializable;
+
+/**
+ * Created by begarco on 25/01/2017.
+ */
+
+public class JUser implements Serializable {
+
+
+ @SerializedName("name")
+ public String name;
+
+ @SerializedName("location")
+ public Float[] location;
+}
diff --git a/app/src/main/java/ovh/exception/watchdogzz/data/User.java b/app/src/main/java/ovh/exception/watchdogzz/data/User.java
new file mode 100644
index 0000000..023e4bf
--- /dev/null
+++ b/app/src/main/java/ovh/exception/watchdogzz/data/User.java
@@ -0,0 +1,141 @@
+package ovh.exception.watchdogzz.data;
+
+import android.net.Uri;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import com.google.gson.annotations.SerializedName;
+
+import java.io.Serializable;
+
+/**
+ * Created by begarco on 19/11/2016.
+ */
+
+public class User implements Parcelable {
+ private String id;
+
+ private String name;
+ private String email;
+ private String idToken;
+ private Uri photoUrl;
+ private boolean isMe;
+
+ private float[] location;
+
+ private GPSPosition position;
+
+ public void constructAfterSerialized() {
+ if(location.length >= 3)
+ position = new GPSPosition(location[0],location[1],location[2]);
+ }
+
+ public User(String id, String name, String email, String idToken, Uri photoUrl, boolean me, GPSPosition pos) {
+ this.setId(id);
+ this.setName(name);
+ this.setEmail(email);
+ this.setIdToken(idToken);
+ this.setPhotoUrl(photoUrl);
+ this.setMe(me);
+ this.setPosition(pos);
+ }
+
+ public User(Parcel p) {
+ this.setId(p.readString());
+ this.setName(p.readString());
+ this.setEmail(p.readString());
+ this.setIdToken(p.readString());
+ this.setPhotoUrl(Uri.parse(p.readString()));
+ this.setMe(Boolean.valueOf(p.readString()));
+ this.setPosition(new GPSPosition(p.readFloat(),p.readFloat(),p.readFloat()));
+ }
+
+ public String getId() {
+ return id;
+ }
+
+ public void setId(String id) {
+ this.id = id;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public String getEmail() {
+ return email;
+ }
+
+ public void setEmail(String email) {
+ this.email = email;
+ }
+
+ public boolean isMe() {
+ return isMe;
+ }
+
+ public void setMe(boolean me) {
+ isMe = me;
+ }
+
+ public GPSPosition getPosition() {
+ return position;
+ }
+
+ public void setPosition(GPSPosition position) {
+ this.position = position;
+ }
+
+ public Uri getPhotoUrl() {
+ return photoUrl;
+ }
+
+ public void setPhotoUrl(Uri photoUrl) {
+ this.photoUrl = photoUrl;
+ }
+
+ public String getIdToken() {
+ return idToken;
+ }
+
+ public void setIdToken(String idToken) {
+ this.idToken = idToken;
+ }
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(Parcel parcel, int i) {
+ parcel.writeString(this.getId());
+ parcel.writeString(this.getName());
+ parcel.writeString(this.getEmail());
+ parcel.writeString(this.getIdToken());
+ parcel.writeString(this.getPhotoUrl().toString());
+ parcel.writeString(String.valueOf(this.isMe()));
+ parcel.writeFloat(this.getPosition().getLatitude());
+ parcel.writeFloat(this.getPosition().getLongitude());
+ parcel.writeFloat(this.getPosition().getAltitude());
+ }
+
+ public static final Parcelable.Creator CREATOR = new Parcelable.Creator()
+ {
+ @Override
+ public User createFromParcel(Parcel source)
+ {
+ return new User(source);
+ }
+
+ @Override
+ public User[] newArray(int size)
+ {
+ return new User[size];
+ }
+ };
+}
diff --git a/app/src/main/java/ovh/exception/watchdogzz/data/UserManager.java b/app/src/main/java/ovh/exception/watchdogzz/data/UserManager.java
new file mode 100644
index 0000000..472cf4c
--- /dev/null
+++ b/app/src/main/java/ovh/exception/watchdogzz/data/UserManager.java
@@ -0,0 +1,75 @@
+package ovh.exception.watchdogzz.data;
+
+import java.util.ArrayList;
+import java.util.Observable;
+
+/**
+ * Created by begarco on 19/11/2016.
+ */
+
+public class UserManager extends Observable {
+ private ArrayList users;
+ private User me;
+
+ public UserManager() {
+ me = null;
+ users = new ArrayList<>();
+ }
+
+ public ArrayList getUsers() {
+ return users;
+ }
+
+ public User getUser(int index) {
+ return users.get(index);
+ }
+
+ public void addUser(User user) {
+ this.users.add(user);
+ this.setChanged();
+ this.notifyObservers(user);
+ }
+
+ public void removeUser(String id) {
+ int index = searchById(id);
+ this.users.remove(index);
+ this.setChanged();
+ this.notifyObservers(new Integer(id));
+ }
+
+ public void updateUser(String id, User user) {
+ int index = searchById(id);
+ this.users.get(index).setPosition(user.getPosition());
+ this.setChanged();
+ this.notifyObservers(this.users.get(index));
+ }
+
+ public boolean contains(User user) {
+ boolean res = false;
+ for (User u : this.getUsers()) {
+ res = (res||(u.getName()==user.getName()));
+ }
+ return res;
+ }
+
+ private int searchById(String id) {
+ int index = -1;
+ int i = 0;
+ String j = "";
+ while(i < users.size() && index==-1) {
+ j = users.get(i).getId();
+ index = j.equals(id)?i:-1;
+ i++;
+ }
+ return index;
+ }
+
+ public User getMe() {
+ return me;
+ }
+
+ public void setMe(User me) {
+ this.me = me;
+ this.addUser(me);
+ }
+}
diff --git a/app/src/main/java/ovh/exception/watchdogzz/model/WDArtefact.java b/app/src/main/java/ovh/exception/watchdogzz/model/WDArtefact.java
new file mode 100644
index 0000000..fc43adb
--- /dev/null
+++ b/app/src/main/java/ovh/exception/watchdogzz/model/WDArtefact.java
@@ -0,0 +1,52 @@
+package ovh.exception.watchdogzz.model;
+
+import android.content.Context;
+
+import javax.microedition.khronos.opengles.GL10;
+
+import ovh.exception.watchdogzz.data.GPSPosition;
+
+/**
+ * Created by begarco on 19/11/2016.
+ */
+
+public class WDArtefact implements WDDrawable {
+ private WDObjet objet;
+ private GPSPosition position;
+ private String label;
+ private String info;
+
+ // Constructor - Setup the data-array buffers
+ public WDArtefact(Context context) {
+ objet = new WDObjet(WDObjet.Shape.CIRCLE, 0,0,0,0.05f,64);
+ }
+
+ // Render this shape
+ public void draw(GL10 gl) {
+ objet.draw(gl);
+ }
+
+ public GPSPosition getPosition() {
+ return position;
+ }
+
+ public void setPosition(GPSPosition position) {
+ this.position = position;
+ }
+
+ public String getLabel() {
+ return label;
+ }
+
+ public void setLabel(String label) {
+ this.label = label;
+ }
+
+ public String getInfo() {
+ return info;
+ }
+
+ public void setInfo(String info) {
+ this.info = info;
+ }
+}
diff --git a/app/src/main/java/ovh/exception/watchdogzz/model/WDDrawable.java b/app/src/main/java/ovh/exception/watchdogzz/model/WDDrawable.java
new file mode 100644
index 0000000..81e8994
--- /dev/null
+++ b/app/src/main/java/ovh/exception/watchdogzz/model/WDDrawable.java
@@ -0,0 +1,10 @@
+package ovh.exception.watchdogzz.model;
+
+import javax.microedition.khronos.opengles.GL10;
+
+/**
+ * Created by begarco on 19/11/2016.
+ */
+public interface WDDrawable {
+ public void draw(GL10 gl);
+}
diff --git a/app/src/main/java/ovh/exception/watchdogzz/model/WDMap.java b/app/src/main/java/ovh/exception/watchdogzz/model/WDMap.java
new file mode 100644
index 0000000..01a96f0
--- /dev/null
+++ b/app/src/main/java/ovh/exception/watchdogzz/model/WDMap.java
@@ -0,0 +1,99 @@
+package ovh.exception.watchdogzz.model;
+
+import android.content.Context;
+import android.util.Log;
+import android.util.Pair;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Observable;
+import java.util.Observer;
+
+import javax.microedition.khronos.opengles.GL10;
+
+import ovh.exception.watchdogzz.data.User;
+
+/**
+ * Created by begarco on 19/11/2016.
+ */
+
+public class WDMap extends Observable implements WDDrawable, Observer {
+ private WDObjet map;
+ private HashMap markers;
+ private Context context;
+
+ // Constructor - Setup the data-array buffers
+ public WDMap(Context context) {
+ this.context = context;
+ WDObjParser parser = new WDObjParser();
+ parser.Parse(context, "isima2d_o");
+ map = parser.GetObjects().get(0);
+ markers = new HashMap<>();
+
+ //markers.add(new Pair(new WDArtefact(context), new float[3]));
+ }
+
+ public void addMarker(String id, WDArtefact art) {
+ markers.put(id,art);
+ }
+
+ // intersection of bat a and b
+ float [] origin = {45.759231f, 3.111185f, 0.0f};
+ //float [] origin = {0,0,0};
+
+
+ // Render this shape
+ public void draw(GL10 gl) {
+ // dessin de la map
+ gl.glPushMatrix();
+ gl.glPushMatrix();
+ gl.glRotatef(180.0f,0.0f,1.0f,0.0f);
+ gl.glRotatef(57.55046185f,0.0f,0.0f,1.0f);
+ gl.glScalef(0.002f,0.002f,0.002f);
+ gl.glTranslatef(-1682f,-1016f,0); // position dans le mesh du point d'origine
+ map.draw(gl);
+ gl.glPopMatrix();
+
+ // dessin des marqueurs
+ for (WDArtefact x : markers.values()) {
+ gl.glPushMatrix();
+ float[] tmp = x.getPosition().getForMap(origin,3169.8f);
+ gl.glTranslatef(tmp[0],tmp[1], 0.5f);
+ Log.d("ME", x.getPosition().toString());
+ x.draw(gl);
+ gl.glPopMatrix();
+ }
+ gl.glPopMatrix();
+ }
+
+ @Override
+ public void update(Observable observable, Object data) {
+ if (data instanceof User) {
+ User u = (User)data;
+ WDArtefact ar;
+ if(markers.containsKey(u.getId())) { // faire update
+ Log.d("ARTEFACT", "update");
+ ar = markers.get(u.getId());
+ ar.setPosition(u.getPosition());
+ ar.setLabel(u.getName());
+ ar.setInfo(u.getEmail());
+ } else { // faire ajout
+ Log.d("ARTEFACT", "add");
+ ar = new WDArtefact(context);
+ ar.setPosition(u.getPosition());
+ ar.setLabel(u.getName());
+ ar.setInfo(u.getEmail());
+ markers.put(u.getId(),ar);
+ }
+ } else if (data instanceof Integer) { // suppression
+ int index = (int) data;
+ Log.d("ARTEFACT", "remove");
+ if(markers.containsKey(index)) {
+ markers.remove(index);
+ }
+ }
+ this.setChanged();
+ this.notifyObservers();
+ }
+}
diff --git a/app/src/main/java/ovh/exception/watchdogzz/model/WDObjParser.java b/app/src/main/java/ovh/exception/watchdogzz/model/WDObjParser.java
new file mode 100644
index 0000000..697d71a
--- /dev/null
+++ b/app/src/main/java/ovh/exception/watchdogzz/model/WDObjParser.java
@@ -0,0 +1,195 @@
+package ovh.exception.watchdogzz.model;
+
+import android.content.Context;
+import android.util.Log;
+
+import java.io.BufferedReader;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.util.ArrayList;
+
+/**
+ * Created by begarco on 19/11/2016.
+ */
+
+public class WDObjParser {
+
+ private ArrayList vertices;
+ private ArrayList vt;
+ private ArrayList vn;
+ private ArrayList faces;
+ private ArrayList textures;
+ private ArrayList normales;
+ private ArrayList objets;
+ private boolean isParsed;
+ private boolean isCreatingObject;
+
+ public WDObjParser() {
+ Clear();
+ }
+
+ /**
+ * Parse un fichier obj en objets 3d
+ * @param context
+ * @param filename
+ */
+ public void Parse(Context context, String filename) {
+
+ Clear();
+
+ try {
+ InputStream inputStream = context.getResources().openRawResource(
+ context.getResources().getIdentifier(filename,
+ "raw", context.getPackageName()));
+
+ if ( inputStream != null ) {
+ InputStreamReader inputStreamReader = new InputStreamReader(inputStream);
+ BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
+ String receiveString = "";
+ StringBuilder stringBuilder = new StringBuilder();
+
+ while ( (receiveString = bufferedReader.readLine()) != null ) {
+
+ if(receiveString.contains("v ")) { // lorsque l'on trouve un sommet
+ float[] line = parseFloat(receiveString.substring(2).split(" "),3);
+ for(int f = 0 ; f < line.length ; ++f)
+ line[f] = line[f];
+ vertices.add(line);
+ } else if(receiveString.contains("vt ")) { // lorsque l'on trouve un sommet de texture
+ try {
+ float[] line = parseFloat(receiveString.substring(3).split(" "),2);
+ vt.add(line);
+ } catch (Exception e) {
+ Log.d("VT",receiveString+" "+receiveString.substring(3).split(" "));
+ }
+ } else if(receiveString.contains("vn ")) { // lorsque l'on trouve une normale
+ try {
+ float[] line = parseFloat(receiveString.substring(3).split(" "),3);
+ vn.add(line);
+ } catch (Exception e) {
+ Log.d("VN",receiveString+" "+receiveString.substring(3).split(" "));
+ }
+ } else if(receiveString.contains("mtllib ")) { // chargement des textures
+ /// TODO peut etre si on fait une texture
+ } else if(receiveString.contains("f ")) { // lorsque l'on trouve une face
+ String[] tmp = receiveString.substring(2).split(" ");
+
+ int [] c = new int[tmp.length]; // indices des vertices
+ int [] d = new int[tmp.length]; // indices des textures
+ int [] e = new int[tmp.length]; // indices des normales
+
+ for (int j = 0; j < c.length; j++) {
+ c[j] = Integer.parseInt(tmp[j].split("/")[0])-1;
+ d[j] = Integer.parseInt(tmp[j].split("/")[1])-1;
+ e[j] = Integer.parseInt(tmp[j].split("/")[2])-1;
+ }
+
+ AppendTriangularized(c,faces);
+ AppendTriangularized(d,textures);
+ AppendTriangularized(e,normales);
+ } else if(receiveString.contains("o ")) { // lorsque l'on trouve un nouvel objet
+ if(this.isCreatingObject)
+ CreateWDObjet();
+ this.isCreatingObject = true;
+ } else if(receiveString.contains("g ")) { // lorsque l'on trouve un nouveau groupe
+ /// pas utile
+ } else if(receiveString.contains("usemtl ")) { // lorsque l'on trouve un nouveau materiau
+ /// TODO peut etre si on fait une texture
+ }
+ }
+
+ inputStream.close();
+
+ // convertir en objet
+ if(isCreatingObject)
+ CreateWDObjet();
+
+ this.isCreatingObject = false;
+
+ isParsed = true;
+ }
+ }
+ catch (FileNotFoundException e) {
+ Log.e("login activity", "File not found: " + e.toString());
+ } catch (IOException e) {
+ Log.e("login activity", "Can not read file: " + e.toString());
+ }
+
+ }
+
+ /**
+ * Nettoie le parser
+ */
+ public void Clear() {
+ vertices = new ArrayList<>();
+ vt = new ArrayList<>();
+ vn = new ArrayList<>();
+ faces = new ArrayList<>();
+ textures = new ArrayList<>();
+ normales = new ArrayList<>();
+ objets = new ArrayList<>();
+ isParsed = false;
+ isCreatingObject = false;
+ }
+
+ private void CreateWDObjet() {
+ WDObjet res = new WDObjet(vertices, faces);
+ faces = new ArrayList<>();
+ objets.add(res);
+ }
+
+ /**
+ * Convertit un tableau de string en tableau de float
+ * @param str
+ * @return
+ */
+ private float[] parseFloat(String[] str, int size) {
+ float[] result = new float[size];
+ for (int i = 0; i < size; ++i) {
+ result[i] = Float.parseFloat(str[i]);
+ }
+ return result;
+ }
+
+ /**
+ * Convertit un tableau de string en tableau de int
+ * @param str
+ * @return
+ */
+ private int[] parseInt(String[] str) {
+ int[] result = new int[str.length];
+ for (int i = 0; i < str.length; ++i) {
+ result[i] = Integer.parseInt(str[i]);
+ }
+ return result;
+ }
+
+ /**
+ * Ajoute une face sous forme de triangles
+ * @param face
+ * @param array
+ */
+ private void AppendTriangularized(int[] face, ArrayList array) {
+ if(face.length == 3) {
+ array.add(face);
+ } else if(face.length == 4) {
+ int[] faceA = new int[3];
+ int[] faceB = new int[3];
+
+ for(int i = 0; i<3; ++i) { // creation des triangles
+ faceA[i] = face[i];
+ faceB[i] = face[(i + 2)%4];
+ }
+
+ // ajout des traingles
+ array.add(faceA);
+ array.add(faceB);
+ }
+ }
+
+ ArrayList GetObjects() {
+ return isParsed ? objets : null;
+ }
+}
diff --git a/app/src/main/java/ovh/exception/watchdogzz/model/WDObjet.java b/app/src/main/java/ovh/exception/watchdogzz/model/WDObjet.java
new file mode 100644
index 0000000..43bd092
--- /dev/null
+++ b/app/src/main/java/ovh/exception/watchdogzz/model/WDObjet.java
@@ -0,0 +1,179 @@
+package ovh.exception.watchdogzz.model;
+
+import android.util.Log;
+
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.nio.FloatBuffer;
+import java.nio.IntBuffer;
+import java.util.ArrayList;
+
+import javax.microedition.khronos.opengles.GL10;
+
+import static java.lang.Math.cos;
+import static java.lang.Math.sin;
+
+/**
+ * Created by begarco on 19/11/2016.
+ */
+
+public class WDObjet implements WDDrawable {
+ private FloatBuffer vertexBuffer; // Buffer for vertex-array
+ private ByteBuffer indexBuffer; // Buffer for index-array
+ private int nbIndices;
+ private Shape type;
+
+ public enum Shape {
+ CUSTOM,
+ CIRCLE,
+ RECTANGLE,
+ TRIANGLE,
+ SPHERE
+ }
+
+ public WDObjet(Shape s, float ... params) {
+
+ // donnees de forme
+ ArrayList vertices = new ArrayList<>();
+ ArrayList faces = new ArrayList<>();
+
+ switch (s) {
+ case CUSTOM:
+ break;
+ case CIRCLE: // x,y,z,rayon,precision
+ if(params.length >= 2) {
+ // traitement des params
+ float[] center = {params[0],params[1],params.length>2?params[2]:0};
+ float rayon = params.length>3?params[3]:1;
+ int precision = params.length>4? (int) params[4] :64;
+
+ // precalculs
+ float pas = 2.0f * (float)Math.PI / (float)precision;
+ vertices.add(center);
+ for (int i = 0; i < precision + 1; i++){
+ float angle = i * pas;
+ float cx = (float) (rayon * cos(angle));
+ float cy = (float) (rayon * sin(angle));
+ float[] cur = { cx+center[0], cy+center[1], center[2] };
+
+ vertices.add(cur);
+ }
+ // ajout des faces
+ for(int i = 1 ; i <= precision ; ++i) {
+ int[] fac = { 0, i, i+1 };
+ faces.add(fac);
+ }
+ // generation
+ fromRawData(vertices, faces);
+ } else {
+ Log.w(WDObjet.class.getCanonicalName(), "Need of x, y, z, rayon and precision to draw a circle.");
+ }
+ break;
+ case RECTANGLE:
+ break;
+ case TRIANGLE: // x1,y1,z1 , x2,y2,z2 , x3,y3,z3
+ if(params.length != 9) {
+ Log.w(WDObjet.class.getCanonicalName(), "Need of x1,y1,z1 , x2,y2,z2 , x3,y3,z3 to draw a triangle.");
+ } else {
+ for(int i = 0 ; i < 3 ; ++i) {
+ float[] a = {params[3*i], params[3*i+1], params[3*i+2]};
+ vertices.add(a);
+ }
+ int[] tri = { 0, 1, 2 };
+ faces.add(tri);
+ fromRawData(vertices, faces);
+ }
+ break;
+ case SPHERE:
+ if(params.length >= 2) {
+ // traitement des params
+ float[] center = {params[0], params[1], params.length > 2 ? params[2] : 0};
+ float rayon = params.length > 3 ? params[3] : 1;
+ float angleA, angleB;
+ float cos, sin;
+ float r1, r2;
+ float h1, h2;
+ float step = 30.0f;
+ float[] v = new float[3];
+ float ratio = (float)Math.PI / 180.0f;
+
+ for (angleA = -90.0f; angleA < 90.0f; angleA += step) {
+ int n = 0;
+
+ r1 = (float) Math.cos(angleA * ratio);
+ r2 = (float) Math.cos((angleA + step) * ratio);
+ h1 = (float) Math.sin(angleA * ratio);
+ h2 = (float) Math.sin((angleA + step) * ratio);
+
+ // Fixed latitude, 360 degrees rotation to traverse a weft
+ for (angleB = 0.0f; angleB <= 360.0f; angleB += step) {
+
+ cos = (float) Math.cos(angleB * ratio);
+ sin = -(float) Math.sin(angleB * ratio);
+
+ v[0] = (r2 * cos);
+ v[1] = (h2);
+ v[2] = (r2 * sin);
+ vertices.add(v);
+ v[0] = (r1 * cos);
+ v[1] = (h1);
+ v[2] = (r1 * sin);
+ vertices.add(v);
+
+ n += 2;
+ }
+ }
+
+ // tracer des faces
+ for (int i = 1; i < vertices.size()-1 ; ++i) {
+ faces.add(new int[]{i, i, i+1});
+ }
+
+ // generation
+ fromRawData(vertices, faces);
+ }
+ break;
+ default:
+ Log.w(WDObjet.class.getCanonicalName(), "You should use public WDObjet(ArrayList vertices, ArrayList faces)");
+ break;
+ }
+ type = s;
+ }
+
+ public WDObjet(ArrayList vertices, ArrayList faces) {
+ fromRawData(vertices, faces);
+ }
+
+ private void fromRawData(ArrayList vertices, ArrayList faces) {
+ // Setup vertex-array buffer. Vertices in float. A float has 4 bytes.
+ ByteBuffer vbb = ByteBuffer.allocateDirect((vertices.size() * Float.SIZE * 3) / Byte.SIZE);
+ vbb.order(ByteOrder.nativeOrder()); // Use native byte order
+ vertexBuffer = vbb.asFloatBuffer(); // Convert byte buffer to float
+ for (float[] vtx : vertices) {
+ vertexBuffer.put(vtx);
+ }
+ vertexBuffer.position(0); // Rewind
+
+ // Setup index-array buffer. Indices in byte.
+ indexBuffer = ByteBuffer.allocateDirect((faces.size() * 3 * Integer.SIZE) / Byte.SIZE);
+ for (int[] face : faces) {
+ for (int val : face) {
+ indexBuffer.put((byte) val);
+ }
+ }
+ indexBuffer.position(0);
+
+ nbIndices = faces.size() * 3;
+ }
+
+ // Render this shape
+ public void draw(GL10 gl) {
+ // Enable vertex-array and define the buffers
+ gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
+ gl.glVertexPointer(3, GL10.GL_FLOAT, 0, vertexBuffer);
+
+ // Draw the primitives via index-array
+ gl.glDrawElements(GL10.GL_TRIANGLES, nbIndices, GL10.GL_UNSIGNED_BYTE, indexBuffer);
+ gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
+ }
+}
diff --git a/app/src/main/java/ovh/exception/watchdogzz/network/DownloadImageTask.java b/app/src/main/java/ovh/exception/watchdogzz/network/DownloadImageTask.java
new file mode 100644
index 0000000..e954b32
--- /dev/null
+++ b/app/src/main/java/ovh/exception/watchdogzz/network/DownloadImageTask.java
@@ -0,0 +1,34 @@
+package ovh.exception.watchdogzz.network;
+
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.os.AsyncTask;
+import android.util.Log;
+import android.widget.ImageView;
+
+import java.io.InputStream;
+
+public class DownloadImageTask extends AsyncTask {
+ ImageView bmImage;
+
+ public DownloadImageTask(ImageView bmImage) {
+ this.bmImage = bmImage;
+ }
+
+ protected Bitmap doInBackground(String... urls) {
+ String urldisplay = urls[0];
+ Bitmap mIcon11 = null;
+ try {
+ InputStream in = new java.net.URL(urldisplay).openStream();
+ mIcon11 = BitmapFactory.decodeStream(in);
+ } catch (Exception e) {
+ Log.e("Error", e.getMessage());
+ e.printStackTrace();
+ }
+ return mIcon11;
+ }
+
+ protected void onPostExecute(Bitmap result) {
+ bmImage.setImageBitmap(result);
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/ovh/exception/watchdogzz/network/IWSConsumer.java b/app/src/main/java/ovh/exception/watchdogzz/network/IWSConsumer.java
new file mode 100644
index 0000000..76ed61e
--- /dev/null
+++ b/app/src/main/java/ovh/exception/watchdogzz/network/IWSConsumer.java
@@ -0,0 +1,7 @@
+package ovh.exception.watchdogzz.network;
+
+import org.json.JSONObject;
+
+public interface IWSConsumer {
+ void consume(JSONObject json);
+}
diff --git a/app/src/main/java/ovh/exception/watchdogzz/network/NetworkManager.java b/app/src/main/java/ovh/exception/watchdogzz/network/NetworkManager.java
new file mode 100644
index 0000000..073b8fc
--- /dev/null
+++ b/app/src/main/java/ovh/exception/watchdogzz/network/NetworkManager.java
@@ -0,0 +1,66 @@
+package ovh.exception.watchdogzz.network;
+
+import android.content.Context;
+import android.graphics.Bitmap;
+import android.util.LruCache;
+
+import com.android.volley.Request;
+import com.android.volley.RequestQueue;
+import com.android.volley.toolbox.ImageLoader;
+import com.android.volley.toolbox.Volley;
+
+/**
+ * Created by begarco on 20/11/2016.
+ */
+
+public class NetworkManager {
+
+ private static NetworkManager mInstance;
+ private RequestQueue mRequestQueue;
+ private ImageLoader mImageLoader;
+ private static Context mCtx;
+
+ private NetworkManager(Context context) {
+ mCtx = context;
+ mRequestQueue = getRequestQueue();
+
+ mImageLoader = new ImageLoader(mRequestQueue, new ImageLoader.ImageCache() {
+ private final LruCache
+ cache = new LruCache(20);
+
+ @Override
+ public Bitmap getBitmap(String url) {
+ return cache.get(url);
+ }
+
+ @Override
+ public void putBitmap(String url, Bitmap bitmap) {
+ cache.put(url, bitmap);
+ }
+ });
+ }
+
+ public static synchronized NetworkManager getInstance(Context context) {
+ if (mInstance == null) {
+ mInstance = new NetworkManager(context);
+ }
+ return mInstance;
+ }
+
+ public RequestQueue getRequestQueue() {
+ if (mRequestQueue == null) {
+ // getApplicationContext() is key, it keeps you from leaking the
+ // Activity or BroadcastReceiver if someone passes one in.
+ mRequestQueue = Volley.newRequestQueue(mCtx.getApplicationContext());
+ }
+ return mRequestQueue;
+ }
+
+ public void addToRequestQueue(Request req) {
+ getRequestQueue().add(req);
+ }
+
+ public ImageLoader getImageLoader() {
+ return mImageLoader;
+ }
+}
diff --git a/app/src/main/java/ovh/exception/watchdogzz/network/PostWebServiceTask.java b/app/src/main/java/ovh/exception/watchdogzz/network/PostWebServiceTask.java
new file mode 100644
index 0000000..103aede
--- /dev/null
+++ b/app/src/main/java/ovh/exception/watchdogzz/network/PostWebServiceTask.java
@@ -0,0 +1,92 @@
+package ovh.exception.watchdogzz.network;
+
+import android.content.Context;
+import android.os.AsyncTask;
+import android.util.ArrayMap;
+import android.util.Log;
+
+import com.android.volley.Request;
+import com.android.volley.Response;
+import com.android.volley.VolleyError;
+import com.android.volley.toolbox.JsonObjectRequest;
+
+import org.json.JSONArray;
+import org.json.JSONException;
+import org.json.JSONObject;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import ovh.exception.watchdogzz.data.User;
+
+public class PostWebServiceTask extends AsyncTask {
+ private IWSConsumer consumer;
+ private Context context;
+ private Boolean isDone;
+ private User me;
+ private JSONObject data = null;
+
+ public PostWebServiceTask(Context context, IWSConsumer consumer, User me) {
+ this.context = context;
+ this.consumer = consumer;
+ this.isDone = false;
+ this.me = me;
+ }
+
+ protected JSONObject doInBackground(String... urls) {
+ String url = urls[0];
+
+ JSONObject result = null;
+
+ JSONObject request = new JSONObject();
+ JSONArray loc = new JSONArray();
+ try {
+ loc.put(me.getPosition().getLatitude());
+ loc.put(me.getPosition().getLongitude());
+ loc.put(me.getPosition().getAltitude());
+ request.put("login", me.getName());
+ request.put("name", me.getName());
+ request.put("location", loc);
+ } catch (JSONException e) {
+ e.printStackTrace();
+ }
+
+ final Map mHeaders = new HashMap<>();
+ mHeaders.put("json", "True");
+
+ Log.d("WS TASK", "Sent: " + request.toString());
+
+ JsonObjectRequest jsObjRequest = new JsonObjectRequest
+ (Request.Method.POST, url, request, new Response.Listener() {
+ @Override
+ public void onResponse(JSONObject response) {
+ Log.d("WS TASK", "Received: " + response.toString());
+ data = response;
+ isDone = true;
+ }
+ }, new Response.ErrorListener() {
+ @Override
+ public void onErrorResponse(VolleyError error) {
+ Log.e("WS TASK", "#" + error.getMessage());
+ isDone = true;
+ }
+ }) {
+ public Map getHeaders() {
+ return mHeaders;
+ }
+ };
+
+ // Access the RequestQueue through your singleton class.
+ NetworkManager.getInstance(context).addToRequestQueue(jsObjRequest);
+
+ while(!isDone);
+
+ result = data;
+
+ return result;
+ }
+
+ protected void onPostExecute(JSONObject result) {
+
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/ovh/exception/watchdogzz/network/PostitionManager.java b/app/src/main/java/ovh/exception/watchdogzz/network/PostitionManager.java
new file mode 100644
index 0000000..e24574c
--- /dev/null
+++ b/app/src/main/java/ovh/exception/watchdogzz/network/PostitionManager.java
@@ -0,0 +1,64 @@
+package ovh.exception.watchdogzz.network;
+
+import android.Manifest;
+import android.app.Activity;
+import android.content.Context;
+import android.content.pm.PackageManager;
+import android.location.Location;
+import android.location.LocationListener;
+import android.location.LocationManager;
+import android.os.Bundle;
+import android.support.v4.app.ActivityCompat;
+import android.util.Log;
+
+import ovh.exception.watchdogzz.activities.MainActivity;
+import ovh.exception.watchdogzz.data.GPSPosition;
+import ovh.exception.watchdogzz.data.User;
+
+/**
+ * Created by begarco on 20/11/2016.
+ */
+
+public class PostitionManager {
+ // Acquire a reference to the system Location Manager
+ private LocationManager locationManager;
+ // Define a listener that responds to location updates
+ private LocationListener locationListener;
+
+ private Context context;
+ private MainActivity thisActivity;
+
+ public PostitionManager(MainActivity context) {
+ this.context = context;
+ this.thisActivity = context;
+
+ locationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);
+
+ locationListener = new LocationListener() {
+ public void onLocationChanged(Location location) {
+ // Called when a new location is found by the network location provider.
+ Log.d("POSITION GPS", location.toString());
+ thisActivity.getUsers().updateUser(thisActivity.getUsers().getMe().getId(),
+ new User("","","","",null,true,new GPSPosition( (float)location.getLongitude(),
+ (float)location.getLatitude(),
+ (float)location.getAltitude())));
+ }
+
+ public void onStatusChanged(String provider, int status, Bundle extras) {
+
+ }
+
+ public void onProviderEnabled(String provider) {
+ }
+
+ public void onProviderDisabled(String provider) {
+ }
+ };
+ if (ActivityCompat.checkSelfPermission(this.context, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this.context, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
+ return;
+ }
+ locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 500, 0, locationListener);
+ }
+
+
+}
diff --git a/app/src/main/java/ovh/exception/watchdogzz/network/WebServiceTask.java b/app/src/main/java/ovh/exception/watchdogzz/network/WebServiceTask.java
new file mode 100644
index 0000000..5394678
--- /dev/null
+++ b/app/src/main/java/ovh/exception/watchdogzz/network/WebServiceTask.java
@@ -0,0 +1,60 @@
+package ovh.exception.watchdogzz.network;
+
+import android.content.Context;
+import android.os.AsyncTask;
+import android.util.Log;
+
+import com.android.volley.Request;
+import com.android.volley.Response;
+import com.android.volley.VolleyError;
+import com.android.volley.toolbox.JsonObjectRequest;
+
+import org.json.JSONObject;
+
+public class WebServiceTask extends AsyncTask {
+ private IWSConsumer consumer;
+ private Context context;
+ private Boolean isDone;
+ private JSONObject data = null;
+
+ public WebServiceTask(Context context, IWSConsumer consumer) {
+ this.context = context;
+ this.consumer = consumer;
+ this.isDone = false;
+ }
+
+ protected JSONObject doInBackground(String... urls) {
+ String url = urls[0];
+
+ JSONObject result = null;
+
+ JsonObjectRequest jsObjRequest = new JsonObjectRequest
+ (Request.Method.GET, url, null, new Response.Listener() {
+ @Override
+ public void onResponse(JSONObject response) {
+ Log.d("WS TASK", "Received: " + response.toString());
+ data = response;
+ isDone = true;
+ }
+ }, new Response.ErrorListener() {
+ @Override
+ public void onErrorResponse(VolleyError error) {
+ Log.e("WS TASK", "#" + error.getMessage());
+ isDone = true;
+ }
+ });
+
+ // Access the RequestQueue through your singleton class.
+ NetworkManager.getInstance(context).addToRequestQueue(jsObjRequest);
+
+ while(!isDone);
+
+ result = data;
+
+ return result;
+ }
+
+ protected void onPostExecute(JSONObject result) {
+ consumer.consume(result);
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/ovh/exception/watchdogzz/view/WDCamera.java b/app/src/main/java/ovh/exception/watchdogzz/view/WDCamera.java
new file mode 100644
index 0000000..4d1b6b6
--- /dev/null
+++ b/app/src/main/java/ovh/exception/watchdogzz/view/WDCamera.java
@@ -0,0 +1,54 @@
+package ovh.exception.watchdogzz.view;
+
+import javax.microedition.khronos.opengles.GL10;
+
+/**
+ * Created by begarco on 19/11/2016.
+ */
+
+public class WDCamera {
+ private float[] mPosition;
+
+ /**
+ * Defini la position de la camera
+ * @param x
+ * @param y
+ * @param z
+ */
+ public WDCamera(float x, float y, float z) {
+ this.mPosition = new float[3];
+ setPosition(x,y,z);
+ }
+
+ /**
+ * Defini la position de la camera
+ * @param x
+ * @param y
+ * @param z
+ */
+ public void setPosition(float x, float y, float z) {
+ mPosition[0] = x;
+ mPosition[1] = y;
+ mPosition[2] = z;
+ }
+
+ /**
+ * utilise la camera
+ * @param gl
+ */
+ public void watch(GL10 gl) {
+ gl.glTranslatef(x(),y(),z());
+ }
+
+ public float x() {
+ return this.mPosition[0];
+ }
+
+ public float y() {
+ return this.mPosition[1];
+ }
+
+ public float z() {
+ return this.mPosition[2];
+ }
+}
diff --git a/app/src/main/java/ovh/exception/watchdogzz/view/WDRenderer.java b/app/src/main/java/ovh/exception/watchdogzz/view/WDRenderer.java
new file mode 100644
index 0000000..00e2997
--- /dev/null
+++ b/app/src/main/java/ovh/exception/watchdogzz/view/WDRenderer.java
@@ -0,0 +1,173 @@
+package ovh.exception.watchdogzz.view;
+
+import android.content.Context;
+import android.opengl.GLSurfaceView.Renderer;
+import android.opengl.GLU;
+
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.nio.FloatBuffer;
+
+import javax.microedition.khronos.egl.EGLConfig;
+import javax.microedition.khronos.opengles.GL10;
+
+import ovh.exception.watchdogzz.model.WDMap;
+
+
+/**
+ * Created by begarco on 19/11/2016.
+ */
+
+public class WDRenderer implements Renderer {
+
+ private Context context; // contexte de l'application
+ private WDCamera camera; // camera
+ private WDMap map; // modele de la carte
+
+
+ private final float[] mat_ambient = { 0.2f, 0.3f, 0.8f, 1.0f };
+ private FloatBuffer mat_ambient_buf;
+ // Parallel incident light
+ private final float[] mat_diffuse = { 0.4f, 0.6f, 0.9f, 1.0f };
+ private FloatBuffer mat_diffuse_buf;
+ // The highlighted area
+ private final float[] mat_specular = { 0.2f * 0.4f, 0.2f * 0.6f, 0.2f * 0.8f, 1.0f };
+ private FloatBuffer mat_specular_buf;
+
+ public volatile float mLightX = 0f;
+ public volatile float mLightY = 0f;
+ public volatile float mLightZ = 3f;
+
+
+ // Constructeur avec contexte
+ public WDRenderer(Context context) {
+ this.context = context;
+ this.setMap(new WDMap(context));
+ this.camera = new WDCamera(0, 0, -8.0f);
+ }
+
+ /**
+ * Methode appelee lors de la premiere creation
+ * @param gl
+ * @param config
+ */
+ @Override
+ public void onSurfaceCreated(GL10 gl, EGLConfig config) {
+ gl.glClearColor(0.63f, 0.63f, 0.63f, 1.0f); // Set color's clear-value to black
+ gl.glClearDepthf(1.0f); // Set depth's clear-value to farthest
+ gl.glEnable(GL10.GL_DEPTH_TEST); // Enables depth-buffer for hidden surface removal
+ gl.glDepthFunc(GL10.GL_LEQUAL); // The type of depth testing to do
+ gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, GL10.GL_NICEST); // nice perspective view
+ gl.glShadeModel(GL10.GL_SMOOTH); // Enable smooth shading of color
+ gl.glDisable(GL10.GL_DITHER); // Disable dithering for better performance
+
+ /** possibilite de rajouter du code d'initialisation **/
+
+ initBuffers();
+ }
+
+ private void initBuffers() {
+ ByteBuffer bufTemp = ByteBuffer.allocateDirect(mat_ambient.length * 4);
+ bufTemp.order(ByteOrder.nativeOrder());
+ mat_ambient_buf = bufTemp.asFloatBuffer();
+ mat_ambient_buf.put(mat_ambient);
+ mat_ambient_buf.position(0);
+
+ bufTemp = ByteBuffer.allocateDirect(mat_diffuse.length * 4);
+ bufTemp.order(ByteOrder.nativeOrder());
+ mat_diffuse_buf = bufTemp.asFloatBuffer();
+ mat_diffuse_buf.put(mat_diffuse);
+ mat_diffuse_buf.position(0);
+
+ bufTemp = ByteBuffer.allocateDirect(mat_specular.length * 4);
+ bufTemp.order(ByteOrder.nativeOrder());
+ mat_specular_buf = bufTemp.asFloatBuffer();
+ mat_specular_buf.put(mat_specular);
+ mat_specular_buf.position(0);
+ }
+
+ /**
+ * Methode de callback appelee lors d'une modification de la vue
+ * @param gl
+ * @param width
+ * @param height
+ */
+ @Override
+ public void onSurfaceChanged(GL10 gl, int width, int height) {
+ if (height == 0) height = 1; // To prevent divide by zero
+ float aspect = (float)width / height;
+
+ // Set the viewport (display area) to cover the entire window
+ gl.glViewport(0, 0, width, height);
+
+ // Setup perspective projection, with aspect ratio matches viewport
+ gl.glMatrixMode(GL10.GL_PROJECTION); // Select projection matrix
+ gl.glLoadIdentity(); // Reset projection matrix
+ // Use perspective projection
+ GLU.gluPerspective(gl, 45, aspect, 0.1f, 100.f);
+
+ gl.glMatrixMode(GL10.GL_MODELVIEW); // Select model-view matrix
+ gl.glLoadIdentity(); // Reset
+
+ /** possibilite de rajouter du code pour le redimensionnement **/
+ }
+
+ /**
+ * dessine la vue
+ * @param gl
+ */
+ @Override
+ public void onDrawFrame(GL10 gl) {
+ // nettoyage
+ gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
+
+ /** dessin de la scene **/
+ gl.glLoadIdentity(); // Reset model-view matrix
+
+ gl.glEnable(GL10.GL_LIGHTING);
+ gl.glEnable(GL10.GL_LIGHT0);
+
+ // Texture of material
+ gl.glMaterialfv(GL10.GL_FRONT_AND_BACK, GL10.GL_AMBIENT, mat_ambient_buf);
+ gl.glMaterialfv(GL10.GL_FRONT_AND_BACK, GL10.GL_DIFFUSE, mat_diffuse_buf);
+ gl.glMaterialfv(GL10.GL_FRONT_AND_BACK, GL10.GL_SPECULAR, mat_specular_buf);
+ // Specular exponent 0~128 less rough
+ gl.glMaterialf(GL10.GL_FRONT_AND_BACK, GL10.GL_SHININESS, 96.0f);
+
+ //The position of the light source
+ float[] light_position = {mLightX, mLightY, mLightZ, 0.0f};
+ ByteBuffer mpbb = ByteBuffer.allocateDirect(light_position.length*4);
+ mpbb.order(ByteOrder.nativeOrder());
+ FloatBuffer mat_posiBuf = mpbb.asFloatBuffer();
+ mat_posiBuf.put(light_position);
+ mat_posiBuf.position(0);
+ gl.glLightfv(GL10.GL_LIGHT0, GL10.GL_POSITION, mat_posiBuf);
+
+ gl.glPushMatrix();
+ this.camera.watch(gl);
+ gl.glPushMatrix();
+ this.getMap().draw(gl); // Draw model
+ gl.glPopMatrix();
+ gl.glPopMatrix();
+ }
+
+ public void moveCamera(float dx, float dy, float dz) {
+ this.camera.setPosition(camera.x()+dx,camera.y()+dy,camera.z()+dz);
+ }
+
+ /**
+ * effectue un zoom de la camera
+ * @param coef
+ */
+ public void zoomCamera(float coef) {
+ this.camera.setPosition(this.camera.x(), this.camera.y(), this.camera.z()*coef);
+ }
+
+ public WDMap getMap() {
+ return map;
+ }
+
+ public void setMap(WDMap map) {
+ this.map = map;
+ }
+}
diff --git a/app/src/main/java/ovh/exception/watchdogzz/view/WDSurfaceView.java b/app/src/main/java/ovh/exception/watchdogzz/view/WDSurfaceView.java
new file mode 100644
index 0000000..7585f79
--- /dev/null
+++ b/app/src/main/java/ovh/exception/watchdogzz/view/WDSurfaceView.java
@@ -0,0 +1,118 @@
+package ovh.exception.watchdogzz.view;
+
+import android.content.Context;
+import android.opengl.GLSurfaceView;
+import android.util.AttributeSet;
+import android.util.Log;
+import android.view.MotionEvent;
+
+import java.util.ArrayList;
+import java.util.Observable;
+import java.util.Observer;
+
+import ovh.exception.watchdogzz.data.User;
+import ovh.exception.watchdogzz.data.UserManager;
+import ovh.exception.watchdogzz.model.WDMap;
+
+/**
+ * Created by begarco on 19/11/2016.
+ */
+
+public class WDSurfaceView extends GLSurfaceView implements Observer {
+
+ private WDRenderer mRenderer;
+
+ // position doigt
+ private float mPreviousX;
+ private float mPreviousY;
+ private boolean isZooming;
+ private float mSpaceBetweenFingers;
+ private int mFirstFinger;
+ private int mSecondFinger;
+
+ public WDSurfaceView(Context context) {
+ this(context, null);
+ }
+
+ public WDSurfaceView(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ isZooming = false;
+ mSpaceBetweenFingers = 0.0f;
+ }
+
+ @Override
+ public void setRenderer(Renderer renderer) {
+ super.setRenderer(renderer);
+ this.mRenderer = (WDRenderer) renderer;
+ setRenderMode(GLSurfaceView.RENDERMODE_WHEN_DIRTY);
+ this.mRenderer.getMap().addObserver(this);
+ }
+
+ public void setRenderer(WDRenderer renderer) {
+ super.setRenderer(renderer);
+ this.mRenderer = renderer;
+ setRenderMode(GLSurfaceView.RENDERMODE_WHEN_DIRTY);
+ this.mRenderer.getMap().addObserver(this);
+ }
+
+ @Override
+ public boolean onTouchEvent(MotionEvent event) {
+
+ boolean b = super.onTouchEvent(event);
+ switch (event.getActionMasked()) {
+ case MotionEvent.ACTION_MOVE:
+ isZooming = isZooming && (event.getPointerCount() > 1);
+ if(this.isZooming){
+ float x1 = event.getX(this.mFirstFinger) - event.getX(this.mSecondFinger);
+ float y1 = event.getY(this.mFirstFinger) - event.getY(this.mSecondFinger);
+ float distance = (float) Math.sqrt(x1 * x1 + y1 * y1);
+ this.mRenderer.zoomCamera(this.mSpaceBetweenFingers/(distance+1));
+ this.mSpaceBetweenFingers = distance;
+ } else {
+ float x = event.getX();
+ float y = event.getY();
+
+ float dx = x - this.mPreviousX;
+ float dy = y - this.mPreviousY;
+ mPreviousX = event.getX();
+ mPreviousY = event.getY();
+
+ this.mRenderer.moveCamera(2 * dx / getWidth(), -2 * dy / getHeight(), 0);
+ }
+
+ requestRender();
+
+ break;
+ case MotionEvent.ACTION_DOWN:
+ this.mFirstFinger = event.getActionIndex();
+ mPreviousX = event.getX();
+ mPreviousY = event.getY();
+ this.isZooming = false;
+ b = true;
+ break;
+ case MotionEvent.ACTION_POINTER_DOWN:
+ if(this.isZooming==false) {
+ mSecondFinger = event.getActionIndex();
+ float x1 = event.getX(this.mFirstFinger) - event.getX(this.mSecondFinger);
+ float y1 = event.getY(this.mFirstFinger) - event.getY(this.mSecondFinger);
+ this.mSpaceBetweenFingers = (float) Math.sqrt(x1 * x1 + y1 * y1);
+ this.isZooming = true;
+ }
+ b = true;
+ break;
+ case MotionEvent.ACTION_POINTER_UP:
+ if(event.getActionIndex() == this.mSecondFinger)
+ this.isZooming = false;
+ break;
+ default:
+ break;
+ }
+
+ return b;
+ }
+
+ @Override
+ public void update(Observable observable, Object data) {
+ requestRender();
+ }
+}
diff --git a/app/src/main/res/drawable-v21/ic_menu_camera.xml b/app/src/main/res/drawable-v21/ic_menu_camera.xml
new file mode 100644
index 0000000..0d9ea10
--- /dev/null
+++ b/app/src/main/res/drawable-v21/ic_menu_camera.xml
@@ -0,0 +1,12 @@
+
+
+
+
diff --git a/app/src/main/res/drawable-v21/ic_menu_gallery.xml b/app/src/main/res/drawable-v21/ic_menu_gallery.xml
new file mode 100644
index 0000000..f6872c4
--- /dev/null
+++ b/app/src/main/res/drawable-v21/ic_menu_gallery.xml
@@ -0,0 +1,9 @@
+
+
+
diff --git a/app/src/main/res/drawable-v21/ic_menu_manage.xml b/app/src/main/res/drawable-v21/ic_menu_manage.xml
new file mode 100644
index 0000000..c1be60b
--- /dev/null
+++ b/app/src/main/res/drawable-v21/ic_menu_manage.xml
@@ -0,0 +1,9 @@
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/drawable-v21/ic_menu_send.xml b/app/src/main/res/drawable-v21/ic_menu_send.xml
new file mode 100644
index 0000000..00c668c
--- /dev/null
+++ b/app/src/main/res/drawable-v21/ic_menu_send.xml
@@ -0,0 +1,9 @@
+
+
+
diff --git a/app/src/main/res/drawable-v21/ic_menu_share.xml b/app/src/main/res/drawable-v21/ic_menu_share.xml
new file mode 100644
index 0000000..a28fb9e
--- /dev/null
+++ b/app/src/main/res/drawable-v21/ic_menu_share.xml
@@ -0,0 +1,9 @@
+
+
+
diff --git a/app/src/main/res/drawable-v21/ic_menu_slideshow.xml b/app/src/main/res/drawable-v21/ic_menu_slideshow.xml
new file mode 100644
index 0000000..209aa64
--- /dev/null
+++ b/app/src/main/res/drawable-v21/ic_menu_slideshow.xml
@@ -0,0 +1,9 @@
+
+
+
diff --git a/app/src/main/res/drawable/logo.png b/app/src/main/res/drawable/logo.png
new file mode 100644
index 0000000..7643fb4
Binary files /dev/null and b/app/src/main/res/drawable/logo.png differ
diff --git a/app/src/main/res/drawable/side_nav_bar.xml b/app/src/main/res/drawable/side_nav_bar.xml
new file mode 100644
index 0000000..458b4b0
--- /dev/null
+++ b/app/src/main/res/drawable/side_nav_bar.xml
@@ -0,0 +1,9 @@
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/activity_login.xml b/app/src/main/res/layout/activity_login.xml
index c1e6b2f..14d683f 100644
--- a/app/src/main/res/layout/activity_login.xml
+++ b/app/src/main/res/layout/activity_login.xml
@@ -1,77 +1,54 @@
-
-
-
-
-
-
+
-
-
+
+
-
-
-
-
+ android:contentDescription="@string/description_logo_wdzz"
+ android:background="@drawable/logo"
+ android:id="@+id/imageView"
+ android:layout_margin="12dp"/>
-
-
-
-
-
-
-
+
+
+
-
+
-
-
-
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml
new file mode 100644
index 0000000..bd74fb7
--- /dev/null
+++ b/app/src/main/res/layout/activity_main.xml
@@ -0,0 +1,25 @@
+
+
+
+
+
+
+
+
diff --git a/app/src/main/res/layout/app_bar_main.xml b/app/src/main/res/layout/app_bar_main.xml
new file mode 100644
index 0000000..7f1a5fb
--- /dev/null
+++ b/app/src/main/res/layout/app_bar_main.xml
@@ -0,0 +1,34 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/src/main/res/layout/app_map_main.xml b/app/src/main/res/layout/app_map_main.xml
new file mode 100644
index 0000000..35700eb
--- /dev/null
+++ b/app/src/main/res/layout/app_map_main.xml
@@ -0,0 +1,29 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/src/main/res/layout/content_main.xml b/app/src/main/res/layout/content_main.xml
new file mode 100644
index 0000000..d8b8664
--- /dev/null
+++ b/app/src/main/res/layout/content_main.xml
@@ -0,0 +1,16 @@
+
+
+
+
diff --git a/app/src/main/res/layout/nav_header_main.xml b/app/src/main/res/layout/nav_header_main.xml
new file mode 100644
index 0000000..b591253
--- /dev/null
+++ b/app/src/main/res/layout/nav_header_main.xml
@@ -0,0 +1,40 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/src/main/res/menu/activity_main_drawer.xml b/app/src/main/res/menu/activity_main_drawer.xml
new file mode 100644
index 0000000..bf24f61
--- /dev/null
+++ b/app/src/main/res/menu/activity_main_drawer.xml
@@ -0,0 +1,32 @@
+
+
diff --git a/app/src/main/res/menu/main.xml b/app/src/main/res/menu/main.xml
new file mode 100644
index 0000000..a2411e3
--- /dev/null
+++ b/app/src/main/res/menu/main.xml
@@ -0,0 +1,9 @@
+
+
+
+
diff --git a/app/src/main/res/mipmap-mdpi/logo.png b/app/src/main/res/mipmap-mdpi/logo.png
new file mode 100644
index 0000000..7643fb4
Binary files /dev/null and b/app/src/main/res/mipmap-mdpi/logo.png differ
diff --git a/app/src/main/res/raw/isima2d_o.obj b/app/src/main/res/raw/isima2d_o.obj
index 5523c7d..de68417 100644
--- a/app/src/main/res/raw/isima2d_o.obj
+++ b/app/src/main/res/raw/isima2d_o.obj
@@ -13,6 +13,7 @@ v 1 1 0
v 338 1016 0
v 338 1212 0
v 1682 1212 0
+## origin
v 1682 1016 0
#batiment a droite -- 9-11
v 1682 120 0
@@ -65,12 +66,12 @@ v 748 580 0
#------------------
#vecteurs normaux
#------------------
-vn 0.0 0.0 1.0
-vn 0.0 0.0 -1.0
-vn 0.0 1.0 0.0
-vn 0.0 -1.0 0.0
-vn 1.0 0.0 0.0
-vn -1.0 0.0 0.0
+vn 0.0 0.0 1.0
+vn 0.0 0.0 -1.0
+vn 0.0 1.0 0.0
+vn 0.0 -1.0 0.0
+vn 1.0 0.0 0.0
+vn -1.0 0.0 0.0
#------------------
#points de texture
diff --git a/app/src/main/res/raw/test.obj b/app/src/main/res/raw/test.obj
new file mode 100644
index 0000000..49fdbf5
--- /dev/null
+++ b/app/src/main/res/raw/test.obj
@@ -0,0 +1,22 @@
+#isima2d.obj
+
+#------------------
+#vertices
+#------------------
+v 0 0 0
+v 1 0 0
+v 0 1 0
+v 1 1 0
+
+
+
+#------------------
+#faces
+#------------------
+
+o isima
+
+#------------------
+
+g isima0
+f 1/1/1 2/1/1 4/1/1 3/1/1
diff --git a/app/src/main/res/values-fr/strings.xml b/app/src/main/res/values-fr/strings.xml
new file mode 100644
index 0000000..b045a52
--- /dev/null
+++ b/app/src/main/res/values-fr/strings.xml
@@ -0,0 +1,20 @@
+
+
+ WatchDogZZ
+
+
+ Se connecter avec Google
+ Email
+ Mot de passe (optoinnel)
+ Activité principale
+
+ Ouvrir la navigation
+ Fermer la navigation
+
+ Options
+
+
+ "Logo de l'application WatchDogZZ."
+ Envoyez votre position à vos amis.
+ Salut, voici ma position fournie par WatchDogZZ :
+
\ No newline at end of file
diff --git a/app/src/main/res/values-v21/styles.xml b/app/src/main/res/values-v21/styles.xml
new file mode 100644
index 0000000..dbbdd40
--- /dev/null
+++ b/app/src/main/res/values-v21/styles.xml
@@ -0,0 +1,9 @@
+
+
+
+
diff --git a/app/src/main/res/values-w820dp/dimens.xml b/app/src/main/res/values-w820dp/dimens.xml
new file mode 100644
index 0000000..63fc816
--- /dev/null
+++ b/app/src/main/res/values-w820dp/dimens.xml
@@ -0,0 +1,6 @@
+
+
+ 64dp
+
diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml
index 3ab3e9c..6ed9888 100644
--- a/app/src/main/res/values/colors.xml
+++ b/app/src/main/res/values/colors.xml
@@ -2,5 +2,5 @@
#3F51B5
#303F9F
- #FF4081
+ #40f9ff
diff --git a/app/src/main/res/values/dimens.xml b/app/src/main/res/values/dimens.xml
index 47c8224..2626ab6 100644
--- a/app/src/main/res/values/dimens.xml
+++ b/app/src/main/res/values/dimens.xml
@@ -2,4 +2,8 @@
16dp
16dp
+
+ 16dp
+ 160dp
+ 16dp
diff --git a/app/src/main/res/values/drawables.xml b/app/src/main/res/values/drawables.xml
new file mode 100644
index 0000000..52c6a6c
--- /dev/null
+++ b/app/src/main/res/values/drawables.xml
@@ -0,0 +1,8 @@
+
+ - @android:drawable/ic_menu_camera
+ - @android:drawable/ic_menu_gallery
+ - @android:drawable/ic_menu_slideshow
+ - @android:drawable/ic_menu_manage
+ - @android:drawable/ic_menu_share
+ - @android:drawable/ic_menu_send
+
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 2346867..4fff60f 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -2,6 +2,7 @@
WatchDogZZ
+ Sign up with Google
Email
Password (optional)
Sign in or register
@@ -13,4 +14,20 @@
"Contacts permissions are needed for providing email
completions."
+ Logo of WatchDogZZ application.
+ "© WatchDogZZ 2016\n© B.B. & B.G. 2016"
+
+
+ MainActivity
+
+ Open navigation drawer
+ Close navigation drawer
+
+ Settings
+
+ 933756986924-ont7s5iohrb9rm3nch8momvatsr4qp47.apps.googleusercontent.com
+
+ Send your position to your friends.
+ Hi, here is my position provided by WatchDogZZ:
+
diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml
index 9513160..5fff3a5 100644
--- a/app/src/main/res/values/styles.xml
+++ b/app/src/main/res/values/styles.xml
@@ -8,4 +8,13 @@
- @color/colorAccent
+
+
+
+
+
+
diff --git a/build.gradle b/build.gradle
index c20bca1..8943770 100644
--- a/build.gradle
+++ b/build.gradle
@@ -5,8 +5,8 @@ buildscript {
jcenter()
}
dependencies {
- classpath 'com.android.tools.build:gradle:2.2.2'
-
+ classpath 'com.android.tools.build:gradle:2.2.3'
+ classpath 'com.google.gms:google-services:3.0.0'
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}