/** * Copyright (c) 2014-present, Facebook, Inc. All rights reserved. * * You are hereby granted a non-exclusive, worldwide, royalty-free license to use, * copy, modify, and distribute this software in source code or binary form for use * in connection with the web services and APIs provided by Facebook. * * As with any software that integrates with the Facebook platform, your use of * this software is subject to the Facebook Developer Principles and Policies * [http://developers.facebook.com/policy/]. This copyright notice shall be * included in all copies or substantial portions of the software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ package com.example.places; import android.Manifest; import android.content.DialogInterface; import android.content.Intent; import android.content.pm.PackageManager; import android.os.Bundle; import android.support.v4.app.ActivityCompat; import android.support.v4.app.FragmentTransaction; import android.support.v7.app.AlertDialog; import android.support.v7.app.AppCompatActivity; import com.example.places.fragments.PlaceInfoFragment; import com.example.places.fragments.PlaceSearchFragment; import com.example.places.fragments.LoginFragment; import com.example.places.model.Place; import com.facebook.AccessToken; import com.facebook.FacebookSdk; /** * This sample application illustrates how to use the Places Graph SDK to: * <ul> * <li>Retrieve a collection of place candidates along with confidence level estimates, that the * user is at those places.</li> * <li>Allow the user to provide feedback on the accuracy of the current place estimate.</li> * <li>Search for nearby places.</li> * <li>Retrieve detailed place information.</li> * <li>Retrieve a cover photo associated with a particular place.</li> * <li>Display places on a map.</li> *</ul> * <p> * {@link PlacesGraphSDKHelper} demonstrates how to create requests with the Places Graph SDK. * * {@link com.example.places.model.Place} and {@link com.example.places.model.PlaceTextUtils} * demonstrates how to parse place information. */ public class MainActivity extends AppCompatActivity implements LoginFragment.Listener, PlaceSearchFragment.Listener, PlaceInfoFragment.Listener { private static final int REQUEST_LOCATION = 0; private static final int REQUEST_CALL_PHONE = 1; /** * The Places Graph SDK can be accessed using either a User Access Token or a Client Token. * A User Access Token will require users to login to Facebook, but a Client Token won't. * * This sample app demonstrates how to use both User Access Tokens and Client Tokens. * To use either one, just change the value of {@code authenticationType} * to USER_TOKEN or CLIENT_TOKEN. */ private enum AuthenticationType { USER_TOKEN, CLIENT_TOKEN, }; /** * This variable specifies whether the sample app uses a User Access Token or a Client Token. * * Change it to AuthenticationType.CLIENT_TOKEN to use a Client Token. * * To use a client token, you will also need to: update "app_id" in strings.xml to * the application ID of your app, and then update the CLIENT_TOKEN constant in this class to * the value of your app client token. You can find the client token value on the Developer * Portal page of your app, under the Advanced Settings section. */ private final AuthenticationType authenticationType = AuthenticationType.USER_TOKEN; /** * To use client token authentication, get your app client token from the developer * portal, and enter it below. The client token is available under your application page in the * Developer Portal, under the Advanced Settings section. Note that you must also change * the app_id to your own Application ID in the file "strings.xml". */ private static final String CLIENT_TOKEN = ""; private Intent callPhoneIntent; public void onCreate(Bundle bundle) { super.onCreate(bundle); setContentView(R.layout.main_activity); /** * You can use the Places Graph SDK with either a User Access Token, or a Client Token. * By default, this code sample is configured to use a User Access Token. */ if (authenticationType == AuthenticationType.USER_TOKEN) { AccessToken accessToken = AccessToken.getCurrentAccessToken(); if (accessToken == null) { /** * When a User Access Token is used, and if the token is not present, * then prompt the user to log into Facebook. */ displayLoginFragment(); } else { displayPlaceListFragment(); } } else { /** * When a Client Token is used, set the client token to the Facebook SDK class * as illustrated below. Users do not need to log into Facebook. PlaceManager requests * can be placed once the client token has been set. */ FacebookSdk.setClientToken(CLIENT_TOKEN); displayPlaceListFragment(); } } public void onStart() { super.onStart(); if (!hasLocationPermission()) { requestLocationPermission(); } } private void requestLocationPermission() { /* * Prompts the user to grant location permissions. This sample app uses the * device's' location to get the current place from the Place Graph SDK, * and to perform local place searches. */ if (ActivityCompat.shouldShowRequestPermissionRationale( this, Manifest.permission.ACCESS_FINE_LOCATION)) { AlertDialog.Builder builder = new AlertDialog.Builder(this); builder.setMessage(R.string.permission_prompt_location); builder.setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { ActivityCompat.requestPermissions( MainActivity.this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_COARSE_LOCATION}, REQUEST_LOCATION); } }); builder.create().show(); } else { ActivityCompat.requestPermissions( this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_COARSE_LOCATION}, REQUEST_LOCATION); } } @Override public void onRequestPermissionsResult( int requestCode, String[] permissions, int[] grantResults) { if (requestCode == REQUEST_CALL_PHONE) { if (callPhoneIntent != null) { startActivity(callPhoneIntent); callPhoneIntent = null; } } else { super.onRequestPermissionsResult(requestCode, permissions, grantResults); } } @Override public void onLoginComplete() { // Event invoked by the LoginFragment when login completes. displayPlaceListFragment(); } @Override public void onPlaceSelected(Place place) { // Event invoked by the PlaceSearchFragment when a place is selected. displayPlaceInfoFragment(place); } @Override public void onLocationPermissionsError() { // Event invoked by the PlaceSearchFragment when the Places Graph SDK fails to retrieve // the current device location due to missing location permissions. requestLocationPermission(); } private void displayPlaceListFragment() { PlaceSearchFragment placeListFragment = PlaceSearchFragment.newInstance(); FragmentTransaction transaction = getSupportFragmentManager().beginTransaction(); transaction.replace(R.id.fragment_placeholder, placeListFragment); transaction.commit(); } private void displayLoginFragment() { LoginFragment loginFragment = LoginFragment.newInstance(); FragmentTransaction transaction = getSupportFragmentManager().beginTransaction(); transaction.replace(R.id.fragment_placeholder, loginFragment); transaction.commit(); } private void displayPlaceInfoFragment(Place place) { PlaceInfoFragment placeInfoFragment = PlaceInfoFragment.newInstance(); Bundle bundle = new Bundle(); bundle.putParcelable(PlaceInfoFragment.EXTRA_PLACE, place); placeInfoFragment.setArguments(bundle); getSupportFragmentManager() .beginTransaction() .add(R.id.fragment_placeholder, placeInfoFragment, "details") .addToBackStack(place.get(Place.NAME)) .commit(); } @Override public void onCallPhone(final Intent intent) { /* * Prompts the user for permission to place a phone call, and then places the call. */ if (hasPermission(Manifest.permission.CALL_PHONE)) { startActivity(intent); } else if (ActivityCompat.shouldShowRequestPermissionRationale( this, Manifest.permission.CALL_PHONE)) { AlertDialog.Builder builder = new AlertDialog.Builder(this); builder.setMessage(R.string.permission_prompt_call_phone); builder.setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { callPhoneIntent = intent; ActivityCompat.requestPermissions( MainActivity.this, new String[]{Manifest.permission.CALL_PHONE}, REQUEST_CALL_PHONE); } }); builder.create().show(); } else { callPhoneIntent = intent; ActivityCompat.requestPermissions( this, new String[]{Manifest.permission.CALL_PHONE}, REQUEST_CALL_PHONE); } } private boolean hasPermission(String permission) { return ActivityCompat.checkSelfPermission(this, permission) == PackageManager.PERMISSION_GRANTED; } @Override public boolean hasLocationPermission() { return hasPermission(Manifest.permission.ACCESS_FINE_LOCATION) || hasPermission(Manifest.permission.ACCESS_COARSE_LOCATION); } @Override public boolean onSupportNavigateUp() { onBackPressed(); return true; } }