Sunday, 20 May 2012

android.widget.TimePicker


android.widget.TimePicker provide a special view for selecting the time of day, in either 24 hour or AM/PM mode. The hour, each minute digit, and AM/PM (if applicable) can be conrolled by vertical spinners. The hour can be entered by keyboard input. Entering in two digit hours can be accomplished by hitting two digits within a timeout of about a second (e.g. '1' then '2' to select 12). The minutes can be entered by entering single digits. Under AM/PM mode, the user can hit 'a', 'A", 'p' or 'P' to pick.

TimePicker


It can be set 12/24 hour mode by calling setIs24HourView() method. And also can be checked by calling it's is24HourView() method.

We can retrieve the hour and minute set by calling getCurrentHour() and getCurrentMinute() methods.

We can also implement our OnTimeChangedListener, it will be called when the time has been adjusted. - BUT, it will not be called if AM/PM button (in 12 hour mode) changed. May be it's a bug!

package com.exercise.AndroidTime;

import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.widget.TimePicker;
import android.widget.TimePicker.OnTimeChangedListener;

public class AndroidTimeActivity extends Activity {

TimePicker myTimePicker;
Button buttonToggle24Hour, buttonGetTime;
TextView infoByPicker, infoByButton;

/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);

myTimePicker = (TimePicker)findViewById(R.id.picker);
buttonToggle24Hour = (Button)findViewById(R.id.toggle24Hour);
buttonGetTime = (Button)findViewById(R.id.gettime);
infoByPicker = (TextView)findViewById(R.id.infoByPicker);
infoByButton = (TextView)findViewById(R.id.infoByButton);

myTimePicker.setOnTimeChangedListener(onTimeChangedListener);
buttonGetTime.setOnClickListener(buttonGetTimeClickListener);

buttonToggle24Hour.setOnClickListener(buttonToggle24HourClickListener);
}

OnTimeChangedListener onTimeChangedListener
= new OnTimeChangedListener(){

@Override
public void onTimeChanged(TimePicker view, int hourOfDay, int minute) {
infoByPicker.setText(
"Triggered by TimePicker.setOnTimeChangedListener: \n"
+ hourOfDay
+ " : "
+ minute + "\n");

}};

Button.OnClickListener buttonGetTimeClickListener
= new Button.OnClickListener(){

@Override
public void onClick(View v) {
infoByButton.setText(
"Triggered by Button: \n"
+ myTimePicker.getCurrentHour()
+ " : "
+ myTimePicker.getCurrentMinute() + "\n");

}

};

Button.OnClickListener buttonToggle24HourClickListener
= new Button.OnClickListener(){

@Override
public void onClick(View v) {
myTimePicker.setIs24HourView(!myTimePicker.is24HourView());
}

};
}


<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >

<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/hello" />
<TimePicker
android:id="@+id/picker"
android:layout_width="fill_parent"
android:layout_height="wrap_content" />
<Button
android:id="@+id/toggle24Hour"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Toggle 12/24 Hour "/>
<Button
android:id="@+id/gettime"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Get Time"/>
<TextView
android:id="@+id/infoByPicker"
android:layout_width="fill_parent"
android:layout_height="wrap_content" />
<TextView
android:id="@+id/infoByButton"
android:layout_width="fill_parent"
android:layout_height="wrap_content" />

</LinearLayout>


Related:
- android.app.TimePickerDialog


Friday, 18 May 2012

Great Cross Platform Programmer's Editor

I am always looking for good tools. When I just need a text editor, I typically use JEdit. It is free, open source, and since it is written in Java, works well on Mac, Linux or Windows. However, JEdit is not always the simplest tool to configure and use.



Recently I ran across Sublime Text. For $60, you get a really nice editor, with an easy to use interface. Plus, the editor is skinnable so you have a number of options on how the editor and your code actually look. It has nice code completion features with customization options. Top that off with the fact it runs on Windows, Mac OS X, Linux. It is definitely worth a look.

Thursday, 17 May 2012

Implement OnItemGestureListener on OpenStreetMap to detect user touch and retrieve touched items properties


Modify the code in last exercise "Create multi-marker OpenStreetMap for Android", add OnItemGestureListener for our ItemizedIconOverlay. Such that the OpenStreetMapView can react user touch. And also it can retrieve the touched item from the passed parameters. Then pass OnItemGestureListener to ItemizedIconOverlay in constructor.

Implement OnItemGestureListener on OpenStreetMap to detect user touch and retrieve touched items properties


package com.exercise.OpenStreetMapView;

import java.util.ArrayList;
import org.osmdroid.util.GeoPoint;
import org.osmdroid.views.MapController;
import org.osmdroid.views.MapView;
import org.osmdroid.views.overlay.ItemizedIconOverlay;
import org.osmdroid.views.overlay.ItemizedIconOverlay.OnItemGestureListener;
import org.osmdroid.views.overlay.OverlayItem;
import org.osmdroid.views.overlay.ScaleBarOverlay;

import android.app.Activity;
import android.os.Bundle;
import android.widget.Toast;

public class AndroidOpenStreetMapViewActivity extends Activity {

private MapView myOpenMapView;
private MapController myMapController;

ArrayList<OverlayItem> anotherOverlayItemArray;

/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);

myOpenMapView = (MapView)findViewById(R.id.openmapview);
myOpenMapView.setBuiltInZoomControls(true);
myMapController = myOpenMapView.getController();
myMapController.setZoom(2);

//--- Create Another Overlay for multi marker
anotherOverlayItemArray = new ArrayList<OverlayItem>();
anotherOverlayItemArray.add(new OverlayItem(
"0, 0", "0, 0", new GeoPoint(0, 0)));
anotherOverlayItemArray.add(new OverlayItem(
"US", "US", new GeoPoint(38.883333, -77.016667)));
anotherOverlayItemArray.add(new OverlayItem(
"China", "China", new GeoPoint(39.916667, 116.383333)));
anotherOverlayItemArray.add(new OverlayItem(
"United Kingdom", "United Kingdom", new GeoPoint(51.5, -0.116667)));
anotherOverlayItemArray.add(new OverlayItem(
"Germany", "Germany", new GeoPoint(52.516667, 13.383333)));
anotherOverlayItemArray.add(new OverlayItem(
"Korea", "Korea", new GeoPoint(38.316667, 127.233333)));
anotherOverlayItemArray.add(new OverlayItem(
"India", "India", new GeoPoint(28.613333, 77.208333)));
anotherOverlayItemArray.add(new OverlayItem(
"Russia", "Russia", new GeoPoint(55.75, 37.616667)));
anotherOverlayItemArray.add(new OverlayItem(
"France", "France", new GeoPoint(48.856667, 2.350833)));
anotherOverlayItemArray.add(new OverlayItem(
"Canada", "Canada", new GeoPoint(45.4, -75.666667)));

ItemizedIconOverlay<OverlayItem> anotherItemizedIconOverlay
= new ItemizedIconOverlay<OverlayItem>(
this, anotherOverlayItemArray, myOnItemGestureListener);
myOpenMapView.getOverlays().add(anotherItemizedIconOverlay);
//---

//Add Scale Bar
ScaleBarOverlay myScaleBarOverlay = new ScaleBarOverlay(this);
myOpenMapView.getOverlays().add(myScaleBarOverlay);
}

OnItemGestureListener<OverlayItem> myOnItemGestureListener
= new OnItemGestureListener<OverlayItem>(){

@Override
public boolean onItemLongPress(int arg0, OverlayItem arg1) {
// TODO Auto-generated method stub
return false;
}

@Override
public boolean onItemSingleTapUp(int index, OverlayItem item) {
Toast.makeText(AndroidOpenStreetMapViewActivity.this,
item.mDescription + "\n"
+ item.mTitle + "\n"
+ item.mGeoPoint.getLatitudeE6() + " : " + item.mGeoPoint.getLongitudeE6(),
Toast.LENGTH_LONG).show();
return true;
}

};

}


Download the files.

Next:
- Add MyLocationOverlay on OpenStreetMap, to display user location and compass.


Create multi-marker OpenStreetMap for Android

A example to craete Android app using OpenStreetMap with multi-marker.

multi-marker OpenStreetMap on Android


AndroidOpenStreetMapViewActivity.java
package com.exercise.OpenStreetMapView;

import java.util.ArrayList;
import org.osmdroid.util.GeoPoint;
import org.osmdroid.views.MapController;
import org.osmdroid.views.MapView;
import org.osmdroid.views.overlay.ItemizedIconOverlay;
import org.osmdroid.views.overlay.OverlayItem;
import org.osmdroid.views.overlay.ScaleBarOverlay;

import android.app.Activity;
import android.os.Bundle;

public class AndroidOpenStreetMapViewActivity extends Activity {

private MapView myOpenMapView;
private MapController myMapController;

ArrayList<OverlayItem> anotherOverlayItemArray;

/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);

myOpenMapView = (MapView)findViewById(R.id.openmapview);
myOpenMapView.setBuiltInZoomControls(true);
myMapController = myOpenMapView.getController();
myMapController.setZoom(2);

//--- Create Another Overlay for multi marker
anotherOverlayItemArray = new ArrayList<OverlayItem>();
anotherOverlayItemArray.add(new OverlayItem(
"0, 0", "0, 0", new GeoPoint(0, 0)));
anotherOverlayItemArray.add(new OverlayItem(
"US", "US", new GeoPoint(38.883333, -77.016667)));
anotherOverlayItemArray.add(new OverlayItem(
"China", "China", new GeoPoint(39.916667, 116.383333)));
anotherOverlayItemArray.add(new OverlayItem(
"United Kingdom", "United Kingdom", new GeoPoint(51.5, -0.116667)));
anotherOverlayItemArray.add(new OverlayItem(
"Germany", "Germany", new GeoPoint(52.516667, 13.383333)));
anotherOverlayItemArray.add(new OverlayItem(
"Korea", "Korea", new GeoPoint(38.316667, 127.233333)));
anotherOverlayItemArray.add(new OverlayItem(
"India", "India", new GeoPoint(28.613333, 77.208333)));
anotherOverlayItemArray.add(new OverlayItem(
"Russia", "Russia", new GeoPoint(55.75, 37.616667)));
anotherOverlayItemArray.add(new OverlayItem(
"France", "France", new GeoPoint(48.856667, 2.350833)));
anotherOverlayItemArray.add(new OverlayItem(
"Canada", "Canada", new GeoPoint(45.4, -75.666667)));

ItemizedIconOverlay<OverlayItem> anotherItemizedIconOverlay
= new ItemizedIconOverlay<OverlayItem>(
this, anotherOverlayItemArray, null);
myOpenMapView.getOverlays().add(anotherItemizedIconOverlay);
//---

//Add Scale Bar
ScaleBarOverlay myScaleBarOverlay = new ScaleBarOverlay(this);
myOpenMapView.getOverlays().add(myScaleBarOverlay);
}

}

main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >

<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/hello" />
<org.osmdroid.views.MapView
android:id="@+id/openmapview"
android:layout_width="fill_parent"
android:layout_height="fill_parent"/>

</LinearLayout>

Permission needed in AndroidManifest.xml
  • android.permission.ACCESS_NETWORK_STATE
  • android.permission.INTERNET
  • android.permission.WRITE_EXTERNAL_STORAGE
  • android.permission.ACCESS_FINE_LOCATION


Download the files.

Related:
- Prepare Java Build Path to osmdroid and slf4j-android libs for OpenStreetMapView
- Display current location marker on OpenStreetMap

Next:
- Implement OnItemGestureListener on OpenStreetMap to detect user touch and retrieve touched items properties


Wednesday, 16 May 2012

Display current location marker on OpenStreetMap


Further works on last exercise "Add Scale Bar on OpenStreetMap", add a marker on OpenStreetMap, to indicate the current location.

Display current location marker on OpenStreetMap


Copy your marker drawing in the folder /res/drawable/. You can find number of Android icons in installed SDK directory: /android-sdks/platforms/<android version>/data/res/

overlayItemArray is a array of OverlayItem, it have none or ONE item of current location only.

In this exercise, create custom MyItemizedIconOverlay class extends from MyItemizedIconOverlay. Then add the MyItemizedIconOverlay object (myItemizedIconOverlay) to the MapView overlay. Refer to the code below the comment "//--- Create Overlay".

To update the item(s) in overlayItemArray, simple use methods of clear(), add()...etc. Refer to the method setOverlayLoc(Location overlayloc).

In the custom ItemizedIconOverlay class, MyItemizedIconOverlay; I override onSingleTapUp() method to return true always - Because the app will FORCE CLOSE without it! (I don't know why at this moment)

Modify AndroidOpenStreetMapViewActivity.java. Other files refer to previous exercises.

package com.exercise.OpenStreetMapView;

import java.util.ArrayList;
import java.util.List;

import org.osmdroid.DefaultResourceProxyImpl;
import org.osmdroid.ResourceProxy;
import org.osmdroid.util.GeoPoint;
import org.osmdroid.views.MapController;
import org.osmdroid.views.MapView;
import org.osmdroid.views.overlay.ItemizedIconOverlay;
import org.osmdroid.views.overlay.OverlayItem;
import org.osmdroid.views.overlay.ScaleBarOverlay;

import android.app.Activity;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Point;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.view.MotionEvent;

public class AndroidOpenStreetMapViewActivity extends Activity {

private MapView myOpenMapView;
private MapController myMapController;

LocationManager locationManager;

ArrayList<OverlayItem> overlayItemArray;

/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);

myOpenMapView = (MapView)findViewById(R.id.openmapview);
myOpenMapView.setBuiltInZoomControls(true);
myMapController = myOpenMapView.getController();
myMapController.setZoom(12);


//--- Create Overlay
overlayItemArray = new ArrayList<OverlayItem>();

DefaultResourceProxyImpl defaultResourceProxyImpl
= new DefaultResourceProxyImpl(this);
MyItemizedIconOverlay myItemizedIconOverlay
= new MyItemizedIconOverlay(
overlayItemArray, null, defaultResourceProxyImpl);
myOpenMapView.getOverlays().add(myItemizedIconOverlay);
//---


locationManager = (LocationManager)getSystemService(Context.LOCATION_SERVICE);

//for demo, getLastKnownLocation from GPS only, not from NETWORK
Location lastLocation
= locationManager.getLastKnownLocation(
LocationManager.GPS_PROVIDER);
if(lastLocation != null){
updateLoc(lastLocation);
}

//Add Scale Bar
ScaleBarOverlay myScaleBarOverlay = new ScaleBarOverlay(this);
myOpenMapView.getOverlays().add(myScaleBarOverlay);
}

@Override
protected void onResume() {
// TODO Auto-generated method stub
super.onResume();
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, myLocationListener);
locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, myLocationListener);
}

@Override
protected void onPause() {
// TODO Auto-generated method stub
super.onPause();
locationManager.removeUpdates(myLocationListener);
}

private void updateLoc(Location loc){
GeoPoint locGeoPoint = new GeoPoint(loc.getLatitude(), loc.getLongitude());
myMapController.setCenter(locGeoPoint);

setOverlayLoc(loc);

myOpenMapView.invalidate();
}

private void setOverlayLoc(Location overlayloc){
GeoPoint overlocGeoPoint = new GeoPoint(overlayloc);
//---
overlayItemArray.clear();

OverlayItem newMyLocationItem = new OverlayItem(
"My Location", "My Location", overlocGeoPoint);
overlayItemArray.add(newMyLocationItem);
//---
}

private LocationListener myLocationListener
= new LocationListener(){

@Override
public void onLocationChanged(Location location) {
// TODO Auto-generated method stub
updateLoc(location);
}

@Override
public void onProviderDisabled(String provider) {
// TODO Auto-generated method stub

}

@Override
public void onProviderEnabled(String provider) {
// TODO Auto-generated method stub

}

@Override
public void onStatusChanged(String provider, int status, Bundle extras) {
// TODO Auto-generated method stub

}

};

private class MyItemizedIconOverlay extends ItemizedIconOverlay<OverlayItem>{

public MyItemizedIconOverlay(
List<OverlayItem> pList,
org.osmdroid.views.overlay.ItemizedIconOverlay.OnItemGestureListener<OverlayItem> pOnItemGestureListener,
ResourceProxy pResourceProxy) {
super(pList, pOnItemGestureListener, pResourceProxy);
// TODO Auto-generated constructor stub
}

@Override
public void draw(Canvas canvas, MapView mapview, boolean arg2) {
// TODO Auto-generated method stub
super.draw(canvas, mapview, arg2);

if(!overlayItemArray.isEmpty()){

//overlayItemArray have only ONE element only, so I hard code to get(0)
GeoPoint in = overlayItemArray.get(0).getPoint();

Point out = new Point();
mapview.getProjection().toPixels(in, out);

Bitmap bm = BitmapFactory.decodeResource(getResources(),
R.drawable.ic_menu_mylocation);
canvas.drawBitmap(bm,
out.x - bm.getWidth()/2, //shift the bitmap center
out.y - bm.getHeight()/2, //shift the bitmap center
null);
}
}

@Override
public boolean onSingleTapUp(MotionEvent event, MapView mapView) {
// TODO Auto-generated method stub
//return super.onSingleTapUp(event, mapView);
return true;
}
}
}


Download the files.

Next:
- Create multi-marker OpenStreetMap for Android


Tuesday, 15 May 2012

Who has the fastest wireless network?

Internet IconThere is a lot of talk about which wireless network is the best. Most opinions are based on anecdotal evidence. For example, the assumption that the AT&T network sucks everywhere because it sucks in San Francisco.



Well PC Magazine went out and did some real testing and here are the results.

  • T-Mobile has the fastest 3G

  • AT&T and Verizon have the fastest 4G

The article has lots of graphs, pictures and city by city data. Well worth a look.