Java tutorial
package hr.foicore.varazdinlandmarksdemo; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; import hr.foicore.varazdinlandmarksdemo.database.POIAdapter; import hr.foicore.varazdinlandmarksdemo.helpers.ArrayAdapterSearchView; import hr.foicore.varazdinlandmarksdemo.json.JSONParser; import hr.foicore.varazdinlandmarksdemo.modules.GoogleMapsModule; import hr.foicore.varazdinlandmarksdemo.modules.SearchModule; import com.google.android.gms.common.ConnectionResult; import com.google.android.gms.common.GooglePlayServicesUtil; import com.google.android.gms.maps.CameraUpdate; import com.google.android.gms.maps.CameraUpdateFactory; 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.OnMyLocationButtonClickListener; import com.google.android.gms.maps.SupportMapFragment; import com.google.android.gms.maps.GoogleMap.OnMapClickListener; import com.google.android.gms.maps.GoogleMap.OnMarkerClickListener; import com.google.android.gms.maps.model.LatLng; import com.google.android.gms.maps.model.Marker; import com.google.android.gms.maps.model.Polyline; import com.google.android.gms.maps.model.PolylineOptions; import com.google.maps.android.PolyUtil; import android.support.v7.app.ActionBarActivity; import android.support.v7.widget.SearchView; import android.support.v4.view.MenuItemCompat; import android.text.Html; import android.annotation.SuppressLint; import android.app.AlertDialog; import android.app.Dialog; import android.app.ProgressDialog; import android.app.SearchManager; import android.content.ActivityNotFoundException; import android.content.Context; import android.content.DialogInterface; import android.content.Intent; import android.content.SharedPreferences; import android.content.pm.ActivityInfo; import android.graphics.Point; import android.location.Criteria; import android.location.Location; import android.location.LocationManager; import android.net.Uri; import android.os.AsyncTask; import android.os.Build; import android.os.Bundle; import android.view.Display; import android.view.KeyEvent; import android.view.Menu; import android.view.MenuItem; import android.view.Surface; import android.view.View; import android.view.View.OnClickListener; import android.widget.AdapterView; import android.widget.AdapterView.OnItemClickListener; import android.widget.ArrayAdapter; import android.widget.TextView; import android.widget.Toast; import android.preference.PreferenceManager; import android.provider.Settings; public class POIMapActivity extends ActionBarActivity implements OnMapClickListener, OnMarkerClickListener, OnMyLocationButtonClickListener, OnInfoWindowClickListener { public GoogleMapsModule gmm; public TextView tvMapMessage; public TextView tvMapDirectionsInfo; public MenuItem miSearch; public MenuItem miDirections; public MenuItem miPlay; // for refreshing UI in onActivityResult // (when location button pressed in other activity) private boolean mAnimateCameraToMarker = false; private boolean mCalculateDirections = false; private boolean mStartGame = false; private double mLatitude; private double mLongitude; private int mActionDirections = 0; // 0 - nothing, 1 pressed, 2 shown private boolean mActionPlay = false; private Polyline mRoute = null; public LatLng userLocation; public ArrayAdapterSearchView searchView; public AlertDialog mapTypeDialog; public int selectedMapType; private ArrayAdapter<String> mAdapter; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_poi_map); SupportMapFragment smf = (SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.f_map); gmm = new GoogleMapsModule(POIMapActivity.this, smf); if (gmm.googleMap != null) { // get and set map type from settings selectedMapType = getSelectedGoogleMapType(); switchGoogleMapType(selectedMapType); gmm.addAllMarkers(POIMapActivity.this); gmm.googleMap.setOnMapClickListener(POIMapActivity.this); gmm.googleMap.setOnMarkerClickListener(POIMapActivity.this); gmm.googleMap.setOnInfoWindowClickListener(POIMapActivity.this); // Setting a custom info window adapter for the google map gmm.googleMap.setInfoWindowAdapter(new InfoWindowAdapter() { // Use default InfoWindow frame @Override public View getInfoWindow(Marker marker) { return null; } // Defines the contents of the InfoWindow @Override public View getInfoContents(Marker marker) { // Getting view from the layout file info_window_layout View v = getLayoutInflater().inflate(R.layout.custom_infowindow_popup, null); TextView tv; tv = (TextView) v.findViewById(R.id.snippet); tv.setText(marker.getSnippet()); // Returning the view containing InfoWindow contents return v; } }); } tvMapMessage = (TextView) findViewById(R.id.tv_map_message); tvMapMessage.setOnClickListener(new OnClickListener() { public void onClick(View v) { if (!gmm.internetEnabled) { POIMapActivity.this.startActivity(new Intent(Settings.ACTION_WIRELESS_SETTINGS)); } else if (!gmm.myLocationEnabled) { startActivityForResult(new Intent(android.provider.Settings.ACTION_LOCATION_SOURCE_SETTINGS), 0); } } }); tvMapDirectionsInfo = (TextView) findViewById(R.id.tv_map_directions_info); lockOrientation(); } @Override protected void onResume() { super.onResume(); // TODO test when google play service is not installed case.. // text view on top of screen logic gmm.handleMapWarningMessages(POIMapActivity.this, tvMapMessage); // Check if google play service is installed on the phone int resultCode = GooglePlayServicesUtil.isGooglePlayServicesAvailable(POIMapActivity.this); if (resultCode != ConnectionResult.SUCCESS) { Dialog dialog = GooglePlayServicesUtil.getErrorDialog(resultCode, POIMapActivity.this, 7); dialog.show(); } else { // animate camera to specific POI marker if (mAnimateCameraToMarker) { CameraUpdate poiLocation = CameraUpdateFactory.newLatLng(new LatLng(mLatitude, mLongitude)); gmm.googleMap.animateCamera(poiLocation); mAnimateCameraToMarker = false; } else if (mCalculateDirections) { drawUserDestRoute(new LatLng(mLatitude, mLongitude)); mCalculateDirections = false; } else if (mStartGame) { gmm.addPlayMarkers(POIMapActivity.this); miPlay.setIcon(R.drawable.ic_action_pause_red); if (gmm.activePOIMarker != null) { drawUserDestRoute(gmm.activePOIMarker.getPosition()); } mActionPlay = true; mStartGame = false; } int selectedMapTypeFromSettings = getSelectedGoogleMapType(); if (selectedMapTypeFromSettings != selectedMapType) { switchGoogleMapType(selectedMapTypeFromSettings); } } } @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.poi_map, menu); miSearch = menu.findItem(R.id.action_search); miDirections = menu.findItem(R.id.action_directions); miPlay = menu.findItem(R.id.action_play); String[] poiNames = new String[gmm.pois.size()]; for (int i = 0; i < gmm.pois.size(); i++) { poiNames[i] = gmm.pois.get(i).getName(); } searchView = (ArrayAdapterSearchView) (SearchView) MenuItemCompat.getActionView(miSearch); mAdapter = new ArrayAdapter<String>(this, R.layout.dropdown_item, poiNames); searchView.setAdapter(mAdapter); searchView.setThreshold(1); // one letter is enough for auto complete searchView.setOnItemClickListener(new OnItemClickListener() { @Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { // when clicked on suggested item SearchModule.searchGoogleMap(POIMapActivity.this, gmm.googleMap, gmm.pois, searchView, mAdapter.getItem(position).toString()); MenuItemCompat.collapseActionView(miSearch); } }); searchView.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { // when clicked on search view (e.g. search icon) searchView.showDropDown(); } }); searchView.setQueryHint(POIMapActivity.this.getResources().getString(R.string.search_hint)); SearchManager searchManager = (SearchManager) getSystemService(Context.SEARCH_SERVICE); if (null != searchView) { searchView.setSearchableInfo(searchManager.getSearchableInfo(getComponentName())); searchView.setIconifiedByDefault(false); } SearchView.OnQueryTextListener queryTextListener = new SearchView.OnQueryTextListener() { public boolean onQueryTextChange(String newText) { // some action if needed return true; } public boolean onQueryTextSubmit(String query) { // get entered query value and search SearchModule.searchGoogleMap(POIMapActivity.this, gmm.googleMap, gmm.pois, searchView, query); MenuItemCompat.collapseActionView(miSearch); return true; } }; searchView.setOnQueryTextListener(queryTextListener); return super.onCreateOptionsMenu(menu); // return true; } @Override public boolean onOptionsItemSelected(MenuItem item) { int id = item.getItemId(); if (id == R.id.action_view_as_grid) { Intent i = new Intent(POIMapActivity.this, POIGridActivity.class); i.putExtra("playOn", mActionPlay); i.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION); // finish(); overridePendingTransition(0, 0); startActivityForResult(i, 1); overridePendingTransition(0, 0); } else if (id == R.id.action_directions) { if (mActionDirections == 1) { // cancel directions action item.setIcon(R.drawable.ic_action_directions); mActionDirections = 0; tvMapDirectionsInfo.setVisibility(View.INVISIBLE); if (mRoute != null) { mRoute.remove(); } } else if (mActionDirections == 0) { // set directions action on item.setIcon(R.drawable.ic_action_directions_pressed); mActionDirections = 1; gmm.handleMapWarningMessages(POIMapActivity.this, tvMapMessage); if (gmm.myLocationEnabled && gmm.internetEnabled) { Toast.makeText(POIMapActivity.this, POIMapActivity.this.getResources().getString(R.string.tap_route_destination), Toast.LENGTH_SHORT).show(); } else { tvMapMessage.setBackgroundColor( POIMapActivity.this.getResources().getColor(R.color.red_transparent)); item.setIcon(R.drawable.ic_action_directions); mActionDirections = 0; tvMapDirectionsInfo.setVisibility(View.INVISIBLE); } } else { // mActionDirections == 3 item.setIcon(R.drawable.ic_action_directions); mActionDirections = 0; tvMapDirectionsInfo.setVisibility(View.INVISIBLE); if (mRoute != null) { mRoute.remove(); } } } else if (id == R.id.action_play) { if (mActionPlay) { // cancel play mode gmm.addAllMarkers(POIMapActivity.this); item.setIcon(R.drawable.ic_action_play); mActionPlay = false; miDirections.setIcon(R.drawable.ic_action_directions); mActionDirections = 0; tvMapDirectionsInfo.setVisibility(View.INVISIBLE); if (mRoute != null) { mRoute.remove(); } } else { gmm.addPlayMarkers(POIMapActivity.this); item.setIcon(R.drawable.ic_action_pause_red); if (gmm.activePOIMarker != null) { drawUserDestRoute(gmm.activePOIMarker.getPosition()); } mActionPlay = true; } } else if (id == R.id.action_google_map_type) { // get google map type names String[] googleMapTypeNames = getResources().getStringArray(R.array.google_map_type_names); // creating and Building the Dialog AlertDialog.Builder builderMapType = new AlertDialog.Builder(this); builderMapType.setTitle(getResources().getString(R.string.action_google_map_type)); builderMapType.setSingleChoiceItems(googleMapTypeNames, selectedMapType, new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int item) { if (item != selectedMapType) { switchGoogleMapType(item); // save selected type in settings SharedPreferences preferences = PreferenceManager .getDefaultSharedPreferences(POIMapActivity.this); SharedPreferences.Editor editor = preferences.edit(); editor.putString("googleMapType", String.valueOf(item)); editor.commit(); } mapTypeDialog.dismiss(); } }); mapTypeDialog = builderMapType.create(); mapTypeDialog.show(); } else if (id == R.id.action_legal_notices) { String licenseInfo = GooglePlayServicesUtil.getOpenSourceSoftwareLicenseInfo(getApplicationContext()); AlertDialog.Builder licenseDialog = new AlertDialog.Builder(POIMapActivity.this); licenseDialog.setTitle(getString(R.string.action_legal_notices)); licenseDialog.setMessage(licenseInfo); licenseDialog.show(); } else if (id == R.id.action_scan_qr_code) { handleQRcodeScanRequest(); } else if (id == R.id.action_about) { String about = getString(R.string.about_application); AlertDialog alertDialog; alertDialog = new AlertDialog.Builder(POIMapActivity.this).create(); alertDialog.setTitle(getString(R.string.action_about)); alertDialog.setMessage(Html.fromHtml(about)); alertDialog.setButton(Dialog.BUTTON_NEGATIVE, getString(R.string.ok), new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int which) { } }); alertDialog.show(); } return super.onOptionsItemSelected(item); } @Override public boolean onMarkerClick(final Marker marker) { gmm.googleMap.animateCamera(CameraUpdateFactory.newLatLng(marker.getPosition())); if (mActionDirections == 1) { // draw route drawUserDestRoute(marker.getPosition()); } else if (marker.getTitle() == null) { marker.showInfoWindow(); } else { /*Toast.makeText( POIMapActivity.this, getResources().getString(R.string.opening) + " " + marker.getTitle() + " " + getResources().getString(R.string.details), Toast.LENGTH_SHORT).show();*/ Intent i = new Intent(POIMapActivity.this, POIDetailsActivity.class); i.putExtra("poiId", Integer.parseInt(marker.getSnippet())); startActivity(i); } return true; } @Override public void onMapClick(LatLng point) { if (mActionDirections == 1) { drawUserDestRoute(point); } } @Override public boolean onMyLocationButtonClick() { if (gmm.googleMap.getMyLocation() == null) { Toast.makeText(POIMapActivity.this, POIMapActivity.this.getResources().getString(R.string.my_location_problem), Toast.LENGTH_LONG) .show(); } return false; } protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); if (requestCode == 0) { // qr code scanner if (resultCode == RESULT_OK) { String contents = data.getStringExtra("SCAN_RESULT"); // String format = data.getStringExtra("SCAN_RESULT_FORMAT"); // Toast.makeText( POIMapActivity.this, contents, // Toast.LENGTH_LONG).show(); POIAdapter POIa = new POIAdapter(POIMapActivity.this); POIa.openToWrite(); int returnedId = POIa.checkQRCode(contents); POIa.close(); if (returnedId != -1) { Toast.makeText(POIMapActivity.this, POIMapActivity.this.getResources().getString(R.string.content_unlocked), Toast.LENGTH_LONG).show(); if (mActionPlay) { gmm.addPlayMarkers(POIMapActivity.this); } else { gmm.addAllMarkers(POIMapActivity.this); } Intent i = new Intent(POIMapActivity.this, POIDetailsActivity.class); i.putExtra("poiId", returnedId); startActivity(i); } else { Toast.makeText(POIMapActivity.this, POIMapActivity.this.getResources().getString(R.string.qr_code_incorrect), Toast.LENGTH_LONG).show(); } // Handle successful scan } else if (resultCode == RESULT_CANCELED) { // Handle cancel } } if (requestCode == 1) { if (resultCode == RESULT_OK) { String type = data.getStringExtra("type"); mLatitude = data.getDoubleExtra("latitude", 46.307506); mLongitude = data.getDoubleExtra("longitude", 16.33829); if (type.equalsIgnoreCase("location")) { mAnimateCameraToMarker = true; } else if (type.equalsIgnoreCase("directions")) { mCalculateDirections = true; } else if (type.equalsIgnoreCase("play")) { mStartGame = true; } } if (resultCode == RESULT_CANCELED) { // code if there's no result } } }// onActivityResult @Override public boolean onKeyDown(int keyCode, KeyEvent event) { if (keyCode == KeyEvent.KEYCODE_SEARCH) { if (MenuItemCompat.isActionViewExpanded(miSearch)) { MenuItemCompat.collapseActionView(miSearch); } else { MenuItemCompat.expandActionView(miSearch); } } return super.onKeyDown(keyCode, event); } protected class connectAsyncTask extends AsyncTask<Void, Void, String> { private ProgressDialog progressDialog; String url; connectAsyncTask(String urlPass) { url = urlPass; } @Override protected void onPreExecute() { super.onPreExecute(); progressDialog = new ProgressDialog(POIMapActivity.this); progressDialog.setMessage(POIMapActivity.this.getResources().getString(R.string.fetching_route)); progressDialog.setIndeterminate(true); progressDialog.show(); } @Override protected String doInBackground(Void... params) { JSONParser jParser = new JSONParser(); String json = jParser.getJSONFromUrl(url); return json; } @Override protected void onPostExecute(String result) { super.onPostExecute(result); progressDialog.hide(); if (result != null) { String encodedPolyline = null; String distanceText = POIMapActivity.this.getResources().getString(R.string.not_available); JSONObject jsonObject; try { jsonObject = new JSONObject(result); JSONArray routeArray = jsonObject.getJSONArray("routes"); JSONObject routes = routeArray.getJSONObject(0); JSONObject overviewPolylines = routes.getJSONObject("overview_polyline"); encodedPolyline = overviewPolylines.getString("points"); JSONArray legsArray = routes.getJSONArray("legs"); JSONObject legs = legsArray.getJSONObject(0); JSONObject distance = legs.getJSONObject("distance"); distanceText = distance.getString("text"); } catch (JSONException e) { e.printStackTrace(); } if (encodedPolyline != null) { PolylineOptions polylineOptions = new PolylineOptions(); polylineOptions .color(POIMapActivity.this.getResources().getColor(R.color.main_theme_color_darker)); if (mRoute != null) { mRoute.remove(); } mRoute = gmm.googleMap.addPolyline(polylineOptions.addAll(PolyUtil.decode(encodedPolyline))); tvMapDirectionsInfo.setVisibility(View.VISIBLE); tvMapDirectionsInfo.setText( POIMapActivity.this.getResources().getString(R.string.distance) + ": " + distanceText); gmm.googleMap.animateCamera(CameraUpdateFactory.newLatLng(userLocation)); } miDirections.setIcon(R.drawable.ic_action_directions_cancel); mActionDirections = 3; } } } public boolean drawUserDestRoute(LatLng destination) { gmm.handleMapWarningMessages(POIMapActivity.this, tvMapMessage); if (!gmm.myLocationEnabled || !gmm.internetEnabled) { tvMapMessage.setBackgroundColor(POIMapActivity.this.getResources().getColor(R.color.red_transparent)); miDirections.setIcon(R.drawable.ic_action_directions); mActionDirections = 0; tvMapDirectionsInfo.setVisibility(View.INVISIBLE); } else { if (gmm.googleMap.getMyLocation() != null) { userLocation = new LatLng(gmm.googleMap.getMyLocation().getLatitude(), gmm.googleMap.getMyLocation().getLongitude()); } else { LocationManager service = (LocationManager) getSystemService(LOCATION_SERVICE); Criteria criteria = new Criteria(); String provider = service.getBestProvider(criteria, false); Location location = service.getLastKnownLocation(provider); if (location != null) { userLocation = new LatLng(location.getLatitude(), location.getLongitude()); } else { Toast.makeText(POIMapActivity.this, POIMapActivity.this.getResources().getString(R.string.my_location_problem), Toast.LENGTH_LONG).show(); return false; } } new connectAsyncTask(gmm.makeURL(userLocation.latitude, userLocation.longitude, destination.latitude, destination.longitude)).execute(); } return true; } @Override public void onInfoWindowClick(Marker marker) { handleQRcodeScanRequest(); } public void handleQRcodeScanRequest() { Intent intent = new Intent("com.google.zxing.client.android.SCAN"); intent.putExtra("SCAN_MODE", "QR_CODE_MODE"); intent.putExtra("SAVE_HISTORY", false); try { startActivityForResult(intent, 0); // request code is 0 } catch (ActivityNotFoundException e) { // No application to view, ask to download one AlertDialog alertDialog = new AlertDialog.Builder(POIMapActivity.this).create();// context).create(); alertDialog.setTitle(getResources().getString(R.string.qr_scanner_not_found)); alertDialog.setMessage(getResources().getString(R.string.install_it_now_question)); alertDialog.setButton(Dialog.BUTTON_NEGATIVE, getResources().getString(R.string.no), new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int which) { } }); alertDialog.setButton(Dialog.BUTTON_POSITIVE, getResources().getString(R.string.yes), new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int which) { try { // TODO test this startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("market://search?q=qr+scanner&c=apps"))); } catch (android.content.ActivityNotFoundException anfe) { startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("http://play.google.com/store/search?q=qr+scanner&c=apps"))); } } }); alertDialog.show(); } } private void switchGoogleMapType(int mapTypeToSwitch) { switch (mapTypeToSwitch) { case 0: gmm.googleMap.setMapType(GoogleMap.MAP_TYPE_NORMAL); break; case 1: gmm.googleMap.setMapType(GoogleMap.MAP_TYPE_HYBRID); break; case 2: gmm.googleMap.setMapType(GoogleMap.MAP_TYPE_SATELLITE); break; case 3: gmm.googleMap.setMapType(GoogleMap.MAP_TYPE_TERRAIN); break; default: mapTypeToSwitch = 0; gmm.googleMap.setMapType(GoogleMap.MAP_TYPE_NORMAL); break; } selectedMapType = mapTypeToSwitch; } private int getSelectedGoogleMapType() { SharedPreferences sharedPreference = PreferenceManager.getDefaultSharedPreferences(POIMapActivity.this); int mapTypeSelected = Integer.parseInt(sharedPreference.getString("googleMapType", "0")); return mapTypeSelected; } @SuppressWarnings("deprecation") @SuppressLint("NewApi") private void lockOrientation() { Display display = POIMapActivity.this.getWindowManager().getDefaultDisplay(); int rotation = display.getRotation(); int height; int width; if (Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB_MR2) { height = display.getHeight(); width = display.getWidth(); } else { Point size = new Point(); display.getSize(size); height = size.y; width = size.x; } switch (rotation) { case Surface.ROTATION_90: if (width > height) POIMapActivity.this.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE); else POIMapActivity.this.setRequestedOrientation(9/* reversePortait */); break; case Surface.ROTATION_180: if (height > width) POIMapActivity.this.setRequestedOrientation(9/* reversePortait */); else POIMapActivity.this.setRequestedOrientation(8/* reverseLandscape */); break; case Surface.ROTATION_270: if (width > height) POIMapActivity.this.setRequestedOrientation(8/* reverseLandscape */); else POIMapActivity.this.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); break; default: if (height > width) POIMapActivity.this.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); else POIMapActivity.this.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE); } } }