Android Google Places: Not returning selected place - java

Followed the tutorial here.
http://www.startingandroid.com/google-places-api-tutorial-for-android/
However, when searching something in the search bar, selecting one from the suggested list, then pressing the Pick Location button, the map displays the user's current location and not the place he/she selected. Can anyone provide a solution for this?
MainActivity.java
public class MainActivity extends AppCompatActivity {
private PlacePicker.IntentBuilder builder;
private PlacesAutoCompleteAdapter mPlacesAdapter;
private Button pickerBtn;
private AutoCompleteTextView myLocation;
private static final int PLACE_PICKER_FLAG = 1;
private static final LatLngBounds BOUNDS_GREATER_SYDNEY = new LatLngBounds(
new LatLng(-34.041458, 150.790100), new LatLng(-33.682247, 151.383362));
protected GoogleApiClient mGoogleApiClient;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addApi(Places.GEO_DATA_API)
.build();
setContentView(R.layout.activity_main);
builder = new PlacePicker.IntentBuilder();
myLocation = (AutoCompleteTextView) findViewById(R.id.myLocation);
mPlacesAdapter = new PlacesAutoCompleteAdapter(this, android.R.layout.simple_list_item_1,
mGoogleApiClient, BOUNDS_GREATER_SYDNEY, null);
myLocation.setOnItemClickListener(mAutocompleteClickListener);
myLocation.setAdapter(mPlacesAdapter);
pickerBtn = (Button) findViewById(R.id.pickerBtn);
pickerBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
try {
builder = new PlacePicker.IntentBuilder();
Intent intent = builder.build(MainActivity.this);
// Start the Intent by requesting a result, identified by a request code.
startActivityForResult(intent, PLACE_PICKER_FLAG);
} catch (GooglePlayServicesRepairableException e) {
GooglePlayServicesUtil
.getErrorDialog(e.getConnectionStatusCode(), MainActivity.this, 0);
} catch (GooglePlayServicesNotAvailableException e) {
Toast.makeText(MainActivity.this, "Google Play Services is not available.",
Toast.LENGTH_LONG)
.show();
}
}
});
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == RESULT_OK) {
switch (requestCode) {
case PLACE_PICKER_FLAG:
Place place = PlacePicker.getPlace(this, data);
myLocation.setText(place.getName() + ", " + place.getAddress());
break;
}
}
}
// Ahh
#Override
protected void onStart() {
super.onStart();
mGoogleApiClient.connect();
}
#Override
protected void onStop() {
mGoogleApiClient.disconnect();
super.onStop();
}
private AdapterView.OnItemClickListener mAutocompleteClickListener
= new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
final PlacesAutoCompleteAdapter.PlaceAutocomplete item = mPlacesAdapter.getItem(position);
final String placeId = String.valueOf(item.placeId);
PendingResult<PlaceBuffer> placeResult = Places.GeoDataApi
.getPlaceById(mGoogleApiClient, placeId);
placeResult.setResultCallback(mUpdatePlaceDetailsCallback);
}
};
private ResultCallback<PlaceBuffer> mUpdatePlaceDetailsCallback
= new ResultCallback<PlaceBuffer>() {
#Override
public void onResult(PlaceBuffer places) {
if (!places.getStatus().isSuccess()) {
Log.e("place", "Place query did not complete. Error: " +
places.getStatus().toString());
return;
}
// Selecting the first object buffer.
final Place place = places.get(0);
}
};
}
PlacesAutoCompleteAdapter.java
public class PlacesAutoCompleteAdapter extends ArrayAdapter<PlacesAutoCompleteAdapter.PlaceAutocomplete> implements Filterable {
private static final String TAG = "PlaceAutocomplete";
/**
* Current results returned by this adapter.
*/
private ArrayList<PlaceAutocomplete> mResultList;
/**
* Handles autocomplete requests.
*/
private GoogleApiClient mGoogleApiClient;
/**
* The bounds used for Places Geo Data autocomplete API requests.
*/
private LatLngBounds mBounds;
/**
* The autocomplete filter used to restrict queries to a specific set of place types.
*/
private AutocompleteFilter mPlaceFilter;
/**
* Initializes with a resource for text rows and autocomplete query bounds.
*
* #see ArrayAdapter#ArrayAdapter(Context, int)
*/
public PlacesAutoCompleteAdapter(Context context, int resource, GoogleApiClient googleApiClient,
LatLngBounds bounds, AutocompleteFilter filter) {
super(context, resource);
mGoogleApiClient = googleApiClient;
mBounds = bounds;
mPlaceFilter = filter;
}
/**
* Sets the bounds for all subsequent queries.
*/
public void setBounds(LatLngBounds bounds) {
mBounds = bounds;
}
/**
* Returns the number of results received in the last autocomplete query.
*/
#Override
public int getCount() {
return mResultList.size();
}
/**
* Returns an item from the last autocomplete query.
*/
#Override
public PlaceAutocomplete getItem(int position) {
return mResultList.get(position);
}
/**
* Returns the filter for the current set of autocomplete results.
*/
#Override
public Filter getFilter() {
Filter filter = new Filter() {
#Override
protected FilterResults performFiltering(CharSequence constraint) {
FilterResults results = new FilterResults();
// Skip the autocomplete query if no constraints are given.
if (constraint != null) {
// Query the autocomplete API for the (constraint) search string.
mResultList = getAutocomplete(constraint);
if (mResultList != null) {
// The API successfully returned results.
results.values = mResultList;
results.count = mResultList.size();
}
}
return results;
}
#Override
protected void publishResults(CharSequence constraint, FilterResults results) {
if (results != null && results.count > 0) {
// The API returned at least one result, update the data.
notifyDataSetChanged();
} else {
// The API did not return any results, invalidate the data set.
notifyDataSetInvalidated();
}
}
};
return filter;
}
private ArrayList<PlaceAutocomplete> getAutocomplete(CharSequence constraint) {
if (mGoogleApiClient.isConnected()) {
Log.i(TAG, "Starting autocomplete query for: " + constraint);
// Submit the query to the autocomplete API and retrieve a PendingResult that will
// contain the results when the query completes.
PendingResult<AutocompletePredictionBuffer> results =
Places.GeoDataApi
.getAutocompletePredictions(mGoogleApiClient, constraint.toString(),
mBounds, mPlaceFilter);
// This method should have been called off the main UI thread. Block and wait for at most 60s
// for a result from the API.
AutocompletePredictionBuffer autocompletePredictions = results
.await(60, TimeUnit.SECONDS);
// Confirm that the query completed successfully, otherwise return null
final Status status = autocompletePredictions.getStatus();
if (!status.isSuccess()) {
Toast.makeText(getContext(), "Error contacting API: " + status.toString(),
Toast.LENGTH_SHORT).show();
Log.e(TAG, "Error getting autocomplete prediction API call: " + status.toString());
autocompletePredictions.release();
return null;
}
Log.i(TAG, "Query completed. Received " + autocompletePredictions.getCount()
+ " predictions.");
// Copy the results into our own data structure, because we can't hold onto the buffer.
// AutocompletePrediction objects encapsulate the API response (place ID and description).
Iterator<AutocompletePrediction> iterator = autocompletePredictions.iterator();
ArrayList resultList = new ArrayList<>(autocompletePredictions.getCount());
while (iterator.hasNext()) {
AutocompletePrediction prediction = iterator.next();
// Get the details of this prediction and copy it into a new PlaceAutocomplete object.
resultList.add(new PlaceAutocomplete(prediction.getPlaceId(),
prediction.getFullText(null)));
}
// Release the buffer now that all data has been copied.
autocompletePredictions.release();
return resultList;
}
Log.e(TAG, "Google API client is not connected for autocomplete query.");
return null;
}
/**
* Holder for Places Geo Data Autocomplete API results.
*/
public class PlaceAutocomplete {
public CharSequence placeId;
public CharSequence description;
PlaceAutocomplete(CharSequence placeId, CharSequence description) {
this.placeId = placeId;
this.description = description;
}
#Override
public String toString() {
return description.toString();
}
}
}

Related

Geofences are not being triggered (Broadcast Receiver)

Geofences are not being triggered using Broadcast Receiver. It was working with IntentService, however it wasn't working when the application is background.. I have changed to Broadcast receiver to make it work irrespective if the application is running in Foreground or background. After I changed it to Broadcast receiver by looking the below example, it stopped working even for Entry and Dwell...
https://github.com/googlesamples/android-play-location/tree/master/Geofencing/app/src/main/java/com/google/android/gms/location/sample/geofencing
Main Activity
public class MainActivity extends AppCompatActivity implements
GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener, ResultCallback<Status> {
private static final String TAG = "Geofence example";
private static final int MULTIPLE_PERMISSIONS = 1;
private static final int REQUEST_PERMISSIONS_REQUEST_CODE = 34;
private static final String ADDRESS_REQUESTED_KEY = "address-request-pending";
private static final String LOCATION_ADDRESS_KEY = "location-address";
String[] permissions = new String[]{
Manifest.permission.ACCESS_FINE_LOCATION,
Manifest.permission.READ_SMS,
Manifest.permission.RECEIVE_SMS,
Manifest.permission.SEND_SMS};
private GeofencingClient mGeofencingClient;
private PendingIntent mGeofencePendingIntent;
private Context mContext;
/**
* Provides access to the Fused Location Provider API.
*/
private FusedLocationProviderClient mFusedLocationClient;
/**
* Represents a geographical location.
*/
private Location mLastLocation;
/**
* Tracks whether the user has requested an address. Becomes true when the user requests an
* address and false when the address (or an error message) is delivered.
*/
private boolean mAddressRequested;
/**
* The formatted location address.
*/
private String mAddressOutput;
/**
* Receiver registered with this activity to get the response from FetchAddressIntentService.
*/
private AddressResultReceiver mResultReceiver;
/**
* Displays the location address.
*/
private TextView mLocationAddressTextView;
/**
* Visible while the address is being fetched.
*/
private ProgressBar mProgressBar;
/**
* Kicks off the request to fetch an address when pressed.
*/
private Button mFetchAddressButton;
private List<Geofence> mGeofenceList;
private GoogleApiClient mGoogleApiClient;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mResultReceiver = new AddressResultReceiver(new Handler());
mLocationAddressTextView = (TextView) findViewById(R.id.location_address_view);
mProgressBar = (ProgressBar) findViewById(R.id.progress_bar);
mFetchAddressButton = (Button) findViewById(R.id.fetch_address_button);
// Set defaults, then update using values stored in the Bundle.
mAddressRequested = false;
mAddressOutput = "";
mContext = this;
updateValuesFromBundle(savedInstanceState);
mGeofencingClient = LocationServices.getGeofencingClient(this);
//LatLng latLng = getLocationFromAddress(mContext, "517 Carrville Rd, Richmond Hill, ON L4C 6E5");
mFusedLocationClient = LocationServices.getFusedLocationProviderClient(this);
SmsReceiver.bindListener(new SMSListener() {
#Override
public void messageReceived(String messageText) {
//From the received text string you may do string operations to get the required OTP
//It depends on your SMS format
Log.d("Message", messageText);
Toast.makeText(MainActivity.this, "Message: " + messageText, Toast.LENGTH_LONG).show();
//startIntentService();
}
});
Log.d(GeofenceTransitionsIntentService.TAG, "OnCreate - Building google API client");
buildGoogleApiClient();
Log.d(GeofenceTransitionsIntentService.TAG, "OnCreate - Before permission check");
if (checkPermissions()) {
Log.d(GeofenceTransitionsIntentService.TAG, "OnCreate - inside Permission ");
getAddress();
}
Log.d(GeofenceTransitionsIntentService.TAG, "mGoogleApiClient = " + mGoogleApiClient);
//test_sendNotification("testing");
updateUIWidgets();
}
#Override
public void onStart() {
super.onStart();
Log.d(GeofenceTransitionsIntentService.TAG, "onStart - before Permission ");
if (!mGoogleApiClient.isConnecting() || !mGoogleApiClient.isConnected()) {
mGoogleApiClient.connect();
}
}
#Override
protected void onStop() {
super.onStop();
if (mGoogleApiClient.isConnecting() || mGoogleApiClient.isConnected()) {
mGoogleApiClient.disconnect();
}
}
private PendingIntent getGeofencePendingIntent() {
// Reuse the PendingIntent if we already have it.
if (mGeofencePendingIntent != null) {
return mGeofencePendingIntent;
}
Intent intent = new Intent(this, GeofenceBroadcastReceiver.class);
// We use FLAG_UPDATE_CURRENT so that we get the same pending intent back when
// calling addGeofences() and removeGeofences().
mGeofencePendingIntent = PendingIntent.getBroadcast(this, 0, intent, PendingIntent.
FLAG_UPDATE_CURRENT);
Log.d(GeofenceTransitionsIntentService.TAG, "getGeofencePendingIntent " + mGeofencePendingIntent);
return mGeofencePendingIntent;
}
/**
* Updates fields based on data stored in the bundle.
*/
private void updateValuesFromBundle(Bundle savedInstanceState) {
if (savedInstanceState != null) {
// Check savedInstanceState to see if the address was previously requested.
if (savedInstanceState.keySet().contains(ADDRESS_REQUESTED_KEY)) {
mAddressRequested = savedInstanceState.getBoolean(ADDRESS_REQUESTED_KEY);
}
// Check savedInstanceState to see if the location address string was previously found
// and stored in the Bundle. If it was found, display the address string in the UI.
if (savedInstanceState.keySet().contains(LOCATION_ADDRESS_KEY)) {
mAddressOutput = savedInstanceState.getString(LOCATION_ADDRESS_KEY);
displayAddressOutput();
}
}
}
/**
* Runs when user clicks the Fetch Address button.
*/
#SuppressWarnings("unused")
public void fetchAddressButtonHandler(View view) {
if (mLastLocation != null) {
Log.d(GeofenceTransitionsIntentService.TAG, "fetchAddressButtonHandler - mLastLocation " + mLastLocation);
startIntentService();
return;
}
// If we have not yet retrieved the user location, we process the user's request by setting
// mAddressRequested to true. As far as the user is concerned, pressing the Fetch Address button
// immediately kicks off the process of getting the address.
mAddressRequested = true;
updateUIWidgets();
}
/**
* Creates an intent, adds location data to it as an extra, and starts the intent service for
* fetching an address.
*/
private void startIntentService() {
// Create an intent for passing to the intent service responsible for fetching the address.
Intent intent = new Intent(this, FetchAddressIntentService.class);
// Pass the result receiver as an extra to the service.
intent.putExtra(Constants.RECEIVER, mResultReceiver);
// Pass the location data as an extra to the service.
intent.putExtra(Constants.LOCATION_DATA_EXTRA, mLastLocation);
// Start the service. If the service isn't already running, it is instantiated and started
// (creating a process for it if needed); if it is running then it remains running. The
// service kills itself automatically once all intents are processed.
startService(intent);
Log.d(GeofenceTransitionsIntentService.TAG, "startIntentService - addGeoFenceList " + (mGeofenceList != null));
addGeoFence();
}
/**
* Gets the address for the last known location.
*/
#SuppressWarnings("MissingPermission")
private void getAddress() {
Log.d(GeofenceTransitionsIntentService.TAG, "MainActivity - getAddress () ");
mFusedLocationClient.getLastLocation()
.addOnSuccessListener(this, new OnSuccessListener<Location>() {
#Override
public void onSuccess(Location location) {
if (location == null) {
Log.w(GeofenceTransitionsIntentService.TAG, "onSuccess:null");
return;
}
mLastLocation = location;
// Determine whether a Geocoder is available.
if (!Geocoder.isPresent()) {
showSnackbar(getString(R.string.no_geocoder_available));
return;
}
// If the user pressed the fetch address button before we had the location,
// this will be set to true indicating that we should kick off the intent
// service after fetching the location.
if (mAddressRequested) {
startIntentService();
}
}
})
.addOnFailureListener(this, new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
Log.w(TAG, "getLastLocation:onFailure", e);
}
});
}
private GeofencingRequest getGeofencingRequest() {
Log.d(GeofenceTransitionsIntentService.TAG, "MainActivity - getGeofencingRequest ");
GeofencingRequest.Builder builder = new GeofencingRequest.Builder();
builder.setInitialTrigger(GeofencingRequest.INITIAL_TRIGGER_ENTER | GeofencingRequest.INITIAL_TRIGGER_DWELL | GeofencingRequest.INITIAL_TRIGGER_EXIT);
builder.addGeofences(mGeofenceList);
return builder.build();
}
private void addGeoFence() {
Log.d(GeofenceTransitionsIntentService.TAG, "MainActivity - mGeofenceList () ");
mGeofenceList = new ArrayList<Geofence>();
for (Map.Entry<String, LatLng> entry : Constants.GEO_FENCE_LIST.entrySet()) {
mGeofenceList.add(new Geofence.Builder()
// Set the request ID of the geofence. This is a string to identify this
// geofence.
.setRequestId(entry.getKey())
// Set the circular region of this geofence.
.setCircularRegion(
entry.getValue().latitude,
entry.getValue().longitude,
Constants.GEOFENCE_RADIUS_IN_METERS
)
.setExpirationDuration(Geofence.NEVER_EXPIRE)
.setLoiteringDelay(6000)
.setTransitionTypes(Geofence.GEOFENCE_TRANSITION_ENTER |
Geofence.GEOFENCE_TRANSITION_EXIT | Geofence.GEOFENCE_TRANSITION_DWELL)
// Create the geofence.
.build());
}
Log.d(GeofenceTransitionsIntentService.TAG, "addGeoFenceList - mGeofenceList " + mGeofenceList);
//getGeofencingRequest();
if (!mGoogleApiClient.isConnected()) {
mGoogleApiClient.connect();
Toast.makeText(this, "not connected", Toast.LENGTH_SHORT).show();
return;
}
Log.d(GeofenceTransitionsIntentService.TAG, "addGeoFenceList - mGoogleApiClient " + mGoogleApiClient.isConnected());
try {
LocationServices.GeofencingApi.addGeofences(
mGoogleApiClient,
// The GeofenceRequest object.
getGeofencingRequest(),
// A pending intent that that is reused when calling removeGeofences(). This
// pending intent is used to generate an intent when a matched geofence
// transition is observed.
getGeofencePendingIntent()
).setResultCallback(this); // Result processed in onResult().
} catch (SecurityException securityException) {
// Catch exception generated if the app does not use ACCESS_FINE_LOCATION permission.
Log.d(GeofenceTransitionsIntentService.TAG, "addGeoFenceList - error " + securityException.getLocalizedMessage());
}
}
/**
* Updates the address in the UI.
*/
private void displayAddressOutput() {
mLocationAddressTextView.setText(mAddressOutput);
}
/**
* Toggles the visibility of the progress bar. Enables or disables the Fetch Address button.
*/
private void updateUIWidgets() {
if (mAddressRequested) {
mProgressBar.setVisibility(ProgressBar.VISIBLE);
mFetchAddressButton.setEnabled(false);
} else {
mProgressBar.setVisibility(ProgressBar.GONE);
mFetchAddressButton.setEnabled(true);
}
}
/**
* Shows a toast with the given text.
*/
private void showToast(String text) {
Toast.makeText(this, text, Toast.LENGTH_SHORT).show();
}
#Override
public void onSaveInstanceState(Bundle savedInstanceState) {
// Save whether the address has been requested.
savedInstanceState.putBoolean(ADDRESS_REQUESTED_KEY, mAddressRequested);
// Save the address string.
savedInstanceState.putString(LOCATION_ADDRESS_KEY, mAddressOutput);
super.onSaveInstanceState(savedInstanceState);
}
#Override
public void onConnected(#Nullable Bundle bundle) {
}
#Override
public void onConnectionSuspended(int i) {
}
#Override
public void onConnectionFailed(#NonNull ConnectionResult connectionResult) {
}
#Override
public void onResult(Status status) {
if (status.isSuccess()) {
Toast.makeText(
this,
"Geofences Added",
Toast.LENGTH_SHORT
).show();
} else {
// Get the status code for the error and log it using a user-friendly message.
Toast.makeText(
this,
"Geofences error - onResult",
Toast.LENGTH_SHORT
).show();
}
}
/**
* Shows a {#link Snackbar} using {#code text}.
*
* #param text The Snackbar text.
*/
private void showSnackbar(final String text) {
View container = findViewById(android.R.id.content);
if (container != null) {
Snackbar.make(container, text, Snackbar.LENGTH_LONG).show();
}
}
private void showSnackbar(final int mainTextStringId, final int actionStringId,
View.OnClickListener listener) {
Snackbar.make(findViewById(android.R.id.content),
getString(mainTextStringId),
Snackbar.LENGTH_INDEFINITE)
.setAction(getString(actionStringId), listener).show();
}
/**
* Return the current state of the permissions needed.
*/
private boolean checkPermissions() {
int result;
List<String> listPermissionsNeeded = new ArrayList<>();
for (String p : permissions) {
result = ContextCompat.checkSelfPermission(getApplicationContext(), p);
if (result != PackageManager.PERMISSION_GRANTED) {
listPermissionsNeeded.add(p);
}
}
if (!listPermissionsNeeded.isEmpty()) {
ActivityCompat.requestPermissions(this, listPermissionsNeeded.toArray(new String[listPermissionsNeeded.size()]), MULTIPLE_PERMISSIONS);
return false;
}
return true;
}
#Override
public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
switch (requestCode) {
case MULTIPLE_PERMISSIONS: {
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// permissions granted.
getAddress();
} else {
String perStr = "";
for (String per : permissions) {
perStr += "\n" + per;
}
// permissions list of don't granted permission
}
return;
}
}
}
protected synchronized void buildGoogleApiClient() {
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(LocationServices.API)
.build();
if (!mGoogleApiClient.isConnecting() || !mGoogleApiClient.isConnected()) {
mGoogleApiClient.connect();
}
Log.d(GeofenceTransitionsIntentService.TAG, "buildGoogleApiClient - mGoogleApiClient " + mGoogleApiClient);
}
private class AddressResultReceiver extends ResultReceiver {
AddressResultReceiver(Handler handler) {
super(handler);
}
#Override
protected void onReceiveResult(int resultCode, Bundle resultData) {
// Display the address string or an error message sent from the intent service.
mAddressOutput = resultData.getString(Constants.RESULT_DATA_KEY);
displayAddressOutput();
// Show a toast message if an address was found.
if (resultCode == Constants.SUCCESS_RESULT) {
showToast(getString(R.string.address_found));
}
Log.d(GeofenceTransitionsIntentService.TAG, "onReceiveResult - onReceiveResult ");
// Reset. Enable the Fetch Address button and stop showing the progress bar.
mAddressRequested = false;
updateUIWidgets();
}
}
}
JobIntentService:
public class GeofenceTransitionsIntentService extends JobIntentService {
protected static final String TAG = "geofence-transitions";
private static final int JOB_ID = 573;
#Override
public void onCreate() {
super.onCreate();
Log.e(TAG, "GeofenceTransitionsIntentService onCreate ");
}
#Override
protected void onHandleWork(#NonNull Intent intent) {
Log.e(TAG, "GeofenceTransitionsIntentService intent " + intent);
GeofencingEvent geofencingEvent = GeofencingEvent.fromIntent(intent);
if (geofencingEvent.hasError()) {
String errorMessage = "error";
Log.e(TAG, errorMessage);
return;
}
// Get the transition type.
int geofenceTransition = geofencingEvent.getGeofenceTransition();
String geofenceTransitionString = getTransitionString(geofenceTransition);
Log.e(TAG, "geofence_transition_geofenceTransition " + geofenceTransition);
// Test that the reported transition was of interest.
if (geofenceTransition == Geofence.GEOFENCE_TRANSITION_ENTER ||
geofenceTransition == Geofence.GEOFENCE_TRANSITION_DWELL || geofenceTransition == Geofence.GEOFENCE_TRANSITION_EXIT) {
// Get the geofences that were triggered. A single event can trigger multiple geofences.
List<Geofence> triggeringGeofences = geofencingEvent.getTriggeringGeofences();
// Get the transition details as a String.
String geofenceTransitionDetails = getGeofenceTransitionDetails(
this,
geofenceTransition,
triggeringGeofences
);
// Send notification and log the transition details.
sendNotification(geofenceTransitionDetails, geofenceTransitionString);
Log.i(TAG, geofenceTransitionDetails);
} else {
// Log the error.
Log.e(TAG, "geofence_transition_invalid_type" + geofenceTransition);
}
}
/**
* Convenience method for enqueuing work in to this service.
*/
public static void enqueueWork(Context context, Intent intent) {
enqueueWork(context, GeofenceTransitionsIntentService.class, JOB_ID, intent);
}
private String getGeofenceTransitionDetails(
Context context,
int geofenceTransition,
List<Geofence> triggeringGeofences) {
String geofenceTransitionString = getTransitionString(geofenceTransition);
// Get the Ids of each geofence that was triggered.
ArrayList triggeringGeofencesIdsList = new ArrayList();
for (Geofence geofence : triggeringGeofences) {
triggeringGeofencesIdsList.add(geofence.getRequestId());
}
String triggeringGeofencesIdsString = TextUtils.join(", ", triggeringGeofencesIdsList);
return geofenceTransitionString + ": " + triggeringGeofencesIdsString;
}
private String getTransitionString(int transitionType) {
switch (transitionType) {
case Geofence.GEOFENCE_TRANSITION_ENTER:
return "Entered";
case Geofence.GEOFENCE_TRANSITION_EXIT:
return "Exited";
case Geofence.GEOFENCE_TRANSITION_DWELL:
return "Dwell";
default:
return "unkwn";
}
}
private void sendNotification(String notificationDetails, String geofenceTransitionString) {
NotificationCompat.Builder mBuilder =
new NotificationCompat.Builder(getApplicationContext(), "notify_geofence");
Intent ii = new Intent(getApplicationContext(), MainActivity.class);
PendingIntent pendingIntent = PendingIntent.getActivity(getApplicationContext(), 0, ii, 0);
//Assign BigText style notification
NotificationCompat.BigTextStyle bigText = new NotificationCompat.BigTextStyle();
bigText.bigText(notificationDetails);
bigText.setSummaryText(geofenceTransitionString);
mBuilder.setContentIntent(pendingIntent);
mBuilder.setSmallIcon(R.mipmap.ic_launcher_round);
mBuilder.setContentTitle("Geofence notification");
mBuilder.setContentText(notificationDetails);
mBuilder.setPriority(Notification.PRIORITY_MAX);
mBuilder.setStyle(bigText);
NotificationManager mNotificationManager =
(NotificationManager) getApplicationContext().getSystemService(Context.NOTIFICATION_SERVICE);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
NotificationChannel channel = new NotificationChannel("notify_001",
"Channel human readable title",
NotificationManager.IMPORTANCE_DEFAULT);
mNotificationManager.createNotificationChannel(channel);
}
mNotificationManager.notify(new Random().nextInt(61) + 20, mBuilder.build());
}
}
Broadcast receiver:
public class GeofenceBroadcastReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
// Enqueues a JobIntentService passing the context and intent as parameters
GeofenceTransitionsIntentService.enqueueWork(context, intent);
}
}
Logs:
2018-10-30 12:40:02.850 24811-24811/com.lakshmiapps.findme D/geofence-transitions: fetchAddressButtonHandler - mLastLocation Location[fused 43.849304,-79.449305 hAcc=14 et=+2d21h3m43s23ms alt=161.3000030517578 vAcc=2 sAcc=??? bAcc=??? {Bundle[mParcelledData.dataSize=52]}]
2018-10-30 12:40:02.857 24811-24811/com.lakshmiapps.findme D/geofence-transitions: startIntentService - addGeoFenceList false
2018-10-30 12:40:02.857 24811-24811/com.lakshmiapps.findme D/geofence-transitions: MainActivity - mGeofenceList ()
2018-10-30 12:40:07.819 24811-24811/com.lakshmiapps.findme D/geofence-transitions: addGeoFenceList - mGeofenceList [Geofence[CIRCLE id:Ross Doan transitions:7 43.857670, -79.443370 1000m, resp=0s, dwell=6000ms, #-1], Geofence[CIRCLE id:Niagara falls transitions:7 43.078350, -79.081910 1000m, resp=0s, dwell=6000ms, #-1], Geofence[CIRCLE id:Taste of Malayalees transitions:7 43.635190, -79.622830 1000m, resp=0s, dwell=6000ms, #-1], Geofence[CIRCLE id:Home transitions:7 43.849301, -79.449306 1000m, resp=0s, dwell=6000ms, #-1], Geofence[CIRCLE id:Luv2Play transitions:7 43.855660, -79.430200 1000m, resp=0s, dwell=6000ms, #-1]]
2018-10-30 12:40:09.534 24811-24811/com.lakshmiapps.findme D/geofence-transitions: addGeoFenceList - mGoogleApiClient true
2018-10-30 12:40:09.534 24811-24811/com.lakshmiapps.findme D/geofence-transitions: MainActivity - getGeofencingRequest
2018-10-30 12:40:13.598 24811-24811/com.lakshmiapps.findme D/geofence-transitions: getGeofencePendingIntent PendingIntent{5fddab6: android.os.BinderProxy#47dc3b7}
2018-10-30 12:40:13.631 4938-5579/? I/GeofencerStateMachine: addGeofences called by com.lakshmiapps.findme
2018-10-30 12:40:13.631 4726-4773/? E/GmsLocationManagerService_FLP: [GeofencingApi] AddGeofence from com.lakshmiapps.findme and size = 5
2018-10-30 12:40:13.632 4726-4773/? D/GeofenceRequestInfo_FLP: removeExpiredGeofences - com.lakshmiapps.findme: 0 fences
2018-10-30 12:40:13.632 4726-4773/? E/GeofenceRequestManager_FLP: [GeofencingApi] AddGeofence 5 fences from com.lakshmiapps.findme
2018-10-30 12:40:13.632 4726-4773/? D/GeofenceRequestManager_FLP: 1540668973552 gpslastknowntime: 243443714 / nlplastknowntime: 248290794
2018-10-30 12:40:16.290 24811-24811/com.lakshmiapps.findme D/geofence-transitions: onReceiveResult - onReceiveResult
2018-10-30 12:44:08.692 4938-24505/? I/GeofencerStateMachine: removeGeofences: removeRequest=RemoveGeofencingRequest[REMOVE_BY_PENDING_INTENT pendingIntent=PendingIntent[creatorPackage=com.marriott.mrt], packageName=null]
Thanks,
Ramesh
Adding
<uses-permission android:name="android.permission.WAKE_LOCK" />
to AndroidManifest.xml seems to solve this issue in my case

How to debug Android code for an unexpected value?

I am new to Android and doing some basic activities on Android Studio. I have the following code which will redirect from LoginActivity to Navigation activity after successful login.
LoginActivity.java code:
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.annotation.TargetApi;
import android.content.Intent;
/**
* A login screen that offers login via email/password.
*/
public class LoginActivity extends AppCompatActivity implements LoaderCallbacks<Cursor> {
/**
* Id to identity READ_CONTACTS permission request.
*/
private static final int REQUEST_READ_CONTACTS = 0;
/**
* A dummy authentication store containing known user names and passwords.
* TODO: remove after connecting to a real authentication system.
*/
private static final String[] DUMMY_CREDENTIALS = new String[]{
"test#gmail.com:hello"
};
/**
* Keep track of the login task to ensure we can cancel it if requested.
*/
private UserLoginTask mAuthTask = null;
// UI references.
private AutoCompleteTextView mEmailView;
private EditText mPasswordView;
private View mProgressView;
private View mLoginFormView;
private boolean loginPassed;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_login);
// Set up the login form.
mEmailView = (AutoCompleteTextView) findViewById(R.id.email);
populateAutoComplete();
mPasswordView = (EditText) findViewById(R.id.password);
Button mEmailSignInButton = (Button) findViewById(R.id.email_sign_in_button);
mEmailSignInButton.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View view) {
attemptLogin();
}
});
mLoginFormView = findViewById(R.id.login_form);
mProgressView = findViewById(R.id.login_progress);
}
private void populateAutoComplete() {
if (!mayRequestContacts()) {
return;
}
getLoaderManager().initLoader(0, null, this);
}
private boolean mayRequestContacts() {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
return true;
}
if (checkSelfPermission(READ_CONTACTS) == PackageManager.PERMISSION_GRANTED) {
return true;
}
if (shouldShowRequestPermissionRationale(READ_CONTACTS)) {
Snackbar.make(mEmailView, R.string.permission_rationale, Snackbar.LENGTH_INDEFINITE)
.setAction(android.R.string.ok, new View.OnClickListener() {
#Override
#TargetApi(Build.VERSION_CODES.M)
public void onClick(View v) {
requestPermissions(new String[]{READ_CONTACTS}, REQUEST_READ_CONTACTS);
}
});
} else {
requestPermissions(new String[]{READ_CONTACTS}, REQUEST_READ_CONTACTS);
}
return false;
}
/**
* Callback received when a permissions request has been completed.
*/
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions,
#NonNull int[] grantResults) {
if (requestCode == REQUEST_READ_CONTACTS) {
if (grantResults.length == 1 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
populateAutoComplete();
}
}
}
/**
* Attempts to sign in or register the account specified by the login form.
* If there are form errors (invalid email, missing fields, etc.), the
* errors are presented and no actual login attempt is made.
*/
private void attemptLogin() {
if (mAuthTask != null) {
return;
}
// Reset errors.
mEmailView.setError(null);
mPasswordView.setError(null);
// Store values at the time of the login attempt.
String email = mEmailView.getText().toString();
String password = mPasswordView.getText().toString();
boolean cancel = false;
View focusView = null;
// Check for a valid email address.
if (TextUtils.isEmpty(email)) {
mEmailView.setError(getString(R.string.error_field_required));
focusView = mEmailView;
cancel = true;
} else if (!isEmailValid(email)) {
mEmailView.setError(getString(R.string.error_invalid_email));
focusView = mEmailView;
cancel = true;
}
// Check for a valid email address.
if(!cancel) {
if (TextUtils.isEmpty(password)) {
mPasswordView.setError(getString(R.string.error_field_required));
focusView = mPasswordView;
cancel = true;
} else if (!isPasswordValid(password)) {
mPasswordView.setError(getString(R.string.error_invalid_password));
focusView = mPasswordView;
cancel = true;
}
}
if (cancel) {
// There was an error; don't attempt login and focus the first
// form field with an error.
focusView.requestFocus();
} else {
// Show a progress spinner, and kick off a background task to
// perform the user login attempt.
showProgress(true);
mAuthTask = new UserLoginTask(email, password);
mAuthTask.execute((Void) null);
if(loginPassed) {
Intent intent = new Intent(this, NavigationActivity.class);
intent.putExtra(EXTRA_MESSAGE, "Test");
startActivity(intent);
}
}
}
private boolean isEmailValid(String email) {
//TODO: Replace this with your own logic
return email.contains("#");
}
private boolean isPasswordValid(String password) {
//TODO: Replace this with your own logic
return password.length() > 4;
}
/**
* Shows the progress UI and hides the login form.
*/
#TargetApi(Build.VERSION_CODES.HONEYCOMB_MR2)
private void showProgress(final boolean show) {
// On Honeycomb MR2 we have the ViewPropertyAnimator APIs, which allow
// for very easy animations. If available, use these APIs to fade-in
// the progress spinner.
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB_MR2) {
int shortAnimTime = getResources().getInteger(android.R.integer.config_shortAnimTime);
mLoginFormView.setVisibility(show ? View.GONE : View.VISIBLE);
mLoginFormView.animate().setDuration(shortAnimTime).alpha(
show ? 0 : 1).setListener(new AnimatorListenerAdapter() {
#Override
public void onAnimationEnd(Animator animation) {
mLoginFormView.setVisibility(show ? View.GONE : View.VISIBLE);
}
});
mProgressView.setVisibility(show ? View.VISIBLE : View.GONE);
mProgressView.animate().setDuration(shortAnimTime).alpha(
show ? 1 : 0).setListener(new AnimatorListenerAdapter() {
#Override
public void onAnimationEnd(Animator animation) {
mProgressView.setVisibility(show ? View.VISIBLE : View.GONE);
}
});
} else {
// The ViewPropertyAnimator APIs are not available, so simply show
// and hide the relevant UI components.
mProgressView.setVisibility(show ? View.VISIBLE : View.GONE);
mLoginFormView.setVisibility(show ? View.GONE : View.VISIBLE);
}
}
#Override
public Loader<Cursor> onCreateLoader(int i, Bundle bundle) {
return new CursorLoader(this,
// Retrieve data rows for the device user's 'profile' contact.
Uri.withAppendedPath(ContactsContract.Profile.CONTENT_URI,
ContactsContract.Contacts.Data.CONTENT_DIRECTORY), ProfileQuery.PROJECTION,
// Select only email addresses.
ContactsContract.Contacts.Data.MIMETYPE +
" = ?", new String[]{ContactsContract.CommonDataKinds.Email
.CONTENT_ITEM_TYPE},
// Show primary email addresses first. Note that there won't be
// a primary email address if the user hasn't specified one.
ContactsContract.Contacts.Data.IS_PRIMARY + " DESC");
}
#Override
public void onLoadFinished(Loader<Cursor> cursorLoader, Cursor cursor) {
List<String> emails = new ArrayList<>();
cursor.moveToFirst();
while (!cursor.isAfterLast()) {
emails.add(cursor.getString(ProfileQuery.ADDRESS));
cursor.moveToNext();
}
addEmailsToAutoComplete(emails);
}
#Override
public void onLoaderReset(Loader<Cursor> cursorLoader) {
}
private void addEmailsToAutoComplete(List<String> emailAddressCollection) {
//Create adapter to tell the AutoCompleteTextView what to show in its dropdown list.
ArrayAdapter<String> adapter =
new ArrayAdapter<>(LoginActivity.this,
android.R.layout.simple_dropdown_item_1line, emailAddressCollection);
mEmailView.setAdapter(adapter);
}
private interface ProfileQuery {
String[] PROJECTION = {
ContactsContract.CommonDataKinds.Email.ADDRESS,
ContactsContract.CommonDataKinds.Email.IS_PRIMARY,
};
int ADDRESS = 0;
int IS_PRIMARY = 1;
}
/**
* Represents an asynchronous login/registration task used to authenticate
* the user.
*/
public class UserLoginTask extends AsyncTask<Void, Void, Boolean> {
private final String mEmail;
private final String mPassword;
UserLoginTask(String email, String password) {
mEmail = email;
mPassword = password;
}
#Override
protected Boolean doInBackground(Void... params) {
// TODO: attempt authentication against a network service.
try {
// Simulate network access.
Thread.sleep(2000);
} catch (InterruptedException e) {
return false;
}
for (String credential : DUMMY_CREDENTIALS) {
String[] pieces = credential.split(":");
if (pieces[0].equals(mEmail)) {
// Account exists, return true if the password matches.
return pieces[1].equals(mPassword);
}
}
// TODO: register the new account here.
return false;
}
#Override
protected void onPostExecute(final Boolean success) {
mAuthTask = null;
showProgress(false);
loginPassed = success;
if (success) {
finish();
} else {
Toast toast=Toast.makeText(getApplicationContext(),"Please enter valid Email and Password",Toast.LENGTH_SHORT);
toast.setMargin(100,50);
toast.show();
/*mPasswordView.setError(getString(R.string.error_incorrect_password));
mPasswordView.requestFocus();*/
mEmailView.requestFocus();
}
}
#Override
protected void onCancelled() {
mAuthTask = null;
showProgress(false);
}
}
}
loginPassed variable is set to true if the credentials are correct else it will be false.
If I remove if condition in the above program if will redirect to NavigationActivity properly but with if condition in place, it will simple close the application.
Not sure where am I going wrong.
First you have to define a global variable loginPassed
Boolean loginPassed;
Then you have to execute the AsyncTask for check the user credentials like this -
new UserLoginTask().execute();
Now in AsyncTask we will check the user's credentials and make operations accordingly
class UserLoginTask extends AsyncTask<Void, Integer, String>
{
String TAG = getClass().getSimpleName();
protected void onPreExecute (){
super.onPreExecute();
Log.d(TAG + " PreExceute","On pre Exceute......");
}
protected String doInBackground(Void...arg0) {
Log.d(TAG + " DoINBackGround","On doInBackground...");
if(validate(email, password))
loginPassed = true;
else
loginPassed = false;
return "";
}
protected void onProgressUpdate(Integer...a){
super.onProgressUpdate(a);
Log.d(TAG + " onProgressUpdate", "You are in progress update ... " + a[0]);
}
protected void onPostExecute(String result) {
super.onPostExecute(result);
Log.d(TAG + " onPostExecute", "" + result);
if(loginPassed){
Intent intent = new Intent(this, NavigationActivity.class);
intent.putExtra(EXTRA_MESSAGE, "Jefry");
startActivity(intent);
}else{
// There was an error; don't attempt login and focus the first
// form field with an error.
focusView.requestFocus();
}
}
}
You declare the loginPassed var, but never place values in it.
When you create a boolean var the default value is false, them the runtime never enter in this if(loginPassed)

How to display sqlite database in the form of cards in android?

This is my code how i store the data in sqlite database.Now i want that all the data from the database display in the form of cards in other activity suppose when i press showdb button then the data displayed.
public class ConfigureNode extends AppCompatActivity implements
LocationListener,
GoogleApiClient.ConnectionCallbacks,
GoogleApiClient.OnConnectionFailedListener {
private static final String TAG = "LocationActivity";
private static final long INTERVAL = 1000 * 10;
private static final long FASTEST_INTERVAL = 1000 * 5;
private SQLiteDatabase db;
Button btnFusedLocation, btnPushData;
TextView tvLocation;
EditText Latval, LongVal,NodeId;
LocationRequest mLocationRequest;
GoogleApiClient mGoogleApiClient;
Location mCurrentLocation;
String mLastUpdateTime;
public String DBPath;
public static String DBName = "sample";
public static final int version = '1';
public static Context currentContext;
protected void createLocationRequest() {
mLocationRequest = new LocationRequest();
mLocationRequest.setInterval(INTERVAL);
mLocationRequest.setFastestInterval(FASTEST_INTERVAL);
mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
createDatabase();
Log.d(TAG, "onCreate ...............................");
//show error dialog if GoolglePlayServices not available
if (!isGooglePlayServicesAvailable()) {
finish();
}
createLocationRequest();
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addApi(LocationServices.API)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.build();
setContentView(R.layout.activity_configure_node);
tvLocation = (TextView) findViewById(R.id.tvLocation);
btnFusedLocation = (Button) findViewById(R.id.btnShowLocation);
Latval = (EditText) findViewById(R.id.latVal);
LongVal = (EditText) findViewById(R.id.longVal);
NodeId=(EditText)findViewById(R.id.NodeId);
btnPushData = (Button) findViewById(R.id.btnPushLoc);
btnPushData.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
insertIntoDB();
}
});
btnFusedLocation.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
updateUI();
}
});
}
#Override
public void onStart() {
super.onStart();
Log.d(TAG, "onStart fired ..............");
mGoogleApiClient.connect();
}
#Override
public void onStop() {
super.onStop();
Log.d(TAG, "onStop fired ..............");
mGoogleApiClient.disconnect();
Log.d(TAG, "isConnected ...............: " + mGoogleApiClient.isConnected());
}
private boolean isGooglePlayServicesAvailable() {
int status = GooglePlayServicesUtil.isGooglePlayServicesAvailable(this);
if (ConnectionResult.SUCCESS == status) {
return true;
} else {
GooglePlayServicesUtil.getErrorDialog(status, this, 0).show();
return false;
}
}
#Override
public void onConnected(Bundle bundle) {
Log.d(TAG, "onConnected - isConnected ...............: " + mGoogleApiClient.isConnected());
startLocationUpdates();
}
protected void startLocationUpdates() {
if (ActivityCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
// TODO: Consider calling
// ActivityCompat#requestPermissions
// here to request the missing permissions, and then overriding
// public void onRequestPermissionsResult(int requestCode, String[] permissions,
// int[] grantResults)
// to handle the case where the user grants the permission. See the documentation
// for ActivityCompat#requestPermissions for more details.
return;
}
PendingResult<Status> pendingResult = LocationServices.FusedLocationApi.requestLocationUpdates(
mGoogleApiClient, mLocationRequest, (com.google.android.gms.location.LocationListener) this);
Log.d(TAG, "Location update started ..............: ");
}
#Override
public void onConnectionSuspended(int i) {
}
#Override
public void onConnectionFailed(ConnectionResult connectionResult) {
Log.d(TAG, "Connection failed: " + connectionResult.toString());
}
#Override
public void onLocationChanged(Location location) {
Log.d(TAG, "Firing onLocationChanged..............................................");
mCurrentLocation = location;
mLastUpdateTime = DateFormat.getTimeInstance().format(new Date());
updateUI();
}
private void updateUI() {
Log.d(TAG, "UI update initiated .............");
if (null != mCurrentLocation) {
String lat = String.valueOf(mCurrentLocation.getLatitude());
String lng = String.valueOf(mCurrentLocation.getLongitude());
tvLocation.setText("At Time: " + mLastUpdateTime + "\n" +
"Latitude: " + lat + "\n" +
"Longitude: " + lng + "\n" +
"Accuracy: " + mCurrentLocation.getAccuracy() + "\n" +
"Provider: " + mCurrentLocation.getProvider());
LongVal.setText(lng);
Latval.setText(lat);
} else {
Toast.makeText(ConfigureNode.this,"location not detected ",Toast.LENGTH_SHORT).show();
}
}
#Override
protected void onPause() {
super.onPause();
stopLocationUpdates();
}
protected void stopLocationUpdates() {
LocationServices.FusedLocationApi.removeLocationUpdates(
mGoogleApiClient, (LocationListener) this);
Log.d(TAG, "Location update stopped .......................");
}
#Override
public void onResume() {
super.onResume();
if (mGoogleApiClient.isConnected()) {
startLocationUpdates();
Log.d(TAG, "Location update resumed .....................");
}
}
protected void createDatabase(){
db=openOrCreateDatabase("PersonDB", Context.MODE_PRIVATE, null);
db.execSQL("CREATE TABLE IF NOT EXISTS persons(id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, name VARCHAR,address VARCHAR,NodeId VARCHAR);");
}
protected void insertIntoDB(){
String name = Latval.getText().toString().trim();
String add = LongVal.getText().toString().trim();
String Nodid=NodeId.getText().toString().trim();
if(name.equals("") || add.equals("")||Nodid.equals("")){
Toast.makeText(getApplicationContext(),"Please fill all fields", Toast.LENGTH_LONG).show();
return;
}
String query = "INSERT INTO persons (name,address,NodeId) VALUES('"+name+"', '"+add+"', '"+Nodid+"');";
db.execSQL(query);
Toast.makeText(getApplicationContext(),"Saved Successfully", Toast.LENGTH_LONG).show();
}
}
From what I can see you have added data to your database. You now need to retrieve data from your database via a query.
Imagine I was storing a bunch of templates in a database, and then want to display all of these in cards or a list.
What I tend to do is create an object, such as Template.java. This object will have getter and setter methods.
I then perform a query on the database fetching all data in there and assigning each one to these Template objects.
I can then create a custom list view for example to display them in a list of cards. To create this custom list I give it an array of all the Template objects I have fetched from the database and in this custom adapter class set the values and styling.
Here are some coding examples:
Fetching from database and creating custom list:
public void populateListView() {
templates.clear();
final String query = "SELECT * FROM tableTemplates ";
Cursor c1 = db.selectQuery(query);
if (c1 != null && c1.getCount() != 0) {
if (c1.moveToFirst()) {
do {
template = new Template();
template.setTemplateName(c1.getString(c1
.getColumnIndex("templateName")));
template.setBuildingNumber(c1.getString(c1
.getColumnIndex("buildingNumber")));
template.setGroupNumber(c1.getString(c1
.getColumnIndex("groupNumber")));
template.setRemote(c1.getString(c1
.getColumnIndex("remote")));
template.setFrequency(c1.getString(c1
.getColumnIndex("frequency")));
templates.add(template);
} while (c1.moveToNext());
}
}
c1.close();
adapter = new TemplateCustomAdapter(
getApplicationContext(), templates);
presetList.setAdapter(adapter);
adapter.notifyDataSetChanged();
}
The custom list adapter:
public class TemplateCustomAdapter extends BaseAdapter {
private Context context;
private ArrayList<Template> templateList;
public TemplateCustomAdapter(Context context, ArrayList<Template> list) {
this.context = context;
templateList = list;
}
#Override
public int getCount() {
return templateList.size();
}
#Override
public Object getItem(int position) {
return templateList.get(position);
}
#Override
public long getItemId(int position) {
return position;
}
/**
* Here we inflate our layout with the view row xml file.
* What the file does is set the look of each row of the list view.
* */
#Override
public View getView(int position, View convertView, ViewGroup arg2) {
final Template template = templateList.get(position);
if (convertView == null) {
LayoutInflater inflater = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = inflater.inflate(R.layout.view_row, null);
}
/**
* Set the layout components with the object variable and return to the activity/fragment.
* */
final TextView templateName = (TextView) convertView.findViewById(R.id.name);
templateName.setText(template.getTemplateName());
return convertView;
}
}
This may help with the list adapter

Android app Register with SQL

I'm currently making a quiz app, and I want to add a feature where users can register, and then use SQL to store this. I have followed this YouTube tutorial:
https://www.youtube.com/watch?v=NT1qxmqH1eM
However, when I have register a new user and try to login with this, it says "invalid password". So the data isn't being stored...
Home.java
Looks like this:
The code for Home.java is:
public class Home extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_home);
Button btnSignIn = (Button) findViewById(R.id.buttonSignIN);
Button btnSignUp = (Button) findViewById(R.id.buttonSignUP);
btnSignIn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intentSignIN = new Intent(Home.this, LoginActivity.class);
startActivity(intentSignIN);
}
});
btnSignUp.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intentSignUP = new Intent(Home.this, Register.class);
startActivity(intentSignUP);
}
});
}
}
Pressing the SIGN UP button takes you to Register.java which looks like this:
The code for Register.java is:
public class Register extends Activity {
LoginDataBaseAdapter helper = new LoginDataBaseAdapter(this);
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_register);
}
public void onRegisterClick(View v)
{
if (v.getId() == R.id.register_complete) //changed from xml in activity_home which has id buttonSignUP
{
EditText email = (EditText)findViewById(R.id.editEmail);
EditText pass1 = (EditText)findViewById(R.id.editTextPassword);
EditText pass2 = (EditText)findViewById(R.id.editTextConfirmPassword);
String emailstr = email.getText().toString();
String pass1str = pass1.getText().toString();
String pass2str = pass2.getText().toString();
if (!pass1str.equals(pass2str))
{
//popup message
Toast pass = Toast.makeText(Register.this, "Passwords don't match!", Toast.LENGTH_SHORT);
pass.show();
}
else
{
//insert input in database
UserInfo u = new UserInfo();
u.setEmail(emailstr);
u.setPass(pass1str);
helper.insertUserInfo(u);
}
Intent registerIntent = new Intent(Register.this, Home.class);
startActivity(registerIntent);
}
}
}
I'm able to enter the details, click "complete registration" which then takes me back to Home.java. However, when I try to log in with a newly registered user, it's says that password is unknown. I guess it means the register data isn't then properly stored, but I can't figure out where I've gone wrong.
LoginActivity.java
I have used the template provided by Android Studio so most of this code isn't written by me. However, I have commented the code that I have added to it in order to create this database:
public class LoginActivity extends AppCompatActivity implements LoaderCallbacks<Cursor> {
LoginDataBaseAdapter helper = new LoginDataBaseAdapter(this); //FOR THE REGISTER DATABASE
/**
* Id to identity READ_CONTACTS permission request.
*/
private static final int REQUEST_READ_CONTACTS = 0;
/**
* A dummy authentication store containing known user names and passwords.
* TODO: remove after connecting to a real authentication system.
*/
private static final String[] DUMMY_CREDENTIALS = new String[]{
"foo#example.com:hello", "bar#example.com:world"
};
private User myUser;
/**
* Keep track of the login task to ensure we can cancel it if requested.
*/
private UserLoginTask mAuthTask = null;
// UI references.
private AutoCompleteTextView mEmailView;
private EditText mPasswordView;
private View mProgressView;
private View mLoginFormView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_login);
// Set up the login form.
mEmailView = (AutoCompleteTextView) findViewById(R.id.email);
populateAutoComplete();
mPasswordView = (EditText) findViewById(R.id.password);
mPasswordView.setOnEditorActionListener(new TextView.OnEditorActionListener() {
#Override
public boolean onEditorAction(TextView textView, int id, KeyEvent keyEvent) {
if (id == R.id.login || id == EditorInfo.IME_NULL) {
attemptLogin();
return true;
}
return false;
}
});
Button mEmailSignInButton = (Button) findViewById(R.id.email_sign_in_button);
mEmailSignInButton.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View view) {
attemptLogin();
}
});
mLoginFormView = findViewById(R.id.login_form);
mProgressView = findViewById(R.id.login_progress);
}
public void onRegisterClick(View v){ //FOR THE REGISTER DATABASE (this method)
EditText a = (EditText)findViewById(R.id.email);
String str = a.getText().toString();
EditText b = (EditText)findViewById(R.id.password);
String pass = b.getText().toString();
String password = helper.searchPass(str);
if (pass.equals(password)){
Intent i = new Intent(LoginActivity.this, Play.class);
i.putExtra("Username", str);
startActivity(i);
}
else {
Toast temp = Toast.makeText(LoginActivity.this, "Username and password don't match!", Toast.LENGTH_SHORT);
temp.show();
}
}
private void populateAutoComplete() {
if (!mayRequestContacts()) {
return;
}
getLoaderManager().initLoader(0, null, this);
}
private boolean mayRequestContacts() {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
return true;
}
if (checkSelfPermission(READ_CONTACTS) == PackageManager.PERMISSION_GRANTED) {
return true;
}
if (shouldShowRequestPermissionRationale(READ_CONTACTS)) {
Snackbar.make(mEmailView, R.string.permission_rationale, Snackbar.LENGTH_INDEFINITE)
.setAction(android.R.string.ok, new View.OnClickListener() {
#Override
#TargetApi(Build.VERSION_CODES.M)
public void onClick(View v) {
requestPermissions(new String[]{READ_CONTACTS}, REQUEST_READ_CONTACTS);
}
});
} else {
requestPermissions(new String[]{READ_CONTACTS}, REQUEST_READ_CONTACTS);
}
return false;
}
/**
* Callback received when a permissions request has been completed.
*/
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions,
#NonNull int[] grantResults) {
if (requestCode == REQUEST_READ_CONTACTS) {
if (grantResults.length == 1 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
populateAutoComplete();
}
}
}
/**
* Attempts to sign in or register the account specified by the login form.
* If there are form errors (invalid email, missing fields, etc.), the
* errors are presented and no actual login attempt is made.
*/
private void attemptLogin() {
if (mAuthTask != null) {
return;
}
// Reset errors.
mEmailView.setError(null);
mPasswordView.setError(null);
// Store values at the time of the login attempt.
String email = mEmailView.getText().toString();
String password = mPasswordView.getText().toString();
boolean cancel = false;
View focusView = null;
// Check for a valid password, if the user entered one.
if (!TextUtils.isEmpty(password) && !isPasswordValid(password)) {
mPasswordView.setError(getString(R.string.error_invalid_password));
focusView = mPasswordView;
cancel = true;
}
// Check for a valid email address.
if (TextUtils.isEmpty(email)) {
mEmailView.setError(getString(R.string.error_field_required));
focusView = mEmailView;
cancel = true;
} else if (!isEmailValid(email)) {
mEmailView.setError(getString(R.string.error_invalid_email));
focusView = mEmailView;
cancel = true;
}
if (cancel) {
// There was an error; don't attempt login and focus the first
// form field with an error.
focusView.requestFocus();
} else {
// Show a progress spinner, and kick off a background task to
// perform the user login attempt.
showProgress(true);
mAuthTask = new UserLoginTask(email, password);
mAuthTask.execute((Void) null);
}
}
private boolean isEmailValid(String email) {
//TODO: Replace this with your own logic
return email.contains("#");
}
private boolean isPasswordValid(String password) {
//TODO: Replace this with your own logic
return password.length() > 4;
}
/**
* Shows the progress UI and hides the login form.
*/
#TargetApi(Build.VERSION_CODES.HONEYCOMB_MR2)
private void showProgress(final boolean show) {
// On Honeycomb MR2 we have the ViewPropertyAnimator APIs, which allow
// for very easy animations. If available, use these APIs to fade-in
// the progress spinner.
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB_MR2) {
int shortAnimTime = getResources().getInteger(android.R.integer.config_shortAnimTime);
mLoginFormView.setVisibility(show ? View.GONE : View.VISIBLE);
mLoginFormView.animate().setDuration(shortAnimTime).alpha(
show ? 0 : 1).setListener(new AnimatorListenerAdapter() {
#Override
public void onAnimationEnd(Animator animation) {
mLoginFormView.setVisibility(show ? View.GONE : View.VISIBLE);
}
});
mProgressView.setVisibility(show ? View.VISIBLE : View.GONE);
mProgressView.animate().setDuration(shortAnimTime).alpha(
show ? 1 : 0).setListener(new AnimatorListenerAdapter() {
#Override
public void onAnimationEnd(Animator animation) {
mProgressView.setVisibility(show ? View.VISIBLE : View.GONE);
}
});
} else {
// The ViewPropertyAnimator APIs are not available, so simply show
// and hide the relevant UI components.
mProgressView.setVisibility(show ? View.VISIBLE : View.GONE);
mLoginFormView.setVisibility(show ? View.GONE : View.VISIBLE);
}
}
#Override
public Loader<Cursor> onCreateLoader(int i, Bundle bundle) {
return new CursorLoader(this,
// Retrieve data rows for the device user's 'profile' contact.
Uri.withAppendedPath(ContactsContract.Profile.CONTENT_URI,
ContactsContract.Contacts.Data.CONTENT_DIRECTORY), ProfileQuery.PROJECTION,
// Select only email addresses.
ContactsContract.Contacts.Data.MIMETYPE +
" = ?", new String[]{ContactsContract.CommonDataKinds.Email
.CONTENT_ITEM_TYPE},
// Show primary email addresses first. Note that there won't be
// a primary email address if the user hasn't specified one.
ContactsContract.Contacts.Data.IS_PRIMARY + " DESC");
}
#Override
public void onLoadFinished(Loader<Cursor> cursorLoader, Cursor cursor) {
List<String> emails = new ArrayList<>();
cursor.moveToFirst();
while (!cursor.isAfterLast()) {
emails.add(cursor.getString(ProfileQuery.ADDRESS));
cursor.moveToNext();
}
addEmailsToAutoComplete(emails);
}
#Override
public void onLoaderReset(Loader<Cursor> cursorLoader) {
}
private void addEmailsToAutoComplete(List<String> emailAddressCollection) {
//Create adapter to tell the AutoCompleteTextView what to show in its dropdown list.
ArrayAdapter<String> adapter =
new ArrayAdapter<>(LoginActivity.this,
android.R.layout.simple_dropdown_item_1line, emailAddressCollection);
mEmailView.setAdapter(adapter);
}
private interface ProfileQuery {
String[] PROJECTION = {
ContactsContract.CommonDataKinds.Email.ADDRESS,
ContactsContract.CommonDataKinds.Email.IS_PRIMARY,
};
int ADDRESS = 0;
int IS_PRIMARY = 1;
}
/**
* Represents an asynchronous login/registration task used to authenticate
* the user.
*/
public class UserLoginTask extends AsyncTask<Void, Void, Boolean> {
private final String mEmail;
private final String mPassword;
UserLoginTask(String email, String password) {
mEmail = email;
mPassword = password;
}
#Override
protected Boolean doInBackground(Void... params) {
DBTools dbTools=null;
// TODO: attempt authentication against a network service.
try {
// Simulate network access.
Thread.sleep(2000);
} catch (InterruptedException e) {
return false;
}
for (String credential : DUMMY_CREDENTIALS) {
String[] pieces = credential.split(":");
if (pieces[0].equals(mEmail)) {
// Account exists, return true if the password matches.
return pieces[1].equals(mPassword);
}
}
// TODO: register the new account here.
return false; //changed
}
#Override
protected void onPostExecute(final Boolean success) {
mAuthTask = null;
showProgress(false);
if (success) { ///if successful login
finish();
Intent intent = new Intent(LoginActivity.this, MainActivity.class);
LoginActivity.this.startActivity(intent);
} else {
mPasswordView.setError(getString(R.string.error_incorrect_password));
mPasswordView.requestFocus();
}
}
#Override
protected void onCancelled() {
mAuthTask = null;
showProgress(false);
}
}
}
LoginDataBaseAdapter.java
public class LoginDataBaseAdapter extends SQLiteOpenHelper {
private static final int DATABASE_VERSION = 1;
private static final String DATABASE_NAME = "userinfo.db";
private static final String TABLE_NAME = "userinfo";
private static final String COLUMN_EMAIL = "email";
private static final String COLUMN_PASS = "pass";
SQLiteDatabase db;
private static final String TABLE_CREATE = "create table userinfo (email text not null, pass text not null);";
public LoginDataBaseAdapter(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
#Override
public void onCreate(SQLiteDatabase db) {
db.execSQL(TABLE_CREATE);
this.db = db;
}
public void insertUserInfo(UserInfo u) {
db = this.getWritableDatabase();
ContentValues values = new ContentValues();
values.put(COLUMN_EMAIL, u.getEmail());
values.put(COLUMN_PASS, u.getPass());
db.insert(TABLE_NAME, null, values);
db.close();
}
public String searchPass(String email) {
db = this.getReadableDatabase();
String query = "select email, pass from " + TABLE_NAME;
Cursor cursor = db.rawQuery(query, null);
String a, b;
b = "not found";
if(cursor.moveToFirst()) {
do{
a = cursor.getString(0);
b = cursor.getString(1);
if(a.equals(email)) {
b = cursor.getString(1);
break;
}
}
while(cursor.moveToNext());
}
return b;
}
#Override
public void onUpgrade (SQLiteDatabase db, int oldVersion, int newVersion) {
String query = "DROP TABLE IF EXISTS "+TABLE_NAME;
db.execSQL(query);
this.onCreate(db);
}
}
UserInfo.java
public class UserInfo {
String email, pass;
public void setEmail(String email)
{
this.email = email;
}
public String getEmail()
{
return this.email;
}
public void setPass(String pass)
{
this.pass = pass;
}
public String getPass()
{
return this.pass;
}
}
I'm new to programming, and I'm doing this for a school project, so a detailed explanation would be helpful. Thanks!
I do not have a specfic answer for your issue but one thing that would help is to check the SQLite database for the username and password after inserting the values. By checking the the values on the database you can see if the values that were recorded for the username. One easy way of checking the database is by using stetho which enables chrome developer tools, among them the ability to see the database.
To add stetho to your app, just add compile 'com.facebook.stetho:stetho:1.4.2' to your dependencies in the app gradle file.
And once the app loads gchrome://inspect/#devices to show the devices and then select your app.
After that you can see the contents of the database

Google map object showing NPE on older devices

I am using this piece of code to initialize the google map object:
googleMap = ( (SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map)).getMap();
It works fine on newer devices , but shows NPE on older devices.Please help!!
This is how I solved the NPE of google maps.
public class WBMapFragment extends LogoBaseFragment implements GooglePlayServicesClient.ConnectionCallbacks, GooglePlayServicesClient.OnConnectionFailedListener {
private GoogleMap map;
private MapView mapView;
#Inject
private MapManager mapManager;
/*
* Define a request code to send to Google Play services This code is
* returned in Activity.onActivityResult
*/
private final static int CONNECTION_FAILURE_RESOLUTION_REQUEST = 9000;
private LocationClient mLocationClient;
#Inject
private IUserLocationProvider userLocation;
private BitmapDescriptor mapPin;
private BitmapDescriptor mapPinUsed;
private SupportMapFragment supportMapFragment;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setRetainInstance(true); //< -- very important line
}
#Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
//I needed this for when I return to the fragment that contained the map
getChildFragmentManager().putFragment(outState, "supportFragment", supportMapFragment);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.fragment_map, null);
if (savedInstanceState == null) {
if (supportMapFragment == null) {
supportMapFragment = SupportMapFragment.newInstance();
getChildFragmentManager().beginTransaction().add(R.id.mapCont, supportMapFragment,SupportMapFragment.class.getSimpleName()).commit();
}
}
return v;
}
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
if (savedInstanceState !=null){
supportMapFragment = (SupportMapFragment) getChildFragmentManager().getFragment(savedInstanceState, "supportFragment");
map = null; //<very important to nullify the map, because the new instance of the map will not be the same
}
mLocationClient = new LocationClient(getActivity(), this, this);
}
/*
* Called when the Activity becomes visible.
*/
#Override
public void onStart() {
super.onStart();
// Connect the client.
if (isGooglePlayServicesAvailable()) {
mLocationClient.connect();
initMap();
}
}
public void initMap() {
if (map == null) {
map = (GoogleMap) supportMapFragment.getMap();
if (map == null) {
//this call is made several times, and on first tried map can be null
return;
}
}
map.getUiSettings().setCompassEnabled(false);
map.getUiSettings().setZoomControlsEnabled(false);
map.setOnMyLocationChangeListener(new OnMyLocationChangeListener() {
#Override
public void onMyLocationChange(Location location) {
if (location != null) {
userLocation.saveLocation(location);
}
}
});
}
#Override
public void onResume() {
super.onResume();
initMap();
updateAnnotations();
}
/*
* Called when the Activity is no longer visible.
*/
#Override
public void onStop() {
// Disconnecting the client invalidates it.
mLocationClient.disconnect();
super.onStop();
}
/*
* Handle results returned to the FragmentActivity by Google Play services
*/
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
// Decide what to do based on the original request code
switch (requestCode) {
case CONNECTION_FAILURE_RESOLUTION_REQUEST:
/*
* If the result code is Activity.RESULT_OK, try to connect again
*/
switch (resultCode) {
case Activity.RESULT_OK:
mLocationClient.connect();
break;
}
}
}
private boolean isGooglePlayServicesAvailable() {
// Check that Google Play services is available
int resultCode = GooglePlayServicesUtil.isGooglePlayServicesAvailable(getActivity());
// If Google Play services is available
if (ConnectionResult.SUCCESS == resultCode) {
// In debug mode, log the status
Log.d("Location Updates", "Google Play services is available.");
MapsInitializer.initialize(getActivity().getApplicationContext());
mapPin = BitmapDescriptorFactory.fromResource(R.drawable.envelope);
mapPinUsed = BitmapDescriptorFactory.fromResource(R.drawable.envelope_open);
return true;
} else {
//here google suggests to display an error dialog, but i found that this only cause problems , better show a toast instead
// Get the error dialog from Google Play services
// Dialog errorDialog =
// GooglePlayServicesUtil.getErrorDialog(resultCode, getActivity(),
// CONNECTION_FAILURE_RESOLUTION_REQUEST);
// If Google Play services can provide an error dialog
// if (errorDialog != null) {
// Create a new DialogFragment for the error dialog
// ErrorDialogFragment errorFragment = new ErrorDialogFragment();
// errorFragment.setDialog(errorDialog);
// errorFragment.show(getActivity().getSupportFragmentManager(),
// "Location Updates");
// }
return false;
}
}
/*
* Called by Location Services when the request to connect the client
* finishes successfully. At this point, you can request the current
* location or start periodic updates
*/
#Override
public void onConnected(Bundle dataBundle) {
// Display the connection status
Location location = mLocationClient.getLastLocation();
if (location != null) {
updateAnnotations();
} else {
// makeText( "Current location was null, enable GPS on emulator!",
// Toast.LENGTH_SHORT);
}
}
private Marker addMarker(GoogleMap map, double lat, double lon, String title, String snippet, boolean isWon) {
MarkerOptions options = new MarkerOptions().position(new LatLng(lat, lon)).title(title).snippet(snippet);
if (isWon) {
options.icon(mapPinUsed);
} else {
options.icon(mapPin);
}
Marker marker = map.addMarker(options);
return marker;
}
private void addMarkerToMap(GoogleMap map, WBMarker beacon) {
addMarker(map, beacon.location.Lat, beacon.location.Lng, beacon.name, beacon.address, beacon.isWon);
}
private void updateAnnotations() {
mapManager.getBeaconData(new IBeaconDataReceivedListener() {
#Override
public void onBeaconDataReceived(List<WBMarker> data) {
if (data.size() > 0) {
map.clear();
}
Location loc = userLocation.getLocation();
LatLng userTarget = new LatLng(loc.getLatitude(), loc.getLongitude());
LatLngBounds.Builder builder = new LatLngBounds.Builder();
List<WBMarker> ret = closeAnnotations(data);
for (WBMarker beacon : data) {
addMarkerToMap(map, beacon);
}
builder.include(userTarget);
CameraUpdate update;
if (ret.size() == 0) {
update = CameraUpdateFactory.newCameraPosition(new CameraPosition(userTarget, 17, 0, loc.getBearing()));
} else {
for (WBMarker beacon : ret) {
builder.include(new LatLng(beacon.location.Lat, beacon.location.Lng));
}
update = CameraUpdateFactory.newLatLngBounds(builder.build(), 50);
}
map.animateCamera(update);
}
});
}
private List<WBMarker> closeAnnotations(List<WBMarker> data) {
Location userLoc = userLocation.getLocation();
List<WBMarker> ret = new ArrayList<WBMarker>();
for (WBMarker beacon : data) {
Location loc = beacon.location.getLocation();
float dist = loc.distanceTo(userLoc);
if (dist < 50000.0f) {
ret.add(beacon);
}
}
return ret;
}
/*
* Called by Location Services if the connection to the location client
* drops because of an error.
*/
#Override
public void onDisconnected() {
// Display the connection status
Toast.makeText(getActivity(),"Disconnected. Please re-connect.", Toast.LENGTH_SHORT).show();
}
/*
* Called by Location Services if the attempt to Location Services fails.
*/
#Override
public void onConnectionFailed(ConnectionResult connectionResult) {
/*
* Google Play services can resolve some errors it detects. If the error
* has a resolution, try sending an Intent to start a Google Play
* services activity that can resolve error.
*/
if (connectionResult.hasResolution()) {
try {
// Start an Activity that tries to resolve the error
connectionResult.startResolutionForResult(getActivity(), CONNECTION_FAILURE_RESOLUTION_REQUEST);
/*
* Thrown if Google Play services canceled the original
* PendingIntent
*/
} catch (IntentSender.SendIntentException e) {
// Log the error
e.printStackTrace();
}
} else {
Toast.makeText(getActivity(), "Sorry. Location services not available to you", Toast.LENGTH_LONG).show();
}
}
}
Old answer:
I also ran into this problem. you should make this call in onResume only! as the map may not be ready before then
You should also call
MapsInitializer.initialize(getActivity().getApplicationContext());
and
GooglePlayUtils.isGooglePlayServicesAvailable(context)
before calling for the map

Categories