Compare commits

...

32 Commits

Author SHA1 Message Date
TiclemFR
db30f70093 Add select path in main activity 2024-08-09 22:05:17 +02:00
clement
f18c396d64 Remove compass and track bearing 2024-07-18 17:38:53 +02:00
clement
647ed86ae1 Test azimuth 2024-07-17 20:02:42 +02:00
clement
9f95c27b0b Test azimuth 2024-07-17 14:48:55 +02:00
clement
f2476ec6cc Correct navigation marker 2024-07-17 14:08:57 +02:00
clement
c718551215 Correct Marker Flag 2024-07-17 12:52:22 +02:00
clement
fd3ecdc255 Add navigation lib and test navigation + TTS for nav 2024-07-16 19:53:24 +02:00
clement
7a8c574454 Upgrade to API 35 2024-07-11 17:30:38 +02:00
clement
f420fc93e9 Undo no volunteer removing code 2024-07-11 17:16:44 +02:00
clement
c7592a97f7 Update implementation 2024-07-11 17:02:54 +02:00
clement
6fddd6f2b1 Update application id 2024-07-11 17:00:51 +02:00
clement
9e37caa4d3 Remove unnecessary elements 2024-07-10 18:28:31 +02:00
clement
b97d209917 Construct uri and launch google maps navigation 2024-07-10 16:18:38 +02:00
clement
49cdd06d5c Display all stop's when selected path 2024-07-10 15:12:31 +02:00
clement
a617a29e75 Add view path list 2024-07-09 19:49:50 +02:00
clement
e096f9ed1c Add verif on path name 2024-07-09 18:50:57 +02:00
clement
116a2a5a4a clean interface and code 2024-07-09 17:59:34 +02:00
clement
26c6061a8f Correct dismiss listener 2024-07-09 17:57:01 +02:00
clement
a744faf0d2 Storing Path name with her stop's 2024-07-09 17:48:08 +02:00
clement
1e7b729e4f Add to form a field to put a name of route and list all markers with coordinate and address 2024-07-09 10:41:43 +02:00
clement
f7a8720669 Add new activity to list actual marker for future edit in a form 2024-07-08 11:20:50 +02:00
clement
eb93531816 Re activate displaying speed and accuracy and get location name with latitude and longitude 2024-07-07 18:28:58 +02:00
TiclemFR
0b288973ca Add another way to get location 2024-07-04 10:06:38 +02:00
TiclemFR
367be18e85 Add Database helper, can save marker in stop table and read it 2024-07-01 15:01:18 +02:00
TiclemFR
998378e9ea Correct Bugs 2024-06-28 19:18:16 +02:00
TiclemFR
c8f310539e Change provider is accuracy is too low 2024-06-27 17:51:48 +02:00
TiclemFR
da5709d5e8 Displaying Speed 2024-06-26 20:31:14 +02:00
TiclemFR
0146559c72 Add button for testing Google Maps 2024-06-22 21:03:00 +02:00
TiclemFR
05e2330958 Display Accuracy and position 2024-06-22 18:12:29 +02:00
TiclemFR
cbd94cb507 Update due to API Change 2024-06-22 09:03:04 +02:00
clement
f2670fbd74 Merge remote-tracking branch 'origin/master' 2024-06-21 21:25:17 +02:00
clement
e6168a8861 Gradle update 2024-06-21 21:24:53 +02:00
37 changed files with 1329 additions and 99 deletions

123
.idea/codeStyles/Project.xml generated Normal file
View File

@@ -0,0 +1,123 @@
<component name="ProjectCodeStyleConfiguration">
<code_scheme name="Project" version="173">
<JetCodeStyleSettings>
<option name="CODE_STYLE_DEFAULTS" value="KOTLIN_OFFICIAL" />
</JetCodeStyleSettings>
<codeStyleSettings language="XML">
<option name="FORCE_REARRANGE_MODE" value="1" />
<indentOptions>
<option name="CONTINUATION_INDENT_SIZE" value="4" />
</indentOptions>
<arrangement>
<rules>
<section>
<rule>
<match>
<AND>
<NAME>xmlns:android</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>^$</XML_NAMESPACE>
</AND>
</match>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>xmlns:.*</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>^$</XML_NAMESPACE>
</AND>
</match>
<order>BY_NAME</order>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>.*:id</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
</AND>
</match>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>.*:name</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
</AND>
</match>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>name</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>^$</XML_NAMESPACE>
</AND>
</match>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>style</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>^$</XML_NAMESPACE>
</AND>
</match>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>.*</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>^$</XML_NAMESPACE>
</AND>
</match>
<order>BY_NAME</order>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>.*</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
</AND>
</match>
<order>ANDROID_ATTRIBUTE_ORDER</order>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>.*</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>.*</XML_NAMESPACE>
</AND>
</match>
<order>BY_NAME</order>
</rule>
</section>
</rules>
</arrangement>
</codeStyleSettings>
<codeStyleSettings language="kotlin">
<option name="CODE_STYLE_DEFAULTS" value="KOTLIN_OFFICIAL" />
</codeStyleSettings>
</code_scheme>
</component>

5
.idea/codeStyles/codeStyleConfig.xml generated Normal file
View File

@@ -0,0 +1,5 @@
<component name="ProjectCodeStyleConfiguration">
<state>
<option name="USE_PER_PROJECT_SETTINGS" value="true" />
</state>
</component>

404
.idea/dbnavigator.xml generated Normal file
View File

@@ -0,0 +1,404 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="DBNavigator.Project.DatabaseFileManager">
<open-files />
</component>
<component name="DBNavigator.Project.Settings">
<connections />
<browser-settings>
<general>
<display-mode value="TABBED" />
<navigation-history-size value="100" />
<show-object-details value="false" />
<enable-sticky-paths value="true" />
</general>
<filters>
<object-type-filter>
<object-type name="SCHEMA" enabled="true" />
<object-type name="USER" enabled="true" />
<object-type name="ROLE" enabled="true" />
<object-type name="PRIVILEGE" enabled="true" />
<object-type name="CHARSET" enabled="true" />
<object-type name="TABLE" enabled="true" />
<object-type name="VIEW" enabled="true" />
<object-type name="MATERIALIZED_VIEW" enabled="true" />
<object-type name="NESTED_TABLE" enabled="true" />
<object-type name="COLUMN" enabled="true" />
<object-type name="INDEX" enabled="true" />
<object-type name="CONSTRAINT" enabled="true" />
<object-type name="DATASET_TRIGGER" enabled="true" />
<object-type name="DATABASE_TRIGGER" enabled="true" />
<object-type name="SYNONYM" enabled="true" />
<object-type name="SEQUENCE" enabled="true" />
<object-type name="PROCEDURE" enabled="true" />
<object-type name="FUNCTION" enabled="true" />
<object-type name="PACKAGE" enabled="true" />
<object-type name="TYPE" enabled="true" />
<object-type name="TYPE_ATTRIBUTE" enabled="true" />
<object-type name="ARGUMENT" enabled="true" />
<object-type name="DIMENSION" enabled="true" />
<object-type name="CLUSTER" enabled="true" />
<object-type name="DBLINK" enabled="true" />
</object-type-filter>
</filters>
<sorting>
<object-type name="COLUMN" sorting-type="NAME" />
<object-type name="FUNCTION" sorting-type="NAME" />
<object-type name="PROCEDURE" sorting-type="NAME" />
<object-type name="ARGUMENT" sorting-type="POSITION" />
<object-type name="TYPE ATTRIBUTE" sorting-type="POSITION" />
</sorting>
<default-editors>
<object-type name="VIEW" editor-type="SELECTION" />
<object-type name="PACKAGE" editor-type="SELECTION" />
<object-type name="TYPE" editor-type="SELECTION" />
</default-editors>
</browser-settings>
<navigation-settings>
<lookup-filters>
<lookup-objects>
<object-type name="SCHEMA" enabled="true" />
<object-type name="USER" enabled="false" />
<object-type name="ROLE" enabled="false" />
<object-type name="PRIVILEGE" enabled="false" />
<object-type name="CHARSET" enabled="false" />
<object-type name="TABLE" enabled="true" />
<object-type name="VIEW" enabled="true" />
<object-type name="MATERIALIZED VIEW" enabled="true" />
<object-type name="INDEX" enabled="true" />
<object-type name="CONSTRAINT" enabled="true" />
<object-type name="DATASET TRIGGER" enabled="true" />
<object-type name="DATABASE TRIGGER" enabled="true" />
<object-type name="SYNONYM" enabled="false" />
<object-type name="SEQUENCE" enabled="true" />
<object-type name="PROCEDURE" enabled="true" />
<object-type name="FUNCTION" enabled="true" />
<object-type name="PACKAGE" enabled="true" />
<object-type name="TYPE" enabled="true" />
<object-type name="DIMENSION" enabled="false" />
<object-type name="CLUSTER" enabled="false" />
<object-type name="DBLINK" enabled="true" />
</lookup-objects>
<force-database-load value="false" />
<prompt-connection-selection value="true" />
<prompt-schema-selection value="true" />
</lookup-filters>
</navigation-settings>
<dataset-grid-settings>
<general>
<enable-zooming value="true" />
<enable-column-tooltip value="true" />
</general>
<sorting>
<nulls-first value="true" />
<max-sorting-columns value="4" />
</sorting>
<audit-columns>
<column-names value="" />
<visible value="true" />
<editable value="false" />
</audit-columns>
</dataset-grid-settings>
<dataset-editor-settings>
<text-editor-popup>
<active value="false" />
<active-if-empty value="false" />
<data-length-threshold value="100" />
<popup-delay value="1000" />
</text-editor-popup>
<values-actions-popup>
<show-popup-button value="true" />
<element-count-threshold value="1000" />
<data-length-threshold value="250" />
</values-actions-popup>
<general>
<fetch-block-size value="100" />
<fetch-timeout value="30" />
<trim-whitespaces value="true" />
<convert-empty-strings-to-null value="true" />
<select-content-on-cell-edit value="true" />
<large-value-preview-active value="true" />
</general>
<filters>
<prompt-filter-dialog value="true" />
<default-filter-type value="BASIC" />
</filters>
<qualified-text-editor text-length-threshold="300">
<content-types>
<content-type name="Text" enabled="true" />
<content-type name="Properties" enabled="true" />
<content-type name="XML" enabled="true" />
<content-type name="DTD" enabled="true" />
<content-type name="HTML" enabled="true" />
<content-type name="XHTML" enabled="true" />
<content-type name="Java" enabled="true" />
<content-type name="SQL" enabled="true" />
<content-type name="PL/SQL" enabled="true" />
<content-type name="JSON" enabled="true" />
<content-type name="JSON5" enabled="true" />
<content-type name="Groovy" enabled="true" />
<content-type name="AIDL" enabled="true" />
<content-type name="YAML" enabled="true" />
<content-type name="Manifest" enabled="true" />
</content-types>
</qualified-text-editor>
<record-navigation>
<navigation-target value="VIEWER" />
</record-navigation>
</dataset-editor-settings>
<code-editor-settings>
<general>
<show-object-navigation-gutter value="false" />
<show-spec-declaration-navigation-gutter value="true" />
<enable-spellchecking value="true" />
<enable-reference-spellchecking value="false" />
</general>
<confirmations>
<save-changes value="false" />
<revert-changes value="true" />
<exit-on-changes value="ASK" />
</confirmations>
</code-editor-settings>
<code-completion-settings>
<filters>
<basic-filter>
<filter-element type="RESERVED_WORD" id="keyword" selected="true" />
<filter-element type="RESERVED_WORD" id="function" selected="true" />
<filter-element type="RESERVED_WORD" id="parameter" selected="true" />
<filter-element type="RESERVED_WORD" id="datatype" selected="true" />
<filter-element type="RESERVED_WORD" id="exception" selected="true" />
<filter-element type="OBJECT" id="schema" selected="true" />
<filter-element type="OBJECT" id="role" selected="true" />
<filter-element type="OBJECT" id="user" selected="true" />
<filter-element type="OBJECT" id="privilege" selected="true" />
<user-schema>
<filter-element type="OBJECT" id="table" selected="true" />
<filter-element type="OBJECT" id="view" selected="true" />
<filter-element type="OBJECT" id="materialized view" selected="true" />
<filter-element type="OBJECT" id="index" selected="true" />
<filter-element type="OBJECT" id="constraint" selected="true" />
<filter-element type="OBJECT" id="trigger" selected="true" />
<filter-element type="OBJECT" id="synonym" selected="false" />
<filter-element type="OBJECT" id="sequence" selected="true" />
<filter-element type="OBJECT" id="procedure" selected="true" />
<filter-element type="OBJECT" id="function" selected="true" />
<filter-element type="OBJECT" id="package" selected="true" />
<filter-element type="OBJECT" id="type" selected="true" />
<filter-element type="OBJECT" id="dimension" selected="true" />
<filter-element type="OBJECT" id="cluster" selected="true" />
<filter-element type="OBJECT" id="dblink" selected="true" />
</user-schema>
<public-schema>
<filter-element type="OBJECT" id="table" selected="false" />
<filter-element type="OBJECT" id="view" selected="false" />
<filter-element type="OBJECT" id="materialized view" selected="false" />
<filter-element type="OBJECT" id="index" selected="false" />
<filter-element type="OBJECT" id="constraint" selected="false" />
<filter-element type="OBJECT" id="trigger" selected="false" />
<filter-element type="OBJECT" id="synonym" selected="false" />
<filter-element type="OBJECT" id="sequence" selected="false" />
<filter-element type="OBJECT" id="procedure" selected="false" />
<filter-element type="OBJECT" id="function" selected="false" />
<filter-element type="OBJECT" id="package" selected="false" />
<filter-element type="OBJECT" id="type" selected="false" />
<filter-element type="OBJECT" id="dimension" selected="false" />
<filter-element type="OBJECT" id="cluster" selected="false" />
<filter-element type="OBJECT" id="dblink" selected="false" />
</public-schema>
<any-schema>
<filter-element type="OBJECT" id="table" selected="true" />
<filter-element type="OBJECT" id="view" selected="true" />
<filter-element type="OBJECT" id="materialized view" selected="true" />
<filter-element type="OBJECT" id="index" selected="true" />
<filter-element type="OBJECT" id="constraint" selected="true" />
<filter-element type="OBJECT" id="trigger" selected="true" />
<filter-element type="OBJECT" id="synonym" selected="true" />
<filter-element type="OBJECT" id="sequence" selected="true" />
<filter-element type="OBJECT" id="procedure" selected="true" />
<filter-element type="OBJECT" id="function" selected="true" />
<filter-element type="OBJECT" id="package" selected="true" />
<filter-element type="OBJECT" id="type" selected="true" />
<filter-element type="OBJECT" id="dimension" selected="true" />
<filter-element type="OBJECT" id="cluster" selected="true" />
<filter-element type="OBJECT" id="dblink" selected="true" />
</any-schema>
</basic-filter>
<extended-filter>
<filter-element type="RESERVED_WORD" id="keyword" selected="true" />
<filter-element type="RESERVED_WORD" id="function" selected="true" />
<filter-element type="RESERVED_WORD" id="parameter" selected="true" />
<filter-element type="RESERVED_WORD" id="datatype" selected="true" />
<filter-element type="RESERVED_WORD" id="exception" selected="true" />
<filter-element type="OBJECT" id="schema" selected="true" />
<filter-element type="OBJECT" id="user" selected="true" />
<filter-element type="OBJECT" id="role" selected="true" />
<filter-element type="OBJECT" id="privilege" selected="true" />
<user-schema>
<filter-element type="OBJECT" id="table" selected="true" />
<filter-element type="OBJECT" id="view" selected="true" />
<filter-element type="OBJECT" id="materialized view" selected="true" />
<filter-element type="OBJECT" id="index" selected="true" />
<filter-element type="OBJECT" id="constraint" selected="true" />
<filter-element type="OBJECT" id="trigger" selected="true" />
<filter-element type="OBJECT" id="synonym" selected="true" />
<filter-element type="OBJECT" id="sequence" selected="true" />
<filter-element type="OBJECT" id="procedure" selected="true" />
<filter-element type="OBJECT" id="function" selected="true" />
<filter-element type="OBJECT" id="package" selected="true" />
<filter-element type="OBJECT" id="type" selected="true" />
<filter-element type="OBJECT" id="dimension" selected="true" />
<filter-element type="OBJECT" id="cluster" selected="true" />
<filter-element type="OBJECT" id="dblink" selected="true" />
</user-schema>
<public-schema>
<filter-element type="OBJECT" id="table" selected="true" />
<filter-element type="OBJECT" id="view" selected="true" />
<filter-element type="OBJECT" id="materialized view" selected="true" />
<filter-element type="OBJECT" id="index" selected="true" />
<filter-element type="OBJECT" id="constraint" selected="true" />
<filter-element type="OBJECT" id="trigger" selected="true" />
<filter-element type="OBJECT" id="synonym" selected="true" />
<filter-element type="OBJECT" id="sequence" selected="true" />
<filter-element type="OBJECT" id="procedure" selected="true" />
<filter-element type="OBJECT" id="function" selected="true" />
<filter-element type="OBJECT" id="package" selected="true" />
<filter-element type="OBJECT" id="type" selected="true" />
<filter-element type="OBJECT" id="dimension" selected="true" />
<filter-element type="OBJECT" id="cluster" selected="true" />
<filter-element type="OBJECT" id="dblink" selected="true" />
</public-schema>
<any-schema>
<filter-element type="OBJECT" id="table" selected="true" />
<filter-element type="OBJECT" id="view" selected="true" />
<filter-element type="OBJECT" id="materialized view" selected="true" />
<filter-element type="OBJECT" id="index" selected="true" />
<filter-element type="OBJECT" id="constraint" selected="true" />
<filter-element type="OBJECT" id="trigger" selected="true" />
<filter-element type="OBJECT" id="synonym" selected="true" />
<filter-element type="OBJECT" id="sequence" selected="true" />
<filter-element type="OBJECT" id="procedure" selected="true" />
<filter-element type="OBJECT" id="function" selected="true" />
<filter-element type="OBJECT" id="package" selected="true" />
<filter-element type="OBJECT" id="type" selected="true" />
<filter-element type="OBJECT" id="dimension" selected="true" />
<filter-element type="OBJECT" id="cluster" selected="true" />
<filter-element type="OBJECT" id="dblink" selected="true" />
</any-schema>
</extended-filter>
</filters>
<sorting enabled="true">
<sorting-element type="RESERVED_WORD" id="keyword" />
<sorting-element type="RESERVED_WORD" id="datatype" />
<sorting-element type="OBJECT" id="column" />
<sorting-element type="OBJECT" id="table" />
<sorting-element type="OBJECT" id="view" />
<sorting-element type="OBJECT" id="materialized view" />
<sorting-element type="OBJECT" id="index" />
<sorting-element type="OBJECT" id="constraint" />
<sorting-element type="OBJECT" id="trigger" />
<sorting-element type="OBJECT" id="synonym" />
<sorting-element type="OBJECT" id="sequence" />
<sorting-element type="OBJECT" id="procedure" />
<sorting-element type="OBJECT" id="function" />
<sorting-element type="OBJECT" id="package" />
<sorting-element type="OBJECT" id="type" />
<sorting-element type="OBJECT" id="dimension" />
<sorting-element type="OBJECT" id="cluster" />
<sorting-element type="OBJECT" id="dblink" />
<sorting-element type="OBJECT" id="schema" />
<sorting-element type="OBJECT" id="role" />
<sorting-element type="OBJECT" id="user" />
<sorting-element type="RESERVED_WORD" id="function" />
<sorting-element type="RESERVED_WORD" id="parameter" />
</sorting>
<format>
<enforce-code-style-case value="true" />
</format>
</code-completion-settings>
<execution-engine-settings>
<statement-execution>
<fetch-block-size value="100" />
<execution-timeout value="20" />
<debug-execution-timeout value="600" />
<focus-result value="false" />
<prompt-execution value="false" />
</statement-execution>
<script-execution>
<command-line-interfaces />
<execution-timeout value="300" />
</script-execution>
<method-execution>
<execution-timeout value="30" />
<debug-execution-timeout value="600" />
<parameter-history-size value="10" />
</method-execution>
</execution-engine-settings>
<operation-settings>
<transactions>
<uncommitted-changes>
<on-project-close value="ASK" />
<on-disconnect value="ASK" />
<on-autocommit-toggle value="ASK" />
</uncommitted-changes>
<multiple-uncommitted-changes>
<on-commit value="ASK" />
<on-rollback value="ASK" />
</multiple-uncommitted-changes>
</transactions>
<session-browser>
<disconnect-session value="ASK" />
<kill-session value="ASK" />
<reload-on-filter-change value="false" />
</session-browser>
<compiler>
<compile-type value="KEEP" />
<compile-dependencies value="ASK" />
<always-show-controls value="false" />
</compiler>
</operation-settings>
<ddl-file-settings>
<extensions>
<mapping file-type-id="VIEW" extensions="vw" />
<mapping file-type-id="TRIGGER" extensions="trg" />
<mapping file-type-id="PROCEDURE" extensions="prc" />
<mapping file-type-id="FUNCTION" extensions="fnc" />
<mapping file-type-id="PACKAGE" extensions="pkg" />
<mapping file-type-id="PACKAGE_SPEC" extensions="pks" />
<mapping file-type-id="PACKAGE_BODY" extensions="pkb" />
<mapping file-type-id="TYPE" extensions="tpe" />
<mapping file-type-id="TYPE_SPEC" extensions="tps" />
<mapping file-type-id="TYPE_BODY" extensions="tpb" />
</extensions>
<general>
<lookup-ddl-files value="true" />
<create-ddl-files value="false" />
<synchronize-ddl-files value="true" />
<use-qualified-names value="false" />
<make-scripts-rerunnable value="true" />
</general>
</ddl-file-settings>
<general-settings>
<regional-settings>
<date-format value="MEDIUM" />
<number-format value="UNGROUPED" />
<locale value="SYSTEM_DEFAULT" />
<use-custom-formats value="false" />
</regional-settings>
<environment>
<environment-types>
<environment-type id="development" name="Development" description="Development environment" color="-2430209/-12296320" readonly-code="false" readonly-data="false" />
<environment-type id="integration" name="Integration" description="Integration environment" color="-2621494/-12163514" readonly-code="true" readonly-data="false" />
<environment-type id="production" name="Production" description="Productive environment" color="-11574/-10271420" readonly-code="true" readonly-data="true" />
<environment-type id="other" name="Other" description="" color="-1576/-10724543" readonly-code="false" readonly-data="false" />
</environment-types>
<visibility-settings>
<connection-tabs value="true" />
<dialog-headers value="true" />
<object-editor-tabs value="true" />
<script-editor-tabs value="false" />
<execution-result-tabs value="true" />
</visibility-settings>
</environment>
</general-settings>
</component>
</project>

View File

@@ -4,7 +4,7 @@
<selectionStates> <selectionStates>
<SelectionState runConfigName="app"> <SelectionState runConfigName="app">
<option name="selectionMode" value="DROPDOWN" /> <option name="selectionMode" value="DROPDOWN" />
<DropdownSelection timestamp="2024-06-20T09:28:45.422751100Z"> <DropdownSelection timestamp="2024-07-01T11:57:37.460926400Z">
<Target type="DEFAULT_BOOT"> <Target type="DEFAULT_BOOT">
<handle> <handle>
<DeviceId pluginId="PhysicalDevice" identifier="serial=y5v4t4fiif555tnb" /> <DeviceId pluginId="PhysicalDevice" identifier="serial=y5v4t4fiif555tnb" />

11
.idea/other.xml generated
View File

@@ -179,17 +179,6 @@
<option name="screenX" value="1080" /> <option name="screenX" value="1080" />
<option name="screenY" value="2400" /> <option name="screenY" value="2400" />
</PersistentDeviceSelectionData> </PersistentDeviceSelectionData>
<PersistentDeviceSelectionData>
<option name="api" value="31" />
<option name="brand" value="samsung" />
<option name="codename" value="q2q" />
<option name="id" value="q2q" />
<option name="manufacturer" value="Samsung" />
<option name="name" value="Galaxy Z Fold3" />
<option name="screenDensity" value="420" />
<option name="screenX" value="1768" />
<option name="screenY" value="2208" />
</PersistentDeviceSelectionData>
<PersistentDeviceSelectionData> <PersistentDeviceSelectionData>
<option name="api" value="34" /> <option name="api" value="34" />
<option name="brand" value="samsung" /> <option name="brand" value="samsung" />

View File

@@ -1,3 +1,4 @@
plugins { plugins {
alias(libs.plugins.android.application) alias(libs.plugins.android.application)
alias(libs.plugins.jetbrains.kotlin.android) alias(libs.plugins.jetbrains.kotlin.android)
@@ -5,12 +6,12 @@ plugins {
android { android {
namespace = "com.example.busroute" namespace = "com.example.busroute"
compileSdk = 34 compileSdk = 35
defaultConfig { defaultConfig {
applicationId = "com.example.busroute" applicationId = "com.example.busroute"
minSdk = 24 minSdk = 26
targetSdk = 34 targetSdk = 35
versionCode = 1 versionCode = 1
versionName = "1.0" versionName = "1.0"
@@ -50,7 +51,6 @@ android {
} }
dependencies { dependencies {
implementation(libs.androidx.core.ktx) implementation(libs.androidx.core.ktx)
implementation(libs.androidx.lifecycle.runtime.ktx) implementation(libs.androidx.lifecycle.runtime.ktx)
implementation(libs.androidx.activity.compose) implementation(libs.androidx.activity.compose)
@@ -60,6 +60,7 @@ dependencies {
implementation(libs.androidx.ui.tooling.preview) implementation(libs.androidx.ui.tooling.preview)
implementation(libs.androidx.material3) implementation(libs.androidx.material3)
implementation(libs.play.services.location) implementation(libs.play.services.location)
implementation(libs.androidx.appcompat)
testImplementation(libs.junit) testImplementation(libs.junit)
androidTestImplementation(libs.androidx.junit) androidTestImplementation(libs.androidx.junit)
androidTestImplementation(libs.androidx.espresso.core) androidTestImplementation(libs.androidx.espresso.core)
@@ -67,6 +68,10 @@ dependencies {
androidTestImplementation(libs.androidx.ui.test.junit4) androidTestImplementation(libs.androidx.ui.test.junit4)
debugImplementation(libs.androidx.ui.tooling) debugImplementation(libs.androidx.ui.tooling)
debugImplementation(libs.androidx.ui.test.manifest) debugImplementation(libs.androidx.ui.test.manifest)
implementation("org.osmdroid:osmdroid-android:6.1.18") implementation(libs.osmdroid.android)
implementation("com.google.android.gms:play-services-location:21.2.0") implementation(files("./libs/osmbonuspack_6.9.0.aar"))
implementation(libs.commons.lang3)
implementation(libs.gson)
implementation(libs.okhttp)
implementation(libs.play.services.location)
} }

Binary file not shown.

View File

@@ -14,8 +14,7 @@
android:label="@string/app_name" android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round" android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true" android:supportsRtl="true"
android:theme="@style/Theme.BusRoute" android:theme="@style/Theme.BusRoute">
tools:targetApi="31">
<activity <activity
android:name=".MainActivity" android:name=".MainActivity"
android:exported="true" android:exported="true"
@@ -23,10 +22,19 @@
android:theme="@style/Theme.BusRoute"> android:theme="@style/Theme.BusRoute">
<intent-filter> <intent-filter>
<action android:name="android.intent.action.MAIN" /> <action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" /> <category android:name="android.intent.category.LAUNCHER" />
</intent-filter> </intent-filter>
</activity> </activity>
<activity
android:name=".ValidateMarker"
android:label="Ajouter une ligne"
android:parentActivityName=".MainActivity"
android:theme="@style/Theme.AppCompat"/>
<activity
android:name=".PathToMaps"
android:label="Charger un trajet"
android:parentActivityName=".MainActivity"
android:theme="@style/Theme.AppCompat"/>
</application> </application>
</manifest> </manifest>

View File

@@ -0,0 +1,9 @@
package com.example.busroute.DataClass
import org.osmdroid.views.overlay.Marker
data class BusStop(val marker: Marker){
override fun toString(): String {
return "${this.marker.position.latitude} | ${this.marker.position.longitude}\n"
}
}

View File

@@ -0,0 +1,23 @@
package com.example.busroute.DataClass
import com.example.busroute.Database.PathContract
import com.example.busroute.Database.StopContract
import com.google.gson.JsonArray
import com.google.gson.JsonObject
data class ExportPath(val pathName:String, val busStop:ArrayList<Stop>){
fun getJson():JsonObject{
val path = JsonObject()
path.addProperty(PathContract.PathEntry.PATH_NAME, pathName)
val stopList = JsonArray()
busStop.forEach {
val stop = JsonObject()
stop.addProperty(StopContract.StopEntry.LATITUDE, it.latitude)
stop.addProperty(StopContract.StopEntry.LONGITUDE, it.longitude)
stop.addProperty(StopContract.StopEntry.ORDER, it.order)
stopList.add(stop)
}
path.add("stop", stopList)
return path
}
}

View File

@@ -0,0 +1,7 @@
package com.example.busroute.DataClass
data class PathList(val id: Int, val name: String){
override fun toString(): String {
return name
}
}

View File

@@ -0,0 +1,3 @@
package com.example.busroute.DataClass
data class Stop(val latitude:Double, val longitude:Double, val order:Int)

View File

@@ -0,0 +1,27 @@
package com.example.busroute.Database
import android.content.Context
import android.database.sqlite.SQLiteDatabase
import android.database.sqlite.SQLiteOpenHelper
class DbHelper(context: Context) : SQLiteOpenHelper(context, DATABASE_NAME, null, DATABASE_VERSION) {
override fun onCreate(db: SQLiteDatabase) {
db.execSQL(PathContract.SQL_CREATE_ENTRIES)
db.execSQL(StopContract.SQL_CREATE_ENTRIES)
}
override fun onUpgrade(db: SQLiteDatabase, oldVersion: Int, newVersion: Int) {
// This database is only a cache for online data, so its upgrade policy is
// to simply to discard the data and start over
db.execSQL(PathContract.SQL_DELETE_ENTRIES)
db.execSQL(StopContract.SQL_DELETE_ENTRIES)
onCreate(db)
}
override fun onDowngrade(db: SQLiteDatabase, oldVersion: Int, newVersion: Int) {
onUpgrade(db, oldVersion, newVersion)
}
companion object {
// If you change the database schema, you must increment the database version.
const val DATABASE_VERSION = 1
const val DATABASE_NAME = "BusRoute.db"
}
}

View File

@@ -0,0 +1,19 @@
package com.example.busroute.Database
import android.provider.BaseColumns
object PathContract {
// Table contents are grouped together in an anonymous object.
object PathEntry : BaseColumns {
const val TABLE_NAME = "path"
const val PATH_NAME = "name"
}
const val SQL_CREATE_ENTRIES =
"CREATE TABLE ${PathEntry.TABLE_NAME} (" +
"${BaseColumns._ID} INTEGER PRIMARY KEY," +
"${PathEntry.PATH_NAME} TEXT"+
")"
const val SQL_DELETE_ENTRIES = "DROP TABLE IF EXISTS ${PathEntry.TABLE_NAME}"
}

View File

@@ -0,0 +1,25 @@
package com.example.busroute.Database
import android.provider.BaseColumns
object StopContract {
// Table contents are grouped together in an anonymous object.
object StopEntry : BaseColumns {
const val TABLE_NAME = "stop"
const val LATITUDE = "latitude"
const val LONGITUDE = "longitude"
const val ORDER = "'order'"
const val PATH_ID = "path_id"
}
const val SQL_CREATE_ENTRIES =
"CREATE TABLE ${StopEntry.TABLE_NAME} (" +
"${BaseColumns._ID} INTEGER PRIMARY KEY," +
"${StopEntry.LATITUDE} DOUBLE, "+
"${StopEntry.LONGITUDE} DOUBLE, "+
"${StopEntry.ORDER} INTEGER, "+
"${StopEntry.PATH_ID} INTEGER"+
")"
const val SQL_DELETE_ENTRIES = "DROP TABLE IF EXISTS ${StopEntry.TABLE_NAME}"
}

View File

@@ -1,47 +1,56 @@
package com.example.busroute package com.example.busroute
import android.Manifest
import android.annotation.SuppressLint import android.annotation.SuppressLint
import android.content.Context import android.app.AlertDialog
import android.content.Intent
import android.content.pm.ActivityInfo
import android.content.pm.PackageManager import android.content.pm.PackageManager
import android.location.Location import android.location.Location
import android.location.LocationManager import android.location.LocationManager
import android.net.Uri
import android.os.Bundle import android.os.Bundle
import android.os.Looper
import android.preference.PreferenceManager import android.preference.PreferenceManager
import android.util.Log import android.speech.tts.TextToSpeech
import android.speech.tts.Voice
import android.view.View
import android.view.WindowManager import android.view.WindowManager
import android.widget.AdapterView
import android.widget.AdapterView.OnItemSelectedListener
import android.widget.ArrayAdapter
import android.widget.Button import android.widget.Button
import android.widget.Spinner
import android.widget.TextView
import androidx.activity.ComponentActivity import androidx.activity.ComponentActivity
import androidx.core.app.ActivityCompat import androidx.core.app.ActivityCompat
import androidx.core.content.ContextCompat import androidx.core.content.ContextCompat
import com.google.android.gms.location.FusedLocationProviderClient import com.example.busroute.DataClass.BusStop
import com.example.busroute.DataClass.PathList
import com.example.busroute.Database.DbHelper
import com.example.busroute.Database.PathContract
import com.google.android.gms.location.LocationCallback import com.google.android.gms.location.LocationCallback
import com.google.android.gms.location.LocationRequest import com.google.android.gms.location.LocationRequest
import com.google.android.gms.location.LocationResult
import com.google.android.gms.location.LocationServices
import com.google.android.gms.location.Priority
import org.osmdroid.api.IMapController import org.osmdroid.api.IMapController
import org.osmdroid.config.Configuration.getInstance import org.osmdroid.config.Configuration.getInstance
import org.osmdroid.tileprovider.tilesource.TileSourceFactory import org.osmdroid.tileprovider.tilesource.TileSourceFactory
import org.osmdroid.util.GeoPoint import org.osmdroid.util.GeoPoint
import org.osmdroid.views.MapView import org.osmdroid.views.MapView
import org.osmdroid.views.overlay.Marker import org.osmdroid.views.overlay.Marker
import org.osmdroid.views.overlay.compass.CompassOverlay
import org.osmdroid.views.overlay.compass.InternalCompassOrientationProvider
import org.osmdroid.views.overlay.gestures.RotationGestureOverlay import org.osmdroid.views.overlay.gestures.RotationGestureOverlay
import org.osmdroid.views.overlay.mylocation.GpsMyLocationProvider
import org.osmdroid.views.overlay.mylocation.IMyLocationProvider
import org.osmdroid.views.overlay.mylocation.MyLocationNewOverlay
import java.util.Locale
class MainActivity : ComponentActivity() { class MainActivity : ComponentActivity() {
private val REQUEST_PERMISSIONS_REQUEST_CODE = 1 private val REQUEST_PERMISSIONS_REQUEST_CODE = 1
private lateinit var map : MapView private lateinit var map : MapView
private lateinit var fusedLocationClient: FusedLocationProviderClient
private lateinit var currentLocation: Location private lateinit var currentLocation: Location
lateinit var locationManager: LocationManager private var lastBearing = 0.0f
private lateinit var locationManager: LocationManager
private lateinit var mapController: IMapController private lateinit var mapController: IMapController
private lateinit var locationByGps: Location
private lateinit var locationByNetwork: Location
private lateinit var positionMarker: Marker private lateinit var positionMarker: Marker
private lateinit var locationCallback: LocationCallback private lateinit var locationCallback: LocationCallback
@@ -49,12 +58,23 @@ class MainActivity : ComponentActivity() {
private var latitude = 0.0 private var latitude = 0.0
private var longitude = 0.0 private var longitude = 0.0
private var navigationEnable = false
private var busStopList: ArrayList<BusStop> = ArrayList()
@SuppressLint("MissingPermission") @SuppressLint("MissingPermission")
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
isLocationPermissionGranted()
window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON) window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON)
requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT
val dbHelper = DbHelper(this)
val tts = TextToSpeech(this, TextToSpeech.OnInitListener{})
tts.setVoice(Voice("French",
Locale.FRENCH, Voice.QUALITY_HIGH,
Voice.LATENCY_LOW, true, null))
tts.setSpeechRate(0.8f)
locationManager = getSystemService(Context.LOCATION_SERVICE) as LocationManager locationManager = getSystemService(LOCATION_SERVICE) as LocationManager
getInstance().load(this, PreferenceManager.getDefaultSharedPreferences(this)) getInstance().load(this, PreferenceManager.getDefaultSharedPreferences(this))
setContentView(R.layout.main) setContentView(R.layout.main)
@@ -64,65 +84,201 @@ class MainActivity : ComponentActivity() {
mapController = map.controller mapController = map.controller
mapController.setZoom(18.0) mapController.setZoom(18.0)
val openMapsButton = findViewById<Button>(R.id.open_maps)
val db = dbHelper.readableDatabase
val addMarkButton = findViewById<Button>(R.id.addMark) val addMarkButton = findViewById<Button>(R.id.addMark)
addMarkButton.setOnClickListener{ addMarkButton.setOnClickListener{
val marker = Marker(map) val marker = Marker(map)
marker.position = GeoPoint(latitude, longitude) marker.position = GeoPoint(latitude, longitude)
marker.title = "MARK BUTTON !!" marker.title = "Bus Stop " + busStopList.size+1
marker.textLabelFontSize = 10
marker.icon = ContextCompat.getDrawable(this, org.osmdroid.library.R.drawable.moreinfo_arrow) marker.icon = ContextCompat.getDrawable(this, org.osmdroid.library.R.drawable.moreinfo_arrow)
map.overlays.add(marker) map.overlays.add(marker)
map.invalidate() map.invalidate()
busStopList.add(BusStop(marker))
} }
val removeMarkButton = findViewById<Button>(R.id.removeMark)
removeMarkButton.setOnClickListener{
if(busStopList.size < 1){
return@setOnClickListener
}
val marker = busStopList.last()
marker.marker.remove(map)
busStopList.remove(marker)
}
val saveMarkButton = findViewById<Button>(R.id.saveMark)
saveMarkButton.setOnClickListener{
var stringList: ArrayList<String> = ArrayList<String>()
busStopList.forEach {
stringList.add(it.toString())
}
if(busStopList.size < 1){
val alert = AlertDialog.Builder(this).setTitle("Aucun point !").setMessage("Il faut au moins 1 point pour continuer !")
alert.show()
return@setOnClickListener
}
val intent = Intent(saveMarkButton.context, ValidateMarker::class.java)
intent.putExtra(ValidateMarker.MARKERS, stringList)
startActivity(intent)
}
// val loadPathButton = findViewById<Button>(R.id.load_path)
// loadPathButton.setOnClickListener {
// val intent = Intent(loadPathButton.context, PathToMaps::class.java)
// startActivity(intent)
// }
val rotationGestureOverlay = RotationGestureOverlay(map) val rotationGestureOverlay = RotationGestureOverlay(map)
rotationGestureOverlay.isEnabled rotationGestureOverlay.isEnabled
map.setMultiTouchControls(true) map.setMultiTouchControls(true)
map.overlays.add(rotationGestureOverlay) map.overlays.add(rotationGestureOverlay)
val compassOverlay = CompassOverlay(this, InternalCompassOrientationProvider(this), map) // val compassOverlay = CompassOverlay(this, InternalCompassOrientationProvider(this), map)
compassOverlay.enableCompass() // compassOverlay.enableCompass()
map.overlays.add(compassOverlay) // map.overlays.add(compassOverlay)
val locationOverlay =
isLocationPermissionGranted() object : MyLocationNewOverlay(GpsMyLocationProvider(this), map) {
val locationClient = LocationServices.getFusedLocationProviderClient(this) override fun onLocationChanged(location: Location?, source: IMyLocationProvider?) {
super.onLocationChanged(location!!, source)
locationRequest = LocationRequest.Builder(Priority.PRIORITY_BALANCED_POWER_ACCURACY,60) if (location.accuracy < 60) {
.setWaitForAccurateLocation(true).setMaxUpdateAgeMillis(30).build() if (location.provider == LocationManager.NETWORK_PROVIDER) {
locationCallback = object : LocationCallback() { location.provider = LocationManager.GPS_PROVIDER
override fun onLocationResult(locationResult: LocationResult) { } else {
locationResult ?: return location.provider = LocationManager.NETWORK_PROVIDER
for (location in locationResult.locations){ }
}
currentLocation = location
latitude = location.latitude latitude = location.latitude
longitude = location.longitude longitude = location.longitude
mapController.animateTo(GeoPoint(latitude, longitude)) if(navigationEnable && currentLocation.hasBearing()){
lastBearing = currentLocation.bearing
positionMarker.position = GeoPoint(latitude, longitude) mapController.animateTo(GeoPoint(latitude, longitude), null, null, -currentLocation.bearing)
positionMarker.title = "You" }
map.overlays.add(positionMarker) else{
map.invalidate() //mapController.animateTo(GeoPoint(latitude, longitude))
Log.i("Position", "$latitude $longitude") }
Log.i("Accuracy Global", "GPS: ${location.accuracy} Network: ${location.accuracy}")
Log.i("Accuracy Chosen", "${location.accuracy}")
} }
} }
locationOverlay.enableMyLocation()
locationOverlay.enableFollowLocation()
map.overlays.add(locationOverlay)
val roadButton = findViewById<Button>(R.id.road)
roadButton.setOnClickListener {
navigationEnable = true
tts.speak("Début de l'itinéraire", TextToSpeech.QUEUE_FLUSH, null,"")
RetrieveRoad(map, latitude,longitude, roadButton.context).execute()
} }
locationClient.requestLocationUpdates(locationRequest, locationCallback, Looper.getMainLooper())
val projection = arrayOf("")
val selection = ""
val selectionArgs = arrayOf("")
val sortOrder = ""
val cursor = db.query(
PathContract.PathEntry.TABLE_NAME, // The table to query
null, // The array of columns to return (pass null to get all)
null, // The columns for the WHERE clause
null, // The values for the WHERE clause
null, // don't group the rows
null, // don't filter by row groups
null // The sort order
)
val items = ArrayList<PathList>()
items.add(PathList(0,"SELECT PATH"))
with(cursor) {
while (moveToNext()) {
val name = getString(getColumnIndexOrThrow(com.example.busroute.Database.PathContract.PathEntry.PATH_NAME))
val id = getInt(getColumnIndexOrThrow(android.provider.BaseColumns._ID))
val path = PathList(id, name)
items.add(path)
}
}
cursor.close()
val comboPath = findViewById<Spinner>(R.id.combo_path)
comboPath.adapter = ArrayAdapter(this,android.R.layout.simple_spinner_dropdown_item, items)
comboPath.onItemSelectedListener = object : OnItemSelectedListener {
override fun onItemSelected(
parentView: AdapterView<*>?,
selectedItemView: View,
position: Int,
id: Long
) {
val iter = busStopList.iterator()
while(iter.hasNext()) {
iter.next().marker.remove(map)
iter.remove()
}
if(position < 1){
addMarkButton.isEnabled = true
return
}
addMarkButton.isEnabled = false
val selectedPath = parentView!!.selectedItem
if(selectedPath != null){
val cursor = db.rawQuery("SELECT * " +
"FROM stop " +
"WHERE path_id = ${(selectedPath as PathList).id} " +
"ORDER BY 'order' ",
arrayOf()
)
with(cursor) {
while (moveToNext()) {
val latitude = getDouble(getColumnIndexOrThrow(com.example.busroute.Database.StopContract.StopEntry.LATITUDE))
val longitude = getDouble(getColumnIndexOrThrow(com.example.busroute.Database.StopContract.StopEntry.LONGITUDE))
val text = TextView(comboPath.context)
val marker = Marker(map)
marker.position = GeoPoint(latitude, longitude)
marker.title = "Bus Stop " + busStopList.size+1
marker.textLabelFontSize = 10
marker.icon = ContextCompat.getDrawable(baseContext, org.osmdroid.library.R.drawable.moreinfo_arrow)
map.overlays.add(marker)
map.invalidate()
busStopList.add(BusStop(marker))
}
}
}
}
override fun onNothingSelected(parentView: AdapterView<*>?) {
// your code here
}
}
openMapsButton.setOnClickListener {
val lastPoint = busStopList.last().marker
var uri = "google.navigation:q=${lastPoint.position.latitude},${lastPoint.position.longitude}&waypoints="
busStopList.forEach {
if(busStopList.indexOf(it) < busStopList.size -1){
val position = it.marker.position
uri += "${position.latitude},${position.longitude}"
if(busStopList.indexOf(it) < busStopList.size -2){
uri += "%7C"
}
}
}
db.close()
val mapIntentUri = Uri.parse(uri)
val mapIntent = Intent(Intent.ACTION_VIEW, mapIntentUri)
mapIntent.setPackage("com.google.android.apps.maps")
startActivity(mapIntent)
}
} }
private fun isLocationPermissionGranted(): Boolean { private fun isLocationPermissionGranted(): Boolean {
return if (ActivityCompat.checkSelfPermission( return if (ActivityCompat.checkSelfPermission(
this, this,
android.Manifest.permission.ACCESS_COARSE_LOCATION Manifest.permission.ACCESS_COARSE_LOCATION
) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission( ) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(
this, this,
android.Manifest.permission.ACCESS_FINE_LOCATION Manifest.permission.ACCESS_FINE_LOCATION
) != PackageManager.PERMISSION_GRANTED ) != PackageManager.PERMISSION_GRANTED
) { ) {
ActivityCompat.requestPermissions( ActivityCompat.requestPermissions(
this, this,
arrayOf( arrayOf(
android.Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_FINE_LOCATION,
android.Manifest.permission.ACCESS_COARSE_LOCATION Manifest.permission.ACCESS_COARSE_LOCATION
), ),
1 1
) )
@@ -151,7 +307,7 @@ class MainActivity : ComponentActivity() {
map.onPause() //needed for compass, my location overlays, v6.0.0 and up map.onPause() //needed for compass, my location overlays, v6.0.0 and up
} }
override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<out String>, grantResults: IntArray) { override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<String>, grantResults: IntArray) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults) super.onRequestPermissionsResult(requestCode, permissions, grantResults)
val permissionsToRequest = ArrayList<String>() val permissionsToRequest = ArrayList<String>()
var i = 0 var i = 0
@@ -166,22 +322,4 @@ class MainActivity : ComponentActivity() {
REQUEST_PERMISSIONS_REQUEST_CODE) REQUEST_PERMISSIONS_REQUEST_CODE)
} }
} }
/*private fun requestPermissionsIfNecessary(String[] permissions) {
val permissionsToRequest = ArrayList<String>();
permissions.forEach { permission ->
if (ContextCompat.checkSelfPermission(this, permission)
!= PackageManager.PERMISSION_GRANTED) {
// Permission is not granted
permissionsToRequest.add(permission);
}
}
if (permissionsToRequest.size() > 0) {
ActivityCompat.requestPermissions(
this,
permissionsToRequest.toArray(new String[0]),
REQUEST_PERMISSIONS_REQUEST_CODE);
}
}*/
} }

View File

@@ -0,0 +1,143 @@
package com.example.busroute
import android.content.Intent
import android.location.Address
import android.location.Geocoder
import android.net.Uri
import android.os.Bundle
import android.provider.BaseColumns
import android.view.View
import android.widget.AdapterView
import android.widget.AdapterView.OnItemSelectedListener
import android.widget.ArrayAdapter
import android.widget.Button
import android.widget.Spinner
import android.widget.TableLayout
import android.widget.TextView
import androidx.appcompat.app.AppCompatActivity
import com.example.busroute.DataClass.ExportPath
import com.example.busroute.DataClass.PathList
import com.example.busroute.DataClass.Stop
import com.example.busroute.Database.DbHelper
import com.example.busroute.Database.PathContract
import com.example.busroute.Database.StopContract
import com.google.gson.JsonArray
import java.util.Locale
class PathToMaps: AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val dbHelper = DbHelper(this)
val db = dbHelper.readableDatabase
val geocoder = Geocoder(this, Locale.getDefault())
val StopPoint = ArrayList<String>()
setContentView(R.layout.select_path)
val projection = arrayOf("")
val selection = ""
val selectionArgs = arrayOf("")
val sortOrder = ""
val cursor = db.query(
PathContract.PathEntry.TABLE_NAME, // The table to query
null, // The array of columns to return (pass null to get all)
null, // The columns for the WHERE clause
null, // The values for the WHERE clause
null, // don't group the rows
null, // don't filter by row groups
null // The sort order
)
val items = ArrayList<PathList>()
with(cursor) {
while (moveToNext()) {
val name = getString(getColumnIndexOrThrow(PathContract.PathEntry.PATH_NAME))
val id = getInt(getColumnIndexOrThrow(BaseColumns._ID))
val path = PathList(id, name)
items.add(path)
}
}
cursor.close()
val stopTable = findViewById<TableLayout>(R.id.stop_table)
val comboPath = findViewById<Spinner>(R.id.combo_path)
comboPath.adapter = ArrayAdapter(this,android.R.layout.simple_spinner_dropdown_item, items)
comboPath.onItemSelectedListener = object : OnItemSelectedListener {
override fun onItemSelected(
parentView: AdapterView<*>?,
selectedItemView: View,
position: Int,
id: Long
) {
stopTable.removeAllViews()
StopPoint.clear()
val selectedPath = parentView!!.selectedItem
if(selectedPath != null){
val cursor = db.rawQuery("SELECT * " +
"FROM stop " +
"WHERE path_id = ${(selectedPath as PathList).id} " +
"ORDER BY 'order' ",
arrayOf()
)
with(cursor) {
while (moveToNext()) {
val latitude = getDouble(getColumnIndexOrThrow(StopContract.StopEntry.LATITUDE))
val longitude = getDouble(getColumnIndexOrThrow(StopContract.StopEntry.LONGITUDE))
val text = TextView(comboPath.context)
val geoResults: MutableList<Address>? = geocoder.getFromLocation(latitude, longitude, 1)
text.text = "$latitude | $longitude\r${geoResults?.get(0)?.getAddressLine(0)}\n"
stopTable.addView(text)
StopPoint.add("$latitude|$longitude")
}
}
}
}
override fun onNothingSelected(parentView: AdapterView<*>?) {
// your code here
}
}
val openMapsButton = findViewById<Button>(R.id.open_maps)
openMapsButton.setOnClickListener {
val lastPoint = StopPoint.last().split("|")
var uri = "google.navigation:q=${lastPoint[0]},${lastPoint[1]}&waypoints="
StopPoint.forEach {
if(StopPoint.indexOf(it) < StopPoint.size -1){
val position = it.split("|")
uri += "${position[0]},${position[1]}"
if(StopPoint.indexOf(it) < StopPoint.size -2){
uri += "%7C"
}
}
}
db.close()
val mapIntentUri = Uri.parse(uri)
val mapIntent = Intent(Intent.ACTION_VIEW, mapIntentUri)
mapIntent.setPackage("com.google.android.apps.maps")
startActivity(mapIntent)
}
val exportJsonButton = findViewById<Button>(R.id.export_json)
exportJsonButton.setOnClickListener {
val exportList = JsonArray()
val busStopList = ArrayList<Stop>()
items.forEach {
val cursor = db.rawQuery("SELECT * " +
"FROM stop " +
"WHERE path_id = ${it.id} " +
"ORDER BY 'order' ",
arrayOf()
)
with(cursor) {
while (moveToNext()) {
val latitude = getDouble(getColumnIndexOrThrow(StopContract.StopEntry.LATITUDE))
val longitude = getDouble(getColumnIndexOrThrow(StopContract.StopEntry.LONGITUDE))
val order = getInt(getColumnIndexOrThrow("order"))
busStopList.add(Stop(latitude, longitude, order))
}
}
exportList.add(ExportPath(it.name, busStopList).getJson())
}
}
}
}

View File

@@ -0,0 +1,81 @@
package com.example.busroute
import android.R
import android.annotation.SuppressLint
import android.content.Context
import android.graphics.drawable.Drawable
import android.os.AsyncTask
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.toArgb
import org.osmdroid.bonuspack.routing.OSRMRoadManager
import org.osmdroid.bonuspack.routing.Road
import org.osmdroid.bonuspack.routing.RoadManager
import org.osmdroid.util.GeoPoint
import org.osmdroid.views.MapView
import org.osmdroid.views.overlay.Marker
@SuppressLint("StaticFieldLeak")
class RetrieveRoad(private var map: MapView,
private var latitude: Double,
private var longitude: Double,
private var context: Context
) :
AsyncTask<String, Void, Void>() {
val icons = HashMap<Int, Int>()
private fun setIcons(){
icons.put(1,com.example.busroute.R.drawable.ic_continue)
icons.put(2,com.example.busroute.R.drawable.ic_continue)
icons.put(6,com.example.busroute.R.drawable.ic_slight_right)
icons.put(7,com.example.busroute.R.drawable.ic_turn_right)
icons.put(8,com.example.busroute.R.drawable.ic_sharp_right)
icons.put(12,com.example.busroute.R.drawable.ic_u_turn)
icons.put(5,com.example.busroute.R.drawable.ic_sharp_left)
icons.put(4,com.example.busroute.R.drawable.ic_turn_left)
icons.put(3,com.example.busroute.R.drawable.ic_slight_left)
icons.put(24,com.example.busroute.R.drawable.ic_arrived)
icons.put(27,com.example.busroute.R.drawable.ic_roundabout)
icons.put(28,com.example.busroute.R.drawable.ic_roundabout)
icons.put(29,com.example.busroute.R.drawable.ic_roundabout)
icons.put(30,com.example.busroute.R.drawable.ic_roundabout)
icons.put(31,com.example.busroute.R.drawable.ic_roundabout)
icons.put(32,com.example.busroute.R.drawable.ic_roundabout)
icons.put(33,com.example.busroute.R.drawable.ic_roundabout)
icons.put(34,com.example.busroute.R.drawable.ic_roundabout)
}
override fun doInBackground(vararg p0: String): Void? {
this.setIcons()
val roadManager: RoadManager = OSRMRoadManager(context, "me")
val waypoints = ArrayList<GeoPoint>()
waypoints.add(GeoPoint(latitude, longitude))
val middlePoint = GeoPoint(45.59, 6.45)
waypoints.add(middlePoint)
val endPoint = GeoPoint(45.48, 6.52)
waypoints.add(endPoint)
val road = roadManager.getRoad(waypoints)
val roadOverlay = RoadManager.buildRoadOverlay(road, Color.Blue.toArgb(), 20f)
roadOverlay.width = 15f
map.overlays.add(roadOverlay)
map.invalidate()
val nodeIcon: Drawable? = context.getDrawable(com.example.busroute.R.drawable.marker_node)
for (i in road.mNodes.indices) {
val node = road.mNodes[i]
val nodeMarker = Marker(map)
nodeMarker.position = node.mLocation
nodeMarker.icon = nodeIcon
nodeMarker.title = "Step $i"
nodeMarker.snippet = node.mInstructions
nodeMarker.subDescription = Road.getLengthDurationText(context, node.mLength, node.mDuration)
var id: Int? = icons.get(node.mManeuverType)
if (id == null){
id = icons.get(1)
}
val icon: Drawable? = context.getDrawable(id!!)
nodeMarker.image = icon
map.overlays.add(nodeMarker)
}
return null
}
}

View File

@@ -0,0 +1,87 @@
package com.example.busroute
import android.app.AlertDialog
import android.content.ContentValues
import android.location.Address
import android.location.Geocoder
import android.os.Bundle
import android.widget.Button
import android.widget.EditText
import android.widget.TableLayout
import android.widget.TextView
import androidx.appcompat.app.AppCompatActivity
import com.example.busroute.Database.DbHelper
import com.example.busroute.Database.PathContract
import com.example.busroute.Database.StopContract
import java.util.ArrayList
import java.util.Locale
class ValidateMarker: AppCompatActivity() {
companion object{
const val MARKERS = "MARKERS"
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val geocoder = Geocoder(this, Locale.getDefault())
val dbHelper = DbHelper(this)
setContentView(R.layout.marker_form)
val table = findViewById<TableLayout>(R.id.table)
val markers: ArrayList<String>? = intent.extras?.getStringArrayList(MARKERS)
markers!!.forEach{
val latitude = it.split(" | ")[0].toDouble()
val longitude = it.split(" | ")[1].toDouble()
val geoResults: MutableList<Address>? = geocoder.getFromLocation(latitude, longitude, 1)
lateinit var address:String
if (geoResults != null) {
if(geoResults.size > 0){
address = geoResults[0].getAddressLine(0)
}
}
val text = TextView(this)
var newText = it
if(!address.isNullOrEmpty()){
newText += "\r${address}\n"
}
text.text = newText
table.addView(text)
}
val validateButton = findViewById<Button>(R.id.validate_form)
validateButton.setOnClickListener{
val newName = findViewById<EditText>(R.id.route_name).text.toString()
if(newName.isBlank() or newName.isEmpty()){
val alert = AlertDialog.Builder(this).setTitle("Nom vide !")
.setMessage("Le nom du trajet est vide !")
alert.show()
return@setOnClickListener
}
val db = dbHelper.writableDatabase
val newPath = ContentValues().apply {
put(PathContract.PathEntry.PATH_NAME, newName)
}
val newPathRowId = db?.insert(PathContract.PathEntry.TABLE_NAME, null, newPath)
if(newPathRowId?.toInt() != -1){
markers.forEach {
val values = ContentValues().apply {
put(StopContract.StopEntry.LATITUDE, it.split(" | ")[0].toDouble())
put(StopContract.StopEntry.LONGITUDE, it.split(" | ")[1].toDouble())
put(StopContract.StopEntry.ORDER, markers.indexOf(it))
put(StopContract.StopEntry.PATH_ID, newPathRowId)
}
val newRowId = db?.insert(StopContract.StopEntry.TABLE_NAME, null, values)
}
val alert = AlertDialog.Builder(this).setTitle("Route sauvegardée")
.setMessage("Le trajet à été créer !").setOnDismissListener{
db.close()
finish()
}
alert.show()
}
}
}
}

View File

@@ -1,6 +1,5 @@
package com.example.busroute.ui.theme package com.example.busroute.ui.theme
import android.app.Activity
import android.os.Build import android.os.Build
import androidx.compose.foundation.isSystemInDarkTheme import androidx.compose.foundation.isSystemInDarkTheme
import androidx.compose.material3.MaterialTheme import androidx.compose.material3.MaterialTheme

Binary file not shown.

After

Width:  |  Height:  |  Size: 489 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 414 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 240 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 716 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 530 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 746 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 635 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 607 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 676 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 656 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 778 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 611 B

View File

@@ -3,21 +3,76 @@
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
android:orientation="vertical" android:orientation="vertical"
android:layout_width="fill_parent" android:layout_width="fill_parent"
android:layout_height="fill_parent"> android:layout_height="fill_parent"
android:fitsSystemWindows="true">
<RelativeLayout tools:ignore="UselessParent"> <RelativeLayout tools:ignore="UselessParent">
<Button <TableLayout
android:id="@+id/addMark" android:layout_width="200dp"
android:layout_alignParentRight="true" android:layout_height="wrap_content"
android:layout_width="150dp"
android:layout_height="50dp"
android:backgroundTint="@color/white" android:backgroundTint="@color/white"
android:textColor="@color/black" android:elevation="600dp">
android:overScrollMode="always" <Spinner
android:clickable="true" android:id="@+id/combo_path"
android:text="Add marker" /> android:background="@color/white"
android:layout_height="35dp">
</Spinner>
</TableLayout>
<TableLayout
android:layout_width="150dp"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
android:elevation="500dp">
<Button
android:id="@+id/addMark"
android:layout_width="150dp"
android:layout_height="wrap_content"
android:backgroundTint="@color/white"
android:focusable="true"
android:textColor="@color/black"
android:clickable="true"
android:text="Add marker" />
<Button
android:id="@+id/removeMark"
android:layout_width="150dp"
android:layout_height="wrap_content"
android:backgroundTint="@color/white"
android:focusable="true"
android:textColor="@color/black"
android:clickable="true"
android:text="Remove last marker" />
<Button
android:id="@+id/saveMark"
android:layout_width="150dp"
android:layout_height="wrap_content"
android:backgroundTint="@color/white"
android:focusable="true"
android:textColor="@color/black"
android:clickable="true"
android:text="Save Markers" />
<Button
android:id="@+id/open_maps"
android:layout_width="150dp"
android:layout_height="wrap_content"
android:backgroundTint="@color/white"
android:focusable="true"
android:textColor="@color/black"
android:text="Lancer le trajet dans Maps">
</Button>
<Button
android:id="@+id/road"
android:layout_width="150dp"
android:layout_height="wrap_content"
android:backgroundTint="@color/white"
android:focusable="true"
android:textColor="@color/black"
android:clickable="true"
android:text="Test Road Manager" />
</TableLayout>
<org.osmdroid.views.MapView <org.osmdroid.views.MapView
android:id="@+id/map" android:id="@+id/map"
android:elevation="0dp"
android:layout_width="fill_parent" android:layout_width="fill_parent"
android:layout_height="fill_parent"> android:layout_height="fill_parent">

View File

@@ -0,0 +1,40 @@
<?xml version="1.0" encoding="utf-8"?>
<TableLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true">
<TableLayout
android:layout_width="200dp"
android:layout_height="wrap_content">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="20dp"
android:textStyle="bold"
android:text="Merci de vérifier les informations"/>
<TextView
android:layout_width="wrap_content"
android:layout_marginTop="20dp"
android:text="Entrez un nom pour la ligne (80 caractères max)"
android:layout_height="wrap_content"/>
<EditText
android:id="@+id/route_name"
android:maxLength="80"
android:minHeight="50dp"
tools:ignore="SpeakableTextPresentCheck" />
<Button
android:layout_width="wrap_content"
android:id="@+id/validate_form"
android:layout_height="wrap_content"
android:text="Valider"/>
</TableLayout>
<TableLayout
android:id="@+id/table"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:clipToPadding="false"
android:padding="16dp" />
</TableLayout>

View File

@@ -0,0 +1,25 @@
<?xml version="1.0" encoding="utf-8"?>
<TableLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true">
<Spinner
android:id="@+id/combo_path"
android:minHeight="50dp">
</Spinner>
<Button
android:id="@+id/open_maps"
android:text="Lancer le trajet dans Maps">
</Button>
<Button
android:id="@+id/export_json"
android:text="Exporter tous les trajets">
</Button>
<TableLayout
android:id="@+id/stop_table"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</TableLayout>

View File

@@ -1,5 +1,7 @@
[versions] [versions]
agp = "8.5.0" agp = "8.5.0"
commonsLang3 = "3.8.1"
gson = "2.11.0"
kotlin = "1.9.0" kotlin = "1.9.0"
coreKtx = "1.13.1" coreKtx = "1.13.1"
junit = "4.13.2" junit = "4.13.2"
@@ -8,15 +10,21 @@ espressoCore = "3.5.1"
lifecycleRuntimeKtx = "2.8.2" lifecycleRuntimeKtx = "2.8.2"
activityCompose = "1.9.0" activityCompose = "1.9.0"
composeBom = "2024.06.00" composeBom = "2024.06.00"
okhttp = "4.7.2"
osmbonuspack = "6.9.0"
osmdroidAndroid = "6.1.18"
playServicesLocation = "21.3.0" playServicesLocation = "21.3.0"
appcompat = "1.7.0"
[libraries] [libraries]
androidx-core-ktx = { group = "androidx.core", name = "core-ktx", version.ref = "coreKtx" } androidx-core-ktx = { group = "androidx.core", name = "core-ktx", version.ref = "coreKtx" }
commons-lang3 = { module = "org.apache.commons:commons-lang3", version = "3.16.0" }
gson = { module = "com.google.code.gson:gson", version.ref = "gson" }
junit = { group = "junit", name = "junit", version.ref = "junit" } junit = { group = "junit", name = "junit", version.ref = "junit" }
androidx-junit = { group = "androidx.test.ext", name = "junit", version.ref = "junitVersion" } androidx-junit = { group = "androidx.test.ext", name = "junit", version = "1.2.1" }
androidx-espresso-core = { group = "androidx.test.espresso", name = "espresso-core", version.ref = "espressoCore" } androidx-espresso-core = { group = "androidx.test.espresso", name = "espresso-core", version = "3.6.1" }
androidx-lifecycle-runtime-ktx = { group = "androidx.lifecycle", name = "lifecycle-runtime-ktx", version.ref = "lifecycleRuntimeKtx" } androidx-lifecycle-runtime-ktx = { group = "androidx.lifecycle", name = "lifecycle-runtime-ktx", version = "2.8.4" }
androidx-activity-compose = { group = "androidx.activity", name = "activity-compose", version.ref = "activityCompose" } androidx-activity-compose = { group = "androidx.activity", name = "activity-compose", version = "1.9.1" }
androidx-compose-bom = { group = "androidx.compose", name = "compose-bom", version.ref = "composeBom" } androidx-compose-bom = { group = "androidx.compose", name = "compose-bom", version.ref = "composeBom" }
androidx-ui = { group = "androidx.compose.ui", name = "ui" } androidx-ui = { group = "androidx.compose.ui", name = "ui" }
androidx-ui-graphics = { group = "androidx.compose.ui", name = "ui-graphics" } androidx-ui-graphics = { group = "androidx.compose.ui", name = "ui-graphics" }
@@ -25,7 +33,11 @@ androidx-ui-tooling-preview = { group = "androidx.compose.ui", name = "ui-toolin
androidx-ui-test-manifest = { group = "androidx.compose.ui", name = "ui-test-manifest" } androidx-ui-test-manifest = { group = "androidx.compose.ui", name = "ui-test-manifest" }
androidx-ui-test-junit4 = { group = "androidx.compose.ui", name = "ui-test-junit4" } androidx-ui-test-junit4 = { group = "androidx.compose.ui", name = "ui-test-junit4" }
androidx-material3 = { group = "androidx.compose.material3", name = "material3" } androidx-material3 = { group = "androidx.compose.material3", name = "material3" }
okhttp = { module = "com.squareup.okhttp3:okhttp", version = "4.12.0" }
osmbonuspack = { module = "com.github.MKergall:osmbonuspack", version.ref = "osmbonuspack" }
osmdroid-android = { module = "org.osmdroid:osmdroid-android", version.ref = "osmdroidAndroid" }
play-services-location = { group = "com.google.android.gms", name = "play-services-location", version.ref = "playServicesLocation" } play-services-location = { group = "com.google.android.gms", name = "play-services-location", version.ref = "playServicesLocation" }
androidx-appcompat = { group = "androidx.appcompat", name = "appcompat", version.ref = "appcompat" }
[plugins] [plugins]
android-application = { id = "com.android.application", version.ref = "agp" } android-application = { id = "com.android.application", version.ref = "agp" }

View File

@@ -8,6 +8,9 @@ pluginManagement {
} }
} }
mavenCentral() mavenCentral()
flatDir {
dirs("libs")
}
gradlePluginPortal() gradlePluginPortal()
} }
} }