0% found this document useful (0 votes)
21 views48 pages

Android Unit 5

Mobile Application Development

Uploaded by

bffs814
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
Download as pdf or txt
0% found this document useful (0 votes)
21 views48 pages

Android Unit 5

Mobile Application Development

Uploaded by

bffs814
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
Download as pdf or txt
Download as pdf or txt
You are on page 1/ 48

Unit 5

Working with Location Services and Maps


Working with Google Maps
Android allows us to integrate Google Maps in our application. For this Google provides us a library
via Google Play Services for using maps. In order to use the Google Maps API, you must register
your application on the Google Developer Console and enable the API.
Google Maps Android API consists of a core set of classes that combine to provide mapping
capabilities in Android applications.
To use the com.google.android.maps package on the Android platform and support all the features
related to a MapView, you must use a MapActivity.
APIs in Google Maps
There are several APIs available in Google Maps: SPONSORED SEARCHES interview questions and
answers process mapping google map location map satellite gps location Map
Web APIs

API Name Description

Google Maps JavaScript


Embed interactive maps with custom features in web pages.
API
Google Street View Image Embed panoramic street view images into applications and
API websites.
Google Static Maps API Generate static map images with custom markers and overlays.

Google Maps Embed API Embed simple maps or Street View panoramas into web pages.

Web Service APIs

API Name Description


Get directions for various modes of transportation between
Google Maps Directions API
locations.
Google Maps Elevation API Retrieve elevation data for specific locations.
Google Maps Distance Calculate travel distances and times between origins and
Matrix API destinations.
Google Maps Geocoding API Convert addresses to geographic coordinates and vice versa.
Google Maps Geolocation Determine device location based on nearby cell towers and
API Wi-Fi.
Google Maps Time Zone API Obtain time zone data based on geographic coordinates.

Google Maps Roads API Identify road segments and retrieve information about them.
Google Places API Web Search for places, businesses, and retrieve detailed
Service information.
Mobile APIs

HARSH KANTAWALA, ASST. PROF, GCET. 1


API Name Description
Integrate interactive maps and location services into Android
Google Maps Android API
apps.
Google Places API for
Access place details, reviews, and more in Android apps.
Android
Google Maps SDK for iOS Integrate maps and location services into iOS applications.
Google Places API for iOS Retrieve place information and reviews in iOS applications.

Steps For Getting the Google Maps Api Key:


An API key is needed to access the Google Maps servers. This key is free and you can use it with
any of your applications. If you have not created project, you can follow the below steps to get
started:
Step 1: Open Google developer console and sign in with your Gmail account:
https://console.developers.google.com/project
Step 2: Now create new project. You can create new project by clicking on the Create Project button
and give name to your project.

Step 3: Now click on APIs & Services and open Dashboard from it.

Step 4: In this open Enable APIS AND SERICES.

HARSH KANTAWALA, ASST. PROF, GCET. 2


Step 5: Now open Google Map Android API.

Step 6: Now enable the Google Maps Android API.

Step 7: Now go to Credentials

Step 8: Here click on Create credentials and choose API key

HARSH KANTAWALA, ASST. PROF, GCET. 3


Step 8: Now API your API key will be generated. Copy it and save it somewhere as we will need it
when implementing Google Map in our Android project.

Elements of Google Map


GoogleMap
• This class is responsible for downloading and displaying map tiles and for displaying and
responding to map controls.
• The GoogleMap object is not created directly by the application but is created when MapView
or MapFragment instances are created.
• A reference to the GoogleMap object can be obtained within application code via a call to the
getMap() method of a MapView, MapFragment or SupportMapFragment instance.
MapView
• A subclass of the View class, this class provides the view canvas onto which the map is drawn
by the GoogleMap object, allowing a map to be placed in the user interface layout of an activity.
SupportMapFragment
• A subclass of the Fragment class, this class allows a map to be placed within a Fragment in an
Android layout.
Shapes
• The drawing of lines and shapes on a map is achieved using the Polyline, Polygon and Circle
classes.

HARSH KANTAWALA, ASST. PROF, GCET. 4


My Location Layer
• My Location Layer displays a button on the map which, when selected by the user, centres the
map on the user's current geographical location.
• If the user is stationary, this location is represented on the map by a blue marker.
• If the user is in motion the location is represented by a chevron indicating the user's direction
of travel.
Marker
• The purpose of the Marker class is to allow locations to be marked on a map. Markers are added
to a map by obtaining a reference to the GoogleMap object associated with a map and then
making a call to the addMarker() method of that object instance.
• The position of a marker is defined via Longitude and Latitude.
• Markers can be configured in several ways, including specifying a title, text and an icon.
• Markers may also be made to be "draggable", allowing the user to move the marker to different
positions on a map.
AndroidMenifest.xml

To perform simple google maps activity or an application we have to give some permissions in our
AndroidMenifest.xml file. That is because of map needs to request to access certain features and
functionalities of the device and network.

1. <uses-permission android:name="android.permission.CHANGE_NETWORK_STATE"/>
- This permission allows the application to change network connectivity state.
- Used to control the network connection, such as enabling/disabling mobile data or Wi-Fi.
- This permission is required if your app needs to programmatically manage network
connections.
2. <uses-permission android:name="android.permission.INTERNET"/>
- This permission allows the application to access the internet.
- It is a fundamental permission for applications that need to make network requests, fetch
data from remote servers, and perform online operations.
- Most apps that involve communication with servers or web services will require this
permission.
3. <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
- This permission allows the application to access approximate or coarse location
information.
- Coarse location refers to less precise location data that can be obtained quickly using
network-based methods, such as cell towers or Wi-Fi access points.
- It's commonly used for applications that need location information but don't require high
accuracy, such as weather apps or location-based advertisements.
4. <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
- This permission allows the application to access precise or fine-grained location
information.
- Fine location data is obtained using GPS or other satellite-based methods, providing
higher accuracy compared to coarse location.
- Apps that require accurate location data, like navigation apps or fitness trackers, will
request this permission.

HARSH KANTAWALA, ASST. PROF, GCET. 5


In Android development, the <meta-data> element is used in the AndroidManifest.xml file to
provide additional metadata about your application to the Android system or external services.
Attributes of meta-data
android:name="com.google.android.geo.API_KEY"
- Specifies the name of the metadata being defined. In our case, it is used to identify that the
metadata contains a Google Maps API key.
- The value "com.google.android.geo.API_KEY" is a predefined key that indicates the API key is
intended for use with the Google Maps services.
android:value="YOUR_KEY"
- This attribute is used to set the value of the metadata, which is the actual API key that you
obtain from the Google Cloud Console. Replace `"YOUR_KEY"` with the actual API key you
receive from Google.

*Note: It is crucial to keep your API key secure and not expose it publicly, as it can be used to
access Google services under your account. If you plan to share your app's source code, consider
using techniques like storing the API key in a secure location or using environment variables to
keep the key confidential.

MapsActivity.java
package harsh.example.map;

import androidx.fragment.app.FragmentActivity;
import android.os.Bundle;
import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.OnMapReadyCallback;
import com.google.android.gms.maps.SupportMapFragment;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.MarkerOptions;
import harsh.example.map.databinding.ActivityMapsBinding;

public class MapsActivity extends FragmentActivity implements


OnMapReadyCallback {

private GoogleMap mMap;


private ActivityMapsBinding binding;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);

HARSH KANTAWALA, ASST. PROF, GCET. 6


binding = ActivityMapsBinding.inflate(getLayoutInflater());
setContentView(binding.getRoot());
// Obtain the SupportMapFragment and get notified when the map is
ready to be used.
SupportMapFragment mapFragment = (SupportMapFragment)
getSupportFragmentManager()
.findFragmentById(R.id.map);
mapFragment.getMapAsync(this);
}
@Override
public void onMapReady(GoogleMap googleMap) {
mMap = googleMap;
// Add a marker in Sydney and move the camera
LatLng gcet = new LatLng(22.560570, 72.919665);
mMap.addMarker(new MarkerOptions().position(gcet).title("Marker is
at GCET"));
mMap.moveCamera(CameraUpdateFactory.newLatLng(gcet));
}
}

Project: MAP
Here, in this Example I have mentioned longitude and latitude of a GCET College. That red symbol
is a Marker. For getting longitude and latitude of any place, press and hold on blue icon of location
in Google Map.

HARSH KANTAWALA, ASST. PROF, GCET. 7


Types of Google Map
There are four types of Google maps.
1. Road map - It is default map type. It displays the default road map view.
2. Satellite - It display Google Earth satellite images.
3. Hybrid - It display the mixture of normal and satellite views.
4. Terrain - It display a physical map based on territory information

The type of map displayed can be modified dynamically by making a call to the setMapType()
method of the corresponding GoogleMap object, passing through one of the following values:
1. GoogleMap.MAP_TYPE_NONE An empty grid with no mapping tiles displayed.
2. GoogleMap.MAP_TYPE_NORMAL The standard view consisting of the classic road map.
3. GoogleMap.MAP_TYPE_SATELLITE - Displays the satellite imagery of the map region.
4. GoogleMap.MAP_TYPE_HYBRID - Displays satellite imagery with the road map superimposed.
5. GoogleMap.MAP_TYPE_TERRAIN - Displays topographical information such as contour lines
and colors.

Example:

MapsActivity.java

package harsh.example.differentmapviewexample;

import androidx.fragment.app.FragmentActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.OnMapReadyCallback;
import com.google.android.gms.maps.SupportMapFragment;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.MarkerOptions;

public class MapsActivity extends FragmentActivity implements


OnMapReadyCallback {

private GoogleMap mMap;


private LatLng cvmu = new LatLng(22.553583, 72.924337);
private Button noneMapBtn, normalMapBtn, satelliteMapBtn, hybridMapBtn,
terrainMapBtn;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);

HARSH KANTAWALA, ASST. PROF, GCET. 8


setContentView(R.layout.activity_maps);

noneMapBtn = findViewById(R.id.idBtnNoneMap);
normalMapBtn = findViewById(R.id.idBtnNormalMap);
satelliteMapBtn = findViewById(R.id.idBtnSatelliteMap);
hybridMapBtn = findViewById(R.id.idBtnHybridMap);
terrainMapBtn = findViewById(R.id.idBtnTerrainMap);

SupportMapFragment mapFragment = (SupportMapFragment)


getSupportFragmentManager().findFragmentById(R.id.map);
mapFragment.getMapAsync(this);

noneMapBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
mMap.setMapType(GoogleMap.MAP_TYPE_NONE);
}
});

normalMapBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
mMap.setMapType(GoogleMap.MAP_TYPE_NORMAL);
}
});

satelliteMapBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
mMap.setMapType(GoogleMap.MAP_TYPE_SATELLITE);
}
});

hybridMapBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
mMap.setMapType(GoogleMap.MAP_TYPE_HYBRID);
}
});

terrainMapBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
mMap.setMapType(GoogleMap.MAP_TYPE_TERRAIN);
}
});
}

HARSH KANTAWALA, ASST. PROF, GCET. 9


@Override
public void onMapReady(GoogleMap googleMap) {
mMap = googleMap;
mMap.addMarker(new MarkerOptions().position(cvmu).title("Marker is
at CVMU"));
mMap.moveCamera(CameraUpdateFactory.newLatLng(cvmu));
}
}

activity_maps.xml

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


<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">

<fragment xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/map"
android:name="com.google.android.gms.maps.SupportMapFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MapsActivity" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_margin="5dp"
android:orientation="vertical"
android:padding="5dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:weightSum="3">
<Button
android:id="@+id/idBtnNoneMap"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_margin="5dp"
android:layout_weight="1"
android:singleLine="false"
android:text="None \n Map"
android:textAllCaps="false"
android:background="#800080"
android:textColor="@color/white" />

HARSH KANTAWALA, ASST. PROF, GCET. 10


<Button
android:id="@+id/idBtnHybridMap"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_margin="5dp"
android:layout_weight="1"
android:singleLine="false"
android:text="Hybrid \n Map"
android:textAllCaps="false"
android:background="#800080"
android:textColor="@color/white" />
<Button
android:id="@+id/idBtnSatelliteMap"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_margin="5dp"
android:layout_weight="1"
android:singleLine="false"
android:text="Satellite \n Map"
android:textAllCaps="false"
android:background="#800080"
android:textColor="@color/white" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:weightSum="2">
<Button
android:id="@+id/idBtnTerrainMap"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_margin="5dp"
android:layout_weight="1"
android:singleLine="false"
android:text="Terrain Map"
android:textAllCaps="false"
android:textColor="@color/white"
android:background="#800080" />
<Button
android:id="@+id/idBtnNormalMap"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_margin="5dp"
android:layout_weight="1"
android:singleLine="false"
android:text="Normal Map"

HARSH KANTAWALA, ASST. PROF, GCET. 11


android:textAllCaps="false"
android:textColor="@color/white"
android:background="#800080" />
</LinearLayout>
</LinearLayout>
</RelativeLayout>

MAP_TYPE_NONE MAP_TYPE_HYBRID MAP_TYPE_SATELLITE

MAP_TYPE_TERRAIN MAP_TYPE_NORMAL

Project: DIFFERENTMAPVIEWEXAMPLE

HARSH KANTAWALA, ASST. PROF, GCET. 12


User Interface (UI) Controls of Google Maps
• Google maps provides various user-friendly controls to user to interact with map.
• We can add, customize, and disable these controls. Some controls are default provided like:
1. Zoom: It display the "+" and "-" button to changing the zoom level of the map. This control
appears in bottom right corner of the map. Enable setZoomControls in MainActivity.java
uiSettings.setZoomControlsEnabled(true); + and - symbol will be added to your
MapsActivity.
2. Pan: Pan Control is used for panning the map.
3. Map type: It provides map type options such as Satellite, Road map and Terrain. It appears
on the top right corner of the map.
4. Street view: It contains Pegman icon which can be used to get the street view of a
particular location, whenever it is dragged.

Displaying the User's Current Location


• The user's current location may be displayed on the map by obtaining a reference to the
GoogleMap object associated with the displayed map and calling the setMyLocationEnabled()
method of that instance, passing through a value of true.
• When the map is ready to display, the onMapReady() method of the activity is called. This
method will also be called when the map is refreshed within the onRequestPermissions
Result() method.
activity_maps.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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:padding="16dp"
tools:context=".MapsActivity">

<Button
android:id="@+id/getLocationButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_marginTop="16dp"
android:text="Get Location" />

<TextView
android:id="@+id/locationTextView"
android:layout_width="wrap_content"

HARSH KANTAWALA, ASST. PROF, GCET. 13


android:layout_height="wrap_content"
android:layout_below="@+id/getLocationButton"
android:layout_centerHorizontal="true"
android:layout_marginTop="16dp"
android:text="Location: "
android:textSize="18sp" />

<fragment
android:id="@+id/map"
android:name="com.google.android.gms.maps.SupportMapFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="@+id/locationTextView"
android:layout_marginTop="16dp" />
</RelativeLayout>

MapsActivity.java
package harsh.example.currentlocationexample;

import android.os.Bundle;

import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.SupportMapFragment;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.OnMapReadyCallback;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.MarkerOptions;
import androidx.annotation.NonNull;
import android.Manifest;
import android.content.pm.PackageManager;
import android.location.Location;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;

import com.google.android.gms.location.FusedLocationProviderClient;
import com.google.android.gms.location.LocationServices;
import com.google.android.gms.maps.model.Marker;
import com.google.android.gms.tasks.OnSuccessListener;

public class MapsActivity extends AppCompatActivity implements

HARSH KANTAWALA, ASST. PROF, GCET. 14


OnMapReadyCallback {
private static final int REQUEST_LOCATION_PERMISSION = 1;
private FusedLocationProviderClient fusedLocationClient;
private GoogleMap mMap;
private Marker currentLocationMarker;
private TextView locationTextView;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_maps);

fusedLocationClient =
LocationServices.getFusedLocationProviderClient(this);
locationTextView = findViewById(R.id.locationTextView);

SupportMapFragment mapFragment = (SupportMapFragment)


getSupportFragmentManager().findFragmentById(R.id.map);
mapFragment.getMapAsync(this);

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


getLocationButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
getLocation();
}
});
}

private void getLocation() {


if (ContextCompat.checkSelfPermission(this,
Manifest.permission.ACCESS_FINE_LOCATION)
!= PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(this, new
String[]{Manifest.permission.ACCESS_FINE_LOCATION},
REQUEST_LOCATION_PERMISSION);
} else {
fusedLocationClient.getLastLocation()
.addOnSuccessListener(this, new
OnSuccessListener<Location>() {
@Override
public void onSuccess(Location location) {
if (location != null) {
double latitude = location.getLatitude();
double longitude = location.getLongitude();
locationTextView.setText("Location: " +
latitude + ", " + longitude);

HARSH KANTAWALA, ASST. PROF, GCET. 15


// Add a marker to the current location
LatLng currentLatLng = new LatLng(latitude,
longitude);
if (currentLocationMarker != null) {
currentLocationMarker.remove();
}
currentLocationMarker = mMap.addMarker(new
MarkerOptions()
.position(currentLatLng)
.title("Current Location"));

mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(currentLatLng, 15));
} else {
locationTextView.setText("Location not
available.");
}
}
});
} }
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull
String[] permissions, @NonNull int[] grantResults) {
if (requestCode == REQUEST_LOCATION_PERMISSION) {
if (grantResults.length > 0 && grantResults[0] ==
PackageManager.PERMISSION_GRANTED) {
getLocation();
} else {
Toast.makeText(this, "Location permission denied.",
Toast.LENGTH_SHORT).show();
}
}
}
@Override
public void onMapReady(GoogleMap googleMap) {
mMap = googleMap;
}

HARSH KANTAWALA, ASST. PROF, GCET. 16


}

Project: CURRENTLOCATIONEXAMPLE

Features of Google Maps


1. It searches places and route directions.
2. It provides distance information.
3. It helps to find traffic details and navigation.
4. It displays street views
5. It receives verbal instructions.
6. It provides location sharing and location editing.

Google Maps and Google Earth

Aspect Google Maps Google Earth


Purpose Navigation, directions, location-based Exploration, 3D visualization, education
services
View 2D representation of Earth's surface 2D and 3D views, immersive
exploration
Features - Real-time traffic updates - Historical imagery
- Public transportation info - Satellite imagery
- Street view imagery - 3D models of landmarks

HARSH KANTAWALA, ASST. PROF, GCET. 17


- Business listings - Geological exploration
- Nearby places search - Virtual globe-trotting
Accessibility Web and mobile apps, embeddable Desktop application (Google Earth Pro)
maps Web version (Google Earth Web)
Mobile apps (limited features)
Use Cases - Everyday navigation - Exploring natural wonders
- Finding local businesses - Historical site visits
- Trip planning - Geographic education
- Research and exploration

Geocoding
- Geocoding is the process of transforming a description of a location-such as a pair of
coordinates, an address, or a name of a place-to a location on the earth's surface.
- Geocoding can best be described as the process of converting a textual based geographical
location (such as a street address) into geographical coordinates expressed in terms of
longitude and latitude.
- Geocoding can be done by entering one location description at a time or by providing many of
them at once in a table. The resulting locations are output as geographic features with
attributes, which can be used for mapping or spatial analysis.
- Geocoding can be achieved using the Android Geocoder class. An instance of the Geocoder class
can, for example, be passed a string representing a location such as a city name, street address
or airport code.
- The geocoder will attempt to find a match for the location and return a list of Address objects
that potentially match the location string, ranked in order with the closest match at position 0
in the list.
- A variety of information can then be extracted from the Address objects, including the
longitude and latitude of the potential matches.

Use of Geolocations
- Geolocation can be used to determine time zone and exact positioning coordinates, such as for
tracking wildlife or cargo shipments.
- Both mobile and desktop devices can use geolocation. There are apps which use location once,
and there are apps which continuously track your location as well. Some famous apps using
Geolocation are
1. Uber Cab booking

HARSH KANTAWALA, ASST. PROF, GCET. 18


2. Google Maps (of course) → Map services
3. Swiggy / Zomato → Food delivery
4. Fitbit Fitness app(Strava)
5. Instagram/ Facebook → For tagging photos
6. Pokemon GO

Effectiveness of Geocoder
- A system that provides geocoding is called a geocoding service (or just geocoder).
- To assess the effectiveness of a geocoder, you need to use two basic parameters:
1. The size of the database: The fuller the base, the more accurate and detailed the response
to the request will be. With a large database, the address can be specified up to the house
even in a small town.
2. Geocoding speed: The speed of a geocoder is determined by the number of requests
processed per second. The more requests the geocoder is able to handle, the more users the
system can service.

Example:
MapsActivity.java
package harsh.example.geocodingexample;

import android.Manifest;
import android.content.pm.PackageManager;
import android.location.Address;
import android.location.Geocoder;
import android.location.Location;
import android.os.Build;
import android.os.Bundle;
import android.view.View;
import android.widget.EditText;
import android.widget.Toast;

import androidx.core.content.ContextCompat;
import androidx.fragment.app.FragmentActivity;

import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.location.LocationListener;
import com.google.android.gms.location.LocationRequest;
import com.google.android.gms.location.LocationServices;
import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.OnMapReadyCallback;
import com.google.android.gms.maps.SupportMapFragment;
import com.google.android.gms.maps.model.BitmapDescriptorFactory;
import com.google.android.gms.maps.model.LatLng;

HARSH KANTAWALA, ASST. PROF, GCET. 19


import com.google.android.gms.maps.model.Marker;
import com.google.android.gms.maps.model.MarkerOptions;

import java.io.IOException;
import java.util.List;

public class MapsActivity extends FragmentActivity implements


OnMapReadyCallback,
LocationListener,GoogleApiClient.ConnectionCallbacks,
GoogleApiClient.OnConnectionFailedListener{

private GoogleMap mMap;


Location mLastLocation;
Marker mCurrLocationMarker;
GoogleApiClient mGoogleApiClient;
LocationRequest mLocationRequest;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_maps);
// Obtain the SupportMapFragment and get notified when the map is
ready to be used.
SupportMapFragment mapFragment = (SupportMapFragment)
getSupportFragmentManager()
.findFragmentById(R.id.map);
mapFragment.getMapAsync(this);

@Override
public void onMapReady(GoogleMap googleMap) {
mMap = googleMap;

if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {


if (ContextCompat.checkSelfPermission(this,
Manifest.permission.ACCESS_FINE_LOCATION)
== PackageManager.PERMISSION_GRANTED) {
buildGoogleApiClient();
mMap.setMyLocationEnabled(true);
}
}
else {
buildGoogleApiClient();
mMap.setMyLocationEnabled(true);
}

HARSH KANTAWALA, ASST. PROF, GCET. 20


}
protected synchronized void buildGoogleApiClient() {
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(LocationServices.API).build();
mGoogleApiClient.connect();
}

@Override
public void onConnected(Bundle bundle) {

mLocationRequest = new LocationRequest();


mLocationRequest.setInterval(1000);
mLocationRequest.setFastestInterval(1000);

mLocationRequest.setPriority(LocationRequest.PRIORITY_BALANCED_POWER_ACCURA
CY);
if (ContextCompat.checkSelfPermission(this,
Manifest.permission.ACCESS_FINE_LOCATION)
== PackageManager.PERMISSION_GRANTED) {

LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient,
mLocationRequest, this);
}

@Override
public void onConnectionSuspended(int i) {

@Override
public void onLocationChanged(Location location) {

mLastLocation = location;
if (mCurrLocationMarker != null) {
mCurrLocationMarker.remove();
}
//Place current location marker
LatLng latLng = new LatLng(location.getLatitude(),
location.getLongitude());
MarkerOptions markerOptions = new MarkerOptions();
markerOptions.position(latLng);
markerOptions.title("Current Position");

HARSH KANTAWALA, ASST. PROF, GCET. 21


markerOptions.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFa
ctory.HUE_GREEN));
mCurrLocationMarker = mMap.addMarker(markerOptions);

//move map camera


mMap.moveCamera(CameraUpdateFactory.newLatLng(latLng));
mMap.animateCamera(CameraUpdateFactory.zoomTo(11));

//stop location updates


if (mGoogleApiClient != null) {

LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiClient,
this);
}

@Override
public void onConnectionFailed(ConnectionResult connectionResult) {

public void searchLocation(View view) {


EditText locationSearch = (EditText) findViewById(R.id.editText);
String location = locationSearch.getText().toString();
List<Address> addressList = null;

if (location != null || !location.equals("")) {


Geocoder geocoder = new Geocoder(this);
try {
addressList = geocoder.getFromLocationName(location, 1);

} catch (IOException e) {
e.printStackTrace();
}
Address address = addressList.get(0);
LatLng latLng = new LatLng(address.getLatitude(),
address.getLongitude());
mMap.addMarker(new
MarkerOptions().position(latLng).title(location));
mMap.animateCamera(CameraUpdateFactory.newLatLng(latLng));
Toast.makeText(getApplicationContext(),address.getLatitude()+"
"+address.getLongitude(),Toast.LENGTH_LONG).show();
}
}

HARSH KANTAWALA, ASST. PROF, GCET. 22


activity_maps.xml
<?xml version="1.0" encoding="utf-8"?>
<fragment xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:map="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/map"
android:name="com.google.android.gms.maps.SupportMapFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="harsh.example.geocodingexample.MapsActivity">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<EditText
android:layout_width="248dp"
android:layout_height="wrap_content"
android:id="@+id/editText"
android:layout_weight="0.5"
android:inputType="textPersonName"
android:hint="Search Location" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="0.5"
android:onClick="searchLocation"
android:text="Search" />
</LinearLayout>
</fragment>

HARSH KANTAWALA, ASST. PROF, GCET. 23


Project: GEOCODINGEXAMPLE
Here, in this example, searchLocation() is called when a user enters a location in the EditText field
and presses a button. It uses a Geocoder to convert the location name entered by the user into
latitude and longitude coordinates. It then adds a marker on the map at that location and centers
the map on that marker.

Reverse Geocoding Revgeocode


- Reverse geocoding is the process of transforming a (latitude, longitude) coordinate into a
(partial) address.
- As reverse geocoding converts geographic latitude longitude coordinates to address so the
amount of detail in a reverse geocoded location description may vary, for example, one might
contain the full street address of the closest building, while another might contain only a city
name and postal code.
- A reverse geocoding Application Programming Interface (API) is a web service. It enables
developers to add to their mapping applications reverse geocoding features.
- The end-user will be able to search a latitude and longitude location and obtain the exact street
address or largest or nearest city.
- An API for reverse geocoding is important because the latitude and longitude of an area remain
the same. This makes it a reliable way to locate streets, landmarks, and other places.
Difference between Forward and Reverse Geocoding

HARSH KANTAWALA, ASST. PROF, GCET. 24


- Forward geocoding is the process of looking up a plain-text address or place name (e.g. Girnar
Mountain), whereas reverse geocoding is performed by passing latitude and longitude values
of a desired location to the API.
- If successful, both types of geocoding return an extensive array of location-related data as well
as multiple potential results along with confidence scores.

Aspect Geocoding Reverse Geocoding


Definition The process of converting an address or The process of converting geographic
place name into geographic coordinates coordinates (latitude and longitude) into a
(latitude and longitude). human-readable address or place name.
Input Address or place name. Latitude and longitude coordinates.
Output Latitude and longitude coordinates. Human-readable address or place name.
Purpose Finding the location on a map based on Determining the address or place name of a
an address or place name. specific geographic location.
Use Cases - Displaying a location marker on a - Showing the address of a location on a
map. map.
- Finding nearby businesses or points - Providing location information in mapping
of interest. applications.
- Geotagging photos or social media - Locating and describing a user's current
posts. location.
Examples - Finding a restaurant by its name and - Showing the address of a GPS-coordinated
displaying it on a map. photo's location.
- Obtaining the coordinates of a city - Identifying the nearest city to a set of
based on its name. coordinates.
API Usually involves calling an API with the Usually involves calling an API with the
Methods address or place name as a parameter. latitude and longitude as parameters.
Example Google Maps Geocoding API, OpenCage Google Maps Reverse Geocoding API,
Services Geocoder, Mapbox Geocoding API. Nominatim Reverse Geocoding, MapQuest
Reverse Geocoding API.

MediaPlayer
• Android is providing MediaPlayer class to access built-in media player services like playing
audio, video etc. In order to use MediaPlayer, we have to call a static Method create() of this
class. This method returns an instance of MediaPlayer class. Syntax:
MediaPlayer mediaPlayer = MediaPlayer.create(this, R.raw.song);

• The second parameter is the name of the song that you want to play. You have to make a new
folder under your project with name raw and place the music file into it.
• Once you have created the MediaPlayer object you can call some methods to start or stop the
music. These methods are listed below.
mediaPlayer.start();
mediaPlayer.pause();

• On call to start() method, the music will start playing from the beginning. If this method is
called again after the pause() method, the music would start playing from where it is left and
not from the beginning.
• In order to start music from the beginning, you have to call reset() method. Its syntax is given
below.

HARSH KANTAWALA, ASST. PROF, GCET. 25


mediaPlayer.reset();

• Some other Methods

Method Description

getCurrentPosition() It is used to get the current position of the song in milliseconds.

getDuration() It is used to get the total time duration of the song in milliseconds.

isPlaying() It returns true / false to indicate whether song playing or not.

pause() It is used to pause the song playing.

setAudioStreamType
it is used to specify the audio streaming type.
()

setDataSource() It is used to specify the path of audio / video file to play.

setVolume() It is used to adjust media player volume either up / down.

seekTo(position) It is used to move song to particular position in milliseconds.

getTrackInfo() It returns an array of track information.

start() It is used to start playing the audio/video.

stop() It is used to stop playing the audio/video.

reset() It is used to reset the MediaPlayer object.

It is used to releases the resources which are associated with


release()
MediaPlayer object.

activity_main.xml

HARSH KANTAWALA, ASST. PROF, GCET. 26


<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingLeft="10dp"
android:paddingRight="10dp">
<TextView
android:id="@+id/txtVw1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Now Playing: "
android:layout_marginTop="30dp"
android:textAppearance="?android:attr/textAppearanceMedium" />
<TextView
android:id="@+id/txtSname"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBaseline="@+id/txtVw1"
android:layout_toRightOf="@+id/txtVw1"
android:text="TextView" />

<ImageView
android:id="@+id/imgLogo"
android:layout_width="350dp"
android:layout_height="350dp"
android:layout_centerHorizontal="true"
android:layout_below="@+id/txtVw1"
android:layout_marginTop="10dp"
android:src="@drawable/cvm" />

<ImageButton
android:id="@+id/btnBackward"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_marginBottom="44dp"
android:layout_marginLeft="20dp"
android:src="@android:drawable/ic_media_rew" />
<ImageButton
android:id="@+id/btnPlay"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignTop="@+id/btnBackward"
android:layout_marginLeft="20dp"
android:layout_toRightOf="@+id/btnBackward"
android:src="@android:drawable/ic_media_play" />
<ImageButton

HARSH KANTAWALA, ASST. PROF, GCET. 27


android:id="@+id/btnPause"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignTop="@+id/btnPlay"
android:layout_marginLeft="20dp"
android:layout_toRightOf="@+id/btnPlay"
android:src="@android:drawable/ic_media_pause" />
<ImageButton
android:id="@+id/btnForward"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignTop="@+id/btnPause"
android:layout_marginLeft="20dp"
android:layout_toRightOf="@+id/btnPause"
android:contentDescription="@+id/imageButton3"
android:src="@android:drawable/ic_media_ff" />
<TextView
android:id="@+id/txtStartTime"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignTop="@+id/sBar"
android:text="0 min, 0 sec" />
<SeekBar
android:id="@+id/sBar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_above="@+id/btnBackward"
android:layout_toLeftOf="@+id/txtSongTime"
android:layout_toRightOf="@+id/txtStartTime" />
<TextView
android:id="@+id/txtSongTime"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toRightOf="@+id/btnForward"
android:layout_alignTop="@+id/sBar"
android:text="0 min, 0 sec " />
</RelativeLayout>

MainActivity.java
package com.example.mediaplayerexample;

import android.media.MediaPlayer;
import android.os.Handler;
import android.os.Bundle;
import android.view.View;
import android.widget.ImageButton;
import android.widget.SeekBar;

HARSH KANTAWALA, ASST. PROF, GCET. 28


import android.widget.TextView;
import android.widget.Toast;
import androidx.appcompat.app.AppCompatActivity;
import java.util.concurrent.TimeUnit;

public class MainActivity extends AppCompatActivity {


private ImageButton forwardbtn, backwardbtn, pausebtn, playbtn;
private MediaPlayer mPlayer;
private TextView songName, startTime, songTime;
private SeekBar songPrgs;
private static int oTime =0, sTime =0, eTime =0, fTime = 5000, bTime =
5000;
private Handler hdlr = new Handler();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
backwardbtn = (ImageButton)findViewById(R.id.btnBackward);
forwardbtn = (ImageButton)findViewById(R.id.btnForward);
playbtn = (ImageButton)findViewById(R.id.btnPlay);
pausebtn = (ImageButton)findViewById(R.id.btnPause);
songName = (TextView)findViewById(R.id.txtSname);
startTime = (TextView)findViewById(R.id.txtStartTime);
songTime = (TextView)findViewById(R.id.txtSongTime);
songName.setText("Mi Song");
mPlayer = MediaPlayer.create(this, R.raw.mysong);
songPrgs = (SeekBar)findViewById(R.id.sBar);
songPrgs.setClickable(false);
pausebtn.setEnabled(false);

playbtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(MainActivity.this, "Playing Audio",
Toast.LENGTH_SHORT).show();
mPlayer.start();
eTime = mPlayer.getDuration();
sTime = mPlayer.getCurrentPosition();
if(oTime == 0){
songPrgs.setMax(eTime);
oTime =1;
}
songTime.setText(String.format("%d min, %d sec",
TimeUnit.MILLISECONDS.toMinutes(eTime),
TimeUnit.MILLISECONDS.toSeconds(eTime) -
TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS. toMinutes(eTime))) );
startTime.setText(String.format("%d min, %d sec",

HARSH KANTAWALA, ASST. PROF, GCET. 29


TimeUnit.MILLISECONDS.toMinutes(sTime),
TimeUnit.MILLISECONDS.toSeconds(sTime) -
TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS. toMinutes(sTime))) );
songPrgs.setProgress(sTime);
hdlr.postDelayed(UpdateSongTime, 100);
pausebtn.setEnabled(true);
playbtn.setEnabled(false);
}
});
pausebtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
mPlayer.pause();
pausebtn.setEnabled(false);
playbtn.setEnabled(true);
Toast.makeText(getApplicationContext(),"Pausing Audio",
Toast.LENGTH_SHORT).show();
}
});
forwardbtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if((sTime + fTime) <= eTime)
{
sTime = sTime + fTime;
mPlayer.seekTo(sTime);
}
else
{
Toast.makeText(getApplicationContext(), "Cannot jump
forward 5 seconds", Toast.LENGTH_SHORT).show();
}
if(!playbtn.isEnabled()){
playbtn.setEnabled(true);
}
}
});
backwardbtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if((sTime - bTime) > 0)
{
sTime = sTime - bTime;
mPlayer.seekTo(sTime);
}
else
{

HARSH KANTAWALA, ASST. PROF, GCET. 30


Toast.makeText(getApplicationContext(), "Cannot jump
backward 5 seconds", Toast.LENGTH_SHORT).show();
}
if(!playbtn.isEnabled()){
playbtn.setEnabled(true);
}
}
});
}
private Runnable UpdateSongTime = new Runnable() {
@Override
public void run() {
sTime = mPlayer.getCurrentPosition();
startTime.setText(String.format("%d min, %d sec",
TimeUnit.MILLISECONDS.toMinutes(sTime),
TimeUnit.MILLISECONDS.toSeconds(sTime) -
TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes(sTime))) );
songPrgs.setProgress(sTime);
hdlr.postDelayed(this, 100);
}
};
}

Project: MEDIAPLAYEREXAMPLE

Here, in this example I have created MediaPlayer object properties to play, pause song and changing
the song position either forward or backward, Here Forward/Backword is there for 5 seconds gap.

VideoPlayer

HARSH KANTAWALA, ASST. PROF, GCET. 31


• By using VideoView component and MediaController class we can easily implement the video
player in android applications to play the videos with multiple playback options, such as play,
pause, forward, backward, etc.
• Generally, the MediaController class in android will provide playback options for video player,
such as play, pause, backward, forward, etc.
• The VideoView class in android will provide the functionality to fetch and play the videos using
video player with minimal setup in android applications.
• Here we used a Uri object to play videos from our application resource directory (res/raw).
• Some other Methods

Method Description

setMediaController() It is used to set the media controller to videoview.

setVideoURI() It is used to set the path of video file.

pause() It is used to pause the video playing.

stopPlayback() it is used to stop the video playing.

seekTo(position) It is used to move video to a particular position in milliseconds.

resume() It is used to resume the video playing.

start() It is used to start playing the audio/video.

stopPlayback() It is used to stop playing the audio/video.

Simple example of implementing a video player to play the video with multiple playback options
using VideoView and MediaController objects.

activity_main.xml

HARSH KANTAWALA, ASST. PROF, GCET. 32


<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingLeft="10dp"
android:paddingRight="10dp">
<VideoView
android:id="@+id/vdVw"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center" />
</RelativeLayout>

MainActivity.java
package com.example.videoplayerapp;

import android.net.Uri;
import android.os.Bundle;
import android.widget.MediaController;
import android.widget.VideoView;
import androidx.appcompat.app.AppCompatActivity;

public class MainActivity extends AppCompatActivity {


@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
VideoView videoView =(VideoView)findViewById(R.id.vdVw);
//Set MediaController to enable play, pause, forward, etc options.
MediaController mediaController= new MediaController(this);
mediaController.setAnchorView(videoView);
//Location of Media File
Uri uri = Uri.parse("android.resource://" + getPackageName() + "/"
+ R.raw.gcetreel);
//Starting VideView By Setting MediaController and URI
videoView.setMediaController(mediaController);
videoView.setVideoURI(uri);
videoView.requestFocus();
videoView.start();
}
}

HARSH KANTAWALA, ASST. PROF, GCET. 33


Project: VIDEOPLAYERAPP

Here, in this example video started playing directly and it’s having all media controls such as play,
pause, forward, backward, etc. options to control the video playing.

Android Audio Recorder


MediaRecorder class will provide a functionality to record audio or video files.

The android multimedia framework provides built-in support for capturing and encoding a variety
of common audio and video formats. We have a multiple way to record audio or video but by using
MediaRecorder class we can easily implement audio or video recording.

To record an audio, we need to use device’s microphone along with MediaRecorder class. In case, if
we want to record video, we need to use device’s camera along with MediaRecorder class.

Permissions required in android manifest file to record audio and save it in device.
<uses-permission android:name="android.permission.RECORD_AUDIO"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.STORAGE"/>

The RECORD_AUDIO, WRITE_EXTERNAL_STORAGE are considered as a dangerous permission because it


may pose a risk to the user’s privacy. Starting with Android 6.0 (API level 23) an app that uses a dangerous
permission must ask the user for approval at run time. After the user has granted permission, the app should
remember and not ask again.

To use MediaRecord class to record an audio, we need to create an instance of MediaRecorder class and set
the source, output, encoding format and output file to store the recorded audio in device. After that we need
to call prepare(), start(), stop(), etc. to start the audio recording in our application.

HARSH KANTAWALA, ASST. PROF, GCET. 34


MediaRecorder class provides a different type of methods to control audio and video.

Method Description

setAudioSource() It is used to specify the source of audio to be recorded.

setVideoSource() It is used to specify the source of the video to be recorded.

setOutputFormat() It is used to specify the audio / video output format.

setAudioEncoder() It is used to specify the audio encoder.

setVideoEncoder() it is used to specify the video encoder.

setOutputFile() It is used to specify the path of a recorded audio/video files to be stored.

stop() It is used to stop the recording process.

start() it is used to start the recording process.

release() Releases the resources which are associated with MediaRecorder object.

Activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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">

<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/imageView"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:src="@drawable/ic_launcher_foreground"/>

<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Record"
android:id="@+id/button"
android:layout_below="@+id/imageView"
android:layout_alignParentLeft="true"
android:layout_marginTop="37dp"
/>

HARSH KANTAWALA, ASST. PROF, GCET. 35


<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="STOP"
android:id="@+id/button2"
android:layout_alignTop="@+id/button"
android:layout_centerHorizontal="true"
/>

<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Play"
android:id="@+id/button3"
android:layout_alignTop="@+id/button2"
android:layout_alignParentRight="true"
android:layout_alignParentEnd="true"
/>

<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="STOP PLAYING RECORDING "
android:id="@+id/button4"
android:layout_below="@+id/button2"
android:layout_centerHorizontal="true"
android:layout_marginTop="10dp"
/>
</RelativeLayout>

MainActivity.java
package com.example.recordingexample;

import androidx.appcompat.app.AppCompatActivity;
import androidx.core.content.ContextCompat;
import androidx.core.app.ActivityCompat;

import android.os.Bundle;

import android.view.View;
import android.media.MediaPlayer;
import android.media.MediaRecorder;
import android.os.Environment;
import android.widget.Button;
import android.widget.Toast;
import java.io.IOException;
import java.util.Random;

HARSH KANTAWALA, ASST. PROF, GCET. 36


import static android.Manifest.permission.RECORD_AUDIO;
import static android.Manifest.permission.WRITE_EXTERNAL_STORAGE;
import android.content.pm.PackageManager;

public class MainActivity extends AppCompatActivity {

Button buttonStart, buttonStop, buttonPlayLastRecordAudio,


buttonStopPlayingRecording ;
String AudioSavePathInDevice = null;
MediaRecorder mediaRecorder ;
Random random ;
String RandomAudioFileName = "ABCDEFGHIJKLMNOP";
public static final int RequestPermissionCode = 1;
MediaPlayer mediaPlayer ;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

buttonStart = (Button) findViewById(R.id.button);


buttonStop = (Button) findViewById(R.id.button2);
buttonPlayLastRecordAudio = (Button) findViewById(R.id.button3);
buttonStopPlayingRecording = (Button)findViewById(R.id.button4);

buttonStop.setEnabled(false);
buttonPlayLastRecordAudio.setEnabled(false);
buttonStopPlayingRecording.setEnabled(false);

random = new Random();

buttonStart.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if(checkPermission()) {
AudioSavePathInDevice =
Environment.getExternalStorageDirectory().getAbsolutePath() + "/" +
CreateRandomAudioFileName(5) + "AudioRecording.3gp";
MediaRecorderReady();
try {
mediaRecorder.prepare();
mediaRecorder.start();
} catch (IllegalStateException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block

HARSH KANTAWALA, ASST. PROF, GCET. 37


e.printStackTrace();
}
buttonStart.setEnabled(false);
buttonStop.setEnabled(true);

Toast.makeText(MainActivity.this, "Recording
started",Toast.LENGTH_LONG).show();
} else {
requestPermission();
}

}
});

buttonStop.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
mediaRecorder.stop();
buttonStop.setEnabled(false);
buttonPlayLastRecordAudio.setEnabled(true);
buttonStart.setEnabled(true);
buttonStopPlayingRecording.setEnabled(false);

Toast.makeText(MainActivity.this, "Recording Completed",


Toast.LENGTH_LONG).show();
}
});

buttonPlayLastRecordAudio.setOnClickListener(new
View.OnClickListener() {
@Override
public void onClick(View view) throws IllegalArgumentException,
SecurityException, IllegalStateException {

buttonStop.setEnabled(false);
buttonStart.setEnabled(false);
buttonStopPlayingRecording.setEnabled(true);

mediaPlayer = new MediaPlayer();


try {
mediaPlayer.setDataSource(AudioSavePathInDevice);
mediaPlayer.prepare();
} catch (IOException e) {
e.printStackTrace();
}

mediaPlayer.start();

HARSH KANTAWALA, ASST. PROF, GCET. 38


Toast.makeText(MainActivity.this, "Recording Playing",
Toast.LENGTH_LONG).show();
}
});

buttonStopPlayingRecording.setOnClickListener(new
View.OnClickListener() {
@Override
public void onClick(View view) {
buttonStop.setEnabled(false);
buttonStart.setEnabled(true);
buttonStopPlayingRecording.setEnabled(false);
buttonPlayLastRecordAudio.setEnabled(true);

if(mediaPlayer != null){
mediaPlayer.stop();
mediaPlayer.release();
MediaRecorderReady();
}
}
});

public void MediaRecorderReady(){


mediaRecorder=new MediaRecorder();
mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);

mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.DEFAULT);
mediaRecorder.setOutputFile(AudioSavePathInDevice);
}

public String CreateRandomAudioFileName(int string){


StringBuilder stringBuilder = new StringBuilder( string );
int i = 0 ;
while(i < string ) {
stringBuilder.append(RandomAudioFileName.
charAt(random.nextInt(RandomAudioFileName.length())));

i++ ;
}
return stringBuilder.toString();
}

private void requestPermission() {


ActivityCompat.requestPermissions(MainActivity.this, new

HARSH KANTAWALA, ASST. PROF, GCET. 39


String[]{WRITE_EXTERNAL_STORAGE, RECORD_AUDIO}, RequestPermissionCode);
}

@Override
public void onRequestPermissionsResult(int requestCode, String
permissions[], int[] grantResults) {
switch (requestCode) {
case RequestPermissionCode:
if (grantResults.length> 0) {
boolean StoragePermission = grantResults[0] ==
PackageManager.PERMISSION_GRANTED;
boolean RecordPermission = grantResults[1] ==
PackageManager.PERMISSION_GRANTED;

if (StoragePermission && RecordPermission) {


Toast.makeText(MainActivity.this, "Permission
Granted", Toast.LENGTH_LONG).show();
} else {
Toast.makeText(MainActivity.this,"Permission
Denied",Toast.LENGTH_LONG).show();
}
}
break;
} }

public boolean checkPermission() {


int result =
ContextCompat.checkSelfPermission(getApplicationContext(),
WRITE_EXTERNAL_STORAGE);
int result1 =
ContextCompat.checkSelfPermission(getApplicationContext(), RECORD_AUDIO);
return result == PackageManager.PERMISSION_GRANTED && result1 ==
PackageManager.PERMISSION_GRANTED;
}
} Along with this code, we must set permissions in AndroidMenfist.xml file as mentioned above.

Project: RECORDINGEXAMPLE

HARSH KANTAWALA, ASST. PROF, GCET. 40


SoundPool in an Android
• Collection of audio samples can be loaded into memory from a resource and can be used.
• SoundPool class is used to play short repeating sound whereas MediaPlayer class is used to
play longer clips like music. It uses a MediaPlayer service to decode the audio.
• For an example, a game consists of several levels of play. For each level, there is a set of unique
sounds that are used only by that level. For that, we used the SoundPool class to do our work.
• As we are using sound in our project, we have to create raw directory in res folder.

activity_main.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:gravity="center"
android:orientation="vertical">
<Button
android:id="@+id/introbutton"
android:layout_width="1in"
android:layout_height="wrap_content"
android:onClick="playSound"
android:text="Introduction" />
<Button
android:id="@+id/generalsound"
android:layout_width="1in"
android:layout_height="wrap_content"
android:onClick="playSound"
android:text="sound 2" />
<Button
android:id="@+id/boostbutton"
android:layout_width="1in"
android:layout_height="wrap_content"
android:onClick="playSound"
android:text="Mario Boost" />
<Button
android:id="@+id/jumbpsound"
android:layout_width="1in"
android:layout_height="wrap_content"
android:onClick="playSound"
android:text="Mario Jump" />
<Button
android:id="@+id/gameoverbutton"
android:layout_width="1in"
android:layout_height="wrap_content"
android:onClick="playSound"

HARSH KANTAWALA, ASST. PROF, GCET. 41


android:text="Mario Gameover" />
</LinearLayout>

MainActivity.java

package com.example.soundpoolexample;

import android.media.AudioAttributes;
import android.media.AudioManager;
import android.media.SoundPool;
import android.os.Build;
import android.os.Bundle;
import android.view.View;
import androidx.appcompat.app.AppCompatActivity;

public class MainActivity extends AppCompatActivity {


private SoundPool soundPool;
private int sound1, sound2, sound3, sound4, sound5;
private int sound3StreamId;

private static final int PRIORITY_HIGH = 1;


private static final int PRIORITY_NORMAL = 0;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {


AudioAttributes audioAttributes = new
AudioAttributes.Builder().setUsage(AudioAttributes.USAGE_ASSISTANCE_SONIFIC
ATION).setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION).build();
soundPool = new
SoundPool.Builder().setMaxStreams(6).setAudioAttributes(audioAttributes).bu
ild();
} else {
soundPool = new SoundPool(6, AudioManager.STREAM_MUSIC, 0);
}

sound1 = soundPool.load(this, R.raw.introsound, PRIORITY_HIGH);


sound2 = soundPool.load(this, R.raw.sound2, PRIORITY_HIGH);
sound3 = soundPool.load(this, R.raw.marioboost, PRIORITY_HIGH);
sound4 = soundPool.load(this, R.raw.mariojump, PRIORITY_HIGH);
sound5 = soundPool.load(this, R.raw.mariogameover, PRIORITY_HIGH);
}

public void playSound(View v) {


int viewId = v.getId();

HARSH KANTAWALA, ASST. PROF, GCET. 42


if (viewId == R.id.introbutton) {
soundPool.play(sound1, 1, 1, 0, 0, 1);
//soundPool.pause(sound3StreamId);
soundPool.autoPause();
} else if (viewId == R.id.generalsound) {
soundPool.play(sound2, 1, 1, 0, 0, 1);
} else if (viewId == R.id.boostbutton) {
sound3StreamId = soundPool.play(sound3, 1, 1, 0, 0, 1);
} else if (viewId == R.id.jumbpsound) {
soundPool.play(sound4, 1, 1, 0, 0, 1);
} else if (viewId == R.id.gameoverbutton) {
soundPool.play(sound5, 1, 1, 0, 0, 1);
}
}
@Override
protected void onDestroy() {
super.onDestroy();
soundPool.release();
soundPool = null;
}
}

Project: SOUNDPOOLEXAMPLE

SoundPool Vs MediaPlayer

Aspect SoundPool MediaPlayer

Use Case Short, simple audio effects Longer audio tracks, music, streaming
Performance Efficient for short sounds Suitable for longer tracks
Memory Management Efficient for multiple sounds Can be less memory efficient

HARSH KANTAWALA, ASST. PROF, GCET. 43


Streaming Not designed for streaming Supports streaming from various sources
Playback Control Limited control (play, pause) More playback control options
Latency Low latency for quick playback Potentially higher latency
Use in Games Suitable for game sound effects Less suitable for complex game audio
Interactive Apps Useful for interactive apps Less suitable for apps with many sounds
Complexity Simpler setup and management More complex setup and management

Android Camera
Camera is useful to capture the photos and videos in our applications. By using camera API we can
control the functionalities of camera based on our requirements.

Android framework provides a two ways such as android.hardware.camera2 API and camera intent
to capture the images and videos in our application.

android.hardware.camera2

It is a primary API for controlling the device cameras. By using this we can take the pictures or
videos from our application using camera.

Intent

We can capture the photos or videos without directly using the Camera object by using Intent action
types either MediaStore.ACTION_IMAGE_CAPTURE or MediaStore.ACTION_VIDEO_CAPTURE.
Intent cInt = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
startActivityForResult(cInt,Image_Capture_Code);

Here, startActivityForResult() method with MediaStore.ACTION_IMAGE_CAPTURE intent


action parameter is used to capture the photos and second parameter Image_Capture_Code
is a locally defined integer that must be greater than 0.

Example

activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingLeft="10dp"
android:paddingRight="10dp">
<Button
android:id="@+id/btnTakePicture"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Take a Photo"
android:textStyle="bold"

HARSH KANTAWALA, ASST. PROF, GCET. 44


android:layout_centerHorizontal="true"
android:layout_alignParentBottom="true" />
<ImageView
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:id="@+id/capturedImage"
android:layout_above="@+id/btnTakePicture"/>
</RelativeLayout>

MainActivity.java
package com.example.cameraapplication;

import android.content.Intent;
import android.graphics.Bitmap;
import android.provider.MediaStore;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.Toast;
import androidx.appcompat.app.AppCompatActivity;

public class MainActivity extends AppCompatActivity {


private Button btnCapture;
private ImageView imgCapture;
private static final int Image_Capture_Code = 1;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btnCapture =(Button)findViewById(R.id.btnTakePicture);
imgCapture = (ImageView) findViewById(R.id.capturedImage);
btnCapture.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent cInt = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
startActivityForResult(cInt,Image_Capture_Code);
}
});
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent
data) {
if (requestCode == Image_Capture_Code) {
if (resultCode == RESULT_OK) {
Bitmap bp = (Bitmap) data.getExtras().get("data");
imgCapture.setImageBitmap(bp);

HARSH KANTAWALA, ASST. PROF, GCET. 45


} else if (resultCode == RESULT_CANCELED) {
Toast.makeText(this, "Cancelled",
Toast.LENGTH_LONG).show();
}
}
}
}

When we click on Take a Photo button, the camera will start and we can take the picture of whatever
we want, the captured image will be shown in defined ImageView.

Project: CAMERAAPPLICATION

Video Recording
Video Recording is a most common feature which we can currently get to see in many android
applications.

This feature is mostly seen used in payments applications where the application has to verify the
identity of the user for authentication as well as doing their KYC. Here, we will see How to record a
video within our android application.

I have build a simple android application in which I will display button and a VideoView in which
when someone click on a button, recording of video will be started and once the video recording is
done, that video will be played in VideoView.

Example:

activity_main.xml

HARSH KANTAWALA, ASST. PROF, GCET. 46


<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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"
tools:context=".MainActivity">
<!-- creating a video view on below line -->
<VideoView
android:id="@+id/videoView"
android:layout_centerInParent="true"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_above="@id/idBtnRecordVideo"
android:layout_margin="5dp" />
<!-- creating a button to record a video on below line -->
<Button
android:id="@+id/idBtnRecordVideo"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_centerInParent="true"
android:layout_margin="10dp"
android:text="Record Video"
android:textAllCaps="false" />
</RelativeLayout>

MainActivity.java
package com.example.videorecorder;

import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import androidx.annotation.Nullable;
import android.content.Intent;
import android.provider.MediaStore;
import android.view.View;
import android.widget.Button;
import android.widget.VideoView;
public class MainActivity extends AppCompatActivity {
// creating variables on below line.
private Button recordVideoBtn;
private VideoView videoView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

HARSH KANTAWALA, ASST. PROF, GCET. 47


// initializing variables on below line.
recordVideoBtn = findViewById(R.id.idBtnRecordVideo);
videoView = findViewById(R.id.videoView);

// adding click listener for recording button.


recordVideoBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// on below line opening an intent to capture a video.
Intent i = new Intent(MediaStore.ACTION_VIDEO_CAPTURE);
// on below line starting an activity for result.
startActivityForResult(i, 1);
}
});
}
@Override
protected void onActivityResult(int requestCode, int resultCode,
@Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == RESULT_OK && requestCode == 1) {
// on below line setting video uri for our video view.
videoView.setVideoURI(data.getData());
// on below line starting a video view
videoView.start(); } }

Project: VIDEORECORDER

HARSH KANTAWALA, ASST. PROF, GCET. 48

You might also like