dizel
dizel

Reputation: 25

Trying to get current location when activity started

I want to zoom to the current location of user when activity started. I have two java class. One of is MapActivity.java and the other is MapFragment.java. I'm trying to do this job on MapFragment.java.

  private Actvity activity;
  private volatile GoogleMap googleMap;
  GoogleApiClient mGoogleApiClient;
  LocationRequest mLocationRequest;

  @Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    activity = getActivity();
}

MapFragment.java/onMapReady ;

@Override
public void onMapReady(GoogleMap map) {
    googleMap = map;

    mGoogleApiClient=new GoogleApiClient.Builder(activity)
            .addApi(LocationServices.API)
            .addConnectionCallbacks(activity)
            .addOnConnectionFailedListener(activity)
            .build();

    mGoogleApiClient.connect();

}

In this onMapReady, .addConnectionCallbacks(activity) and .addOnConnectionFailedListener(activity) are giving warning like in the image;

enter image description here

In the examples that I have analyzed before they are implementing GoogleApiClient.ConnectionCallbacks and GoogleApiCleint.OnConnectionFailedListener not casting. Without implementing, I couldn't get these functions;

 @Override
public void onConnected(Bundle bundle) {

    mLocationRequest=LocationRequest.create();
    mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);

    mLocationRequest.setInterval(1000);

    LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient,mLocationRequest,this);

}

@Override
public void onConnectionSuspended(int i) {

}
 @Override
public void onConnectionFailed(ConnectionResult connectionResult) {

}

And also I have to get LocationListeners's method;

@Override
public void onLocationChanged(Location location) {
    if(location == null){
        Toast.makeText(this,"Cant get current location",Toast.LENGTH_LONG).show();

    }
    else{
        LatLng ll= new LatLng(location.getLatitude(),location.getLongitude());
        CameraUpdate update= CameraUpdateFactory.newLatLngZoom(ll,15);
        mGoogleMap.animateCamera(update);
    }
}

If I implement them by hand in the fragment, does it cause any problem? What is the proper way to get current location in fragment activity?

Upvotes: 1

Views: 253

Answers (2)

Sathish Kumar VG
Sathish Kumar VG

Reputation: 2172

I have implemented a Fragment in Activity and Location listener and MapReady is called in fragment to get current location. Refer the below code.

MainActivity.Java

public class MainActivity extends AppCompatActivity {
     public static final String TAG = MainActivity.class.getSimpleName();
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        setFragment(new MapFragment());
    }
    // class for being re-used by several instances
    protected void setFragment(Fragment fragment) {
        FragmentManager fragmentManager = getSupportFragmentManager();
        FragmentTransaction fragmentTransaction =
                fragmentManager.beginTransaction();
        fragmentTransaction.replace(android.R.id.content, fragment);
        fragmentTransaction.commit();
    }
}

Activity_Main.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout android:layout_width="match_parent"
    android:layout_height="match_parent"
    xmlns:android="http://schemas.android.com/apk/res/android">
        <FrameLayout
        android:id="@+id/frame_containerone"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />
    <ImageView
        android:id="@+id/imagenext"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:layout_alignParentRight="true"
        android:layout_margin="16dp"
        />
</RelativeLayout>

MapFragment.Java

public class MapFragment extends Fragment implements GoogleApiClient.ConnectionCallbacks,
        GoogleApiClient.OnConnectionFailedListener,
        LocationListener, OnMapReadyCallback {
    private static final String TAG = "MapFragment";
    MainActivity mActivity;
    private final static int CONNECTION_FAILURE_RESOLUTION_REQUEST = 9000;
    private GoogleMap mMap; // Might be null if Google Play services APK is not available.
    SupportMapFragment mapFragment;
    private GoogleApiClient mGoogleApiClient;
    private LocationRequest mLocationRequest;
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.map_fragment, null, true);
        mActivity = ((MainActivity) getActivity());
        initViews(view);
        return view;
    }
    private void initViews(View view) {
        mGoogleApiClient = new GoogleApiClient.Builder(mActivity)
                .addConnectionCallbacks(this)
                .addOnConnectionFailedListener(this)
                .addApi(LocationServices.API)
                .build();
        // Create the LocationRequest object
        mLocationRequest = LocationRequest.create()
                .setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY)
                .setInterval(10 * 1000)        // 10 seconds, in milliseconds
                .setFastestInterval(1 * 1000); // 1 second, in milliseconds
        mapFragment = (SupportMapFragment) this.getChildFragmentManager().findFragmentById(R.id.map);
        mapFragment.getMapAsync(this);
    }
    @Override
    public void onMapReady(GoogleMap map) {
        mMap = map;
        mMap.setMapType(GoogleMap.MAP_TYPE_NORMAL);
    }
    @Override
    public void onConnected(@Nullable Bundle bundle) {
        if (ActivityCompat.checkSelfPermission(mActivity, android.Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(mActivity, android.Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
            return;
        }
        Location location = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);
        if (location == null) {
            LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, this);
        } else {
            handleNewLocation(location);
        }
    }
    private void handleNewLocation(Location location) {
        Log.d(TAG, location.toString());
        double currentLatitude = location.getLatitude();
        double currentLongitude = location.getLongitude();
        LatLng latLng = new LatLng(currentLatitude, currentLongitude);
        MarkerOptions options = new MarkerOptions()
                .position(latLng)
                .title("I am here!");
        mMap.addMarker(options);
        mMap.moveCamera(CameraUpdateFactory.newLatLng(latLng));
    }
    @Override
    public void onConnectionSuspended(int i) {
    }
    @Override
    public void onConnectionFailed(@NonNull ConnectionResult connectionResult) {
        if (connectionResult.hasResolution()) {
            try {
                // Start an Activity that tries to resolve the error
                connectionResult.startResolutionForResult(mActivity, CONNECTION_FAILURE_RESOLUTION_REQUEST);
                /*
                 * Thrown if Google Play services canceled the original
                 * PendingIntent
                 */
            } catch (IntentSender.SendIntentException e) {
                // Log the error
                e.printStackTrace();
            }
        } else {
            /*
             * If no resolution is available, display a dialog to the
             * user with the error.
             */
            Log.i(TAG, "Location services connection failed with code " + connectionResult.getErrorCode());
        }
    }
    @Override
    public void onLocationChanged(Location location) {
        handleNewLocation(location);
    }
    @Override
    public void onResume() {
        super.onResume();
        setUpMapIfNeeded();
        mGoogleApiClient.connect();
    }
    private void setUpMapIfNeeded() {
        // Do a null check to confirm that we have not already instantiated the map.
        if (mMap == null) {
            // Try to obtain the map from the SupportMapFragment.
            mapFragment = (SupportMapFragment) this.getChildFragmentManager().findFragmentById(R.id.map);
            mapFragment.getMapAsync(this);//    mapFragment.getMapAsync((OnMapReadyCallback) mActivity);
        }
    }
    @Override
    public void onPause() {
        super.onPause();
        if (mGoogleApiClient.isConnected()) {
            LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiClient, this);
            mGoogleApiClient.disconnect();
        }
    }
}

map_fragment.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">
   <!-- <fragment xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@+id/map"
        android:name="com.google.android.gms.maps.SupportMapFragment"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />-->
        <fragment
            android:id="@+id/map"
            android:name="com.google.android.gms.maps.SupportMapFragment"
            android:layout_width="match_parent"
            android:layout_height="388dp"
            android:layout_weight="0.40" />
</LinearLayout>

Manifest:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.theme.fragment">
    <permission
        android:name="com.theme.fragment.permission.MAPS_RECEIVE"
        android:protectionLevel="signature" />
    <uses-permission android:name="com.theme.fragment.permission.MAPS_RECEIVE" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="com.google.android.providers.gsf.permission.READ_GSERVICES" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <!-- Required to show current location -->
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <!-- Goolge API Key -->
        <meta-data
            android:name="com.google.android.maps.v2.API_KEY"
            android:value="Your_Api key" />
    </application>
</manifest>

Upvotes: 0

Paresh
Paresh

Reputation: 6857

If I implement them by hand in the fragment, does it cause any problem?

No. All you need to do is implement ConnectionCallbacks and OnConnectionFailedListener.

What is the proper way to get current location in fragment activity?

public class MyFragment extends Fragment implements
        ConnectionCallbacks, OnConnectionFailedListener {

    // Create an instance of GoogleAPIClient.
    if (mGoogleApiClient == null) {
    mGoogleApiClient = new GoogleApiClient.Builder(this)
        .addConnectionCallbacks(this)
        .addOnConnectionFailedListener(this)
        .addApi(LocationServices.API)
        .build();
    }

    protected void onStart() {
        mGoogleApiClient.connect();
        super.onStart();
    }

    protected void onStop() {
        mGoogleApiClient.disconnect();
        super.onStop();
    }
   @Override
   public void onConnected(Bundle connectionHint) {
        mLastLocation = LocationServices.FusedLocationApi.getLastLocation(
                mGoogleApiClient); // this is your location
        if (mLastLocation != null) {              
         mLatitudeText.setText(String.valueOf(mLastLocation.getLatitude()));
       mLongitudeText.setText(String.valueOf(mLastLocation.getLongitude()));
        }
    }
}

Reference

Upvotes: 1

Related Questions