I dati registrati sono coerenti ed ho provato ad incrociare il segnale con la distanza dalle antenne ripresa dai database che sono disponibili su Internet (non e' dato sapere quale sia il grado di attendibilita' della posizione GPS dell'antenna)
Mettendo in grafico un po' di distanze dall'antenna contro il segnale misurato si ha una notevole dispersione dei punti
Per adesso il sistema e' stato provato solo in ambito urbano con una notevole densita' di antenne e di disturbi.Il suo uso reale sara' in aree lontane dall'ambiente urbano e sono previste prove nei prossimi giorni
Manifest
-------------------------------------------------
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.test.onrelease"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="18" />
<uses-permission android:name="android.permission.SEND_SMS" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"></uses-permission>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"></uses-permission>
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
android:name="com.test.onrelease.MainActivity"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
-------------------------------------------------
Layout
-------------------------------------------------
<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:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context=".MainActivity" >
<Button
android:id="@+id/button1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="Invia" />
<TextView
android:id="@+id/lat"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignBottom="@+id/button1"
android:layout_centerHorizontal="true"
android:layout_marginBottom="15dp"
android:gravity="center_horizontal"
android:text="TextView" />
<TextView
android:id="@+id/p1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignTop="@+id/button1"
android:layout_centerHorizontal="true"
android:layout_marginTop="18dp"
android:gravity="center_horizontal"
android:text="TextView" />
<TextView
android:id="@+id/p2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/p1"
android:layout_centerHorizontal="true"
android:gravity="center_horizontal"
android:text="TextView" />
<TextView
android:id="@+id/segnale"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/p2"
android:layout_centerHorizontal="true"
android:gravity="center_horizontal"
android:text="TextView" />
<TextView
android:id="@+id/gpsfix"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_above="@+id/lat"
android:layout_alignLeft="@+id/button1"
android:layout_marginBottom="14dp"
android:gravity="center_horizontal"
android:text="TextView" />
<TextView
android:id="@+id/last_pos"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_above="@+id/gpsfix"
android:layout_centerHorizontal="true"
android:layout_marginBottom="18dp"
android:gravity="center_horizontal" />
<TextView
android:id="@+id/tipo"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/segnale"
android:layout_centerHorizontal="true"
android:text="TextView" />
</RelativeLayout>
-------------------------------------------------
Main
--------------------------------------------------
package com.test.onrelease;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.sql.Date;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.List;
import java.util.TimeZone;
import android.location.Location;
import android.location.LocationManager;
import android.os.Bundle;
import android.os.Environment;
import android.os.PowerManager;
import android.os.PowerManager.WakeLock;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.graphics.Color;
import android.telephony.CellLocation;
import android.telephony.NeighboringCellInfo;
import android.telephony.PhoneStateListener;
import android.telephony.SignalStrength;
import android.telephony.SmsManager;
import android.telephony.TelephonyManager;
import android.telephony.gsm.GsmCellLocation;
import android.util.Log;
import android.view.*;
import android.view.View.OnTouchListener;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;
import android.location.LocationListener;
public class MainActivity extends Activity {
private Button pulsante;
//gestione dei tempi di pressione del pulsante
long lastDown;
long lastDuration;
//gestione del GPS
private double latitudine;
private double longitudine;
private double last_lat;
private double last_long;
private String tempo_gps;
private long old_time; //tempo ultima acquisizione
private long last_time;
private boolean gps_fix; //true se si ha il fix del GPS
private LocationManager mlocManager;
private MyLocationListener mlocListener;
private TextView gpsfix;
private TextView posizione;
private String nr_phone;
private int signalStrengthValue;
private int cid;
private int lac;
private int mcc;
private int mnc;
private int rssi;
private TextView ph1;
private TextView ph2;
private TextView segnale;
private TelephonyManager mTelephonyMgr;
private String networkOperator;
private GsmCellLocation cellLocation;
private TextView last_pos;
private TextView type;
private TextView vicini;
private WakeLock wl;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
gps_fix = false;
last_time = 0;
mlocManager = (LocationManager)getSystemService(Context.LOCATION_SERVICE);
mlocListener = new MyLocationListener();
mlocManager.requestLocationUpdates( LocationManager.GPS_PROVIDER, 0, 0, mlocListener);
// se il GPS non e' abilitato richiede l'intervento dell'utente
if (!mlocManager.isProviderEnabled(LocationManager.GPS_PROVIDER)) {
startActivity(new Intent(android.provider.Settings.ACTION_LOCATION_SOURCE_SETTINGS));
}
//prende il numero di telefono se disponibile
//TelephonyManager mTelephonyMgr;
mTelephonyMgr = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
// richiede le informazioni di cella
networkOperator = mTelephonyMgr.getNetworkOperator();
cellLocation = (GsmCellLocation) mTelephonyMgr.getCellLocation();
//il numero di telefono non e' codificato nella SIM
nr_phone = mTelephonyMgr.getLine1Number();
cid = cellLocation.getCid();
lac = cellLocation.getLac();
if (networkOperator != null) {
mcc = Integer.parseInt(networkOperator.substring(0, 3));
mnc = Integer.parseInt(networkOperator.substring(3));
}
//definisce il tipo di connessione (UTMS/HDSPA/GPRS
int tipo = mTelephonyMgr.getNetworkType();
type = (TextView)findViewById(R.id.tipo);
switch (tipo)
{
case 7:
type.setText("1xRTT");
break;
case 4:
type.setText("CDMA");
break;
case 2:
type.setText("EDGE");
break;
case 14:
type.setText("eHRPD");
break;
case 5:
type.setText("EVDO rev. 0");
break;
case 6:
type.setText("EVDO rev. A");
break;
case 12:
type.setText("EVDO rev. B");
break;
case 1:
type.setText("GPRS/GSM");
break;
case 8:
type.setText("HSDPA");
break;
case 10:
type.setText("HSPA");
break;
case 15:
type.setText("HSPA+");
break;
case 9:
type.setText("HSUPA");
break;
case 11:
type.setText("iDen");
break;
case 13:
type.setText("LTE");
break;
case 3:
type.setText("UMTS");
break;
case 0:
type.setText("Unknown");
break;
}
//la ricerca delle celle vicine sembra funzionare solo in 2G
List<NeighboringCellInfo> NeighboringList = mTelephonyMgr.getNeighboringCellInfo();
String stringNeighboring = "Neighboring List- Lac : Cid : RSSI\n";
for(int i=0; i < NeighboringList.size(); i++){
String dBm;
int rssi = NeighboringList.get(i).getRssi();
if(rssi == NeighboringCellInfo.UNKNOWN_RSSI){
dBm = "Unknown RSSI";
}else{
dBm = String.valueOf(-113 + 2 * rssi) + " dBm";
}
stringNeighboring = stringNeighboring
+ String.valueOf(NeighboringList.get(i).getLac()) +" : "
+ String.valueOf(NeighboringList.get(i).getCid()) +" : "
+ dBm +"\n";
}
AndroidPhoneStateListener phoneStateListener = new AndroidPhoneStateListener ();
mTelephonyMgr.listen(phoneStateListener, PhoneStateListener.LISTEN_SIGNAL_STRENGTHS);
pulsante = (Button) findViewById(R.id.button1);
pulsante.setText("In attesa posizione GPS");
pulsante.setEnabled(false);
posizione = (TextView)findViewById(R.id.lat);
gpsfix = (TextView)findViewById(R.id.gpsfix);
ph1 = (TextView) findViewById(R.id.p1);
ph2 = (TextView) findViewById(R.id.p2);
segnale = (TextView) findViewById(R.id.segnale);
last_pos = (TextView) findViewById(R.id.last_pos);
gpsfix.setText("00:00:00");
posizione.setText("0/0");
ph1.setText("CID:"+Integer.toString(cid)+" LAC:"+Integer.toString(lac));
ph2.setText("MCC:"+Integer.toString(mcc)+" MNC:"+Integer.toString(mnc));
//gestione della pressione del pulsante
pulsante.setOnTouchListener(new OnTouchListener() {
public boolean onTouch(View v, MotionEvent event) {
// registra il tempo di pressione del pulsante
if(event.getAction() == MotionEvent.ACTION_DOWN) {
lastDown = System.currentTimeMillis();
} else if (event.getAction() == MotionEvent.ACTION_UP) {
// registra il rilascio del pulsante
lastDuration = System.currentTimeMillis() - lastDown;
// se il tasto e' stato premuto almeno 1 sec genera l'evento di invio SMS
if (lastDuration > 1000)
{
pulsante.setBackgroundColor(Color.RED);
pulsante.setText("Richiesta accettata. Invio in corso");
// invio SMS
try {
SmsManager smsManager = SmsManager.getDefault();
String testo_sms = Double.toString(latitudine)+"/"+Double.toString(longitudine)+"/"+tempo_gps+"/"+nr_phone+"/"+Integer.toString(cid)+"/"+Integer.toString(lac)+"/"+Integer.toString(mcc)+"/"+Integer.toString(mnc)+"/"+Integer.toString(signalStrengthValue);
smsManager.sendTextMessage("xxxxxxxx", null, testo_sms, null, null);
Toast.makeText(getApplicationContext(), "SMS Inviato",
Toast.LENGTH_LONG).show();
} catch (Exception e) {
Toast.makeText(getApplicationContext(),
"Ritento spedizione SMS",
Toast.LENGTH_LONG).show();
e.printStackTrace();
}
// fine invio SMS
}
else
{
pulsante.setBackgroundColor(Color.GREEN);
pulsante.setText("Premere il pulsante per almeno 1 secondo");
}
}
return false;
}
});
}
public class MyLocationListener implements LocationListener
{
@Override
public void onLocationChanged(Location loc)
{
latitudine = loc.getLatitude();
longitudine = loc.getLongitude();
long tempo = loc.getTime();
// e' considerato di avere il fix gps se non ci sono piu' di 5 secondi
// tra due letture consecutive
if ((tempo-old_time < 5000) && (old_time > 0))
{
gps_fix = true;
pulsante.setEnabled(true);
pulsante.setBackgroundColor(Color.GREEN);
pulsante.setText("Premere il pulsante per almeno 1 secondo");
Date date = new Date(tempo);
SimpleDateFormat format = new SimpleDateFormat("dd/MM/yy HH:mm:ss zzz a");
format.setTimeZone(TimeZone.getTimeZone("GMT"));
tempo_gps= format.format(date);
gpsfix.setText(tempo_gps);
posizione.setText(loc.convert(longitudine, loc.FORMAT_SECONDS)+"/"+loc.convert(latitudine, loc.FORMAT_SECONDS));
//se sono passati 10 minuti dall'ultimo scambio variabili
//popolando le variabili dell'ultima posizione
if (last_time - tempo > 600000)
{
last_time = tempo;
last_lat=latitudine;
last_long = longitudine;
last_pos.setText(Location.convert(last_long, loc.FORMAT_SECONDS)+"/"+loc.convert(last_lat, loc.FORMAT_SECONDS));
}
}
old_time = tempo;
}
@Override
public void onProviderDisabled(String provider)
{
gps_fix = false;
Toast.makeText( getApplicationContext(),R.string.gps_disabled,Toast.LENGTH_SHORT ).show();
}
@Override
public void onProviderEnabled(String provider)
{
Toast.makeText( getApplicationContext(),R.string.gps_enabled,Toast.LENGTH_SHORT).show();
}
@Override
public void onStatusChanged(String provider, int status, Bundle extras)
{
}
}
@Override
protected void onStop()
{
//mlocManager.removeUpdates(mlocListener);
super.onStop();
}
@Override
protected void onDestroy()
{
mlocManager.removeUpdates(mlocListener);
super.onStop();
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
public double FSPL(int db)
{
double distanza;
distanza = Math.pow(10,(-db - 98.89)/20);
return distanza;
}
public double FSPLDbm(int dbm)
{
double distanza;
double db1;
double Pm = 1000*Math.pow(10,(dbm/10));
db1 = 10*Math.log10(Pm);
distanza = Math.pow(10,(-db1 - 98.89)/20);
return distanza;
}
public class AndroidPhoneStateListener extends PhoneStateListener {
private double d;
public void ononCellLocationChanged(CellLocation location)
{
networkOperator = mTelephonyMgr.getNetworkOperator();
cellLocation = (GsmCellLocation) mTelephonyMgr.getCellLocation();
//il numero di telefono non e' codificato nella SIM
nr_phone = mTelephonyMgr.getLine1Number();
cid = cellLocation.getCid();
lac = cellLocation.getLac();
if (networkOperator != null) {
mcc = Integer.parseInt(networkOperator.substring(0, 3));
mnc = Integer.parseInt(networkOperator.substring(3));
}
ph1.setText("CID:"+Integer.toString(cid)+" LAC:"+Integer.toString(lac));
ph2.setText("MCC:"+Integer.toString(mcc)+" MNC:"+Integer.toString(mnc));
//definisce il tipo di connessione (UTMS/HDSPA/GPRS
int tipo = mTelephonyMgr.getNetworkType();
type = (TextView)findViewById(R.id.tipo);
switch (tipo)
{
case 7:
type.setText("1xRTT");
break;
case 4:
type.setText("CDMA");
break;
case 2:
type.setText("EDGE");
break;
case 14:
type.setText("eHRPD");
break;
case 5:
type.setText("EVDO rev. 0");
break;
case 6:
type.setText("EVDO rev. A");
break;
case 12:
type.setText("EVDO rev. B");
break;
case 1:
type.setText("GPRS/GSM");
break;
case 8:
type.setText("HSDPA");
break;
case 10:
type.setText("HSPA");
break;
case 15:
type.setText("HSPA+");
break;
case 9:
type.setText("HSUPA");
break;
case 11:
type.setText("iDen");
break;
case 13:
type.setText("LTE");
break;
case 3:
type.setText("UMTS");
break;
case 0:
type.setText("Unknown");
break;
}
}
@Override
public void onSignalStrengthsChanged(SignalStrength signalStrength) {
super.onSignalStrengthsChanged(signalStrength);
networkOperator = mTelephonyMgr.getNetworkOperator();
cellLocation = (GsmCellLocation) mTelephonyMgr.getCellLocation();
//il numero di telefono non e' codificato nella SIM
nr_phone = mTelephonyMgr.getLine1Number();
cid = cellLocation.getCid();
lac = cellLocation.getLac();
if (networkOperator != null) {
mcc = Integer.parseInt(networkOperator.substring(0, 3));
mnc = Integer.parseInt(networkOperator.substring(3));
}
ph1.setText("CID:"+Integer.toString(cid)+" LAC:"+Integer.toString(lac));
ph2.setText("MCC:"+Integer.toString(mcc)+" MNC:"+Integer.toString(mnc));
//definisce il tipo di connessione (UTMS/HDSPA/GPRS
int tipo = mTelephonyMgr.getNetworkType();
type = (TextView)findViewById(R.id.tipo);
switch (tipo)
{
case 7:
type.setText("1xRTT");
break;
case 4:
type.setText("CDMA");
break;
case 2:
type.setText("EDGE");
break;
case 14:
type.setText("eHRPD");
break;
case 5:
type.setText("EVDO rev. 0");
break;
case 6:
type.setText("EVDO rev. A");
break;
case 12:
type.setText("EVDO rev. B");
break;
case 1:
type.setText("GPRS/GSM");
break;
case 8:
type.setText("HSDPA");
break;
case 10:
type.setText("HSPA");
break;
case 15:
type.setText("HSPA+");
break;
case 9:
type.setText("HSUPA");
break;
case 11:
type.setText("iDen");
break;
case 13:
type.setText("LTE");
break;
case 3:
type.setText("UMTS");
break;
case 0:
type.setText("Unknown");
break;
}
if (signalStrength.isGsm()) {
if (signalStrength.getGsmSignalStrength() != 99)
signalStrengthValue = signalStrength.getGsmSignalStrength() * 2 - 113;
else
signalStrengthValue = signalStrength.getGsmSignalStrength();
}
if (!signalStrength.isGsm()){
signalStrengthValue = signalStrength.getCdmaDbm();
if (signalStrength.getCdmaDbm() < signalStrength.getEvdoDbm())
{
signalStrengthValue = signalStrength.getCdmaDbm();
}
else
{
signalStrengthValue = signalStrength.getEvdoDbm();
}
}
if (signalStrength.isGsm())
{
d = FSPL(signalStrengthValue);
}
else
{
d = FSPLDbm(signalStrengthValue);
}
DecimalFormat df = new DecimalFormat("#.##");
segnale.setText("Segnale : "+Integer.toString(signalStrengthValue)+"dB / "+df.format(d)+"Km");
// salva su file
File root = Environment.getExternalStorageDirectory();
if (root.canWrite()){
File data_file = new File(root, "onrelease.txt");
FileWriter data_file_writer = null;
try {
data_file_writer = new FileWriter(data_file,true);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
BufferedWriter out = new BufferedWriter(data_file_writer);
try {
out.write(gpsfix.getText().toString()+";"+Double.toString(longitudine)+";"+Double.toString(latitudine)+";"+type.getText().toString()+";"+Integer.toString(mnc)+";"+Integer.toString(mcc)+";"+Integer.toString(lac)+";"+Integer.toString(cid)+";"+Integer.toString(signalStrengthValue)+";"+df.format(d)+"\n");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
out.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}