Fazer ligação dentro de evento onTap de um Overlay [RESOLVIDO]

Olá pessoal.

Criei um aplicativo que usa mapas. Ele mostra vários estabelecimentos na tela, cada um identificado por uma respectiva imagem de bandeira (que nada mais é do que um Overlay). Quando a bandeira é clicada, o evento onTap da classe ImagemOverlay é chamado, imprimindo na tela um Toast informando qual é o endereço da bandeira que cliquei.

Porém, preciso modificar esse Toast para que quando a bandeira for clicada seja feita uma ligação para o estabelecimento. Eis o problema: a definição da classe ImagemOverlay é:

A tela que a chama é a MainActivity:

E a linha que chama o Overlay, dentro da MainActivity, é:

Para eu chamar uma ligação, preciso digitar as seguintes linhas:

Uri uri = Uri.parse(number); Intent it = new Intent(Intent.ACTION_CALL, uri); startActivity(it);

Porém, preciso fazer isso na classe ImagemOverlay, que extende de Overlay, e não Activity. E para fazer uma ligação, preciso digitar as 3 linhas acima de uma classe que estende de uma Activity. Porém, para identificar quando a bandeirinha foi clicada, preciso tratá-la obrigatoriamente numa classe que estende de Overlay.

Logo, preciso tratar um Overlay e fazer uma ligação na mesma classe. Mas não tem como fazer isso, pois em Java uma classe pode ter apenas uma superclasse.

Como devo proceder? Alguém tem alguma dica?

Ninguém consegue me ajudar? Acho que é o quarto ou quinto tópico que posto no GUJ que ninguém ajuda.

Eu tentei chamar métodos da classe MainActivity, dentro da classe ImagemOverlay (mais especificamente, dentro do evento onTap desta classe), através da linha de código abaixo:

MainActivity m = new MainActivity(); m.chamaBandeira(shortname, address, phoneFormat(phone), flagname);

Mas toda vez que eu chamava tal método, cujo corpo é:

public void chamaBandeira(String shortname, String address, String phone, String flagname) { Log.i("map", "[MainActivity].chamaBandeira() -> Shortname: " + shortname + ", Address: " + address + ", Phone: " + phone + ", Flagname: " + flagname); Intent it = new Intent(this, BandeiraActivity.class); it.putExtra("shortname", shortname); it.putExtra("address", address); it.putExtra("phone", phone); it.putExtra("flagname", flagname); startActivity(it); }

Acarretava o seguinte erro:

[list]04-08 18:59:07.749: I/map(518 ): [MainActivity].chamaBandeira() -> Shortname: NOVO HAMBURGO, Address: Rua Joaquim Pedro Soares 339 , Phone: 5130654430, Flagname: You Move
04-08 18:59:07.749: D/AndroidRuntime(518 ): Shutting down VM
04-08 18:59:07.749: W/dalvikvm(518 ): threadid=1: thread exiting with uncaught exception (group=0x4001d800)
04-08 18:59:07.769: E/AndroidRuntime(518 ): FATAL EXCEPTION: main
04-08 18:59:07.769: E/AndroidRuntime(518 ): java.lang.NullPointerException
04-08 18:59:07.769: E/AndroidRuntime(518 ): at android.content.ContextWrapper.getPackageName(ContextWrapper.java:120)
04-08 18:59:07.769: E/AndroidRuntime(518 ): at android.content.ComponentName.(ComponentName.java:75)
04-08 18:59:07.769: E/AndroidRuntime(518 ): at android.content.Intent.(Intent.java:2678 )
04-08 18:59:07.769: E/AndroidRuntime(518 ): at br.mindset.android.unidades.mapa.Menu.info(Menu.java:31)
04-08 18:59:07.769: E/AndroidRuntime(518 ): at br.mindset.android.unidades.mapa.TesteOverlay.onTap(TesteOverlay.java:69)
04-08 18:59:07.769: E/AndroidRuntime(518 ): at com.google.android.maps.OverlayBundle.onTap(OverlayBundle.java:83)
04-08 18:59:07.769: E/AndroidRuntime(518 ): at com.google.android.maps.MapView$1.onSingleTapUp(MapView.java:347)
04-08 18:59:07.769: E/AndroidRuntime(518 ): at com.google.android.maps.GestureDetector.onTouchEvent(GestureDetector.java:533)
04-08 18:59:07.769: E/AndroidRuntime(518 ): at com.google.android.maps.MapView.onTouchEvent(MapView.java:647)
04-08 18:59:07.769: E/AndroidRuntime(518 ): at android.view.View.dispatchTouchEvent(View.java:3766)
04-08 18:59:07.769: E/AndroidRuntime(518 ): at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:897)
04-08 18:59:07.769: E/AndroidRuntime(518 ): at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:936)
04-08 18:59:07.769: E/AndroidRuntime(518 ): at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:936)
04-08 18:59:07.769: E/AndroidRuntime(518 ): at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:936)
04-08 18:59:07.769: E/AndroidRuntime(518 ): at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:936)
04-08 18:59:07.769: E/AndroidRuntime(518 ): at com.android.internal.policy.impl.PhoneWindow$DecorView.superDispatchTouchEvent(PhoneWindow.java:1671)
04-08 18:59:07.769: E/AndroidRuntime(518 ): at com.android.internal.policy.impl.PhoneWindow.superDispatchTouchEvent(PhoneWindow.java:1107)
04-08 18:59:07.769: E/AndroidRuntime(518 ): at android.app.Activity.dispatchTouchEvent(Activity.java:2086)
04-08 18:59:07.769: E/AndroidRuntime(518 ): at com.android.internal.policy.impl.PhoneWindow$DecorView.dispatchTouchEvent(PhoneWindow.java:1655)
04-08 18:59:07.769: E/AndroidRuntime(518 ): at android.view.ViewRoot.handleMessage(ViewRoot.java:1785)
04-08 18:59:07.769: E/AndroidRuntime(518 ): at android.os.Handler.dispatchMessage(Handler.java:99)
04-08 18:59:07.769: E/AndroidRuntime(518 ): at android.os.Looper.loop(Looper.java:123)
04-08 18:59:07.769: E/AndroidRuntime(518 ): at android.app.ActivityThread.main(ActivityThread.java:4627)
04-08 18:59:07.769: E/AndroidRuntime(518 ): at java.lang.reflect.Method.invokeNative(Native Method)
04-08 18:59:07.769: E/AndroidRuntime(518 ): at java.lang.reflect.Method.invoke(Method.java:521)
04-08 18:59:07.769: E/AndroidRuntime(518 ): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:868 )
04-08 18:59:07.769: E/AndroidRuntime(518 ): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626)
04-08 18:59:07.769: E/AndroidRuntime(518 ): at dalvik.system.NativeStart.main(Native Method)[/list]

Quando postei pela primeira vez neste tópico, minha abordagem era, quando a bandeirinha (Overlay) fosse clicada, um Toast seria aberto, informando ao usuário informações sobre o estabelecimento (nome, endereço e telefone). Porém, meu chefe pediu para incluir neste Toast um botão que, quando clicado, realizasse a ligação para o telefone mostrado no Toast. O problema é que quando o botão é mostrado no Toast, não se pode clicar neste, pois o Toast é uma estrutura temporária. Mesmo setando Toast.LENGTH_LONG, não consigo clicar no botão.

Então, para este novo tópico, decidi mudar minha abordagem, criando um XML (chamado flag.xml) que contivesse a seguinte estrutura:

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

<ImageView android:layout_width="fill_parent" android:layout_height="fill_parent"
    android:id="@+id/flag" android:layout_gravity="center"/>
<TextView android:layout_width="fill_parent" android:layout_height="fill_parent"
	android:id="@+id/txtShortname" android:text="@string/shortname"
	android:gravity="center"/>
<TextView android:layout_width="fill_parent" android:layout_height="fill_parent"
	android:id="@+id/txtAddress" android:text="@string/address"
	android:gravity="center"/>
<TextView android:layout_width="fill_parent" android:layout_height="fill_parent"
	android:id="@+id/txtPhone" android:text="@string/phone"
	android:gravity="center"/>
<Button android:layout_width="0dip" android:layout_height="fill_parent"
    android:id="@+id/btnLigar" android:contentDescription="@string/txtLigar"/>

[/code]

Logo, quando o botão fosse clicado, não mais um Toast seria jogado na tela, mas sim o método chamaBandeira (da classe MainActivity) seria chamado. Em chamaBandeira seria chamada a tela BandeiraActivity, que implementaria a flag.xml. Logo, quando a bandeira fosse clicada, seria mostrada a tela BandeiraActivity. Porém, quando clico na bandeirinha, o erro já reportado acima é mostrado, como se fosse proibido chamar uma Activity a partir de outra classe.

Alguém conhece uma outra técnica para eu conseguir disponibilizar o tal botão, para que eu possa fazer a ligação para o telefone do estabelecimento?

Cara sei que parece ridiculo mas:

Colocou no manifeste essa activity ?

não pode usar um AlertDialog ao invés do Toast ?

C;k, coloquei sim.

aechiara, não tinha pensado nisso. Vou pesquisar sobre esse AlertDialog, para ver se tem como colocar View’s inteiras dentro desta estrutura.

Você está utilizando de Overlays e não de ItemizedOverlays.
Você precisa implementar essa lista de OverlaysItem que são guardados em um ItemizedOverlay List que depois você adiciona no MapOverlays do MapView.

Então no Método onTap, você coloca para criar um Dialog.

Dialog d = new Dialog(context);
d.setContentView(R.layout.LAYOUT);
d.show();

Interessante sua dica, Felipe, pois nunca ouvi falar de ItemizedOverlay.

Você tem algum exemplo de uso desta classe? Não entendi bem o que você disse na última mensagem.

Opa, acabei de notar que na página 491 do livro do Lecheta é falado desta classe.

Vou dar uma estudada e qualquer coisa pergunto aqui.

Felipe, tenho uma dúvida:

Usando o ItemizedOverlay e implementando o evento onTap, consigo realizar uma ligação telefônica dentro do evento onTap? Pois para realizar uma ligação preciso estar em uma classe que estende de Activity, e o evento onTap se localiza na classe que estende de ItemizedOverlay.

[quote=graffiti75]Felipe, tenho uma dúvida:

Usando o ItemizedOverlay e implementando o evento onTap, consigo realizar uma ligação telefônica dentro do evento onTap? Pois para realizar uma ligação preciso estar em uma classe que estende de Activity, e o evento onTap se localiza na classe que estende de ItemizedOverlay.[/quote]

não tive tempo de testar, mas procurando outra coisa na Internet, achei isso que talvez te ajude:

http://eagle.phys.utk.edu/guidry/android/mapOverlayDemo.html

Obrigado pela dica aechiara. Darei uma olhada nesse link.

Até agora já implementei 3 abordagens para o mesmo aplicativo:

1) Quando a bandeira é clicada, é mostrado um AlertDialog, que possui o botão “Habilitar Ligação”. Quando este botão é clicado, um rodapé é habilitado (ou seja, seu status é mudado de gone para visible). Neste rodapé é mostrado o botão “Ligar”, que realiza a ligação telefônica. Este botão consegue realizar a ligação porque ele se encontra na classe MainActivity, e quando ele é clicado, seu evento é disparado. Curiosamente, as linhas abaixo funcionam em um evento onClick. Porém, se eu chamar a partir de ImagemOverlay.onTap um método qualquer, as linhas abaixo não funcionam. Isso (as linhas abaixo funcionarem num evento, mas não em um método chamado de outra classe) deve ter algo a ver com o fluxo de execução do Android que, suspeito eu, é imutável via linhas de código.

Uri uri = Uri.parse(number); Intent it = new Intent(Intent.ACTION_CALL, uri); startActivity(it);

2) Usar um TabHost, contendo na primeira aba o mapa, e na segunda as informações do estabelecimento (com o tão famigerado botão “Ligar”). Desta forma, a primeira aba estenderia de MapActivity, e a segunda de Activity. Logo, estendendo de Activity, a ligação telefônica pode ser realizada.

3) Quando a bandeira é clicada, é habilitado um rodapé contendo o nome, endereço, telefone e o botão “Ligar”. Este rodapé é maior que o do exemplo 1. Neste, o rodapé ocupa 1/3 da tela. Como o rodapé está dentro de MainActivity (que estende de Activity, o que possibilita a ligação telefônica), a ligação pode ser realizada.

Bom, todas essas abordagens são muito boas. Mas todas elas são alternativas de implementação mais custosas. A alternativa mais óbvia seria realizar uma ligação dentro da mesma classe em que as bandeiras são clicadas. Mas pelo jeito isso é IMPOSSÍVEL em Android.

lá de dentro do onTab não da para fazer algo do tipo:

[code]@Override
public boolean onTap(GeoPoint p, MapView mapView)
{
// …

Intent intent = new Intent();
intent.setClass(mapView.getContext(), AIntentQueVcQuer.class);
startActivity(intent);

// ...

}[/code]

ou

    // ...

    Intent intent = new Intent(mapView.getContext(), AIntentQueVcQuer.class);
    startActivity(intent);

    // ...

Então aechiara:

Dentro da classe MainActivity, que estende de MapActivity, eu consigo. Mas dentro de ImagemOverlay, que estende de Overlay, não.

Digitando os códigos abaixo dentro de ImagemOverlay:

Intent it = new Intent(Intent.ACTION_CALL, Uri.parse("tel: 0414130775847")); startActivity(it);

Aparece um erro, que retrato na figura abaixo.

http://www.4shared.com/photo/47cIS1nh/Erro.html

[quote=graffiti75]Então aechiara:

Dentro da classe MainActivity, que estende de MapActivity, eu consigo. Mas dentro de ImagemOverlay, que estende de Overlay, não.

Digitando os códigos abaixo dentro de ImagemOverlay:

Intent it = new Intent(Intent.ACTION_CALL, Uri.parse("tel: 0414130775847")); startActivity(it);

Aparece um erro, que retrato na figura abaixo.

http://www.4shared.com/photo/47cIS1nh/Erro.html[/quote]

proxy barrou a página do erro, não consegui ver, mas eu ainda acho que é pq vc não está utilizando o contexto para chamar o startActivity

Então aechiara, em uma chamada a uma ligação telefônica não existe contexto. O que existe é a ACTION_CALL. E mesmo chamando outra tela, quando digito startActivity ou startActivityForResult, o mesmo erro que o proxy barrou aparece.

Você deve estar em uma empresa, que barrou o link do 4shared. Quando você chegar em casa e ver a imagem, verá que não é um erro de compilação, nem de execução, mas sim um indicador de erro quando ainda estamos editando o código-fonte.

graffiti75 é isso mesmo, aqui barra o 4shared

o que eu sei é que vc só consegue chamar startActivity ou o startActivityForResult de um objeto context

então se vc não está em uma activity, antes de chamar o startActivity, em teoria vc deveria pegar o context e chamar

Mas na prática isso não é possível, infelizmente (a não ser que alguém me prove o contrário). Eu já desisti de tentar solucionar este problema.

graffiti75 vc quer/pode compartilhar essa parte do código do map e do overlay para gente dar uma olhada melhor, de repente até testar no emulador ?

apenas esse trecho e que não comprometa ou exponha a sua aplicação

MainActivity:

[code]package br.empresa.android.unidadesfooter.mapa;

import java.util.List;

import android.app.ProgressDialog;
import android.content.Context;
import android.content.Intent;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TableLayout;
import android.widget.TextView;
import br.mindset.android.unidadesfooter.R;
import br.mindset.android.unidadesfooter.global.Global;
import br.mindset.android.unidadesfooter.webservice.CallRestClient;
import br.mindset.android.unidadesfooter.webservice.model.Unidade;
import br.mindset.android.unidadesfooter.webservice.parser.Parser;

import com.google.android.maps.GeoPoint;
import com.google.android.maps.MapActivity;
import com.google.android.maps.MapController;
import com.google.android.maps.MapView;
import com.google.android.maps.MyLocationOverlay;

public class MainActivity extends MapActivity implements LocationListener, OnClickListener {
// Atributos de mapa
private MapView mapa;
private MapController controlador;
private MyLocationOverlay ondeEstou;
// Atributos para o Dialog
private ProgressDialog dialog;
private Handler handler = new Handler();
// Codigo de operadora
private String operadora = “041”;

@Override
public void onCreate(Bundle icicle) {
	super.onCreate(icicle);
	Log.i("map", "[MainActivity].onCreate().");
	setContentView(R.layout.mapview);

	// Inicializa estruturas da tela
	Log.i("map", "[MainActivity].onCreate() -> Inicializa estruturas.");
	mapa = (MapView) findViewById(R.id.mapMapa);
	
	Global.TBL_TABELA = (TableLayout) findViewById(R.id.tblTable);
	Global.IMG_UNIDADE = (ImageView) findViewById(R.id.imgFlag);
	Global.TXT_NOME = (TextView) findViewById(R.id.txtShortname);
	Global.TXT_ENDERECO = (TextView) findViewById(R.id.txtAddress);
	Global.TXT_FONE = (TextView) findViewById(R.id.txtPhone);
	Global.BTN_LIGAR = (Button) findViewById(R.id.btnLigar);
	Global.BTN_OCULTAR = (Button) findViewById(R.id.btnOcultar);

	// Eventos de botao
	Global.BTN_LIGAR.setOnClickListener(this);
	Global.BTN_OCULTAR.setOnClickListener(this);
	
	// Abre a janela com a barra de progresso
	Log.i("map", "[MainActivity].onCreate() -> Abre Progress Dialog.");
	dialog = ProgressDialog.show(this, "Carregando", "Processando unidades, por favor aguarde...", false, true);
	processaUnidades();
	
	// Centraliza o mapa na ultima localizacao conhecida
	controlador = mapa.getController();
	Location loc = getLocationManager().getLastKnownLocation(LocationManager.GPS_PROVIDER);
	
	// Se existe ultima localizacao converte para GeoPoint
	if (loc != null) {
		GeoPoint ponto = new Coordenada(loc);
		Log.i("map", "[MainActivity] Ultima localizacao: " + ponto);
		controlador.setCenter(ponto);
	}
	ondeEstou = new MyLocationOverlay(this, mapa);
	ondeEstou.runOnFirstFix(new Runnable() {
		public void run() {
			Log.i("map", "[MainActivity] MyOverlay runOnFirstFix: " + ondeEstou.getMyLocation());
		}
	});
	
	// Adiciona overlays na tela, atualiza ultima posicao, seta zoom para 10 e ativa controla de zoom na tela
	Log.i("map", "[MainActivity].onCreate() -> Adiciona Overlays na tela.");
	mapa.getOverlays().add(ondeEstou);
	getLocationManager().requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, this);
	controlador.setZoom(10);
	mapa.setBuiltInZoomControls(true);
}

// Adicionar todos os Overlays na tela
private void processaUnidades() {
	new Thread() {
		@Override
		public void run() {
			Log.i("map", "[MainActivity].processaUnidades() -> Realiza carregamento de dados.");
			// Faz processamento (passa ao mapa a coordenada de todas as unidades da WiseUp e YouMove)
			CallRestClient webservice = new CallRestClient();
			String retornoWebservice = webservice.callRestClient();
			List<Unidade> listaUnidades = Parser.decodificaUnidades(retornoWebservice);
			for (Unidade u : listaUnidades) {
				ImagemOverlay imagem = new ImagemOverlay(new Coordenada(u.getLatitude(), u.getLongitude()), R.drawable.ponto,
					u.getShortname(), u.getAddress(), u.getPhone(), u.getFlagname());
				mapa.getOverlays().add(imagem);
			}
			
			// Atualiza a tela
			carregaTela();
		}
	}.start();
}

// Utiliza um Handler para atualizar a tela
private void carregaTela() {
	handler.post(new Runnable(){
		public void run() {
			// Fecha a janela de progresso
			Log.i("map", "[MainActivity].carregaTela() -> Fecha Progress Dialog.");
			dialog.dismiss();
		}
	});
}

@Override
public void onClick(View v) {
	String telefone = Global.TXT_FONE.getText().toString();
	
	// Se e botao de ligar
	if (v == Global.BTN_LIGAR) {
		Log.i("map", "[MainActivity].onClick().'BTN_LIGAR' -> Chamado para telefone " + operadora + telefone + ".");
		Uri uri = Uri.parse("tel: " + operadora + telefone);
		Intent it = new Intent(Intent.ACTION_CALL, uri);
		Log.i("map", "[MainActivity].onClick().'BTN_LIGAR' -> Realizando ligacao.");
		startActivity(it);
	} else
		
	// Se e botao de ocultar
	if (v == Global.BTN_OCULTAR) {
		Log.i("map", "[MainActivity].onClick().'BTN_OCULTAR'.");
		Global.TBL_TABELA.setVisibility(View.GONE);
	}
}

//===========================
//===== METODOS DE MENU =====
//===========================
@Override
public boolean onCreateOptionsMenu(Menu menu) {
	super.onCreateOptionsMenu(menu);
	Log.i("map", "[MainActivity].onCreateoptionsMenu().");
	menu.add(0, 0, 0, "Hibrido");
	menu.add(0, 1, 1, "Mapa");
	menu.add(0, 2, 2, "Satelite");
	return true;
}

@Override
public boolean onMenuItemSelected(int featureId, MenuItem item) {
	Log.i("map", "[MainActivity].onMenuItemSelected().");
	// Clicou no menu
	switch (item.getItemId()) {
		case 0:
			// Hibrido
			mapa.setStreetView(false);
			mapa.setSatellite(false);
			mapa.setTraffic(true);
			break;
		case 1:
			// Mapa
			mapa.setStreetView(true);
			mapa.setSatellite(false);
			mapa.setTraffic(false);
			break;
		case 2:
			// Satelite
			mapa.setSatellite(true);
			mapa.setStreetView(false);
			mapa.setTraffic(false);
			break;	
	}
	return true;
}

private LocationManager getLocationManager() {
	Log.i("map", "[MainActivity].getLocationManager().");
	return (LocationManager) getSystemService(Context.LOCATION_SERVICE);
}

//==========================
//===== METODOS DE GPS =====
//==========================
public void onLocationChanged(Location location) {
	Log.i("map", "[MainActivity].onLocationChanged: latitude: " + location.getLatitude() + ", longitude: " + location.getLongitude());
	GeoPoint point = new Coordenada(location);
	controlador.animateTo(point);
	mapa.invalidate();
}

@Override
protected boolean isRouteDisplayed() {
	return false;
}

public void onProviderDisabled(String provider) {}
public void onProviderEnabled(String provider) {}
public void onStatusChanged(String provider, int status, Bundle extras) {}

//====================================
//===== METODOS DE CICLO DE VIDA =====
//====================================
protected void onStart() {
	super.onStart();
	Log.i("map", "[MainActivity].onStart().");
}

protected void onRestart() {
	super.onRestart();
	Log.i("map", "[MainActivity].onRestart().");
}

protected void onStop() {
	super.onStop();
	Log.i("map", "[MainActivity].onStop().");
}

@Override
protected void onResume() {
	super.onResume();
	Log.i("map", "[MainActivity].onResume().");
	
	// Registra o listener
	ondeEstou.enableMyLocation();
	
	// Omite estruturas da tela
	Log.i("map", "[MainActivity].onResume() -> Omitindo estruturas da tela.");
	Global.TBL_TABELA.setVisibility(View.GONE);
}

@Override
protected void onPause() {
	super.onPause();
	Log.i("map", "[MainActivity].onPause().");
	// Remove o listener
	ondeEstou.disableMyLocation();
}

@Override
protected void onDestroy() {
	super.onDestroy();
	Log.i("map", "[MainActivity].onDestroy().");
	// Remove o listener para nao ficar atualizando mesmo depois de sair
	getLocationManager().removeUpdates(this);
}

}[/code]

ImagemOverlay:

package br.mindset.empresa.unidadesfooter.mapa;

import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Point;
import android.graphics.RectF;
import android.util.Log;
import android.view.View;
import br.mindset.android.unidadesfooter.R;
import br.mindset.android.unidadesfooter.global.Global;

import com.google.android.maps.GeoPoint;
import com.google.android.maps.MapView;
import com.google.android.maps.Overlay;

public class ImagemOverlay extends Overlay {
	// Atributo para desenhar um Overlay no mapa; id da imagem do Overlay; coordenada atual do mapa 
	private Paint paint = new Paint();
	private Integer imagemId;
	private GeoPoint coordenada;
	// Atributos com informacoes que serao mostradas no Toast quando o Overlay for clicado
	private String nome;
	private String endereco;
	private String fone;
	private String unidade;
	// Atributos para montar o Overlay na tela
	private Integer width;
	private Integer height;
	// Margem de erro (em pixels) em volta do ponto clicado a fim de determinar se clicamos nele 
	private Integer margin;

	public ImagemOverlay(GeoPoint geoPoint, int resId, String nome, String endereco, String fone, String unidade) {
		this.coordenada = geoPoint;
		this.imagemId = resId;
		this.nome = nome;
		this.endereco = endereco;
		this.fone = fone;
		this.unidade = unidade;
	}

	@Override
	public void draw(Canvas canvas, MapView mapView, boolean shadow) {
		super.draw(canvas, mapView, shadow);
		// Converte as coordenadas para pixels
		Point p = mapView.getProjection().toPixels(coordenada, null);
		
		// Obtem as dimensoes da imagem, em pixels
		Bitmap bitmap = BitmapFactory.decodeResource(mapView.getResources(), this.imagemId);
		width = bitmap.getWidth();
		height = bitmap.getHeight();
		
		// Desenha uma moldura (retangulo) em volta da imagem
		RectF r = new RectF(p.x, p.y, p.x + width, p.y + height);
		canvas.drawBitmap(bitmap, null, r, paint);
	}
	
	@Override
	public boolean onTap(GeoPoint geoPoint, MapView mapView) {
		Point ponto = mapView.getProjection().toPixels(this.coordenada, null);
		
		// Cria o retangulo que emoldurara o Overlay
		margin = (int) Math.floor(height / 3);
		RectF recf = new RectF(ponto.x - margin, ponto.y - margin, ponto.x + margin, ponto.y + margin);
		
		// Converte para ponto em pixels
		Point newPoint = mapView.getProjection().toPixels(geoPoint, null);
		
		// Corrige coordenada do ponto clicado na tela
		Integer centerWidth = (int) Math.floor(width / 2);
		Integer centerHeight = (int) Math.floor(height / 2);
		
		// Verifica se o ponto esta contido no retangulo
		boolean ok = recf.contains(newPoint.x - centerWidth, newPoint.y - centerHeight);
		if (ok) {
			Log.v("map", "[ImagemOverlay] Clicou dentro da bandeira!");
			
			// Habilita estruturas da tela
			Log.i("map", "[ImagemOverlay].onTap() -> Habilita estruturas na tela.");
			Global.TBL_TABELA.setVisibility(View.VISIBLE);
			
			// Verifica se e Empresa1 ou Empresa2
	        if (this.unidade.equals("Empresa1")) {
	        	Log.i("map", "[ImagemOverlay].onTap() -> Unidade pertence a Empresa1.");
	        	Global.IMG_UNIDADE.setImageResource(R.drawable.empresa1);
	        } else if (this.unidade.equals("Empresa2")) {
	        	Log.i("map", "[ImagemOverlay].onTap() -> Unidade pertence a Empresa2.");
	        	Global.IMG_UNIDADE.setImageResource(R.drawable.empresa2);
	        }
	        
			// Habilita ou nao botao para realizar ligacao telefonica
			if ("".equals(this.fone) || this.fone == null) {
				Log.i("map", "[ImagemOverlay].onTap() -> Botao 'BTN_LIGAR' desabilitado.");
				Global.BTN_LIGAR.setEnabled(false);
			} else {
				Log.i("map", "[ImagemOverlay].onTap() -> Botao 'BTN_LIGAR' habilitado.");
				Global.BTN_LIGAR.setEnabled(true);
			}
	        
			// Seta valores das variaveis TextView
	        Log.i("map", "[ImagemOverlay].onTap() -> Seta valores das variaveis TextView.");
	        Global.TXT_NOME.setText(this.nome);
	        Global.TXT_ENDERECO.setText(this.endereco);
	        Global.TXT_FONE.setText(phoneFormat(this.fone));
			
	        return true;
		}
		return super.onTap(geoPoint, mapView);
	}

	public static String phoneFormat(String text) {
		Log.i("map", "[ImagemOverlay].phoneFormat().");
		String saida = ""; 
		char ch;
		for (int i = 0; i < text.length(); i++) { 
			ch = text.charAt(i); 
			if (ch != ' ' && ch != '(' && ch != ')' && ch != '-') { 
				saida += ch;
			}
		}
		return saida; 
	}
	
	//====================================
	//===== METODOS DE CICLO DE VIDA =====
	//====================================
	protected void onStart() {
		Log.i("map", "[ImagemOverlay].onStart().");
	}
	
	protected void onRestart() {
		Log.i("map", "[ImagemOverlay].onRestart().");
	}

	protected void onStop() {
		Log.i("map", "[ImagemOverlay].onStop().");
	}
	
	protected void onResume() {
		Log.i("map", "[ImagemOverlay].onResume().");
	}

	protected void onPause() {
		Log.i("map", "[ImagemOverlay].onPause().");
	}

	protected void onDestroy() {
		Log.i("map", "[ImagemOverlay].onDestroy().");
	}
}

fiz um teste rápido aqui, deu certo no emulador (estou sem aparelho para testar), ve se consegue adaptar para vc

não foi difícil, foi só fazer

   Uri uri = Uri.parse("tel: 0411199999999");  
   Intent it = new Intent(Intent.ACTION_CALL, uri);
   mContext.startActivity(it);

chamando o startActivity a partir de um objeto context

vou colar o código aqui, mas se quiser eu te mando o projeto zipado:

MainActivity

package br.com.empresa.testegooglemaps;

import java.util.List;

import android.graphics.drawable.Drawable;
import android.os.Bundle;

import com.google.android.maps.GeoPoint;
import com.google.android.maps.MapActivity;
import com.google.android.maps.MapView;
import com.google.android.maps.Overlay;
import com.google.android.maps.OverlayItem;

public class MainActivity extends MapActivity
{

	@Override
	public void onCreate(Bundle savedInstanceState)
	{
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main);
		MapView mapView = (MapView) findViewById(R.id.mapview);
		mapView.setBuiltInZoomControls(true);

		List<Overlay> mapOverlays = mapView.getOverlays();
		Drawable drawable = this.getResources().getDrawable(R.drawable.androidmarker);
		MapItemizedOverlay itemizedoverlay = new MapItemizedOverlay(drawable, this);
		
		GeoPoint point = new GeoPoint(19240000,-99120000);
		OverlayItem overlayitem = new OverlayItem(point, "Ligar para tel: 0411199999999 ?", "nao usado");
		
		itemizedoverlay.addOverlay(overlayitem);
		mapOverlays.add(itemizedoverlay);
	}

	@Override
	protected boolean isRouteDisplayed()
	{
		// TODO Auto-generated method stub
		return false;
	}

}

MapItemizedOverlay

package br.com.empresa.testegooglemaps;

import java.util.ArrayList;

import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.graphics.drawable.Drawable;
import android.net.Uri;

import com.google.android.maps.ItemizedOverlay;
import com.google.android.maps.OverlayItem;

@SuppressWarnings("rawtypes")
public class MapItemizedOverlay extends ItemizedOverlay
{
	private ArrayList<OverlayItem> mOverlays = new ArrayList<OverlayItem>();
	private Context mContext = null;

	public MapItemizedOverlay(Drawable d)
	{
		super(d);
	}

	public MapItemizedOverlay(Drawable defaultMarker, Context context)
	{
		super(boundCenterBottom(defaultMarker));
		mContext = context;

	}

	@Override
	public int size()
	{
		return mOverlays.size();
	}

	@Override
	protected OverlayItem createItem(int item)
	{
		return mOverlays.get(item);
	}

	public void addOverlay(OverlayItem overlay)
	{
		mOverlays.add(overlay);
		populate();
	}

	@Override
	protected boolean onTap(int index)
	{
		OverlayItem item = mOverlays.get(index);

		AlertDialog.Builder builder = new AlertDialog.Builder(mContext);
		builder.setMessage(item.getTitle()).setCancelable(false)
				.setPositiveButton("Yes", new DialogInterface.OnClickListener()
				{
					public void onClick(DialogInterface dialog, int id)
					{
						Uri uri = Uri.parse("tel: 0411199999999");  
		            Intent it = new Intent(Intent.ACTION_CALL, uri);
		            mContext.startActivity(it);
					}
				}).setNegativeButton("No", new DialogInterface.OnClickListener()
				{
					public void onClick(DialogInterface dialog, int id)
					{
						dialog.cancel();
					}
				});
		AlertDialog alert = builder.create();
		alert.show();

		// AlertDialog.Builder dialog = new AlertDialog.Builder(mContext);
		// dialog.setTitle(item.getTitle());
		// dialog.setMessage(item.getSnippet());
		// dialog.show();
		return true;
	}

}

main.xml

<?xml version="1.0" encoding="utf-8"?>
<com.google.android.maps.MapView
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/mapview"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:clickable="true"
    android:apiKey="key de debug do maps"

/>

e muito importante não esquecer aqui as permissões

AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="br.com.jarsoft.testegooglemaps"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk android:minSdkVersion="15" />

    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.CALL_PRIVILEGED"></uses-permission>
    <uses-permission android:name="android.permission.CALL_PHONE"></uses-permission>

    <application
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name" >
        
        <uses-library android:name="com.google.android.maps" android:required="true"/>
        
        <activity
            android:name=".MainActivity"
            android:label="@string/app_name"             
            android:theme="@android:style/Theme.NoTitleBar" >
            
        </activity>
    </application>
        
    
</manifest>

espero que funcione aí para você, qualquer coisa fala aí