Assignment COMP 1786 Mobile Application Design and Development Thuê làm code lh zalo: 0834684568 Greenwich HCM Assignment COMP 1786 Mobile Application Design and Development Thuê làm code lh zalo: 0834684568 Greenwich HCM
Trang 1Mobile Application Design and Development (COMP1786)
Full Name: DAO VINH KHANG ID: Khangdvgcs200222
( Email: dk9621h@gre.ac.uk )
Trang 2Table of content
Contents
• Checklist of features ( Java ) 5
• Checklist of features ( C# Xamarin) 6
Integration with Google Maps: 37
Storing Hike Data in Local Database: 41
• Feature screenshot (C# Xamarin) 70
User Interface (UI), List of saved hikes, CRUD Operations 70
Data storage, SQL database 75
• Reflect on the application development process 76
Database Integration: 76
User Interface: 76
System Analysis and Design: 76
Areas for Improvement: 77
Security: 77
Compatibility with Multiple Screen Sizes: 77
Testing and Debugging: 77
• Reflect on the application development process ( C# Xamarin ) 77
• Evaluate your application 78
User Registration and Login: 78
Profile Management: 78
Hike Planning and Recording: 79
Trang 3Areas for Improvement: 80
• Evaluate your application ( C# Xamrin ) 80
Trang 4Figure 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
Trang 5List 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
Add an Itinerary
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
Delete Confirmation
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
List Observations
List of Observations Displays a list of observations made during hikes Link to Specific Itinerary Links observations to specific hiking itineraries
Enter Observations
Record Observations Allows users to record observations and notes during a hike Associate with an Itinerary Associates observations with a specific hike
Pedestrian Rating
Rate Pedestrian-Friendliness Allows users to rate the pedestrian-friendliness of hiking trails Display and Update Ratings Displays and updates ratings for each trail
Hiking Chat
Hiking Chat Implements a chat feature for hikers to communicate and share their hiking experiences
Trang 6Real-time Message Display Displays chat messages in real-time
• Checklist of features ( C# Xamarin)
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
• Feature screenshot
User Registration and Login:
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
Trang 7Figure 1 Login
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)
Trang 8public 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(); }
Trang 9XML:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto"
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() {
Toast.makeText(this, "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() {
Toast.makeText(this, "Password error", Toast.LENGTH_SHORT).show();
}
private void showUsernameNotFoundMessage() {
Toast.makeText(this, "Username not found",
private void startRegisterActivity() {
Intent intent = new Intent(MainActivity.this, RegisterActivity.class);
startActivity(intent); }
}
Trang 10xmlns:tools="http://schemas.android.com/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>
User Registration:
Trang 11UI: 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
Trang 12Figure 2 Register
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;
Trang 13public 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) {
Trang 14if (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() {
Toast.makeText(this, "Registration failed", Toast.LENGTH_SHORT).show();
} }
XML:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/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" />
Trang 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>
Trang 16User 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
Trang 17Figure 3 MainScreen
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)
Trang 18import 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() {
Uri videoUri = Uri.parse("android.resource://" + getPackageName()
String username = getIntent().getStringExtra("username"); String fullName = sharedPreferences.getString(username +
fullNameTextView.setText("Full Name"); namescreenTextView.setText("Name Screen");
Trang 19public 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="http://schemas.android.com/apk/res/android"
Trang 20xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/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"
Trang 21android: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" />
Trang 22android: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
Trang 23Figure 4 Hike Planning
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;
Trang 24public 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() {
Trang 25private boolean validateFields() {
String hikeName = hikeNameEditText.getText().toString().trim();
Trang 26getSharedPreferences("HikeData", Context.MODE_PRIVATE);
int hikeCount = sharedPreferences.getInt("HikeCount", 0) + 1;
SharedPreferences.Editor editor = sharedPreferences.edit(); editor.putString("HikeName" + hikeCount,
private void showSuccessMessage() {
Toast.makeText(AddAHike.this, "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);
Trang 27android: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"
Trang 28android: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"
/>
Trang 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
Trang 30Figure 5 Observation
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
Trang 31public 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;
Trang 32observationListView = 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) {
Trang 33Intent 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();
Trang 34SharedPreferences.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"
Trang 35android: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"
Trang 36android: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>
Trang 37Integration 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
Trang 38Figure 6 Google Maps
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
Trang 39public 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());
Trang 40private 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" />