com.SecUpwN.AIMSICD.activities.MapViewer.java Source code

Java tutorial

Introduction

Here is the source code for com.SecUpwN.AIMSICD.activities.MapViewer.java

Source

/* Android IMSI Catcher Detector
 *      Copyright (C) 2014
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU General Public License for more details.
 *
 * You may obtain a copy of the License at
 *      https://github.com/SecUpwN/Android-IMSI-Catcher-Detector/blob/master/LICENSE
 */

package com.SecUpwN.AIMSICD.activities;

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.UiSettings;
import com.google.android.gms.maps.model.CameraPosition;
import com.google.android.gms.maps.model.CircleOptions;
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.SecUpwN.AIMSICD.R;
import com.SecUpwN.AIMSICD.adapters.AIMSICDDbAdapter;
import com.SecUpwN.AIMSICD.service.AimsicdService;
import com.SecUpwN.AIMSICD.utils.Cell;
import com.SecUpwN.AIMSICD.utils.Helpers;
import com.SecUpwN.AIMSICD.utils.RequestTask;

import android.app.AlertDialog;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.ServiceConnection;
import android.content.SharedPreferences;
import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
import android.database.Cursor;
import android.location.Location;
import android.os.Bundle;
import android.os.IBinder;
import android.support.v4.app.FragmentActivity;
import android.support.v4.content.LocalBroadcastManager;
import android.telephony.TelephonyManager;
import android.util.Log;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.widget.TableRow;
import android.widget.TextView;

import java.util.HashMap;
import java.util.Map;

public class MapViewer extends FragmentActivity implements OnSharedPreferenceChangeListener {

    private final String TAG = "AIMSICD_MapViewer";
    public static final String updateOpenCellIDMarkers = "update_opencell_markers";

    private GoogleMap mMap;
    private AIMSICDDbAdapter mDbHelper;
    private Context mContext;
    private SharedPreferences prefs;
    private AimsicdService mAimsicdService;
    private boolean mBound;

    private LatLng loc = null;
    private final Map<Marker, MarkerData> mMarkerMap = new HashMap<>();

    /**
     * Called when the activity is first created.
     */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        Log.i(TAG, "Starting MapViewer");
        super.onCreate(savedInstanceState);

        if (GooglePlayServicesUtil.isGooglePlayServicesAvailable(this) != ConnectionResult.SUCCESS) {
            final AlertDialog.Builder builder = new AlertDialog.Builder(this);
            builder.setMessage(R.string.error_google_play_services_message)
                    .setTitle(R.string.error_google_play_services_title);
            builder.create().show();
            finish();
        }

        setContentView(R.layout.map);
        setUpMapIfNeeded();
        mContext = this;
        mDbHelper = new AIMSICDDbAdapter(mContext);
        // Bind to LocalService
        Intent intent = new Intent(mContext, AimsicdService.class);
        mContext.bindService(intent, mConnection, Context.BIND_AUTO_CREATE);
    }

    @Override
    public void onResume() {
        super.onResume();
        setUpMapIfNeeded();

        prefs = this.getSharedPreferences(AimsicdService.SHARED_PREFERENCES_BASENAME, 0);
        prefs.registerOnSharedPreferenceChangeListener(this);

        LocalBroadcastManager.getInstance(this).registerReceiver(mMessageReceiver,
                new IntentFilter(updateOpenCellIDMarkers));

        if (!mBound) {
            // Bind to LocalService
            Intent intent = new Intent(mContext, AimsicdService.class);
            mContext.bindService(intent, mConnection, Context.BIND_AUTO_CREATE);
        }

        loadPreferences();
        loadEntries();
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        prefs.unregisterOnSharedPreferenceChangeListener(this);
        // Unbind from the service
        if (mBound) {
            mContext.unbindService(mConnection);
            mBound = false;
        }

        LocalBroadcastManager.getInstance(this).unregisterReceiver(mMessageReceiver);
    }

    @Override
    protected void onPause() {
        super.onPause();
        LocalBroadcastManager.getInstance(this).unregisterReceiver(mMessageReceiver);
    }

    private final BroadcastReceiver mMessageReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            loadOpenCellIDMarkers();
        }
    };

    /**
     * Service Connection to bind the activity to the service
     */
    private final ServiceConnection mConnection = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            // We've bound to LocalService, cast the IBinder and get LocalService instance
            mAimsicdService = ((AimsicdService.AimscidBinder) service).getService();
            mBound = true;
        }

        @Override
        public void onServiceDisconnected(ComponentName arg0) {
            Log.e(TAG, "Service Disconnected");
            mBound = false;
        }
    };

    private void loadPreferences() {
        String mapTypePref = getResources().getString(R.string.pref_map_type_key);
        prefs = mContext.getSharedPreferences(AimsicdService.SHARED_PREFERENCES_BASENAME, 0);
        if (prefs.contains(mapTypePref)) {
            int mapType = Integer.parseInt(prefs.getString(mapTypePref, "0"));
            switch (mapType) {
            case 0:
                mMap.setMapType(GoogleMap.MAP_TYPE_NORMAL);
                break;
            case 1:
                mMap.setMapType(GoogleMap.MAP_TYPE_HYBRID);
                break;
            case 2:
                mMap.setMapType(GoogleMap.MAP_TYPE_SATELLITE);
                break;
            case 3:
                mMap.setMapType(GoogleMap.MAP_TYPE_TERRAIN);
                break;
            }
        }
    }

    /**
     * Initialises the Map and sets initial options
     */
    private void setUpMapIfNeeded() {
        // Do a null check to confirm that we have not already instantiated the
        // map.
        if (mMap == null) {
            mMap = ((MapFragment) getFragmentManager().findFragmentById(R.id.map)).getMap();

            // Check if we were successful in obtaining the map.
            if (mMap != null) {
                // The Map is verified. It is now safe to manipulate the map.
                UiSettings uiSettings = mMap.getUiSettings();
                uiSettings.setZoomControlsEnabled(true);
                uiSettings.setCompassEnabled(true);
                uiSettings.setMyLocationButtonEnabled(true);
                uiSettings.setScrollGesturesEnabled(true);
                uiSettings.setZoomGesturesEnabled(true);
                uiSettings.setTiltGesturesEnabled(true);
                uiSettings.setRotateGesturesEnabled(true);
                mMap.setMyLocationEnabled(true);
                // Setting a custom info window adapter for the google map
                mMap.setInfoWindowAdapter(new GoogleMap.InfoWindowAdapter() {

                    // Use default InfoWindow frame
                    @Override
                    public View getInfoWindow(Marker arg0) {
                        return null;
                    }

                    // Defines the contents of the InfoWindow
                    @Override
                    public View getInfoContents(Marker arg0) {

                        TextView tv;

                        // Getting view from the layout file info_window_layout
                        View v = getLayoutInflater().inflate(R.layout.marker_info_window, null);

                        if (v != null) {
                            final MarkerData data = mMarkerMap.get(arg0);
                            if (data != null) {
                                if (data.openCellID) {
                                    TableRow tr = (TableRow) v.findViewById(R.id.open_cell_label);
                                    tr.setVisibility(View.VISIBLE);
                                }

                                tv = (TextView) v.findViewById(R.id.cell_id);
                                tv.setText(data.cellID);
                                tv = (TextView) v.findViewById(R.id.lat);
                                tv.setText(String.valueOf(data.lat));
                                tv = (TextView) v.findViewById(R.id.lng);
                                tv.setText(String.valueOf(data.lng));
                                tv = (TextView) v.findViewById(R.id.mcc);
                                tv.setText(data.mcc);
                                tv = (TextView) v.findViewById(R.id.mnc);
                                tv.setText(data.mnc);
                                tv = (TextView) v.findViewById(R.id.samples);
                                tv.setText(data.samples);
                            }
                        }

                        // Returning the view containing InfoWindow contents
                        return v;
                    }
                });
            } else {
                Helpers.msgShort(this, "Unable to create map!");
            }
        }
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        MenuInflater inflater = getMenuInflater();
        inflater.inflate(R.menu.map_viewer_menu, menu);
        return super.onCreateOptionsMenu(menu);
    }

    @Override
    public boolean onPrepareOptionsMenu(Menu menu) {
        return super.onCreateOptionsMenu(menu);
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle item selection
        switch (item.getItemId()) {
        case R.id.map_preferences:
            Intent intent = new Intent(this, MapPrefActivity.class);
            startActivity(intent);
            return true;
        case R.id.get_opencellid: {
            if (mBound) {
                Location lastKnown = mAimsicdService.mDevice.getLastLocation();
                if (lastKnown != null) {
                    Helpers.msgShort(this, "Contacting OpenCellID.org for data...");
                    Cell cell = new Cell();
                    cell = mAimsicdService.mDevice.mCell;
                    cell.setLon(lastKnown.getLongitude());
                    cell.setLat(lastKnown.getLatitude());
                    Helpers.getOpenCellData(mContext, cell, RequestTask.OPEN_CELL_ID_REQUEST_FROM_MAP);
                    return true;
                }
            }
            if (loc != null) {
                Helpers.msgShort(this, "Contacting OpenCellID.org for data...");
                Cell cell = new Cell();
                cell.setLat(loc.latitude);
                cell.setLon(loc.longitude);
                Helpers.getOpenCellData(mContext, cell, RequestTask.OPEN_CELL_ID_REQUEST_FROM_MAP);
            } else {
                Helpers.msgShort(mContext,
                        "Unable to determine your last location. \nEnable Location Services and try again.");
            }
            return true;
        }
        default:
            return super.onOptionsItemSelected(item);
        }
    }

    /**
     * Loads Signal Strength Database details to plot on the map,
     * only entries which have a location (lon, lat) are used.
     */
    private void loadEntries() {
        final int SIGNAL_SIZE_RATIO = 15;
        int signal;
        int color;
        mMap.clear();
        CircleOptions circleOptions;
        mDbHelper.open();
        Cursor c = mDbHelper.getCellData();
        if (c.moveToFirst()) {
            do {
                final int cellID = c.getInt(0);
                final int lac = c.getInt(1);
                final int net = c.getInt(2);
                final double dlat = Double.parseDouble(c.getString(3));
                final double dlng = Double.parseDouble(c.getString(4));
                if (dlat == 0.0 && dlng == 0.0) {
                    continue;
                }
                signal = c.getInt(5);
                if (signal <= 0) {
                    signal = 20;
                }

                if ((dlat != 0.0) || (dlng != 0.0)) {
                    loc = new LatLng(dlat, dlng);
                    switch (net) {
                    case TelephonyManager.NETWORK_TYPE_UNKNOWN:
                        color = 0xF0F8FF;
                        break;
                    case TelephonyManager.NETWORK_TYPE_GPRS:
                        color = 0xA9A9A9;
                        break;
                    case TelephonyManager.NETWORK_TYPE_EDGE:
                        color = 0x87CEFA;
                        break;
                    case TelephonyManager.NETWORK_TYPE_UMTS:
                        color = 0x7CFC00;
                        break;
                    case TelephonyManager.NETWORK_TYPE_HSDPA:
                        color = 0xFF6347;
                        break;
                    case TelephonyManager.NETWORK_TYPE_HSUPA:
                        color = 0xFF00FF;
                        break;
                    case TelephonyManager.NETWORK_TYPE_HSPA:
                        color = 0x238E6B;
                        break;
                    case TelephonyManager.NETWORK_TYPE_CDMA:
                        color = 0x8A2BE2;
                        break;
                    case TelephonyManager.NETWORK_TYPE_EVDO_0:
                        color = 0xFF69B4;
                        break;
                    case TelephonyManager.NETWORK_TYPE_EVDO_A:
                        color = 0xFFFF00;
                        break;
                    case TelephonyManager.NETWORK_TYPE_1xRTT:
                        color = 0x7CFC00;
                        break;
                    default:
                        color = 0xF0F8FF;
                        break;
                    }

                    // Add Signal radius circle based on signal strength
                    circleOptions = new CircleOptions().center(loc).radius(signal * SIGNAL_SIZE_RATIO)
                            .fillColor(color).strokeColor(color).visible(true);

                    mMap.addCircle(circleOptions);

                    // Add map marker for CellID
                    Marker marker = mMap.addMarker(
                            new MarkerOptions().position(loc).draggable(false).title("CellID - " + cellID));
                    mMarkerMap.put(marker, new MarkerData("" + cellID, "" + loc.latitude, "" + loc.longitude,
                            "" + lac, "", "", "", false));
                }

            } while (c.moveToNext());
        } else {
            Helpers.msgShort(this, "No tracked locations found to overlay on map.");
        }

        if (loc != null && (loc.latitude != 0.0 && loc.longitude != 0.0)) {
            CameraPosition POSITION = new CameraPosition.Builder().target(loc).zoom(16).build();
            mMap.animateCamera(CameraUpdateFactory.newCameraPosition(POSITION));
        } else {
            if (mBound) {
                // Try and find last known location and zoom there
                Location lastLoc = mAimsicdService.lastKnownLocation();
                if (lastLoc != null && lastLoc.hasAccuracy()) {
                    loc = new LatLng(lastLoc.getLatitude(), lastLoc.getLongitude());
                    CameraPosition POSITION = new CameraPosition.Builder().target(loc).zoom(16).build();

                    mMap.animateCamera(CameraUpdateFactory.newCameraPosition(POSITION));
                } else {
                    //Use Mcc to move camera to an approximate location near Countries Capital
                    int mcc = mAimsicdService.mDevice.mCell.getMCC();
                    double[] d = mDbHelper.getDefaultLocation(mcc);
                    loc = new LatLng(d[0], d[1]);
                    CameraPosition POSITION = new CameraPosition.Builder().target(loc).zoom(13).build();

                    mMap.animateCamera(CameraUpdateFactory.newCameraPosition(POSITION));
                }
            }
        }

        loadOpenCellIDMarkers();
        c.close();
        mDbHelper.close();
    }

    private void loadOpenCellIDMarkers() {
        //Check if OpenCellID data exists and if so load this now
        mDbHelper.open();
        Cursor c = mDbHelper.getOpenCellIDData();
        if (c.moveToFirst()) {
            do {
                final double dlat = Double.parseDouble(c.getString(4));
                final double dlng = Double.parseDouble(c.getString(5));
                final int cellID = c.getInt(0);
                final int lac = c.getInt(1);
                final LatLng location = new LatLng(dlat, dlng);
                final int mcc = c.getInt(2);
                final int mnc = c.getInt(3);
                final int samples = c.getInt(7);
                // Add map marker for CellID
                Marker marker = mMap.addMarker(
                        new MarkerOptions().position(location).draggable(false).title("CellID - " + cellID));

                mMarkerMap.put(marker, new MarkerData("" + cellID, "" + loc.latitude, "" + loc.longitude, "" + lac,
                        "" + mcc, "" + mnc, "" + samples, true));

            } while (c.moveToNext());
        }
        c.close();
        mDbHelper.close();
    }

    public class MarkerData {

        public final String cellID;
        public final String lat;
        public final String lng;
        public final String lac;
        public final String mcc;
        public final String mnc;
        public final String samples;
        public final boolean openCellID;

        MarkerData(String cell_id, String latitude, String longitude, String local_area_code,
                String mobile_country_code, String mobile_network_code, String samples_taken,
                boolean openCellID_Data) {
            cellID = cell_id;
            lat = latitude;
            lng = longitude;
            lac = local_area_code;
            mcc = mobile_country_code;
            mnc = mobile_network_code;
            samples = samples_taken;
            openCellID = openCellID_Data;
        }
    }

    public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
        final String KEY_MAP_TYPE = getBaseContext().getString(R.string.pref_map_type_key);

        if (key.equals(KEY_MAP_TYPE)) {
            int item = Integer.parseInt(sharedPreferences.getString(key, "0"));
            switch (item) {
            case 0:
                mMap.setMapType(GoogleMap.MAP_TYPE_NORMAL);
                break;
            case 1:
                mMap.setMapType(GoogleMap.MAP_TYPE_HYBRID);
                break;
            case 2:
                mMap.setMapType(GoogleMap.MAP_TYPE_SATELLITE);
                break;
            case 3:
                mMap.setMapType(GoogleMap.MAP_TYPE_TERRAIN);
                break;
            }
        }
    }
}