Tải bản đầy đủ (.pdf) (89 trang)

COMP1786M01202324 Mobile Application Design and Development

Bạn đang xem bản rút gọn của tài liệu. Xem và tải ngay bản đầy đủ của tài liệu tại đây (1.49 MB, 89 trang )

<span class="text_page_counter">Trang 1</span><div class="page_container" data-page="1">

<b>Mobile Application Design and Development (COMP1786) </b>

<b>Full Name: DAO VINH KHANG ID: Khangdvgcs200222 </b>

<b>( Email: ) </b>

</div><span class="text_page_counter">Trang 2</span><div class="page_container" data-page="2">

<b>Table of content </b>

Contents

• <b>Checklist of features ( Java ) ... 5 </b>

• <b>Checklist of features ( C# Xamarin) ... 6 </b>

<b>Integration with Google Maps: ... 37 </b>

<b>Storing Hike Data in Local Database: ... 41 </b>

• <b>Feature screenshot (C# Xamarin) ... 70 </b>

<b>User Interface (UI), List of saved hikes, CRUD Operations ... 70 </b>

<b>Data storage, SQL database ... 75 </b>

• <b>Reflect on the application development process... 76 </b>

<b>Database Integration: ... 76 </b>

<b>User Interface: ... 76 </b>

<b>System Analysis and Design: ... 76 </b>

<b>Areas for Improvement: ... 77 </b>

<b>Security: ... 77 </b>

<b>Compatibility with Multiple Screen Sizes: ... 77 </b>

<b>Testing and Debugging: ... 77 </b>

• <b>Reflect on the application development process ( C# Xamarin ) ... 77 </b>

• <b>Evaluate your application ... 78 </b>

<b>User Registration and Login: ... 78 </b>

<b>Profile Management: ... 78 </b>

<b>Hike Planning and Recording: ... 79 </b>

</div><span class="text_page_counter">Trang 3</span><div class="page_container" data-page="3">

<b>Areas for Improvement: ... 80 </b>

• <b>Evaluate your application ( C# Xamrin ) ... 80 </b>

</div><span class="text_page_counter">Trang 4</span><div class="page_container" data-page="4">

Figure 6 Google Maps ... 38

Figure 7 List of Hike ... 46

Figure 8 PedestrianRating ... 52

Figure 9 Set Goal ... 56

Figure 10 Hiking Chat ... 62

Figure 11 Hiking Guide ... 65

Figure 12 Hiking Shoping... 68

Figure 13 User Interface... 70

Figure 14 List Hike ... 71

</div><span class="text_page_counter">Trang 5</span><div class="page_container" data-page="5">

List of Itineraries Displays a list of hiking itineraries for the user.

Itinerary Details Allows users to view the details of an itinerary when they select one from the list.

<b>Add an Itinerary </b>

Create a New Itinerary Users can create a new hiking itinerary with details such as location, date, distance, and notes.

Save New Itinerary Saves the details of the new itinerary to the database.

<b>Delete Confirmation </b>

Confirm Deletion Displays a confirmation dialog when the user wants to delete an item from the hiking itinerary list.

Perform Deletion Deletes the item when the user confirms the deletion.

<b>List Observations </b>

List of Observations Displays a list of observations made during hikes. Link to Specific Itinerary Links observations to specific hiking itineraries.

<b>Enter Observations </b>

Record Observations Allows users to record observations and notes during a hike. Associate with an Itinerary Associates observations with a specific hike.

<b>Pedestrian Rating </b>

Rate Pedestrian-Friendliness Allows users to rate the pedestrian-friendliness of hiking trails. Display and Update Ratings Displays and updates ratings for each trail.

<b>Hiking Chat </b>

Hiking Chat Implements a chat feature for hikers to communicate and share their hiking experiences.

</div><span class="text_page_counter">Trang 6</span><div class="page_container" data-page="6">

Real-time Message Display Displays chat messages in real-time.

<b>• Checklist of features ( C# Xamarin) </b>

User Interface (UI) Responsive UI design using Xamarin.Forms for both iOS and Android, with a main page containing input fields for Hiking Name, Location,

Date, Description, and a "Choose Photo" button to select an image.

Data storage Uses an SQLite database to store information about hiking trips.

SQL database Connects and interacts with an SQLite database to store and retrieve information about hiking

trips.

CRUD Operations (Create, Read, Update, Delete) Allows users to create, read, update and delete mountain trip records.

Data synchronization Ensure data synchronization between your device and remote data (if available) to stay up-to-date

on your hike.

List of saved hikes Displays a list of saved trekking trips as a list or table, helping users easily view trip information.

<b>• Feature screenshot </b>

User Registration and Login:

<b>User Login: </b>

UI: Create a login screen with fields for Email and Password. Validation: Check input validity and completeness.

Backend: Send login data to the server for verification. Receive and handle the server's response.

</div><span class="text_page_counter">Trang 7</span><div class="page_container" data-page="7">

<i>Figure 1 Login </i>

This Java code is for an Android login screen (MainActivity). It checks entered credentials against stored user data in SharedPreferences, displays appropriate messages, and navigates to the main screen upon successful login. It also provides an option to navigate to the registration screen (RegisterActivity).

</div><span class="text_page_counter">Trang 8</span><div class="page_container" data-page="8">

public class MainActivity extends AppCompatActivity { private EditText usernameEditText, passwordEditText; private SharedPreferences sharedPreferences;

private static final String PREFS_NAME = "MyPrefs";

public void onLoginClick(View view) { String username = getUsernameInput(); String password = getPasswordInput();

private String getUsernameInput() {

return usernameEditText.getText().toString(); }

</div><span class="text_page_counter">Trang 9</span><div class="page_container" data-page="9">

XML:

<?xml version="1.0" encoding="utf-8"?>

<LinearLayout xmlns:android=" xmlns:app="

private String getPasswordInput() {

return passwordEditText.getText().toString(); }

private boolean isUsernameRegistered(String username) { return sharedPreferences.contains(username);

}

private String getSavedPassword(String username) { return sharedPreferences.getString(username, "");

private void showLoginSuccessMessage() {

<i> Toast.makeText(this, </i>"Logged in successfully", Toast.LENGTH_SHORT).show();

}

private Intent createMainScreenIntent(String username) { Intent mainScreenIntent = new Intent(this, Home.class); mainScreenIntent.putExtra("username", username);

return mainScreenIntent; }

private void showPasswordErrorMessage() {

<i> Toast.makeText(this, </i>"Password error", Toast.LENGTH_SHORT).show();

}

private void showUsernameNotFoundMessage() {

<i> Toast.makeText(this, </i>"Username not found",

private void startRegisterActivity() {

Intent intent = new Intent(MainActivity.this, RegisterActivity.class);

startActivity(intent); }

}

</div><span class="text_page_counter">Trang 10</span><div class="page_container" data-page="10">

xmlns:tools=" android:layout_width="match_parent"

android:layout_height="match_parent"

android:background="@drawable/background_walking" android:orientation="vertical"

android:padding="16dp"

tools:context="com.example.HikingApp_GCS200222.MainActivity"> <ImageView

android:id="@+id/imageView5"

android:layout_width="wrap_content"

android:id="@+id/usernameEditText" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="16dp" android:hint="Username"

android:minHeight="48dp" /> <EditText

android:id="@+id/passwordEditText" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="16dp" android:hint="Password"

android:inputType="textPassword" android:minHeight="48dp" /> <Button

android:id="@+id/loginButton"

android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="16dp"

android:backgroundTint="@android:color/holo_blue_light" android:text="Login"

android:onClick="onLoginClick" /> <Button

android:id="@+id/registerButton" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="16dp"

android:backgroundTint="@android:color/holo_blue_light" android:text="Register"

android:onClick="onRegisterClick" /> </LinearLayout>

<b>User Registration: </b>

</div><span class="text_page_counter">Trang 11</span><div class="page_container" data-page="11">

UI: Design a registration screen with fields like Name, Email, Password, and Confirm Password.

Validation: Verify input format and length. Ensure password and confirmation match. Backend: Send registration data to a server API to store user information in a database. User Login:

UI: Create a login screen with fields for Email and Password. Validation: Check input validity and completeness.

Backend: Send login data to the server for verification. Receive and handle the server's response.

</div><span class="text_page_counter">Trang 12</span><div class="page_container" data-page="12">

<i>Figure 2 Register </i>

This Android RegisterActivity handles user registration by collecting information such as full name, display name, username, password, and confirming the password. It validates the input, saves user information to SharedPreferences, and navigates to the main screen (MainActivity) upon successful registration. The activity includes methods for input validation, data saving, and displaying a registration failed message.

package com.example.HikingApp_GCS200222; import android.content.Intent;

import android.content.SharedPreferences; import android.os.Bundle;

</div><span class="text_page_counter">Trang 13</span><div class="page_container" data-page="13">

public class RegisterActivity extends AppCompatActivity { private EditText fullNameEditText, namescreenEditText, usernameEditText, passwordEditText, confirmPasswordEditText; private SharedPreferences sharedPreferences;

private static final String PREFS_NAME = "MyPrefs";

public void onRegisterClick(View view) {

String fullName = getEditTextValue(fullNameEditText); String namescreen = getEditTextValue(namescreenEditText); String username = getEditTextValue(usernameEditText); String password = getEditTextValue(passwordEditText);

private boolean validateRegistration(String fullName, String

namescreen, String username, String password, String confirmPassword) {

</div><span class="text_page_counter">Trang 14</span><div class="page_container" data-page="14">

if (isEmpty(fullName) || isEmpty(namescreen) || isEmpty(username)

private void saveUserInformation(String username, String password, String fullName, String namescreen) {

SharedPreferences.Editor editor = sharedPreferences.edit(); editor.putString(username, password);

editor.putString(username + "_fullname", fullName); editor.putString(username + "_namescreen", namescreen); editor.apply();

}

private void startMainActivity() {

Intent intent = new Intent(RegisterActivity.this, MainActivity.class);

startActivity(intent); finish();

}

private void showRegistrationFailedMessage() {

<i> Toast.makeText(this, </i>"Registration failed", Toast.LENGTH_SHORT).show();

} }

XML:

<?xml version="1.0" encoding="utf-8"?>

<LinearLayout xmlns:android=" xmlns:app="

xmlns:tools=" android:layout_width="match_parent"

android:layout_height="match_parent" android:orientation="vertical"

android:padding="16dp"

android:background="@drawable/background_walking"

tools:context="com.example.HikingApp_GCS200222.RegisterActivity"> <ImageView

android:id="@+id/imageView5"

android:layout_width="match_parent" android:layout_height="236dp"

app:srcCompat="@drawable/pathfit3" />

</div><span class="text_page_counter">Trang 15</span><div class="page_container" data-page="15">

<EditText

android:id="@+id/fullNameEditText" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="16dp" android:hint="Full Name"

android:minHeight="48dp" /> <EditText

android:id="@+id/namescreenEditText" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="16dp" android:hint="Namescreen"

android:minHeight="48dp" /> <EditText

android:id="@+id/usernameEditText" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="16dp" android:hint="Username"

android:minHeight="48dp" /> <EditText

android:id="@+id/passwordEditText" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="16dp" android:hint="Password"

android:inputType="textPassword" android:minHeight="48dp" /> <EditText

android:id="@+id/confirmPasswordEditText" android:layout_width="match_parent"

android:layout_height="wrap_content" android:layout_marginTop="16dp" android:hint="Confirm Password" android:inputType="textPassword" android:minHeight="48dp" /> <Button

android:id="@+id/registerButton" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="16dp"

android:backgroundTint="@android:color/holo_blue_light" android:text="Register"

android:textColor="#E9EFE9" android:textStyle="bold"

android:onClick="onRegisterClick" /> </LinearLayout>

</div><span class="text_page_counter">Trang 16</span><div class="page_container" data-page="16">

User Registration: Users can create new accounts by providing their email and a password. Login: Registered users can log in with their credentials to access the app's features. Main Screen:

MainScreen is the screen users see when they open their app. This is where main functions and important information are organized and displayed. On the home screen, users can usually access the most important features of the app conveniently and quickly without having to go through many steps.

Elements that typically appear on the home screen include icons (icons) or buttons for key features, notifications, user personal information, and other options that depend on the user's goals. application. The goal is to create a user experience that is comfortable and easy to use from the home screen.

</div><span class="text_page_counter">Trang 17</span><div class="page_container" data-page="17">

<i>Figure 3 MainScreen </i>

This Android Home activity displays user information, includes a VideoView, and provides buttons to navigate to various features of a hiking app. It initializes views, sets up a video view, displays user information retrieved from SharedPreferences, and handles button clicks to navigate to different functionalities. The activity also includes a logout button that clears the user session and returns to the login screen (MainActivity).

</div><span class="text_page_counter">Trang 18</span><div class="page_container" data-page="18">

import androidx.appcompat.app.AppCompatActivity; import com.example.myproject.R;

public class Home extends AppCompatActivity {

private TextView fullNameTextView, namescreenTextView; private SharedPreferences sharedPreferences;

private static final String PREFS_NAME = "MyPrefs"; private VideoView videoView;

private void setupVideoView() {

<i> Uri videoUri = Uri.parse(</i>"android.resource://" + getPackageName()

String username = getIntent().getStringExtra("username"); String fullName = sharedPreferences.getString(username +

fullNameTextView.setText("Full Name"); namescreenTextView.setText("Name Screen");

</div><span class="text_page_counter">Trang 19</span><div class="page_container" data-page="19">

public void onClick(View v) {

Intent intent = new Intent(Home.this, destinationClass); startActivity(intent);

} }); }

private void setLogoutButtonAction(int buttonId) { Button logOutButton = findViewById(buttonId);

private void clearUserSession() {

SharedPreferences.Editor editor = sharedPreferences.edit(); editor.remove("username");

editor.apply(); }

private void navigateToLoginScreen() {

Intent loginIntent = new Intent(Home.this, MainActivity.class);

<?xml version="1.0" encoding="utf-8"?>

<LinearLayout xmlns:android="

</div><span class="text_page_counter">Trang 20</span><div class="page_container" data-page="20">

xmlns:app=" xmlns:tools=" android:layout_width="match_parent"

android:layout_height="match_parent"

android:background="@drawable/background_walking" android:orientation="vertical"

android:padding="16dp"

tools:context="com.example.HikingApp_GCS200222.Home"> <!-- Full Name -->

<RelativeLayout

android:layout_width="match_parent" android:layout_height="wrap_content"

tools:context="com.example.HikingApp_GCS200222.Home" tools:ignore="ExtraText">

<!-- TextView cho tên đầy đủ --> <TextView

android:id="@+id/fullNameTextView" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentStart="true" android:layout_alignParentTop="true" android:text="Account"

android:textSize="15dp"

tools:ignore="DuplicateIds,TextSizeCheck" /> <!-- TextView cho namescreen -->

<TextView

android:id="@+id/namescreenTextView" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentStart="true" android:layout_below="@id/fullNameTextView"

android:id="@+id/addHikeButton" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="16dp" android:text="Record a Hike"

android:backgroundTint="@android:color/holo_blue_light" /> <Button

android:id="@+id/recordHikeButton" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="16dp" android:text="Google Map"

</div><span class="text_page_counter">Trang 21</span><div class="page_container" data-page="21">

android:backgroundTint="@android:color/holo_blue_light" /> <Button

android:id="@+id/planHikeButton" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="16dp" android:text="Observe a Hike"

android:backgroundTint="@android:color/holo_blue_light" /> <Button

android:id="@+id/searchTrailsButton" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="16dp"

android:backgroundTint="@android:color/holo_blue_light" android:text="Shoping" />

<LinearLayout

android:layout_width="wrap_content" android:layout_height="wrap_content" android:orientation="horizontal">

android:backgroundTint="@android:color/holo_blue_light" android:text="Hiking Rating" /> android:text="Hiking Guide"

android:backgroundTint="@android:color/holo_blue_light" /> android:text="Hiking Chat"

android:backgroundTint="@android:color/holo_blue_light" />

</div><span class="text_page_counter">Trang 22</span><div class="page_container" data-page="22">

android:backgroundTint="@android:color/holo_blue_light" /> </LinearLayout>

<Button

android:id="@+id/logoutButton" android:layout_width="wrap_content" android:layout_height="wrap_content"

android:backgroundTint="@android:color/holo_blue_light" android:text="Log Out" />

<VideoView

android:id="@+id/videoView"

android:layout_width="wrap_content" android:layout_height="253dp"

android:layout_marginTop="16dp" /> </LinearLayout>

Profile Editing: Users can edit their profiles, update information, and set profile pictures. Hike Planning and Recording:

Hiking Plan (Planning Your Hiking Trip):

Function: Allows users to plan hiking activities before doing them.

Interface: Provides tools for selecting detection locations, destinations, and important points on the map. Users can also view information about difficulty, distance, and estimated time.

Record your hiking trip (Hiking Journey Recording):

Function: Allows users to record information about actual climbing activities.

Interface: Includes buttons or features to start and end recording. Information such as start time, end time, distance traveled, etc., is displayed and can be saved.

</div><span class="text_page_counter">Trang 23</span><div class="page_container" data-page="23">

<i>Figure 4 Hike Planning </i>

The AddAHike activity in the HikingApp allows users to input details about a hike, validates the input, saves the information to SharedPreferences, and provides options to view a list of hikes or return to the home screen. It includes EditTexts, a CheckBox, a Spinner for difficulty levels, and buttons for adding a hike, viewing the list, and returning. Validation ensures all required fields are filled, and the distance is a positive number. The entered hike details are then stored in SharedPreferences.

package com.example.HikingApp_GCS200222; import android.content.Context;

import android.content.Intent;

</div><span class="text_page_counter">Trang 24</span><div class="page_container" data-page="24">

public class AddAHike extends AppCompatActivity {

private EditText hikeNameEditText, hikeLocationEditText,

hikeDateEditText, hikeDistanceEditText, descriptionEditText; private CheckBox parkingCheckBox;

private Spinner difficultySpinner;

private void setupButtonClickListeners() {

Button addHikeButton = findViewById(R.id.addHikeButton); Button listButton = findViewById(R.id.listButton);

Button backButton = findViewById(R.id.backButton);

addHikeButton.setOnClickListener(new View.OnClickListener() {

</div><span class="text_page_counter">Trang 25</span><div class="page_container" data-page="25">

private boolean validateFields() {

String hikeName = hikeNameEditText.getText().toString().trim();

</div><span class="text_page_counter">Trang 26</span><div class="page_container" data-page="26">

getSharedPreferences("HikeData", Context.MODE_PRIVATE);

int hikeCount = sharedPreferences.getInt("HikeCount", 0) + 1;

SharedPreferences.Editor editor = sharedPreferences.edit(); editor.putString("HikeName" + hikeCount,

private void showSuccessMessage() {

<i> Toast.makeText(AddAHike.this, </i>"Hike added successfully!",

private void startListActivity() {

Intent intent = new Intent(AddAHike.this, Listmain.class); startActivity(intent);

}

private void returnToHomeActivity() {

Intent mainIntent = new Intent(AddAHike.this, Home.class); startActivity(mainIntent);

</div><span class="text_page_counter">Trang 27</span><div class="page_container" data-page="27">

android:layout_width="match_parent"

android:layout_height="match_parent"

android:background="@drawable/background_walking" android:padding="16dp"

tools:context="com.example.HikingApp_GCS200222.AddAHike"> <LinearLayout

android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical"> <EditText

android:id="@+id/hikeNameEditText" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginBottom="16dp" android:hint="Hike Name"

android:inputType="text" android:minHeight="48dp" android:textStyle="bold" />

<EditText

android:id="@+id/hikeLocationEditText" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginBottom="16dp" android:hint="Location"

android:inputType="text" android:minHeight="48dp" android:textStyle="bold" />

<EditText

android:id="@+id/hikeDateEditText" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginBottom="16dp" android:hint="Date"

android:inputType="date"

</div><span class="text_page_counter">Trang 28</span><div class="page_container" data-page="28">

android:layout_height="wrap_content" android:layout_marginBottom="16dp"

android:entries="@array/difficulty_levels" android:minHeight="48dp"

tools:ignore="DuplicateIds" android:textStyle="bold" />

<EditText

android:id="@+id/hikeDistanceEditText" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginBottom="16dp" android:hint="Hike Distance (in km)" android:inputType="numberDecimal" android:minHeight="48dp"

android:textStyle="bold" />

<EditText

android:id="@+id/descriptionEditText" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginBottom="16dp" android:hint="Description (Optional)" android:inputType="textMultiLine"

android:id="@+id/parkingCheckBox" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginBottom="16dp" android:text="Has Parking"

android:textStyle="bold" />

<Button

android:id="@+id/addHikeButton" android:layout_width="wrap_content" android:layout_height="wrap_content"

android:backgroundTint="@android:color/holo_blue_light" android:text="Add Hike"

/>

</div><span class="text_page_counter">Trang 29</span><div class="page_container" data-page="29">

<Button

android:id="@+id/backButton"

android:layout_width="wrap_content" android:layout_height="wrap_content"

android:backgroundTint="@android:color/holo_blue_light" android:text="Back to Main Screen"

android:textStyle="bold"

android:layout_marginTop="25dp" android:layout_marginLeft="150dp" />

<Button

android:id="@+id/listButton"

android:layout_width="wrap_content" android:layout_height="wrap_content"

android:backgroundTint="@android:color/holo_blue_light" android:text="List"

Interface: May include a text input section or even a recording tool to record comments. Images or videos can also be captured and recorded.

Destination Notes:

Function: Allows users to add notes or comments on important points.

Interface: Provides options to add notes when the user reaches a special location, such as a viewpoint, peak, or wildlife area.

</div><span class="text_page_counter">Trang 30</span><div class="page_container" data-page="30">

<i>Figure 5 Observation </i>

ObserveHikeActivity in the HikingApp allows users to observe and record details about a hike, such as location, time, event description, additional info, note, and title. Users can also take a photo to associate with the observation. The observations are displayed in a

ListView, and the data is stored using Database SQLite. Users can add, remove, or clear observations. The takePhotoButton invokes the device's camera to capture and display a photo for the observation.

</div><span class="text_page_counter">Trang 31</span><div class="page_container" data-page="31">

public class ObserveHikeActivity extends AppCompatActivity { private EditText locationEditText, timeEditText,

eventDescriptionEditText,

additionalInfoEditText, noteEditText, titleEditText;

private Button addButton, clearButton, backButton, takePhotoButton; private ListView observationListView;

private Adapter observationAdapter;

private List<Observation> observationList; private ImageView photoImageView;

private SharedPreferences sharedPreferences;

private static final String OBSERVATION_PREFS = "observation_prefs"; private static final int REQUEST_IMAGE_CAPTURE = 1;

</div><span class="text_page_counter">Trang 32</span><div class="page_container" data-page="32">

observationListView = findViewById(R.id.observationListView); sharedPreferences = getSharedPreferences(OBSERVATION_PREFS, MODE_PRIVATE);

String json = sharedPreferences.getString("observations", null); Type type = new TypeToken<List<Observation>>() {}.getType(); observationList = new ArrayList<>();

public void onClick(View v) {

Intent intent = new Intent(ObserveHikeActivity.this,

public void onItemClick(AdapterView<?> parent, View view, int position, long id) {

</div><span class="text_page_counter">Trang 33</span><div class="page_container" data-page="33">

Intent takePictureIntent = new

super.onActivityResult(requestCode, resultCode, data); if (requestCode == REQUEST_IMAGE_CAPTURE && resultCode == RESULT_OK) {

Bundle extras = data.getExtras();

Bitmap imageBitmap = (Bitmap) extras.get("data"); photoImageView.setImageBitmap(imageBitmap);

photoImageView.setVisibility(View.VISIBLE); }

}

private void addObservation() {

String location = locationEditText.getText().toString(); String time = timeEditText.getText().toString();

String eventDescription =

eventDescriptionEditText.getText().toString(); String additionalInfo =

additionalInfoEditText.getText().toString();

String note = noteEditText.getText().toString(); String title = titleEditText.getText().toString();

Observation observation = new Observation(location, time, eventDescription, additionalInfo, note, title);

SharedPreferences.Editor editor = sharedPreferences.edit(); editor.putString("observations", new

Gson().toJson(observationList)); editor.apply();

</div><span class="text_page_counter">Trang 34</span><div class="page_container" data-page="34">

SharedPreferences.Editor editor = sharedPreferences.edit(); editor.putString("observations", new android:layout_width="match_parent"

android:layout_height="match_parent"

android:background="@drawable/background_walking" android:padding="16dp"

tools:context="com.example.HikingApp_GCS200222.ObserveHikeActivity"> <EditText

android:id="@+id/locationEditText" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginBottom="8dp" android:hint="Location"

android:minHeight="48dp" /> <EditText

android:id="@+id/timeEditText" android:layout_width="match_parent"

</div><span class="text_page_counter">Trang 35</span><div class="page_container" data-page="35">

android:layout_height="wrap_content"

android:layout_below="@+id/locationEditText" android:layout_marginBottom="8dp"

android:hint="Time"

android:minHeight="48dp" /> <EditText

android:id="@+id/eventDescriptionEditText" android:layout_width="match_parent"

android:layout_height="wrap_content" android:layout_below="@+id/timeEditText" android:layout_marginBottom="8dp"

android:hint="Event Description" android:minHeight="48dp" /> <EditText

android:id="@+id/additionalInfoEditText" android:layout_width="match_parent" android:layout_height="wrap_content"

android:layout_below="@+id/eventDescriptionEditText" android:layout_marginBottom="8dp"

android:hint="Additional Info" android:minHeight="48dp" /> <EditText

android:id="@+id/noteEditText" android:layout_width="match_parent" android:layout_height="wrap_content"

android:layout_below="@+id/additionalInfoEditText"

android:layout_height="wrap_content" android:layout_below="@+id/noteEditText" android:layout_marginBottom="16dp"

android:hint="Title"

android:minHeight="48dp" /> <Button

android:id="@+id/addButton"

android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_below="@+id/titleEditText" android:layout_marginTop="-2dp"

android:text="Add"

android:backgroundTint="@android:color/holo_blue_light" />

<ListView

android:id="@+id/observationListView" android:layout_width="wrap_content" android:layout_height="189dp"

android:layout_below="@+id/addButton"

</div><span class="text_page_counter">Trang 36</span><div class="page_container" data-page="36">

android:layout_marginTop="11dp" /> <Button

android:id="@+id/clearButton"

android:layout_width="wrap_content" android:layout_height="50dp"

android:layout_below="@+id/observationListView" android:layout_marginTop="6dp"

android:minHeight="48dp"

android:text="Clear Observations" tools:ignore="TouchTargetSizeCheck"

android:text="Back"

tools:ignore="TouchTargetSizeCheck"

android:layout_above="@+id/observationListView" android:layout_below="@+id/addButton"

android:layout_alignEnd="@+id/titleEditText" android:layout_marginTop="-54dp"

android:layout_marginEnd="15dp" android:layout_marginBottom="5dp"

android:backgroundTint="@android:color/holo_blue_light" android:text="Take Photo" />

<ImageView

android:id="@+id/photoImageView" android:layout_width="match_parent" android:layout_height="wrap_content"

android:layout_below="@+id/takePhotoButton" android:layout_marginTop="16dp"

android:scaleType="centerCrop" android:visibility="gone" />

</RelativeLayout>

</div><span class="text_page_counter">Trang 37</span><div class="page_container" data-page="37">

Integration with Google Maps: Show Map:

Function: Integrate Google maps directly into the application to help users view and locate their location.

Interface: Part of the main screen or a special separate screen that displays a map with zoom in, zoom out and GPS navigation functions.

Plan Your Route:

Function: Allows users to plan their hiking journey by selecting a route on the map.

Interface: Provides tools to select departure points, destinations and important points on the map.

Highlight Important Points:

Function: Users can mark important points on the map, set limits such as scenic spots, water points, or road entrances.

Interface: Integrates tools to mark and annotate directly on the map. Real Time and Location Tracking:

Function: Displays the user's real-time location on the map and records the location as they move.

Interface: Provides information related to location, speed and distance on the map.

</div><span class="text_page_counter">Trang 38</span><div class="page_container" data-page="38">

<i>Figure 6 Google Maps </i>

GoogleMapActivity in the HikingApp integrates a WebView to display Google Maps. It requests location permissions if needed, loads the Google Maps URL with a specified location, and provides a back button to navigate back to the home screen. The WebView settings enable JavaScript and geolocation, allowing users to interact with the map. The app handles geolocation permissions and reloading the WebView after obtaining location

</div><span class="text_page_counter">Trang 39</span><div class="page_container" data-page="39">

public class GoogleMapActivity extends AppCompatActivity {

private static final int LOCATION_PERMISSION_REQUEST_CODE = 1;

private void initializeWebViewSettings(WebView webView) { WebSettings webSettings = webView.getSettings(); webSettings.setJavaScriptEnabled(true);

webSettings.setGeolocationEnabled(true);

webView.setWebViewClient(new WebViewClient());

</div><span class="text_page_counter">Trang 40</span><div class="page_container" data-page="40">

private void navigateToHomeScreen() {

Intent mainScreenIntent = new Intent(GoogleMapActivity.this, Home.class);

startActivity(mainScreenIntent); }

@Override

public void onRequestPermissionsResult(int requestCode, @NonNull

String[] permissions, @NonNull int[] grantResults) {

android:layout_width="match_parent" android:layout_height="match_parent"> <WebView

android:id="@+id/webView"

android:layout_width="match_parent" android:layout_height="match_parent" />

</div>

×