diff --git a/.idea/libraries/Gradle__com_google_zxing_core_3_2_1_jar.xml b/.idea/libraries/Gradle__com_google_zxing_core_3_2_1_jar.xml new file mode 100644 index 0000000..2aa9110 --- /dev/null +++ b/.idea/libraries/Gradle__com_google_zxing_core_3_2_1_jar.xml @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Gradle__de_measite_minidns_minidns_core_0_2_4_jar.xml b/.idea/libraries/Gradle__de_measite_minidns_minidns_core_0_2_4_jar.xml new file mode 100644 index 0000000..07e3ef7 --- /dev/null +++ b/.idea/libraries/Gradle__de_measite_minidns_minidns_core_0_2_4_jar.xml @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Gradle__de_measite_minidns_minidns_dnssec_0_2_4_jar.xml b/.idea/libraries/Gradle__de_measite_minidns_minidns_dnssec_0_2_4_jar.xml new file mode 100644 index 0000000..7ec29b8 --- /dev/null +++ b/.idea/libraries/Gradle__de_measite_minidns_minidns_dnssec_0_2_4_jar.xml @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Gradle__de_measite_minidns_minidns_hla_0_2_4_jar.xml b/.idea/libraries/Gradle__de_measite_minidns_minidns_hla_0_2_4_jar.xml new file mode 100644 index 0000000..080fbcb --- /dev/null +++ b/.idea/libraries/Gradle__de_measite_minidns_minidns_hla_0_2_4_jar.xml @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Gradle__de_measite_minidns_minidns_iterative_resolver_0_2_4_jar.xml b/.idea/libraries/Gradle__de_measite_minidns_minidns_iterative_resolver_0_2_4_jar.xml new file mode 100644 index 0000000..8f45624 --- /dev/null +++ b/.idea/libraries/Gradle__de_measite_minidns_minidns_iterative_resolver_0_2_4_jar.xml @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Gradle__me_dm7_barcodescanner_core_1_9.xml b/.idea/libraries/Gradle__me_dm7_barcodescanner_core_1_9.xml new file mode 100644 index 0000000..e67e056 --- /dev/null +++ b/.idea/libraries/Gradle__me_dm7_barcodescanner_core_1_9.xml @@ -0,0 +1,10 @@ + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Gradle__me_dm7_barcodescanner_zxing_1_9.xml b/.idea/libraries/Gradle__me_dm7_barcodescanner_zxing_1_9.xml new file mode 100644 index 0000000..d82500b --- /dev/null +++ b/.idea/libraries/Gradle__me_dm7_barcodescanner_zxing_1_9.xml @@ -0,0 +1,10 @@ + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Gradle__org_igniterealtime_smack_smack_android_4_2_0_jar.xml b/.idea/libraries/Gradle__org_igniterealtime_smack_smack_android_4_2_0_jar.xml new file mode 100644 index 0000000..a8a8e1a --- /dev/null +++ b/.idea/libraries/Gradle__org_igniterealtime_smack_smack_android_4_2_0_jar.xml @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Gradle__org_igniterealtime_smack_smack_android_extensions_4_2_0_jar.xml b/.idea/libraries/Gradle__org_igniterealtime_smack_smack_android_extensions_4_2_0_jar.xml new file mode 100644 index 0000000..d627944 --- /dev/null +++ b/.idea/libraries/Gradle__org_igniterealtime_smack_smack_android_extensions_4_2_0_jar.xml @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Gradle__org_igniterealtime_smack_smack_core_4_2_0_jar.xml b/.idea/libraries/Gradle__org_igniterealtime_smack_smack_core_4_2_0_jar.xml new file mode 100644 index 0000000..8a767ad --- /dev/null +++ b/.idea/libraries/Gradle__org_igniterealtime_smack_smack_core_4_2_0_jar.xml @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Gradle__org_igniterealtime_smack_smack_extensions_4_2_0_jar.xml b/.idea/libraries/Gradle__org_igniterealtime_smack_smack_extensions_4_2_0_jar.xml new file mode 100644 index 0000000..0e58feb --- /dev/null +++ b/.idea/libraries/Gradle__org_igniterealtime_smack_smack_extensions_4_2_0_jar.xml @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Gradle__org_igniterealtime_smack_smack_im_4_2_0_jar.xml b/.idea/libraries/Gradle__org_igniterealtime_smack_smack_im_4_2_0_jar.xml new file mode 100644 index 0000000..da2431c --- /dev/null +++ b/.idea/libraries/Gradle__org_igniterealtime_smack_smack_im_4_2_0_jar.xml @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Gradle__org_igniterealtime_smack_smack_resolver_minidns_4_2_0_jar.xml b/.idea/libraries/Gradle__org_igniterealtime_smack_smack_resolver_minidns_4_2_0_jar.xml new file mode 100644 index 0000000..65beb0b --- /dev/null +++ b/.idea/libraries/Gradle__org_igniterealtime_smack_smack_resolver_minidns_4_2_0_jar.xml @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Gradle__org_igniterealtime_smack_smack_sasl_provided_4_2_0_jar.xml b/.idea/libraries/Gradle__org_igniterealtime_smack_smack_sasl_provided_4_2_0_jar.xml new file mode 100644 index 0000000..cc730ed --- /dev/null +++ b/.idea/libraries/Gradle__org_igniterealtime_smack_smack_sasl_provided_4_2_0_jar.xml @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Gradle__org_igniterealtime_smack_smack_tcp_4_2_0_jar.xml b/.idea/libraries/Gradle__org_igniterealtime_smack_smack_tcp_4_2_0_jar.xml new file mode 100644 index 0000000..e83cf0b --- /dev/null +++ b/.idea/libraries/Gradle__org_igniterealtime_smack_smack_tcp_4_2_0_jar.xml @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Gradle__org_jxmpp_jxmpp_core_0_5_0_jar.xml b/.idea/libraries/Gradle__org_jxmpp_jxmpp_core_0_5_0_jar.xml new file mode 100644 index 0000000..2167aa9 --- /dev/null +++ b/.idea/libraries/Gradle__org_jxmpp_jxmpp_core_0_5_0_jar.xml @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Gradle__org_jxmpp_jxmpp_jid_0_5_0_jar.xml b/.idea/libraries/Gradle__org_jxmpp_jxmpp_jid_0_5_0_jar.xml new file mode 100644 index 0000000..c3df87f --- /dev/null +++ b/.idea/libraries/Gradle__org_jxmpp_jxmpp_jid_0_5_0_jar.xml @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Gradle__org_jxmpp_jxmpp_util_cache_0_5_0_jar.xml b/.idea/libraries/Gradle__org_jxmpp_jxmpp_util_cache_0_5_0_jar.xml new file mode 100644 index 0000000..f4306a6 --- /dev/null +++ b/.idea/libraries/Gradle__org_jxmpp_jxmpp_util_cache_0_5_0_jar.xml @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Gradle__xpp3_xpp3_1_1_4c_jar.xml b/.idea/libraries/Gradle__xpp3_xpp3_1_1_4c_jar.xml new file mode 100644 index 0000000..d706be1 --- /dev/null +++ b/.idea/libraries/Gradle__xpp3_xpp3_1_1_4c_jar.xml @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/app/app.iml b/app/app.iml index e8645c8..e908ad8 100644 --- a/app/app.iml +++ b/app/app.iml @@ -116,6 +116,31 @@ + + + + + + + + + + + + + + + + + + + + + + + + + @@ -123,30 +148,24 @@ - - - - - - - + - + + - - - - - - - + + - - + + + + + + \ No newline at end of file diff --git a/app/build.gradle b/app/build.gradle index d6ae687..2db6af7 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -28,4 +28,13 @@ dependencies { androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2' implementation 'org.osmdroid:osmdroid-android:6.0.2' + // XMPP (Smack) + //implementation "org.igniterealtime.smack:smack-android:4.2.0" + implementation "org.igniterealtime.smack:smack-android-extensions:4.2.0" + implementation "org.igniterealtime.smack:smack-tcp:4.2.0" + + // QR Code (Zxing) + implementation 'com.google.zxing:core:3.2.1' + implementation 'me.dm7.barcodescanner:zxing:1.9' + //implementation 'com.journeyapps:zxing-android-embedded:3.4.0' } diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index dbd585b..821655e 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -22,6 +22,9 @@ + + + @@ -32,4 +35,5 @@ + \ No newline at end of file diff --git a/app/src/main/java/fr/chteufleur/mytrackingdog/MainActivity.java b/app/src/main/java/fr/chteufleur/mytrackingdog/MainActivity.java index cb42c42..e6cf277 100644 --- a/app/src/main/java/fr/chteufleur/mytrackingdog/MainActivity.java +++ b/app/src/main/java/fr/chteufleur/mytrackingdog/MainActivity.java @@ -18,6 +18,7 @@ import android.support.annotation.NonNull; import android.support.annotation.RequiresApi; import android.support.v7.app.AppCompatActivity; import android.support.v7.widget.Toolbar; +import android.util.Log; import android.view.Menu; import android.view.MenuItem; import android.view.MotionEvent; @@ -28,6 +29,9 @@ import android.widget.Button; import android.widget.TextView; import android.widget.Toast; +import org.jivesoftware.smack.SmackException; +import org.jivesoftware.smack.XMPPException; +import org.jxmpp.stringprep.XmppStringprepException; import org.osmdroid.api.IMapController; import org.osmdroid.config.Configuration; import org.osmdroid.tileprovider.tilesource.TileSourceFactory; @@ -44,6 +48,7 @@ import org.osmdroid.views.overlay.mylocation.GpsMyLocationProvider; import org.osmdroid.views.overlay.mylocation.MyLocationNewOverlay; import java.io.File; +import java.io.IOException; import java.util.ArrayList; import java.util.List; import java.util.Observable; @@ -53,16 +58,22 @@ import fr.chteufleur.mytrackingdog.models.beans.MyLocation; import fr.chteufleur.mytrackingdog.models.beans.MyLocationArray; import fr.chteufleur.mytrackingdog.models.beans.WayPointLocation; import fr.chteufleur.mytrackingdog.services.ServiceGps; +import fr.chteufleur.mytrackingdog.services.ServiceXmpp; public class MainActivity extends AppCompatActivity implements IOrientationConsumer, Observer { public static final String TAG = MainActivity.class.getName(); + private static final int ACTIVITY_REQUEST_PICK_FILE = 1; + private static final int ACTIVITY_QR_CODE_GENERATOR = 2; + private static final int ACTIVITY_QR_CODE_READER = 3; + public static String appName = ""; private MyLocationNewOverlay mLocationOverlay; private IOrientationProvider compass = null; private ServiceGps serviceGps = null; + private ServiceXmpp serviceXmpp = null; private Context ctx = null; private MapView map = null; @@ -188,6 +199,22 @@ public class MainActivity extends AppCompatActivity implements IOrientationConsu ); serviceGps.addObserver(this); } + + if (serviceXmpp == null) { + try { + serviceXmpp = new ServiceXmpp(getResources()); + serviceXmpp.addObserver(this); + serviceXmpp.connect(); + } catch (InterruptedException e) { + Toast.makeText(ctx, "Échec du service XMPP.", Toast.LENGTH_LONG).show(); + } catch (XMPPException e) { + Toast.makeText(ctx, "Échec du service XMPP.", Toast.LENGTH_LONG).show(); + } catch (SmackException e) { + Toast.makeText(ctx, "Échec du service XMPP.", Toast.LENGTH_LONG).show(); + } catch (IOException e) { + Toast.makeText(ctx, "Échec du service XMPP.", Toast.LENGTH_LONG).show(); + } + } } private void changeStatusTrace() { @@ -365,6 +392,9 @@ public class MainActivity extends AppCompatActivity implements IOrientationConsu if (serviceGps != null) { serviceGps.stop(); } + if (serviceXmpp != null) { + serviceXmpp.close(); + } zoomed = false; } @@ -389,9 +419,17 @@ public class MainActivity extends AppCompatActivity implements IOrientationConsu if (id == R.id.action_import_gpx) { Intent intent = new Intent(this, FilePicker.class); intent.putExtra(FilePicker.EXTRA_FILE_PATH, Environment.getExternalStorageDirectory().getAbsolutePath() + "/" + appName); - startActivityForResult(intent, REQUEST_PICK_FILE); + startActivityForResult(intent, ACTIVITY_REQUEST_PICK_FILE); return true; + } else if (id == R.id.action_qr_code_generator) { + Intent intent = new Intent(this, QRCodeGeneratorActivity.class); + startActivityForResult(intent, ACTIVITY_QR_CODE_GENERATOR); + + } else if (id == R.id.action_qr_code_reader) { + Intent intent = new Intent(this, QRCodeReaderActivity.class); + startActivityForResult(intent, ACTIVITY_QR_CODE_READER); + } else if (id == R.id.action_send_gpx_trail) { File trailFile = serviceGps.getLastExportedTrailFile(); if (trailFile != null) { @@ -415,13 +453,12 @@ public class MainActivity extends AppCompatActivity implements IOrientationConsu return super.onOptionsItemSelected(item); } - private static final int REQUEST_PICK_FILE = 1; @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { if (resultCode == RESULT_OK) { switch (requestCode) { - case REQUEST_PICK_FILE: + case ACTIVITY_REQUEST_PICK_FILE: if (data.hasExtra(FilePicker.EXTRA_FILE_PATH)) { serviceGps.importGpxTrace(new File(data.getStringExtra(FilePicker.EXTRA_FILE_PATH))); updateDogTrace(); @@ -444,6 +481,23 @@ public class MainActivity extends AppCompatActivity implements IOrientationConsu } } break; + + case ACTIVITY_QR_CODE_READER: + if (data.hasExtra(QRCodeReaderActivity.EXTRA_SCANNED_TEXT)) { + String text = data.getStringExtra(QRCodeReaderActivity.EXTRA_SCANNED_TEXT); + try { + serviceXmpp.setOtherJid(text); + serviceXmpp.sendPresenceAvailable(); + Log.i(TAG, "TEXT: "+text); + } catch (SmackException.NotConnectedException e) { + Log.e(TAG, "Fail send presence", e); + } catch (InterruptedException e) { + Log.e(TAG, "Fail send presence", e); + } catch (XmppStringprepException e) { + Log.e(TAG, "Fail send presence", e); + } + } + break; } } } @@ -557,44 +611,53 @@ public class MainActivity extends AppCompatActivity implements IOrientationConsu @Override public void update(Observable observable, Object o) { if (observable == serviceGps) { - if (o instanceof String && o.equals(ServiceGps.NOTIF_NEW_LOCATION)) { - MyLocation loc = serviceGps.getCurrentLocation(); - if (loc != null) { - GeoPoint currentPoint = new GeoPoint(loc.getLatitude(), loc.getLongitude(), loc.getAltitude()); - if (mLocationOverlay.isFollowLocationEnabled()) { - map.getController().setCenter(currentPoint); - } - if (serviceGps.isTraceurActivated()) { - updateTrailTrace(); - if (lastLocation != null) { - distance += loc.distanceTo(lastLocation); - updateDistance(); - } - lastLocation = loc; - } else if (serviceGps.isDogActivated()) { - updateDogTrace(); - if (lastLocation != null) { - distance += loc.distanceTo(lastLocation); - updateDistance(); - } - lastLocation = loc; - } + updateServiceGps(o); + } else if (observable == serviceXmpp) { + updateServiceXmpp(o); + } + } - float orientation = serviceGps.getOrientation(deviceOrientation); - if (orientation >= 0) { - map.setMapOrientation(orientation); + public void updateServiceGps(Object o) { + if (o instanceof String && o.equals(ServiceGps.NOTIF_NEW_LOCATION)) { + MyLocation loc = serviceGps.getCurrentLocation(); + if (loc != null) { + GeoPoint currentPoint = new GeoPoint(loc.getLatitude(), loc.getLongitude(), loc.getAltitude()); + if (mLocationOverlay.isFollowLocationEnabled()) { + map.getController().setCenter(currentPoint); + } + if (serviceGps.isTraceurActivated()) { + updateTrailTrace(); + if (lastLocation != null) { + distance += loc.distanceTo(lastLocation); + updateDistance(); } + lastLocation = loc; + } else if (serviceGps.isDogActivated()) { + updateDogTrace(); + if (lastLocation != null) { + distance += loc.distanceTo(lastLocation); + updateDistance(); + } + lastLocation = loc; + } - if (!zoomed) { - IMapController mapController = map.getController(); - mapController.setZoom(20.0); - zoomed = true; - } + float orientation = serviceGps.getOrientation(deviceOrientation); + if (orientation >= 0) { + map.setMapOrientation(orientation); + } + + if (!zoomed) { + IMapController mapController = map.getController(); + mapController.setZoom(20.0); + zoomed = true; } } } } + public void updateServiceXmpp(Object o) { + } + private List convertListLocation(MyLocationArray list) { List ret = new ArrayList<>(); if (list != null) { diff --git a/app/src/main/java/fr/chteufleur/mytrackingdog/QRCodeGeneratorActivity.java b/app/src/main/java/fr/chteufleur/mytrackingdog/QRCodeGeneratorActivity.java new file mode 100644 index 0000000..b59d7c3 --- /dev/null +++ b/app/src/main/java/fr/chteufleur/mytrackingdog/QRCodeGeneratorActivity.java @@ -0,0 +1,60 @@ +package fr.chteufleur.mytrackingdog; + +import android.app.Activity; +import android.content.res.Resources; +import android.graphics.Bitmap; +import android.os.Bundle; +import android.util.Log; +import android.widget.ImageView; + +import com.google.zxing.BarcodeFormat; +import com.google.zxing.MultiFormatWriter; +import com.google.zxing.WriterException; +import com.google.zxing.common.BitMatrix; + +public class QRCodeGeneratorActivity extends Activity { + + public static final String TAG = QRCodeGeneratorActivity.class.getName(); + public final static int QRcodeWidth = 500 ; + + private ImageView imageView; + private static Bitmap image = null; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.qr_code_generator); + + imageView = findViewById(R.id.qr_code_image); + if (image != null) { + imageView.setImageBitmap(image); + } + } + + public static void textToImageEncode(String value, Resources resources) throws WriterException { + Log.i(TAG, "QR CODE "+value); + BitMatrix bitMatrix; + try { + bitMatrix = new MultiFormatWriter().encode( + value, + BarcodeFormat.DATA_MATRIX.QR_CODE, + QRcodeWidth, QRcodeWidth, null + ); + } catch (IllegalArgumentException Illegalargumentexception) { + return; + } + int bitMatrixWidth = bitMatrix.getWidth(); + int bitMatrixHeight = bitMatrix.getHeight(); + int[] pixels = new int[bitMatrixWidth * bitMatrixHeight]; + for (int y = 0; y < bitMatrixHeight; y++) { + int offset = y * bitMatrixWidth; + for (int x = 0; x < bitMatrixWidth; x++) { + pixels[offset + x] = bitMatrix.get(x, y) ? + resources.getColor(R.color.black):resources.getColor(R.color.white); + } + } + image = Bitmap.createBitmap(bitMatrixWidth, bitMatrixHeight, Bitmap.Config.ARGB_4444); + image.setPixels(pixels, 0, 500, 0, 0, bitMatrixWidth, bitMatrixHeight); + Log.i(TAG, "FIN GENERATION QR CODE"); + } +} diff --git a/app/src/main/java/fr/chteufleur/mytrackingdog/QRCodeReaderActivity.java b/app/src/main/java/fr/chteufleur/mytrackingdog/QRCodeReaderActivity.java new file mode 100644 index 0000000..90a1da6 --- /dev/null +++ b/app/src/main/java/fr/chteufleur/mytrackingdog/QRCodeReaderActivity.java @@ -0,0 +1,64 @@ +package fr.chteufleur.mytrackingdog; + +import android.Manifest; +import android.app.Activity; +import android.content.Intent; +import android.content.pm.PackageManager; +import android.os.Build; +import android.os.Bundle; +import android.support.annotation.RequiresApi; + +import com.google.zxing.Result; + +import me.dm7.barcodescanner.zxing.ZXingScannerView; + +public class QRCodeReaderActivity extends Activity implements ZXingScannerView.ResultHandler { + + private final int REQUEST_CODE_ASK_PERMISSION = 123; + + public static final String EXTRA_SCANNED_TEXT = "scanned_text"; + public static final String TAG = QRCodeReaderActivity.class.getName(); + + private ZXingScannerView mScannerView; + + + @RequiresApi(api = Build.VERSION_CODES.M) + protected void checkPermissions() { + int hasCameraPermission = checkSelfPermission(Manifest.permission.CAMERA); + if (hasCameraPermission != PackageManager.PERMISSION_GRANTED) { + requestPermissions(new String[]{Manifest.permission.CAMERA}, REQUEST_CODE_ASK_PERMISSION); + } + } + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + checkPermissions(); + } + setContentView(R.layout.qr_code_reader); + mScannerView = new ZXingScannerView(this); + setContentView(mScannerView); + } + + @Override + public void onResume() { + super.onResume(); + mScannerView.setResultHandler(this); // Register ourselves as a handler for scan results. + mScannerView.startCamera(); // Start camera on resume + } + + @Override + public void onPause() { + super.onPause(); + mScannerView.stopCamera(); // Stop camera on pause + } + + @Override + public void handleResult(Result rawResult) { + Intent extra = new Intent(); + extra.putExtra(EXTRA_SCANNED_TEXT, rawResult.getText()); + setResult(RESULT_OK, extra); + finish(); + } +} diff --git a/app/src/main/java/fr/chteufleur/mytrackingdog/models/xmpp/commands/TrailGeolocCommand.java b/app/src/main/java/fr/chteufleur/mytrackingdog/models/xmpp/commands/TrailGeolocCommand.java new file mode 100644 index 0000000..fbeae57 --- /dev/null +++ b/app/src/main/java/fr/chteufleur/mytrackingdog/models/xmpp/commands/TrailGeolocCommand.java @@ -0,0 +1,102 @@ +package fr.chteufleur.mytrackingdog.models.xmpp.commands; + +import android.util.Log; + +import org.jivesoftware.smack.SmackException; +import org.jivesoftware.smack.XMPPException; +import org.jivesoftware.smackx.commands.AdHocCommandNote; +import org.jivesoftware.smackx.commands.LocalCommand; +import org.jivesoftware.smackx.xdata.Form; +import org.jivesoftware.smackx.xdata.FormField; +import org.jivesoftware.smackx.xdata.packet.DataForm; +import org.jxmpp.jid.Jid; + +import java.util.List; + +public class TrailGeolocCommand extends LocalCommand { + + public static final String TAG = TrailGeolocCommand.class.getName(); + + public static final String FIELD_PARAM_LATITUDE = "latitude"; + public static final String FIELD_PARAM_LONGITUDE = "longitude"; + public static final String FIELD_PARAM_TIME = "time"; + + private long latitude; + private long longitude; + private int time; + + + @Override + public boolean isLastStage() { + return getCurrentStage() == 1; + } + + @Override + public boolean hasPermission(Jid jid) { + // TODO + return true; + } + + @Override + public void execute() throws SmackException.NoResponseException, XMPPException.XMPPErrorException, SmackException.NotConnectedException, InterruptedException { + Form result = new Form(DataForm.Type.form); + setExecuteAction(Action.next); + + FormField resultFieldLatitude = new FormField(FIELD_PARAM_LATITUDE); + resultFieldLatitude.setLabel(FIELD_PARAM_LATITUDE); + resultFieldLatitude.setType(FormField.Type.text_single); + result.addField(resultFieldLatitude); + + FormField resultFieldLongitude = new FormField(FIELD_PARAM_LONGITUDE); + resultFieldLongitude.setLabel(FIELD_PARAM_LONGITUDE); + resultFieldLongitude.setType(FormField.Type.text_single); + result.addField(resultFieldLongitude); + + FormField resultFieldTime = new FormField(FIELD_PARAM_TIME); + resultFieldTime.setLabel(FIELD_PARAM_TIME); + resultFieldTime.setType(FormField.Type.text_single); + result.addField(resultFieldTime); + + this.addActionAvailable(Action.next); + setForm(result); + } + + @Override + public void next(Form response) throws SmackException.NoResponseException, XMPPException.XMPPErrorException, SmackException.NotConnectedException, InterruptedException { + FormField formLatitude = response.getField(FIELD_PARAM_LATITUDE); + FormField formLongitude = response.getField(FIELD_PARAM_LONGITUDE); + FormField formTime = response.getField(FIELD_PARAM_TIME); + + if (formLatitude != null && formLongitude != null && formTime != null) { + List latitudeStrs = formLatitude.getValues(); + List longitudeStrs = response.getField(FIELD_PARAM_LONGITUDE).getValues(); + List timeStrs = response.getField(FIELD_PARAM_TIME).getValues(); + + for (String latitudeStr : latitudeStrs) { + Log.i(TAG, "Next latitude: " + latitudeStr); + } + for (String longitudeStr : longitudeStrs) { + Log.i(TAG, "Next longitude: " + longitudeStr); + } + for (String timeStr : timeStrs) { + Log.i(TAG, "Next time: " + timeStr); + } + + this.addNote(new AdHocCommandNote(AdHocCommandNote.Type.info, "SUCCESS")); + } else { + this.addNote((new AdHocCommandNote(AdHocCommandNote.Type.error, "FAIL"))); + } + } + + @Override + public void complete(Form response) throws SmackException.NoResponseException, XMPPException.XMPPErrorException, SmackException.NotConnectedException, InterruptedException { + } + + @Override + public void prev() throws SmackException.NoResponseException, XMPPException.XMPPErrorException, SmackException.NotConnectedException, InterruptedException { + } + + @Override + public void cancel() throws SmackException.NoResponseException, XMPPException.XMPPErrorException, SmackException.NotConnectedException, InterruptedException { + } +} diff --git a/app/src/main/java/fr/chteufleur/mytrackingdog/services/ServiceGps.java b/app/src/main/java/fr/chteufleur/mytrackingdog/services/ServiceGps.java index b65cc0d..4d976b8 100644 --- a/app/src/main/java/fr/chteufleur/mytrackingdog/services/ServiceGps.java +++ b/app/src/main/java/fr/chteufleur/mytrackingdog/services/ServiceGps.java @@ -34,7 +34,7 @@ import fr.chteufleur.mytrackingdog.models.beans.WayPointLocation; public class ServiceGps extends Observable implements IServiceGps, LocationListener { private static final String TAG = ServiceGps.class.getName(); - public static final String NOTIF_NEW_LOCATION = "fr.chteufleur.mytrackingdog.services.servicegps.newlocation"; + public static final String NOTIF_NEW_LOCATION = ServiceGps.class.getName()+".newlocation"; private static final String PREF_VIBRATION_NEAR_OBJECT_ENABLED = "PREF_VIBRATION_NEAR_OBJECT_ENABLED"; diff --git a/app/src/main/java/fr/chteufleur/mytrackingdog/services/ServiceXmpp.java b/app/src/main/java/fr/chteufleur/mytrackingdog/services/ServiceXmpp.java new file mode 100644 index 0000000..ce69ccc --- /dev/null +++ b/app/src/main/java/fr/chteufleur/mytrackingdog/services/ServiceXmpp.java @@ -0,0 +1,177 @@ +package fr.chteufleur.mytrackingdog.services; + +import android.content.res.Resources; +import android.os.StrictMode; +import android.util.Log; + +import com.google.zxing.WriterException; + +import org.jivesoftware.smack.AbstractXMPPConnection; +import org.jivesoftware.smack.ConnectionConfiguration; +import org.jivesoftware.smack.SmackException; +import org.jivesoftware.smack.XMPPException; +import org.jivesoftware.smack.packet.Presence; +import org.jivesoftware.smack.roster.PresenceEventListener; +import org.jivesoftware.smack.roster.Roster; +import org.jivesoftware.smack.tcp.XMPPTCPConnection; +import org.jivesoftware.smack.tcp.XMPPTCPConnectionConfiguration; +import org.jivesoftware.smackx.commands.AdHocCommandManager; +import org.jivesoftware.smackx.commands.LocalCommand; +import org.jxmpp.jid.BareJid; +import org.jxmpp.jid.FullJid; +import org.jxmpp.jid.Jid; +import org.jxmpp.jid.impl.JidCreate; +import org.jxmpp.jid.impl.LocalAndDomainpartJid; +import org.jxmpp.jid.impl.LocalDomainAndResourcepartJid; +import org.jxmpp.stringprep.XmppStringprepException; + +import java.io.IOException; +import java.net.Inet4Address; +import java.net.UnknownHostException; +import java.util.Observable; + +import fr.chteufleur.mytrackingdog.QRCodeGeneratorActivity; +import fr.chteufleur.mytrackingdog.models.xmpp.commands.TrailGeolocCommand; + +public class ServiceXmpp extends Observable implements PresenceEventListener { + public static final String TAG = ServiceXmpp.class.getName(); + + private static final String XMPP_NODE_TRAIL_GEOLOC = "trail_geoloc"; + private static final String XMPP_IP_SERVER = "51.254.205.203"; + private static final String XMPP_DOMAIN_SERVER = "anon.xmpp.kingpenguin.tk"; + //private static final String XMPP_DOMAIN_SERVER = "kingpenguin.tk"; + private static final int XMPP_PORT = 5222; + + private final Resources resources; + private final XMPPTCPConnectionConfiguration configuration; + private AdHocCommandManager commandManager; + private AbstractXMPPConnection connection; + private String jid; + + private String otherJid; + + private Roster roster; + + public ServiceXmpp(Resources resources) throws UnknownHostException, XmppStringprepException { + this.resources = resources; + this.configuration = XMPPTCPConnectionConfiguration.builder() + .setSecurityMode(ConnectionConfiguration.SecurityMode.ifpossible) + .setHostAddress(Inet4Address.getByName(XMPP_IP_SERVER)) + .setPort(XMPP_PORT) + .setXmppDomain(XMPP_DOMAIN_SERVER) + .setDebuggerEnabled(true) + .performSaslAnonymousAuthentication() + .setKeystoreType(null) + .build(); + } + + public boolean connect() throws InterruptedException, XMPPException, SmackException, IOException { + StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build(); + StrictMode.setThreadPolicy(policy); + + boolean isConnected; + connection = new XMPPTCPConnection(configuration); + + commandManager = AdHocCommandManager.getAddHocCommandsManager(connection); + + connection.connect(); + connection.login(); + + commandManager.registerCommand(XMPP_NODE_TRAIL_GEOLOC, XMPP_NODE_TRAIL_GEOLOC, TrailGeolocCommand.class); + + roster = Roster.getInstanceFor(connection); + roster.addPresenceEventListener(this); + + isConnected = connection.isConnected(); + if (isConnected) { + jid = connection.getUser().asEntityBareJidString(); + Log.i(TAG, "JID: "+jid); + try { + QRCodeGeneratorActivity.textToImageEncode(jid, resources); + } catch (WriterException ex) { + Log.e(TAG, "Failed to generate QR Code"); + } + } + return isConnected; + } + + public void close() { + if (otherJid != null) { + try { + sendPresenceUnavailable(otherJid); + } catch (SmackException.NotConnectedException ex) { + } catch (InterruptedException ex) { + } catch (XmppStringprepException ex) { + } + } + if (connection != null) { + connection.disconnect(); + } + } + + // + public void sendPresenceAvailable() throws SmackException.NotConnectedException, InterruptedException, XmppStringprepException { + if (otherJid != null) { + sendPresence(JidCreate.bareFrom(otherJid), Presence.Type.available); + } + } + + public void sendPresenceAvailable(String to) throws SmackException.NotConnectedException, InterruptedException, XmppStringprepException { + sendPresence(JidCreate.bareFrom(to), Presence.Type.available); + } + + public void sendPresenceUnavailable(String to) throws SmackException.NotConnectedException, InterruptedException, XmppStringprepException { + sendPresence(JidCreate.bareFrom(to), Presence.Type.unavailable); + } + + private void sendPresence(Jid to, Presence.Type type) throws SmackException.NotConnectedException, InterruptedException { + if (connection != null) { + Presence presence = new Presence(to, type); + presence.setStatus(""); + connection.sendStanza(presence); + } + } + + @Override + public void presenceAvailable(FullJid address, Presence availablePresence) { + String bareJid = address.asBareJid().toString(); + if (!bareJid.equals(jid) && (otherJid == null || !bareJid.equals(otherJid))) { + Log.i(TAG, "PRESENCE AVAILABLE RECEIVED FROM "+bareJid); + otherJid = bareJid; + try { + sendPresenceAvailable(bareJid); + } catch (SmackException.NotConnectedException e) { + e.printStackTrace(); + } catch (InterruptedException e) { + e.printStackTrace(); + } catch (XmppStringprepException e) { + e.printStackTrace(); + } + } + } + + @Override + public void presenceUnavailable(FullJid address, Presence presence) { + } + + @Override + public void presenceError(Jid address, Presence errorPresence) { + } + + @Override + public void presenceSubscribed(BareJid address, Presence subscribedPresence) { + } + + @Override + public void presenceUnsubscribed(BareJid address, Presence unsubscribedPresence) { + } + // + + public void setOtherJid(String otherJid) { + this.otherJid = otherJid; + } + + public boolean isOtherJidSet() { + return this.otherJid != null; + } +} diff --git a/app/src/main/res/layout/qr_code_generator.xml b/app/src/main/res/layout/qr_code_generator.xml new file mode 100644 index 0000000..757eeb3 --- /dev/null +++ b/app/src/main/res/layout/qr_code_generator.xml @@ -0,0 +1,15 @@ + + + + + + diff --git a/app/src/main/res/layout/qr_code_reader.xml b/app/src/main/res/layout/qr_code_reader.xml new file mode 100644 index 0000000..182f537 --- /dev/null +++ b/app/src/main/res/layout/qr_code_reader.xml @@ -0,0 +1,12 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/menu/menu_main.xml b/app/src/main/res/menu/menu_main.xml index 33711fa..b689f1f 100644 --- a/app/src/main/res/menu/menu_main.xml +++ b/app/src/main/res/menu/menu_main.xml @@ -18,6 +18,14 @@ android:orderInCategory="100" android:title="@string/action_active_vibration_object" app:showAsAction="never" /> - - + + diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml index 3ab3e9c..a898f17 100644 --- a/app/src/main/res/values/colors.xml +++ b/app/src/main/res/values/colors.xml @@ -3,4 +3,6 @@ #3F51B5 #303F9F #FF4081 + #000000 + #ffffff diff --git a/app/src/main/res/values/dimens.xml b/app/src/main/res/values/dimens.xml index 59a0b0c..4d6ddf5 100644 --- a/app/src/main/res/values/dimens.xml +++ b/app/src/main/res/values/dimens.xml @@ -1,3 +1,5 @@ 16dp + 16dp + 16dp diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 8275f4e..14a58d0 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -11,4 +11,6 @@ Envoyer trace du traceur Envoyer par Active vibration objets + Affiche identifiant + Lecture identifiant