it.tidalwave.bluebill.mobile.android.location.LocationPickerActivity Maven / Gradle / Ivy
The newest version!
/***********************************************************************************************************************
*
* blueBill Mobile - Android - open source birding
* Copyright (C) 2009-2011 by Tidalwave s.a.s. (http://www.tidalwave.it)
*
***********************************************************************************************************************
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
* specific language governing permissions and limitations under the License.
*
***********************************************************************************************************************
*
* WWW: http://bluebill.tidalwave.it/mobile
* SCM: https://java.net/hg/bluebill-mobile~android-src
*
**********************************************************************************************************************/
package it.tidalwave.bluebill.mobile.android.location;
import java.util.concurrent.ExecutorService;
import it.tidalwave.bluebill.mobile.android.util.CommonOptionsMenuController;
import it.tidalwave.bluebill.mobile.android.util.CommonOptionsMenuControllerProvider;
import javax.annotation.Nonnull;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import it.tidalwave.util.NotFoundException;
import it.tidalwave.netbeans.util.Locator;
import it.tidalwave.geo.Coordinate;
import it.tidalwave.geo.Range;
import it.tidalwave.observation.Location;
import it.tidalwave.observation.Observation;
import it.tidalwave.observation.simple.SimpleLocation;
import it.tidalwave.mobile.location.LocationFinder;
import it.tidalwave.mobile.location.LocationFinder.State;
import it.tidalwave.mobile.location.LocationPreferences;
import it.tidalwave.observation.bluebill.ObservationClipboard;
import it.tidalwave.bluebill.mobile.preferences.NetworkingPreferences;
import android.app.Activity;
import android.graphics.drawable.Drawable;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.location.Address;
import android.location.LocationProvider;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.ProgressBar;
import it.tidalwave.mobile.android.ui.AndroidUtilities;
import it.tidalwave.mobile.android.ui.AndroidFlowController;
import it.tidalwave.bluebill.mobile.android.R;
import it.tidalwave.role.spi.DefaultDisplayable;
import java.io.IOException;
import lombok.extern.slf4j.Slf4j;
import static org.openide.util.NbBundle.*;
/***********************************************************************************************************************
*
* The activity that allows to enter a location for the current {@link Observation}.
*
* FIXME: refactor to MVC.
*
* @stereotype View
* @stereotype Activity
*
* @author Fabrizio Giudici
* @version $Id$
*
**********************************************************************************************************************/
@Slf4j
public class LocationPickerActivity extends Activity
{
public static final Class LocationPickerActivity = LocationPickerActivity.class;
private static final Class _ = LocationPickerActivity.class;
@Nonnull
private final LocationPreferences locationPreferences = Locator.find(LocationPreferences.class);
@Nonnull
private final NetworkingPreferences networkingPreferences = Locator.find(NetworkingPreferences.class);
@Nonnull
private final LocationFinder locationFinder = Locator.find(LocationFinder.class);
private TextView tvState;
private TextView tvProvider;
private EditText etCoordinate;
private EditText etPlace;
private ImageButton btRecomputePlace;
private ImageButton btResamplePosition;
private Button btOk;
private ProgressBar pbProgress;
private ImageView ivMap;
private Map map = new HashMap();
private Handler handler;
private AndroidFlowController controlFlow;
private final CommonOptionsMenuController commonOptionsMenuController = Locator.find(CommonOptionsMenuControllerProvider.class).createCommonOptionsMenuController(this);
@Nonnull
private final ExecutorService executorService = Locator.find(ExecutorService.class);
/*******************************************************************************************************************
*
*
******************************************************************************************************************/
private final PropertyChangeListener locationFinderListener = new PropertyChangeListener()
{
public void propertyChange (final @Nonnull PropertyChangeEvent event)
{
handler.post(new Runnable()
{
public void run()
{
updateDisplay();
}
});
}
};
/*******************************************************************************************************************
*
*
******************************************************************************************************************/
private final View.OnClickListener commitLocationListener = new View.OnClickListener()
{
public void onClick (final @Nonnull View view)
{
commitLocation();
}
};
/*******************************************************************************************************************
*
*
******************************************************************************************************************/
private final View.OnClickListener startLocationFinderListener = new View.OnClickListener()
{
public void onClick (final @Nonnull View view)
{
locationFinder.start();
}
};
/*******************************************************************************************************************
*
*
******************************************************************************************************************/
private final View.OnClickListener findAddressListener = new View.OnClickListener()
{
public void onClick (final @Nonnull View view)
{
locationFinder.findAddress();
}
};
/*******************************************************************************************************************
*
* {@inheritDoc}
*
******************************************************************************************************************/
@Override
protected void onCreate (final @Nonnull Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_location_picker);
handler = new Handler();
tvProvider = (TextView)findViewById(R.id.tvProvider);
etCoordinate = (EditText)findViewById(R.id.etCoordinate);
tvState = (TextView)findViewById(R.id.tvState);
etPlace = (EditText)findViewById(R.id.etPlace);
btOk = (Button)findViewById(R.id.btOk);
btRecomputePlace = (ImageButton)findViewById(R.id.btRecomputePlace);
btResamplePosition = ((ImageButton)findViewById(R.id.btResamplePosition));
pbProgress = (ProgressBar)findViewById(R.id.pbProgress);
ivMap = (ImageView)findViewById(R.id.ivMap);
etPlace.requestFocus();
pbProgress.setIndeterminate(true);
btRecomputePlace.setEnabled(false);
// FIXME: disable if the locationFinder is already working
btOk.setOnClickListener(commitLocationListener);
btResamplePosition.setOnClickListener(startLocationFinderListener);
btRecomputePlace.setOnClickListener(findAddressListener);
controlFlow = AndroidFlowController.forActivity(this);
}
/*******************************************************************************************************************
*
* When the activity is resumed, the {@link LocationFinder} is eventually reactivated; the UI is updated for some
* things in the UI that might have been changed after new settings in the preferences.
*
******************************************************************************************************************/
@Override
protected void onResume()
{
super.onResume();
// here, so you can detect the locale change
map.clear();
map.put(State.COMPUTING_RANGE, getMessage(_, "computingRange"));
map.put(State.SEARCHING_FOR_ADDRESS, getMessage(_, "placeSearchInProgress"));
map.put(State.IDLE, "");
final boolean geoCodingEnabled = locationFinder.isAddressSearchEnabled();
findViewById(R.id.tvGeocodingDisabled).setVisibility(AndroidUtilities.visibility(!geoCodingEnabled));
btRecomputePlace.setVisibility(AndroidUtilities.visibility(geoCodingEnabled));
// btRecomputePlace.setEnabled(locationFinder.isAddressSearchEnabled());
locationFinder.addPropertyChangeListener(locationFinderListener);
// locationFinder.start(); // pre-started by ObservationsActivity
updateDisplay();
}
/*******************************************************************************************************************
*
* When the activity is paused, the {@link LocationFinder} is stopped (e.g. to turn the GPS off).
*
******************************************************************************************************************/
@Override
protected void onPause()
{
super.onPause();
locationFinder.removePropertyChangeListener(locationFinderListener);
locationFinder.stop();
}
/*******************************************************************************************************************
*
*
******************************************************************************************************************/
@Override
protected void onActivityResult (final int requestCode, final int resultCode, final @Nonnull Intent data)
{
setResult(resultCode, data);
finish();
}
/*******************************************************************************************************************
*
* {@inheritDoc}
*
******************************************************************************************************************/
@Override
public boolean onCreateOptionsMenu (final @Nonnull Menu menu)
{
getMenuInflater().inflate(R.menu.common_options_menu, menu);
return true;
}
/*******************************************************************************************************************
*
* {@inheritDoc}
*
******************************************************************************************************************/
@Override
public boolean onOptionsItemSelected (final @Nonnull MenuItem item)
{
return commonOptionsMenuController.onOptionsItemSelected(item);
}
/*******************************************************************************************************************
*
* Adds the picked location to the {@link Observation} being built in the {@link ObservationClipboard}.
*
******************************************************************************************************************/
private void commitLocation()
{
final List