Thursday, January 31, 2013
Wednesday, January 30, 2013
Move Google Maps V2 with auto best zoom
We can build LatLngBounds object including certain points, and move GoogleMap to the bounds with auto estimated best zoom.
Download the files.
The series:
A simple example using Google Maps Android API v2, step by step.
package com.example.androidmapsv2;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.GooglePlayServicesUtil;
import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.MapFragment;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.LatLngBounds;
import com.google.android.gms.maps.model.MarkerOptions;
import android.os.Build;
import android.os.Bundle;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.FragmentManager;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewTreeObserver.OnGlobalLayoutListener;
import android.widget.Toast;
public class MainActivity extends Activity {
private static final LatLng Leicester_Square = new LatLng(51.510278, -0.130278);
private static final LatLng Covent_Garden = new LatLng(51.51197, -0.1228);
private static final LatLng Piccadilly_Circus = new LatLng(51.51, -0.134444);
private static final LatLng Embankment = new LatLng(51.507, -0.122);
private static final LatLng Charing_Cross = new LatLng(51.5073, -0.12755);
final int RQS_GooglePlayServices = 1;
MapFragment myMapFragment;
GoogleMap myMap;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
FragmentManager myFragmentManager = getFragmentManager();
MapFragment myMapFragment =
(MapFragment)myFragmentManager.findFragmentById(R.id.map);
myMap = myMapFragment.getMap();
myMap.setMapType(GoogleMap.MAP_TYPE_HYBRID);
myMap.addMarker(new MarkerOptions().position(Leicester_Square).title("Leicester Square"));
myMap.addMarker(new MarkerOptions().position(Covent_Garden).title("Covent Garden"));
myMap.addMarker(new MarkerOptions().position(Piccadilly_Circus).title("Piccadilly Circus"));
myMap.addMarker(new MarkerOptions().position(Embankment).title("Embankment"));
myMap.addMarker(new MarkerOptions().position(Charing_Cross).title("Charing Cross"));
final View mapView = getFragmentManager().findFragmentById(R.id.map).getView();
if (mapView.getViewTreeObserver().isAlive()) {
mapView.getViewTreeObserver().addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
@SuppressLint("NewApi") // We check which build version we are using.
@Override
public void onGlobalLayout() {
LatLngBounds bounds = new LatLngBounds.Builder()
.include(Leicester_Square)
.include(Covent_Garden)
.include(Piccadilly_Circus)
.include(Embankment)
.include(Charing_Cross)
.build();
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN) {
mapView.getViewTreeObserver().removeGlobalOnLayoutListener(this);
} else {
mapView.getViewTreeObserver().removeOnGlobalLayoutListener(this);
}
myMap.moveCamera(CameraUpdateFactory.newLatLngBounds(bounds, 50));
}});
}
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.activity_main, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.menu_legalnotices:
String LicenseInfo = GooglePlayServicesUtil.getOpenSourceSoftwareLicenseInfo(
getApplicationContext());
AlertDialog.Builder LicenseDialog = new AlertDialog.Builder(MainActivity.this);
LicenseDialog.setTitle("Legal Notices");
LicenseDialog.setMessage(LicenseInfo);
LicenseDialog.show();
return true;
}
return super.onOptionsItemSelected(item);
}
@Override
protected void onResume() {
super.onResume();
int resultCode = GooglePlayServicesUtil.isGooglePlayServicesAvailable(getApplicationContext());
if (resultCode == ConnectionResult.SUCCESS){
Toast.makeText(getApplicationContext(),
"isGooglePlayServicesAvailable SUCCESS",
Toast.LENGTH_LONG).show();
}else{
GooglePlayServicesUtil.getErrorDialog(resultCode, this, RQS_GooglePlayServices);
}
}
}
Download the files.
The series:
A simple example using Google Maps Android API v2, step by step.
Monday, January 28, 2013
Set options of Google Maps Android API v2 in XML
So far we set options of Google Maps Android API v2 using java code, we can also set options in XML.
Modify layout file, to add options in <fragment> of "com.google.android.gms.maps.MapFragment", also need to include xmlns:map="http://schemas.android.com/apk/res-auto".
Download the files.
The series:
A simple example using Google Maps Android API v2, step by step.
Modify layout file, to add options in <fragment> of "com.google.android.gms.maps.MapFragment", also need to include xmlns:map="http://schemas.android.com/apk/res-auto".
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".MainActivity" >
<fragment
xmlns:map="http://schemas.android.com/apk/res-auto"
android:id="@+id/map"
android:layout_width="match_parent"
android:layout_height="match_parent"
class="com.google.android.gms.maps.MapFragment"
map:cameraBearing="45"
map:cameraTargetLat="51.507222"
map:cameraTargetLng="-0.1275"
map:cameraTilt="30"
map:cameraZoom="12"
map:mapType="satellite"
map:uiCompass="true"
map:uiRotateGestures="true"
map:uiScrollGestures="true"
map:uiTiltGestures="true"
map:uiZoomControls="true"
map:uiZoomGestures="true"/>
</LinearLayout>
package com.example.androidmapsv2;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.GooglePlayServicesUtil;
import com.google.android.gms.maps.MapFragment;
import android.os.Bundle;
import android.app.Activity;
import android.app.AlertDialog;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.Toast;
public class MainActivity extends Activity {
final int RQS_GooglePlayServices = 1;
MapFragment myMapFragment;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.activity_main, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.menu_legalnotices:
String LicenseInfo = GooglePlayServicesUtil.getOpenSourceSoftwareLicenseInfo(
getApplicationContext());
AlertDialog.Builder LicenseDialog = new AlertDialog.Builder(MainActivity.this);
LicenseDialog.setTitle("Legal Notices");
LicenseDialog.setMessage(LicenseInfo);
LicenseDialog.show();
return true;
}
return super.onOptionsItemSelected(item);
}
@Override
protected void onResume() {
super.onResume();
int resultCode = GooglePlayServicesUtil.isGooglePlayServicesAvailable(getApplicationContext());
if (resultCode == ConnectionResult.SUCCESS){
Toast.makeText(getApplicationContext(),
"isGooglePlayServicesAvailable SUCCESS",
Toast.LENGTH_LONG).show();
}else{
GooglePlayServicesUtil.getErrorDialog(resultCode, this, RQS_GooglePlayServices);
}
}
}
Download the files.
The series:
A simple example using Google Maps Android API v2, step by step.
Sunday, January 27, 2013
Create MapFragment and GoogleMap using Java code
In previous exercises, MapFragment and SupportMapFragment are defined in XML of layout file. We can create it using Java code, without XML.
Download the files.
The series:
A simple example using Google Maps Android API v2, step by step.
package com.example.androidmapsv2;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.GooglePlayServicesUtil;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.MapFragment;
import android.os.Bundle;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.FragmentManager;
import android.app.FragmentTransaction;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.Toast;
public class MainActivity extends Activity {
final int RQS_GooglePlayServices = 1;
private GoogleMap myMap;
MapFragment myMapFragment;
private static final String TAG_MYMAPFRAGMENT = "TAG_MyMapFragment";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//setContentView(R.layout.activity_main);
FragmentManager myFragmentManager = getFragmentManager();
myMapFragment =
(MapFragment)myFragmentManager.findFragmentByTag(TAG_MYMAPFRAGMENT);
if(myMapFragment == null){
myMapFragment = MapFragment.newInstance();
FragmentTransaction fragmentTransaction = myFragmentManager.beginTransaction();
fragmentTransaction.add(android.R.id.content, myMapFragment, TAG_MYMAPFRAGMENT);
fragmentTransaction.commit();
}
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.activity_main, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.menu_legalnotices:
String LicenseInfo = GooglePlayServicesUtil.getOpenSourceSoftwareLicenseInfo(
getApplicationContext());
AlertDialog.Builder LicenseDialog = new AlertDialog.Builder(MainActivity.this);
LicenseDialog.setTitle("Legal Notices");
LicenseDialog.setMessage(LicenseInfo);
LicenseDialog.show();
return true;
}
return super.onOptionsItemSelected(item);
}
@Override
protected void onResume() {
super.onResume();
int resultCode = GooglePlayServicesUtil.isGooglePlayServicesAvailable(getApplicationContext());
if (resultCode == ConnectionResult.SUCCESS){
Toast.makeText(getApplicationContext(),
"isGooglePlayServicesAvailable SUCCESS",
Toast.LENGTH_LONG).show();
if(myMap == null){
myMap = myMapFragment.getMap();
if(myMap != null){
myMap.setMyLocationEnabled(true);
myMap.setMapType(GoogleMap.MAP_TYPE_HYBRID);
}else{
Toast.makeText(getApplicationContext(),
"cannot getMap!",
Toast.LENGTH_LONG).show();
}
}
}else{
GooglePlayServicesUtil.getErrorDialog(resultCode, this, RQS_GooglePlayServices);
}
}
}
Download the files.
The series:
A simple example using Google Maps Android API v2, step by step.
keytool error: java.lang.Exception: Keystore file does not exist
If you have a new Android development setup on your system, and it's your first project, and you want to "display the SHA1 (or MD5) certificate fingerprint". May be you will get the error of:
keytool error: java.lang.Exception: Keystore file does not exist: /.../.android/debug.keystore
To generate the debug.keystore, you have to run any app at least one time. Just create and run any simple "Hello World" to generate it.
keytool error: java.lang.Exception: Keystore file does not exist: /.../.android/debug.keystore
To generate the debug.keystore, you have to run any app at least one time. Just create and run any simple "Hello World" to generate it.
Friday, January 25, 2013
Thursday, January 24, 2013
Detect and animate to user location
Last exercise "Implement LocationSource and LocationListener for Google Maps Android API v2" to detect user location. We can modify onLocationChanged() method to animate to updated user location; such that the GoogleMap will always center on user location.
The series:
A simple example using Google Maps Android API v2, step by step.
@Override
public void onLocationChanged(Location location) {
if (myLocationListener != null) {
myLocationListener.onLocationChanged(location);
double lat = location.getLatitude();
double lon = location.getLongitude();
tvLocInfo.setText(
"lat: " + lat + "\n" +
"lon: " + lon);
LatLng latlng= new LatLng(location.getLatitude(), location.getLongitude());
myMap.animateCamera(CameraUpdateFactory.newLatLng(latlng));
}
}
The series:
A simple example using Google Maps Android API v2, step by step.
Rename project after Existing Android Code Into Workspace
It's a tips in using Eclipse. After import Existing Android Code Into Workspace, the project name will be MainActivity, or the name of the main activity. In order to rename it, right click the project -> Refactor -> Rename...
Implement LocationSource and LocationListener for Google Maps Android API v2
Example to Implement LocationSource and LocationListener for Google Maps Android API v2.
Download the files.
Next:
- Detect and animate to user location
The series:
A simple example using Google Maps Android API v2, step by step.
package com.example.androidmapsv2;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.GooglePlayServicesUtil;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.LocationSource;
import com.google.android.gms.maps.MapFragment;
import android.location.Criteria;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.FragmentManager;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.TextView;
import android.widget.Toast;
public class MainActivity extends Activity
implements LocationSource, LocationListener{
final int RQS_GooglePlayServices = 1;
private GoogleMap myMap;
TextView tvLocInfo;
LocationManager myLocationManager = null;
OnLocationChangedListener myLocationListener = null;
Criteria myCriteria;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tvLocInfo = (TextView)findViewById(R.id.locinfo);
FragmentManager myFragmentManager = getFragmentManager();
MapFragment myMapFragment
= (MapFragment)myFragmentManager.findFragmentById(R.id.map);
myMap = myMapFragment.getMap();
myMap.setMyLocationEnabled(true);
myMap.setMapType(GoogleMap.MAP_TYPE_HYBRID);
myCriteria = new Criteria();
myCriteria.setAccuracy(Criteria.ACCURACY_FINE);
myLocationManager = (LocationManager)getSystemService(LOCATION_SERVICE);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.activity_main, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.menu_legalnotices:
String LicenseInfo = GooglePlayServicesUtil.getOpenSourceSoftwareLicenseInfo(
getApplicationContext());
AlertDialog.Builder LicenseDialog = new AlertDialog.Builder(MainActivity.this);
LicenseDialog.setTitle("Legal Notices");
LicenseDialog.setMessage(LicenseInfo);
LicenseDialog.show();
return true;
}
return super.onOptionsItemSelected(item);
}
@Override
protected void onResume() {
super.onResume();
int resultCode = GooglePlayServicesUtil.isGooglePlayServicesAvailable(getApplicationContext());
if (resultCode == ConnectionResult.SUCCESS){
Toast.makeText(getApplicationContext(),
"isGooglePlayServicesAvailable SUCCESS",
Toast.LENGTH_LONG).show();
//Register for location updates using a Criteria, and a callback on the specified looper thread.
myLocationManager.requestLocationUpdates(
0L, //minTime
0.0f, //minDistance
myCriteria, //criteria
this, //listener
null); //looper
//Replaces the location source of the my-location layer.
myMap.setLocationSource(this);
}else{
GooglePlayServicesUtil.getErrorDialog(resultCode, this, RQS_GooglePlayServices);
}
}
@Override
protected void onPause() {
myMap.setLocationSource(null);
myLocationManager.removeUpdates(this);
super.onPause();
}
@Override
public void activate(OnLocationChangedListener listener) {
myLocationListener = listener;
}
@Override
public void deactivate() {
myLocationListener = null;
}
@Override
public void onLocationChanged(Location location) {
if (myLocationListener != null) {
myLocationListener.onLocationChanged(location);
double lat = location.getLatitude();
double lon = location.getLongitude();
tvLocInfo.setText(
"lat: " + lat + "\n" +
"lon: " + lon);
}
}
@Override
public void onProviderDisabled(String arg0) {
// TODO Auto-generated method stub
}
@Override
public void onProviderEnabled(String arg0) {
// TODO Auto-generated method stub
}
@Override
public void onStatusChanged(String arg0, int arg1, Bundle arg2) {
// TODO Auto-generated method stub
}
}
Download the files.
Next:
- Detect and animate to user location
The series:
A simple example using Google Maps Android API v2, step by step.
Tuesday, January 22, 2013
Display another layout over GoogleMap
This example demonstrate how to place LinearLayout over GoogleMap, using XML.
The series:
A simple example using Google Maps Android API v2, step by step.
<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"
android:orientation="vertical"
tools:context=".MainActivity" >
<fragment
android:id="@+id/map"
android:layout_width="match_parent"
android:layout_height="match_parent"
class="com.google.android.gms.maps.MapFragment"/>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
android:background="#A0FFFFFF" >
<TextView
android:id="@+id/locinfo"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/ic_launcher" />
</LinearLayout>
</RelativeLayout>
The series:
A simple example using Google Maps Android API v2, step by step.
Monday, January 21, 2013
Detect Info Window Click, implements OnInfoWindowClickListener.
To detect user click on Info Window, implements OnInfoWindowClickListener. And setOnInfoWindowClickListener() to register it.
Modify from the post "Create custom info contents for GoogleMaps V2, by implementing custom InfoWindowAdapter".
Download the files.
The series:
A simple example using Google Maps Android API v2, step by step.
Modify from the post "Create custom info contents for GoogleMaps V2, by implementing custom InfoWindowAdapter".
package com.example.androidmapsv2;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.GooglePlayServicesUtil;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.GoogleMap.InfoWindowAdapter;
import com.google.android.gms.maps.GoogleMap.OnInfoWindowClickListener;
import com.google.android.gms.maps.GoogleMap.OnMapLongClickListener;
import com.google.android.gms.maps.MapFragment;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.Marker;
import com.google.android.gms.maps.model.MarkerOptions;
import android.os.Bundle;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.FragmentManager;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.TextView;
import android.widget.Toast;
public class MainActivity extends Activity
implements OnMapLongClickListener, OnInfoWindowClickListener{
class MyInfoWindowAdapter implements InfoWindowAdapter{
private final View myContentsView;
MyInfoWindowAdapter(){
myContentsView = getLayoutInflater().inflate(R.layout.custom_info_contents, null);
}
@Override
public View getInfoContents(Marker marker) {
TextView tvTitle = ((TextView)myContentsView.findViewById(R.id.title));
tvTitle.setText(marker.getTitle());
TextView tvSnippet = ((TextView)myContentsView.findViewById(R.id.snippet));
tvSnippet.setText(marker.getSnippet());
return myContentsView;
}
@Override
public View getInfoWindow(Marker marker) {
// TODO Auto-generated method stub
return null;
}
}
final int RQS_GooglePlayServices = 1;
private GoogleMap myMap;
TextView tvLocInfo;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tvLocInfo = (TextView)findViewById(R.id.locinfo);
FragmentManager myFragmentManager = getFragmentManager();
MapFragment myMapFragment
= (MapFragment)myFragmentManager.findFragmentById(R.id.map);
myMap = myMapFragment.getMap();
myMap.setMyLocationEnabled(true);
myMap.setMapType(GoogleMap.MAP_TYPE_TERRAIN);
myMap.getUiSettings().setZoomControlsEnabled(true);
myMap.getUiSettings().setCompassEnabled(true);
myMap.getUiSettings().setMyLocationButtonEnabled(true);
myMap.getUiSettings().setAllGesturesEnabled(true);
myMap.setTrafficEnabled(true);
myMap.setOnMapLongClickListener(this);
myMap.setInfoWindowAdapter(new MyInfoWindowAdapter());
myMap.setOnInfoWindowClickListener(this);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.activity_main, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.menu_legalnotices:
String LicenseInfo = GooglePlayServicesUtil.getOpenSourceSoftwareLicenseInfo(
getApplicationContext());
AlertDialog.Builder LicenseDialog = new AlertDialog.Builder(MainActivity.this);
LicenseDialog.setTitle("Legal Notices");
LicenseDialog.setMessage(LicenseInfo);
LicenseDialog.show();
return true;
}
return super.onOptionsItemSelected(item);
}
@Override
protected void onResume() {
super.onResume();
int resultCode = GooglePlayServicesUtil.isGooglePlayServicesAvailable(getApplicationContext());
if (resultCode == ConnectionResult.SUCCESS){
Toast.makeText(getApplicationContext(),
"isGooglePlayServicesAvailable SUCCESS",
Toast.LENGTH_LONG).show();
}else{
GooglePlayServicesUtil.getErrorDialog(resultCode, this, RQS_GooglePlayServices);
}
}
@Override
public void onMapLongClick(LatLng point) {
tvLocInfo.setText("New marker added@" + point.toString());
Marker newMarker = myMap.addMarker(new MarkerOptions()
.position(point)
.snippet(point.toString()));
newMarker.setTitle(newMarker.getId());
}
@Override
public void onInfoWindowClick(Marker marker) {
Toast.makeText(getBaseContext(),
"Info Window clicked@" + marker.getId(),
Toast.LENGTH_SHORT).show();
}
}
Download the files.
The series:
A simple example using Google Maps Android API v2, step by step.
Professional Android Open Accessory Programming with Arduino
Learn how to control your home or car from your Android smartphone - air conditioning, lights, entertainment systems, and more!
Android Open Accessory is a new, simple, and secure protocol for connecting any microcontroller-empowered device to an Android smartphone or tablet. This Wrox guide shows Android programmers how to use AOA with Arduino, the microcontroller platform, to control such systems as lighting, air conditioning, and entertainment systems from Android devices. Furthermore, it teaches the circuit-building skills needed to create games and practical products that also take advantage of Android technology.
- Introduces Android Open Accessory and shows how to set up the hardware and development environment
- Explains how to code both Android and Arduino elements of an accessory
- Features four complete projects developers can build using various sensors and indicators/actuators, including source code
- Gives Android developers the tools to create powerful, sophisticated projects
Professional Android Open Accessory with Android ADK and Arduino opens exciting new opportunities for Android developers.
Friday, January 18, 2013
Custom InfoWindowAdapter with dynamic icon
Last exercise demonstrate how to "implement custom InfoWindowAdapter", with fixed icon defined in XML. We can generate the icon dynamically in run-time.
To implement dynamic icon, modify layout of the info windows(custom_info_contents.xml) - remove the assigned android:src and assigne android:id="@+id/icon".
Modify getInfoContents(Marker marker) to load the icon in run-time.
The series:
A simple example using Google Maps Android API v2, step by step.
To implement dynamic icon, modify layout of the info windows(custom_info_contents.xml) - remove the assigned android:src and assigne android:id="@+id/icon".
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical">
<ImageView
android:id="@+id/icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginRight="5dp"
android:adjustViewBounds="true"/>
<TextView
android:id="@+id/title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="12dp"
android:textStyle="bold"/>
<TextView
android:id="@+id/snippet"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="10dp"/>
</LinearLayout>
</LinearLayout>
Modify getInfoContents(Marker marker) to load the icon in run-time.
@Override
public View getInfoContents(Marker marker) {
TextView tvTitle = ((TextView)myContentsView.findViewById(R.id.title));
tvTitle.setText(marker.getTitle());
TextView tvSnippet = ((TextView)myContentsView.findViewById(R.id.snippet));
tvSnippet.setText(marker.getSnippet());
ImageView ivIcon = ((ImageView)myContentsView.findViewById(R.id.icon));
ivIcon.setImageDrawable(getResources().getDrawable(android.R.drawable.ic_menu_gallery));
return myContentsView;
}
The series:
A simple example using Google Maps Android API v2, step by step.
Thursday, January 17, 2013
Create custom info contents for GoogleMaps V2, by implementing custom InfoWindowAdapter
Create /res/layout/custom_info_contents.xml to define the layout of our custom info contents.
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginRight="5dp"
android:adjustViewBounds="true"
android:src="@drawable/ic_launcher"/>
<TextView
android:id="@+id/title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="12dp"
android:textStyle="bold"/>
<TextView
android:id="@+id/snippet"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="10dp"/>
</LinearLayout>
</LinearLayout>
To implement our custom info contents, we have to create our custom InfoWindowAdapter class. Override getInfoContents(Marker marker) to return our custom view. And call myMap.setInfoWindowAdapter(new MyInfoWindowAdapter()) to set our InfoWindowAdapter. In this exercise, we haven't handle getInfoWindow(Marker marker), simple return null.
package com.example.androidmapsv2;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.GooglePlayServicesUtil;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.GoogleMap.InfoWindowAdapter;
import com.google.android.gms.maps.GoogleMap.OnMapLongClickListener;
import com.google.android.gms.maps.MapFragment;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.Marker;
import com.google.android.gms.maps.model.MarkerOptions;
import android.os.Bundle;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.FragmentManager;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.TextView;
import android.widget.Toast;
public class MainActivity extends Activity
implements OnMapLongClickListener{
class MyInfoWindowAdapter implements InfoWindowAdapter{
private final View myContentsView;
MyInfoWindowAdapter(){
myContentsView = getLayoutInflater().inflate(R.layout.custom_info_contents, null);
}
@Override
public View getInfoContents(Marker marker) {
TextView tvTitle = ((TextView)myContentsView.findViewById(R.id.title));
tvTitle.setText(marker.getTitle());
TextView tvSnippet = ((TextView)myContentsView.findViewById(R.id.snippet));
tvSnippet.setText(marker.getSnippet());
return myContentsView;
}
@Override
public View getInfoWindow(Marker marker) {
// TODO Auto-generated method stub
return null;
}
}
final int RQS_GooglePlayServices = 1;
GoogleMap myMap;
TextView tvLocInfo;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tvLocInfo = (TextView)findViewById(R.id.locinfo);
FragmentManager myFragmentManager = getFragmentManager();
MapFragment myMapFragment
= (MapFragment)myFragmentManager.findFragmentById(R.id.map);
myMap = myMapFragment.getMap();
myMap.setMyLocationEnabled(true);
//myMap.setMapType(GoogleMap.MAP_TYPE_HYBRID);
//myMap.setMapType(GoogleMap.MAP_TYPE_NORMAL);
//myMap.setMapType(GoogleMap.MAP_TYPE_SATELLITE);
myMap.setMapType(GoogleMap.MAP_TYPE_TERRAIN);
myMap.getUiSettings().setZoomControlsEnabled(true);
myMap.getUiSettings().setCompassEnabled(true);
myMap.getUiSettings().setMyLocationButtonEnabled(true);
myMap.getUiSettings().setRotateGesturesEnabled(true);
myMap.getUiSettings().setScrollGesturesEnabled(true);
myMap.getUiSettings().setTiltGesturesEnabled(true);
myMap.getUiSettings().setZoomGesturesEnabled(true);
//or myMap.getUiSettings().setAllGesturesEnabled(true);
myMap.setTrafficEnabled(true);
myMap.setOnMapLongClickListener(this);
myMap.setInfoWindowAdapter(new MyInfoWindowAdapter());
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.activity_main, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.menu_legalnotices:
String LicenseInfo = GooglePlayServicesUtil.getOpenSourceSoftwareLicenseInfo(
getApplicationContext());
AlertDialog.Builder LicenseDialog = new AlertDialog.Builder(MainActivity.this);
LicenseDialog.setTitle("Legal Notices");
LicenseDialog.setMessage(LicenseInfo);
LicenseDialog.show();
return true;
}
return super.onOptionsItemSelected(item);
}
@Override
protected void onResume() {
super.onResume();
int resultCode = GooglePlayServicesUtil.isGooglePlayServicesAvailable(getApplicationContext());
if (resultCode == ConnectionResult.SUCCESS){
Toast.makeText(getApplicationContext(),
"isGooglePlayServicesAvailable SUCCESS",
Toast.LENGTH_LONG).show();
}else{
GooglePlayServicesUtil.getErrorDialog(resultCode, this, RQS_GooglePlayServices);
}
}
@Override
public void onMapLongClick(LatLng point) {
tvLocInfo.setText("New marker added@" + point.toString());
Marker newMarker = myMap.addMarker(new MarkerOptions()
.position(point)
.snippet(point.toString()));
newMarker.setTitle(newMarker.getId());
}
}
As a exercise, you can try to return null in getInfoContents(Marker marker), and return the custom view in getInfoWindow(Marker marker) to check the result.
Download the files.
Next:
- Implement Custom InfoWindowAdapter with dynamic icon
- Detect Info Window Click, implements OnInfoWindowClickListener
The series:
A simple example using Google Maps Android API v2, step by step.
Implement bouncing marker for Google Maps Android API v2
Example to implement a bouncing marker:
//Make the marker bounce
final Handler handler = new Handler();
final long startTime = SystemClock.uptimeMillis();
final long duration = 2000;
Projection proj = myMap.getProjection();
final LatLng markerLatLng = marker.getPosition();
Point startPoint = proj.toScreenLocation(markerLatLng);
startPoint.offset(0, -100);
final LatLng startLatLng = proj.fromScreenLocation(startPoint);
final Interpolator interpolator = new BounceInterpolator();
handler.post(new Runnable() {
@Override
public void run() {
long elapsed = SystemClock.uptimeMillis() - startTime;
float t = interpolator.getInterpolation((float) elapsed / duration);
double lng = t * markerLatLng.longitude + (1 - t) * startLatLng.longitude;
double lat = t * markerLatLng.latitude + (1 - t) * startLatLng.latitude;
marker.setPosition(new LatLng(lat, lng));
if (t < 1.0) {
// Post again 16ms later.
handler.postDelayed(this, 16);
}
}
});
The code in main activity:
package com.example.androidmapsv2;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.GooglePlayServicesUtil;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.Projection;
import com.google.android.gms.maps.GoogleMap.OnMapLongClickListener;
import com.google.android.gms.maps.GoogleMap.OnMarkerClickListener;
import com.google.android.gms.maps.MapFragment;
import com.google.android.gms.maps.model.BitmapDescriptor;
import com.google.android.gms.maps.model.BitmapDescriptorFactory;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.Marker;
import com.google.android.gms.maps.model.MarkerOptions;
import android.os.Bundle;
import android.os.Handler;
import android.os.SystemClock;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.FragmentManager;
import android.graphics.Point;
import android.view.Menu;
import android.view.MenuItem;
import android.view.animation.BounceInterpolator;
import android.view.animation.Interpolator;
import android.widget.TextView;
import android.widget.Toast;
public class MainActivity extends Activity
implements OnMapLongClickListener, OnMarkerClickListener{
final int RQS_GooglePlayServices = 1;
GoogleMap myMap;
TextView tvLocInfo;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tvLocInfo = (TextView)findViewById(R.id.locinfo);
FragmentManager myFragmentManager = getFragmentManager();
MapFragment myMapFragment
= (MapFragment)myFragmentManager.findFragmentById(R.id.map);
myMap = myMapFragment.getMap();
myMap.setMyLocationEnabled(true);
//myMap.setMapType(GoogleMap.MAP_TYPE_HYBRID);
//myMap.setMapType(GoogleMap.MAP_TYPE_NORMAL);
//myMap.setMapType(GoogleMap.MAP_TYPE_SATELLITE);
myMap.setMapType(GoogleMap.MAP_TYPE_TERRAIN);
myMap.getUiSettings().setZoomControlsEnabled(true);
myMap.getUiSettings().setCompassEnabled(true);
myMap.getUiSettings().setMyLocationButtonEnabled(true);
myMap.getUiSettings().setRotateGesturesEnabled(true);
myMap.getUiSettings().setScrollGesturesEnabled(true);
myMap.getUiSettings().setTiltGesturesEnabled(true);
myMap.getUiSettings().setZoomGesturesEnabled(true);
//or myMap.getUiSettings().setAllGesturesEnabled(true);
myMap.setTrafficEnabled(true);
myMap.setOnMapLongClickListener(this);
myMap.setOnMarkerClickListener(this);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.activity_main, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.menu_legalnotices:
String LicenseInfo = GooglePlayServicesUtil.getOpenSourceSoftwareLicenseInfo(
getApplicationContext());
AlertDialog.Builder LicenseDialog = new AlertDialog.Builder(MainActivity.this);
LicenseDialog.setTitle("Legal Notices");
LicenseDialog.setMessage(LicenseInfo);
LicenseDialog.show();
return true;
}
return super.onOptionsItemSelected(item);
}
@Override
protected void onResume() {
super.onResume();
int resultCode = GooglePlayServicesUtil.isGooglePlayServicesAvailable(getApplicationContext());
if (resultCode == ConnectionResult.SUCCESS){
Toast.makeText(getApplicationContext(),
"isGooglePlayServicesAvailable SUCCESS",
Toast.LENGTH_LONG).show();
}else{
GooglePlayServicesUtil.getErrorDialog(resultCode, this, RQS_GooglePlayServices);
}
}
@Override
public void onMapLongClick(LatLng point) {
tvLocInfo.setText("New marker added@" + point.toString());
BitmapDescriptor bitmapDescriptor
= BitmapDescriptorFactory.fromResource(R.drawable.ic_launcher);
myMap.addMarker(new MarkerOptions()
.position(point)
.icon(bitmapDescriptor)
.title(point.toString()));
}
@Override
public boolean onMarkerClick(final Marker marker) {
//Make the marker bounce
final Handler handler = new Handler();
final long startTime = SystemClock.uptimeMillis();
final long duration = 2000;
Projection proj = myMap.getProjection();
final LatLng markerLatLng = marker.getPosition();
Point startPoint = proj.toScreenLocation(markerLatLng);
startPoint.offset(0, -100);
final LatLng startLatLng = proj.fromScreenLocation(startPoint);
final Interpolator interpolator = new BounceInterpolator();
handler.post(new Runnable() {
@Override
public void run() {
long elapsed = SystemClock.uptimeMillis() - startTime;
float t = interpolator.getInterpolation((float) elapsed / duration);
double lng = t * markerLatLng.longitude + (1 - t) * startLatLng.longitude;
double lat = t * markerLatLng.latitude + (1 - t) * startLatLng.latitude;
marker.setPosition(new LatLng(lat, lng));
if (t < 1.0) {
// Post again 16ms later.
handler.postDelayed(this, 16);
}
}
});
//return false; //have not consumed the event
return true; //have consumed the event
}
}
Download the files.
The series:
A simple example using Google Maps Android API v2, step by step.
Wednesday, January 16, 2013
Google TV Add-on with emulator is available in Android SDK
Google TV SDK Add-on allows developers to create Google TV-specific Android Virtual Devices (AVDs) for the Android emulator. The Google TV Add-on package is available from the Android AVD and SDK Manager. To know more about Google TV Add-on and how to install, read GoogleTV Add-On doc.
You now have the Google TV Add-on. To learn how to run the emulator, see the section Using Emulator.
Load custom marker on GoogleMap V2
To load custom icon as marker of GoogleMap V2, save the icon in drawable folder. Load it using the code:
The series:
A simple example using Google Maps Android API v2, step by step.
BitmapDescriptor bitmapDescriptor
= BitmapDescriptorFactory.fromResource(R.drawable.ic_launcher);
myMap.addMarker(new MarkerOptions()
.position(point)
.icon(bitmapDescriptor)
.title(point.toString()));
The series:
A simple example using Google Maps Android API v2, step by step.
Tuesday, January 15, 2013
Change marker color of GoogleMaps V2
To change color of the default marker of Google Maps Android API v2, add .icon(BitmapDescriptor) when create MarkerOptions.
Download the files.
The series:
A simple example using Google Maps Android API v2, step by step.
BitmapDescriptor bitmapDescriptor
= BitmapDescriptorFactory.defaultMarker(
BitmapDescriptorFactory.HUE_AZURE);
myMap.addMarker(new MarkerOptions()
.position(point)
.icon(bitmapDescriptor)
.title(point.toString()));
Download the files.
The series:
A simple example using Google Maps Android API v2, step by step.
Monday, January 14, 2013
UPDATE NOW! Oracle JDK 7u11 released
Oracle releasdd JDK 7u11 to answer the the flaw in Java software integrated with web browsers.
This release contains fixes for security vulnerabilities. For more information, see Oracle Security Alert for CVE-2013-0422.
Java SE 7 Update 11 is available from the following download sites:
Saturday, January 12, 2013
Oracle is aware of a flaw in Java software integrated with web browsers
Posted at +Oracle: Oracle is aware of a flaw in Java software integrated with web browsers. The flaw is limited to JDK7. It does not exist in other releases of Java, and does not affect Java applications directly installed and running on servers, desktops, laptops, and other devices. A fix will be available shortly.
Friday, January 11, 2013
Create Google Play Badges for your apps in multi-language
Visit here to create your Google Play badges, allow you to promote your app with official branding in your online ads, promotional materials, or anywhere else you want a link to your app.
Link: http://developer.android.com/distribute/googleplay/promote/badges.html
Thursday, January 10, 2013
Turn on Traffic Layer of GoogleMap V2
To turn on/off the traffic layer of GoogleMap, simple call the method setTrafficEnabled(boolean enabled).
Example:
The series:
A simple example using Google Maps Android API v2, step by step.
Example:
myMap.setTrafficEnabled(true);
The series:
A simple example using Google Maps Android API v2, step by step.
Wednesday, January 9, 2013
Enable/Disable various gestures for GoogleMap
To enable/disable various gestures for GoogleMap, call setRotateGesturesEnabled(boolean enabled), setScrollGesturesEnabled(boolean enabled), setTiltGesturesEnabled(boolean enabled) and setZoomGesturesEnabled(boolean enabled), or you can call setAllGesturesEnabled(boolean enabled) to set all gestures.
Example:
The series:
A simple example using Google Maps Android API v2, step by step.
Example:
myMap.getUiSettings().setRotateGesturesEnabled(true);
myMap.getUiSettings().setScrollGesturesEnabled(true);
myMap.getUiSettings().setTiltGesturesEnabled(true);
myMap.getUiSettings().setZoomGesturesEnabled(true);
//or myMap.getUiSettings().setAllGesturesEnabled(true);
The series:
A simple example using Google Maps Android API v2, step by step.
Tuesday, January 8, 2013
Display ZoomControls, Compass and MyLocation buttons on GoogleMap.
To enable/disable ZoomControls, Compass and MyLocation buttons on GoogleMap, call the following methods of the UiSettings for GoogleMap.
The series:
A simple example using Google Maps Android API v2, step by step.
- setZoomControlsEnabled (boolean enabled):
Enables or disables the zoom controls. If enabled, the zoom controls are a pair of buttons (one for zooming in, one for zooming out) that appear on the screen. When pressed, they cause the camera to zoom in (or out) by one zoom level. If disabled, the zoom controls are not shown.
By default, the zoom controls are enabled.
- setCompassEnabled (boolean enabled):
Enables or disables the compass. The compass is an icon on the map that indicates the direction of north on the map. If enabled, it is only shown when the camera is tilted or rotated away from its default orientation (tilt of 0 and a bearing of 0). When a user clicks the compass, the camera orients itself to its default orientation and fades away shortly after. If disabled, the compass will never be displayed.
By default, the compass is enabled (and hence shown when the camera is not in the default orientation).
- setMyLocationButtonEnabled (boolean enabled):
Enables or disables the my-location button. The my-location button causes the camera to move such that the user's location is in the center of the map. If the button is enabled, it is only shown when the my-location layer is enabled.
By default, the my-location button is enabled (and hence shown when the my-location layer is enabled).
myMap.getUiSettings().setZoomControlsEnabled(true);
myMap.getUiSettings().setCompassEnabled(true);
myMap.getUiSettings().setMyLocationButtonEnabled(true);
The series:
A simple example using Google Maps Android API v2, step by step.
Reminder: Windows 8 Previews will expire SOON!
- Windows 8 Developer Preview and Consumer Preview will expire on January 15, 2013
- Windows 8 Release Preview will expire on January 16, 2013
Source: Microsoft Community
Monday, January 7, 2013
Nokia HERE, delivering maps for Apple iPhone, Android and Firefox OS
Nokia is taking its mapping solutions out to the wider world in the form of HERE, offering HERE for iOS for Apple iPhone and iPad users and offering Android developers the chance to make compelling mapping apps for their own platform.
Source: NOKNOK, powered by Nokia
Source: NOKNOK, powered by Nokia
Google Maps Android API v2 example: Draggable Marker
To make the marker draggable:
- sets the draggability for the marker to true by calling draggable(true) when new the MarkerOptions.
- implements OnMarkerDragListener in your activity.
- call myMap.setOnMarkerDragListener(this).
- override onMarkerDrag(), onMarkerDragEnd() and onMarkerDragStart().
Download the files.
The series:
A simple example using Google Maps Android API v2, step by step.
- sets the draggability for the marker to true by calling draggable(true) when new the MarkerOptions.
- implements OnMarkerDragListener in your activity.
- call myMap.setOnMarkerDragListener(this).
- override onMarkerDrag(), onMarkerDragEnd() and onMarkerDragStart().
package com.example.androidmapsv2;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.GooglePlayServicesUtil;
import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.GoogleMap.OnMapLongClickListener;
import com.google.android.gms.maps.GoogleMap.OnMarkerDragListener;
import com.google.android.gms.maps.MapFragment;
import com.google.android.gms.maps.GoogleMap.OnMapClickListener;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.Marker;
import com.google.android.gms.maps.model.MarkerOptions;
import com.google.android.gms.maps.model.Polygon;
import com.google.android.gms.maps.model.PolygonOptions;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.FragmentManager;
import android.location.Location;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.TextView;
import android.widget.Toast;
public class MainActivity extends Activity
implements OnMapClickListener, OnMapLongClickListener, OnMarkerDragListener{
final int RQS_GooglePlayServices = 1;
private GoogleMap myMap;
Location myLocation;
TextView tvLocInfo;
boolean markerClicked;
PolygonOptions polygonOptions;
Polygon polygon;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tvLocInfo = (TextView)findViewById(R.id.locinfo);
FragmentManager myFragmentManager = getFragmentManager();
MapFragment myMapFragment
= (MapFragment)myFragmentManager.findFragmentById(R.id.map);
myMap = myMapFragment.getMap();
myMap.setMyLocationEnabled(true);
myMap.setMapType(GoogleMap.MAP_TYPE_HYBRID);
myMap.setOnMapClickListener(this);
myMap.setOnMapLongClickListener(this);
myMap.setOnMarkerDragListener(this);
markerClicked = false;
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.activity_main, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.menu_legalnotices:
String LicenseInfo = GooglePlayServicesUtil.getOpenSourceSoftwareLicenseInfo(
getApplicationContext());
AlertDialog.Builder LicenseDialog = new AlertDialog.Builder(MainActivity.this);
LicenseDialog.setTitle("Legal Notices");
LicenseDialog.setMessage(LicenseInfo);
LicenseDialog.show();
return true;
}
return super.onOptionsItemSelected(item);
}
@Override
protected void onResume() {
super.onResume();
int resultCode = GooglePlayServicesUtil.isGooglePlayServicesAvailable(getApplicationContext());
if (resultCode == ConnectionResult.SUCCESS){
Toast.makeText(getApplicationContext(),
"isGooglePlayServicesAvailable SUCCESS",
Toast.LENGTH_LONG).show();
}else{
GooglePlayServicesUtil.getErrorDialog(resultCode, this, RQS_GooglePlayServices);
}
}
@Override
public void onMapClick(LatLng point) {
tvLocInfo.setText(point.toString());
myMap.animateCamera(CameraUpdateFactory.newLatLng(point));
markerClicked = false;
}
@Override
public void onMapLongClick(LatLng point) {
tvLocInfo.setText("New marker added@" + point.toString());
myMap.addMarker(new MarkerOptions()
.position(point)
.draggable(true));
markerClicked = false;
}
@Override
public void onMarkerDrag(Marker marker) {
tvLocInfo.setText("Marker " + marker.getId() + " Drag@" + marker.getPosition());
}
@Override
public void onMarkerDragEnd(Marker marker) {
tvLocInfo.setText("Marker " + marker.getId() + " DragEnd");
}
@Override
public void onMarkerDragStart(Marker marker) {
tvLocInfo.setText("Marker " + marker.getId() + " DragStart");
}
}
Download the files.
The series:
A simple example using Google Maps Android API v2, step by step.
Sunday, January 6, 2013
Tips to add Support Library
In case you need to add Android Support Library, such as android-support-v4.jar; Google documents suggested to:
- In Eclipse Select Project > Properties, select Java Build Path, and navigate to Libraries.
- Select Add External Jars, include the following jar files, and click OK: <android-sdk-folder>/extras/android/compatibility/v4/android-support-v4.jar
But...I found that it is not always work, even always NOT work!
No error when you compile your code, but fail with error "Caused by: java.lang.NoClassDefFoundError: youractivity" at runtime.
My alternatively, Right click your project, select Android Tools > Add Support Library...
----------
Here is another solution advised by Stefan de Bruijn in comments:
- create a folder called "libs", NOT "lib".
- copy the required jar in "libs" folder.
- Update Java Build Path by selecting "Add JARs..." (NOT "Add External JARs...") to add the jar in libs.
- like this: java.lang.NoClassDefFoundError: com.google.ads.AdView.
- In Eclipse Select Project > Properties, select Java Build Path, and navigate to Libraries.
- Select Add External Jars, include the following jar files, and click OK: <android-sdk-folder>/extras/android/compatibility/v4/android-support-v4.jar
But...I found that it is not always work, even always NOT work!
No error when you compile your code, but fail with error "Caused by: java.lang.NoClassDefFoundError: youractivity" at runtime.
My alternatively, Right click your project, select Android Tools > Add Support Library...
----------
Here is another solution advised by Stefan de Bruijn in comments:
- create a folder called "libs", NOT "lib".
- copy the required jar in "libs" folder.
- Update Java Build Path by selecting "Add JARs..." (NOT "Add External JARs...") to add the jar in libs.
- like this: java.lang.NoClassDefFoundError: com.google.ads.AdView.
Friday, January 4, 2013
Google Maps Android API v2 example: Draw Polygon on GoogleMap
Last post demonstrate how to "Draw Polyline on GoogleMap of Google Maps Android API v2", we can draw Polygon using the almost same procedure.
Download the files.
Next:
- Implement Draggable Marker
Update:
- Google Maps Android API v2 now support anti-clockwise polygons
The series:
A simple example using Google Maps Android API v2, step by step.
package com.example.androidmapsv2;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.GooglePlayServicesUtil;
import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.GoogleMap.OnMapLongClickListener;
import com.google.android.gms.maps.GoogleMap.OnMarkerClickListener;
import com.google.android.gms.maps.MapFragment;
import com.google.android.gms.maps.GoogleMap.OnMapClickListener;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.Marker;
import com.google.android.gms.maps.model.MarkerOptions;
import com.google.android.gms.maps.model.Polygon;
import com.google.android.gms.maps.model.PolygonOptions;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.FragmentManager;
import android.graphics.Color;
import android.location.Location;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.TextView;
import android.widget.Toast;
public class MainActivity extends Activity
implements OnMapClickListener, OnMapLongClickListener, OnMarkerClickListener{
final int RQS_GooglePlayServices = 1;
private GoogleMap myMap;
Location myLocation;
TextView tvLocInfo;
boolean markerClicked;
PolygonOptions polygonOptions;
Polygon polygon;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tvLocInfo = (TextView)findViewById(R.id.locinfo);
FragmentManager myFragmentManager = getFragmentManager();
MapFragment myMapFragment
= (MapFragment)myFragmentManager.findFragmentById(R.id.map);
myMap = myMapFragment.getMap();
myMap.setMyLocationEnabled(true);
myMap.setMapType(GoogleMap.MAP_TYPE_HYBRID);
myMap.setOnMapClickListener(this);
myMap.setOnMapLongClickListener(this);
myMap.setOnMarkerClickListener(this);
markerClicked = false;
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.activity_main, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.menu_legalnotices:
String LicenseInfo = GooglePlayServicesUtil.getOpenSourceSoftwareLicenseInfo(
getApplicationContext());
AlertDialog.Builder LicenseDialog = new AlertDialog.Builder(MainActivity.this);
LicenseDialog.setTitle("Legal Notices");
LicenseDialog.setMessage(LicenseInfo);
LicenseDialog.show();
return true;
}
return super.onOptionsItemSelected(item);
}
@Override
protected void onResume() {
super.onResume();
int resultCode = GooglePlayServicesUtil.isGooglePlayServicesAvailable(getApplicationContext());
if (resultCode == ConnectionResult.SUCCESS){
Toast.makeText(getApplicationContext(),
"isGooglePlayServicesAvailable SUCCESS",
Toast.LENGTH_LONG).show();
}else{
GooglePlayServicesUtil.getErrorDialog(resultCode, this, RQS_GooglePlayServices);
}
}
@Override
public void onMapClick(LatLng point) {
tvLocInfo.setText(point.toString());
myMap.animateCamera(CameraUpdateFactory.newLatLng(point));
markerClicked = false;
}
@Override
public void onMapLongClick(LatLng point) {
tvLocInfo.setText("New marker added@" + point.toString());
myMap.addMarker(new MarkerOptions().position(point).title(point.toString()));
markerClicked = false;
}
@Override
public boolean onMarkerClick(Marker marker) {
if(markerClicked){
if(polygon != null){
polygon.remove();
polygon = null;
}
polygonOptions.add(marker.getPosition());
polygonOptions.strokeColor(Color.RED);
polygonOptions.fillColor(Color.BLUE);
polygon = myMap.addPolygon(polygonOptions);
}else{
if(polygon != null){
polygon.remove();
polygon = null;
}
polygonOptions = new PolygonOptions().add(marker.getPosition());
markerClicked = true;
}
return true;
}
}
Download the files.
Next:
- Implement Draggable Marker
Update:
- Google Maps Android API v2 now support anti-clockwise polygons
The series:
A simple example using Google Maps Android API v2, step by step.