0

I'm trying to implement google map in a fragment, I have succeeded adding the map and markers on it, but now I need to show current users location and when it updates. I've tried following answers on this, but all answers were not giving any results only closing application instantly or giving error without even starting application. I've followed many guides on setting users location in activity, but failed to transfer that knowledge to fragment. Please keep in mind I've just started coding with android studio and I might not understand all the information.

MainActivity

public class MainActivity extends AppCompatActivity{
private Button btn1, btn2;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    btn1 = (Button) findViewById(R.id.btn1);
    btn2 = (Button) findViewById(R.id.btn2);

    btn1.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            addFragment(new OneFragment(), false, "one");
        }
    });

    btn2.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            addFragment(new MapFragment(), false, "one");
        }
    });

}

public void addFragment(Fragment fragment, boolean addToBackStack, String tag) {
    FragmentManager manager = getSupportFragmentManager();
    FragmentTransaction ft = manager.beginTransaction();

    if (addToBackStack) {
        ft.addToBackStack(tag);
    }
    ft.replace(R.id.container_frame_back, fragment, tag);
    ft.commitAllowingStateLoss();
}
}

MapFragment

    public class MapFragment extends Fragment implements OnMapReadyCallback, LocationListener {

    LocationManager locationManager;
    MarkerOptions mo;
    final static String[] PERMISSIONS = {
            Manifest.permission.ACCESS_COARSE_LOCATION,     Manifest.permission.ACCESS_FINE_LOCATION};
    final static int PERMISSION_ALL = 1;
    private GoogleMap mMap;
    LatLng myCoordinates;
    Marker marker;
    public MapFragment() {
        // Required empty public constructor
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        locationManager = (LocationManager) getLayoutInflater().getContext().getSystemService(Context.LOCATION_SERVICE);
        mo = new MarkerOptions().position(new LatLng(54.687157, 25.279652)).title("My current location");
        if (Build.VERSION.SDK_INT >= 23 && !isPermissionGranted()) {
            requestPermissions(PERMISSIONS, PERMISSION_ALL);
        } else requestLocation();
        if (!isLocationEnabled()) {
            showAlert(1);
        }
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        // Inflate the layout for this fragment
        View rootView = inflater.inflate(R.layout.fragment_map, container, false);
        SupportMapFragment mapFragment = (SupportMapFragment)     getChildFragmentManager().findFragmentById(R.id.frg);  //use SuppoprtMapFragment     for using in fragment instead of activity  MapFragment = activity       SupportMapFragment = fragment
        mapFragment.getMapAsync(new OnMapReadyCallback() {
            @Override
            public void onMapReady(GoogleMap mMap) {
                mMap.setMapType(GoogleMap.MAP_TYPE_NORMAL);

                mMap.clear(); //clear old markers

                CameraPosition googlePlex = CameraPosition.builder()
                        .target(new LatLng(37.4219999,-122.0862462))
                        .zoom(10)
                        .bearing(0)
                        .tilt(45)
                        .build();

                    mMap.animateCamera(CameraUpdateFactory.newCameraPosition(googlePlex), 10000, null);

                mMap.addMarker(new MarkerOptions()
                        .position(new LatLng(37.4219999, -122.0862462))
                        .title("Spider Man")
                        .icon(bitmapDescriptorFromVector(getActivity(),R.drawable.spider)));

                mMap.addMarker(new MarkerOptions()
                        .position(new LatLng(37.4629101,-122.2449094))
                        .title("Iron Man")
                        .snippet("His Talent : Plenty of money"));

                mMap.addMarker(new MarkerOptions()
                        .position(new LatLng(37.3092293,-122.1136845))
                        .title("Captain America"));
            }
        });


        return rootView;
    }

    private BitmapDescriptor bitmapDescriptorFromVector(Context context, int vectorResId) {
        Drawable vectorDrawable = ContextCompat.getDrawable(context, vectorResId);
        vectorDrawable.setBounds(0, 0, vectorDrawable.getIntrinsicWidth(), vectorDrawable.getIntrinsicHeight());
        Bitmap bitmap = Bitmap.createBitmap(vectorDrawable.getIntrinsicWidth(), vectorDrawable.getIntrinsicHeight(), Bitmap.Config.ARGB_8888);
        Canvas canvas = new Canvas(bitmap);
        vectorDrawable.draw(canvas);
        return BitmapDescriptorFactory.fromBitmap(bitmap);
    }

    @Override
    public void onLocationChanged(Location location) {
        myCoordinates = new LatLng(location.getLatitude(), location.getLongitude());
        marker.setPosition(myCoordinates);
        mMap.animateCamera(CameraUpdateFactory.newLatLngZoom(myCoordinates,16f));
    }

    @Override
    public void onStatusChanged(String s, int i, Bundle bundle) {

    }

    @Override
    public void onProviderEnabled(String s) {

    }

    @Override
    public void onProviderDisabled(String s) {

    }

    @Override
    public void onMapReady(GoogleMap googleMap) {

    }
    private boolean isPermissionGranted(){
            if(getLayoutInflater().getContext().checkSelfPermission(Manifest.permission.ACCESS_COARSE_LOCATION) == PackageManager.PERMISSION_GRANTED
                ||getLayoutInflater().getContext().checkSelfPermission(Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
            Log.v("mylog","Permission is granted");
            return true;
        }
        else
        {
            Log.v("mylog", "Permission not granted");
            return false;
        }
    }
    private boolean isLocationEnabled(){
        return     locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER) | locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
    }
    private void showAlert(final int status){
        String message, title, btnText;
        if (status == 1) {
            message = "Your Locations Settings is set to 'Off'.\nPlease Enable Location to " +
                    "use this app";
            title = "Enable Location";
            btnText = "Location Settings";
        } else {
            message = "Please allow this app to access location!";
            title = "Permission access";
            btnText = "Grant";
        }
        final AlertDialog.Builder dialog = new AlertDialog.Builder(getLayoutInflater().getContext());
        dialog.setCancelable(false);
        dialog.setTitle(title)
                .setMessage(message)
                .setPositiveButton(btnText, new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface paramDialogInterface, int paramInt) {
                        if (status == 1) {
                            Intent myIntent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
                            startActivity(myIntent);
                        } else
                            requestPermissions(PERMISSIONS, PERMISSION_ALL);
                    }
                })
                .setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface paramDialogInterface, int paramInt) {
                        getActivity().finish();
                    }
                });

        dialog.show();
    }
    private void requestLocation() {
        Criteria criteria = new Criteria();
        criteria.setAccuracy(Criteria.ACCURACY_FINE);
        criteria.setPowerRequirement(Criteria.POWER_HIGH);
        String provider = locationManager.getBestProvider(criteria, true);
        if (getLayoutInflater().getContext().checkSelfPermission(Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED &&getLayoutInflater().getContext().checkSelfPermission(Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
            // TODO: Consider calling
            //    Activity#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 Activity#requestPermissions for more details.
            return;
        }
        locationManager.requestLocationUpdates(provider, 5000, 10, this);
    }
}

MapsActivity

public class MapsActivity extends FragmentActivity implements OnMapReadyCallback, LocationListener {
final static int PERMISSION_ALL = 1;
final static String[] PERMISSIONS = {
        Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_FINE_LOCATION};
private GoogleMap mMap;
MarkerOptions mo;
Marker marker;
LocationManager locationManager;
Circle userCircle;
LatLng myCoordinates;

Marker marker1;
Marker marker2;
Marker marker3;
Marker marker4;

MarkerOptions mo1;
MarkerOptions mo2;
MarkerOptions mo3;
MarkerOptions mo4;

static boolean marker1Visibility = false;
static boolean marker2Visibility = false;
static boolean marker3Visibility = false;
static boolean marker4Visibility = false;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_maps);
    SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
            .findFragmentById(R.id.map);
    mapFragment.getMapAsync(this);
    locationManager = (LocationManager) getSystemService(LOCATION_SERVICE);
    mo = new MarkerOptions().position(new LatLng(54.687157, 25.279652)).title("My current location")
            .icon(vectorToBitmap(R.drawable.ic_user,Color.parseColor("#4287f5")));
    if (Build.VERSION.SDK_INT >= 23 && !isPermissionGranted()) {
        requestPermissions(PERMISSIONS, PERMISSION_ALL);
    } else requestLocation();
    if (!isLocationEnabled()) {
        showAlert(1);
    }

}


@Override
public void onMapReady(GoogleMap googleMap) {
    setMarker();
    mMap = googleMap;
    marker = mMap.addMarker(mo);
    marker1 = mMap.addMarker(mo1);
    marker1.setVisible(marker1Visibility);
    marker2 = mMap.addMarker(mo2);
    marker2.setVisible(marker2Visibility);
    marker3 = mMap.addMarker(mo3);
    marker3.setVisible(marker3Visibility);
    marker4 = mMap.addMarker(mo4);
    marker4.setVisible(marker4Visibility);
    mMap.animateCamera(CameraUpdateFactory.newLatLngZoom(mo.getPosition(),14f));

}

@Override
protected void onResume() {
    super.onResume();
}

@Override
public void onLocationChanged(Location location) {
    myCoordinates = new LatLng(location.getLatitude(), location.getLongitude());
    marker.setPosition(myCoordinates);
    checkMarker();

    if(userCircle != null)
    {
        userCircle.remove();
    }
    mMap.getUiSettings().setMapToolbarEnabled(true);
     userCircle = mMap.addCircle( new CircleOptions()
            .center(myCoordinates)
            .radius(100)
            .strokeWidth(3f)
            .strokeColor(Color.BLUE)
            .fillColor(Color.argb(70,135,206,250)));
    mMap.animateCamera(CameraUpdateFactory.newLatLngZoom(myCoordinates,16f));
}

@Override
public void onStatusChanged(String s, int i, Bundle bundle) {

}

@Override
public void onProviderEnabled(String s) {

}

@Override
public void onProviderDisabled(String s) {

}

private void requestLocation() {
    Criteria criteria = new Criteria();
    criteria.setAccuracy(Criteria.ACCURACY_FINE);
    criteria.setPowerRequirement(Criteria.POWER_HIGH);
    String provider = locationManager.getBestProvider(criteria, true);
    if (checkSelfPermission(Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && checkSelfPermission(Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
        // TODO: Consider calling
        //    Activity#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 Activity#requestPermissions for more details.
        return;
    }
    locationManager.requestLocationUpdates(provider, 5000, 10, this);
}
private boolean isLocationEnabled(){
    return locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER) | locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
}
private boolean isPermissionGranted(){
    if(checkSelfPermission(Manifest.permission.ACCESS_COARSE_LOCATION) == PackageManager.PERMISSION_GRANTED
            || checkSelfPermission(Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
        Log.v("mylog","Permission is granted");
        return true;
    }
    else
    {
        Log.v("mylog", "Permission not granted");
        return false;
    }
}
private void showAlert(final int status){
    String message, title, btnText;
    if (status == 1) {
        message = "Your Locations Settings is set to 'Off'.\nPlease Enable Location to " +
                "use this app";
        title = "Enable Location";
        btnText = "Location Settings";
    } else {
        message = "Please allow this app to access location!";
        title = "Permission access";
        btnText = "Grant";
    }
    final AlertDialog.Builder dialog = new AlertDialog.Builder(this);
    dialog.setCancelable(false);
    dialog.setTitle(title)
            .setMessage(message)
            .setPositiveButton(btnText, new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface paramDialogInterface, int paramInt) {
                    if (status == 1) {
                        Intent myIntent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
                        startActivity(myIntent);
                    } else
                        requestPermissions(PERMISSIONS, PERMISSION_ALL);
                }
            })
            .setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface paramDialogInterface, int paramInt) {
                    finish();
                }
            });

    dialog.show();
}
private BitmapDescriptor vectorToBitmap(@DrawableRes int id, @ColorInt int color) {
    Drawable vectorDrawable = ResourcesCompat.getDrawable(getResources(), id, null);
    Bitmap bitmap = Bitmap.createBitmap(vectorDrawable.getIntrinsicWidth(),
            vectorDrawable.getIntrinsicHeight(), Bitmap.Config.ARGB_8888);
    Canvas canvas = new Canvas(bitmap);
    vectorDrawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight());
    DrawableCompat.setTint(vectorDrawable, color);
    vectorDrawable.draw(canvas);
    return BitmapDescriptorFactory.fromBitmap(bitmap);
}

private void setMarker()
{
    mo1 = new MarkerOptions().position(new LatLng(54.712199,25.302195)).title("Marker1").icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_GREEN));
    mo2 = new MarkerOptions().position(new LatLng(54.7230324,25.2958683)).title("Marker2").icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_GREEN));
    mo3 = new MarkerOptions().position(new LatLng(54.7190283,25.3034968)).title("Marker3").icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_GREEN));
    mo4 = new MarkerOptions().position(new LatLng(54.7057832,25.2972182)).title("Express Pica").icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_GREEN));
}

private void checkMarker()
{
    if(distanceBetween(mo1.getPosition().latitude,mo1.getPosition().longitude,myCoordinates.latitude,myCoordinates.longitude) <= 70)
    {
        marker1.setVisible(true);
        marker1Visibility = true;
    }
    if(distanceBetween(mo2.getPosition().latitude,mo2.getPosition().longitude,myCoordinates.latitude,myCoordinates.longitude) <= 70)
    {
        marker2.setVisible(true);
        marker2Visibility = true;
    }
    if(distanceBetween(mo3.getPosition().latitude,mo3.getPosition().longitude,myCoordinates.latitude,myCoordinates.longitude) <= 70)
    {
        marker3.setVisible(true);
        marker3Visibility = true;
    }
    if(distanceBetween(mo4.getPosition().latitude,mo4.getPosition().longitude,myCoordinates.latitude,myCoordinates.longitude) <= 70)
    {
        marker4.setVisible(true);
        marker4Visibility = true;
    }


}
private double distanceBetween(double lat1, double lon1, double lat2, double lon2) {
    double theta = lon1 - lon2;
    double dist = Math.sin(deg2rad(lat1))
            * Math.sin(deg2rad(lat2))
            + Math.cos(deg2rad(lat1))
            * Math.cos(deg2rad(lat2))
            * Math.cos(deg2rad(theta));
    dist = Math.acos(dist);
    dist = dist * 180.0 / Math.PI;
    dist = dist * 60 * 1.1515*1000;
    return (dist);
}

private double deg2rad(double deg) {
    return (deg * Math.PI / 180.0);
}
}

Gradle.build app

apply plugin: 'com.android.application'

android {
compileSdkVersion 29
buildToolsVersion "29.0.2"
defaultConfig {
    applicationId "This Does Not Matter"
    minSdkVersion 23
    targetSdkVersion 29
    versionCode 1
    versionName "1.0"
    testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
buildTypes {
    release {
        minifyEnabled false
        proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
    }
}
}

dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation 'androidx.appcompat:appcompat:1.1.0'
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
implementation 'androidx.legacy:legacy-support-v4:1.0.0'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'androidx.test.ext:junit:1.1.1'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
implementation 'com.google.android.material:material:1.0.0'
implementation 'com.google.android.gms:play-services:12.0.1'
}

Current error message

    2019-11-17 13:59:17.932 30953-30993/com.eif.petrasbukelis.twiftoffun E/AndroidRuntime: FATAL EXCEPTION: Thread-3
    Process: com.eif.petrasbukelis.twiftoffun, PID: 30953
    java.lang.NoClassDefFoundError: Failed resolution of: Lorg/apache/http/ProtocolVersion;
        at bs.b(:com.google.android.gms.dynamite_mapsdynamite@19629065@19.6.29 (100400-0):2)
        at br.a(:com.google.android.gms.dynamite_mapsdynamite@19629065@19.6.29 (100400-0):3)
        at bt.a(:com.google.android.gms.dynamite_mapsdynamite@19629065@19.6.29 (100400-0):20)
        at com.google.maps.api.android.lib6.drd.ak.a(:com.google.android.gms.dynamite_mapsdynamite@19629065@19.6.29 (100400-0):6)
        at ax.a(:com.google.android.gms.dynamite_mapsdynamite@19629065@19.6.29 (100400-0):13)
        at ax.run(:com.google.android.gms.dynamite_mapsdynamite@19629065@19.6.29 (100400-0):49)
     Caused by: java.lang.ClassNotFoundException: Didn't find class "org.apache.http.ProtocolVersion" on path: DexPathList[[zip file "/data/user_de/0/com.google.android.gms/app_chimera/m/000000fd/MapsDynamite.apk"],nativeLibraryDirectories=[/data/user_de/0/com.google.android.gms/app_chimera/m/000000fd/MapsDynamite.apk!/lib/arm64-v8a, /system/lib64]]
        at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:134)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:379)
        at w.loadClass(:com.google.android.gms.dynamite_dynamiteloader@19629065@19.6.29 (100400-0):16)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:312)
        at bs.b(:com.google.android.gms.dynamite_mapsdynamite@19629065@19.6.29 (100400-0):2) 
        at br.a(:com.google.android.gms.dynamite_mapsdynamite@19629065@19.6.29 (100400-0):3) 
        at bt.a(:com.google.android.gms.dynamite_mapsdynamite@19629065@19.6.29 (100400-0):20) 
        at com.google.maps.api.android.lib6.drd.ak.a(:com.google.android.gms.dynamite_mapsdynamite@19629065@19.6.29 (100400-0):6) 
        at ax.a(:com.google.android.gms.dynamite_mapsdynamite@19629065@19.6.29 (100400-0):13) 
        at ax.run(:com.google.android.gms.dynamite_mapsdynamite@19629065@19.6.29 (100400-0):49) 
2019-11-17 13:59:17.977 30953-30953/com.eif.petrasbukelis.twiftoffun E/SchedPolicy: set_timerslack_ns write failed: Operation not permitted
2019-11-17 13:59:18.711 30953-30975/com.eif.petrasbukelis.twiftoffun I/elis.twiftoffu: ProcessProfilingInfo new_methods=12 is saved saved_to_disk=1 resolve_classes_delay=8000
2019-11-17 13:59:19.656 30953-31019/com.eif.petrasbukelis.twiftoffun W/DynamiteModule: Local module descriptor class for com.google.android.gms.googlecertificates not found.
2019-11-17 13:59:19.666 30953-31019/com.eif.petrasbukelis.twiftoffun I/DynamiteModule: Considering local module com.google.android.gms.googlecertificates:0 and remote module com.google.android.gms.googlecertificates:4
2019-11-17 13:59:19.666 30953-31019/com.eif.petrasbukelis.twiftoffun I/DynamiteModule: Selected remote version of com.google.android.gms.googlecertificates, version >= 4
2019-11-17 13:59:19.672 30953-31019/com.eif.petrasbukelis.twiftoffun I/DynamiteLoaderV2: [71] Googlecertificates
2019-11-17 13:59:19.675 30953-31019/com.eif.petrasbukelis.twiftoffun W/elis.twiftoffu: Unsupported class loader
  • 2
    add what errors you have got, add the stacktrace from the logcat if there are crashes and also, remove unnecessary codes that are not directly related to the question – touhid udoy Nov 17 '19 at 10:16
  • I have written working code for getting users location in MapActivity class that I'm showing code for, my question right now is how to make that work in fragment? – Petras Bukelis Nov 17 '19 at 11:06
  • I have updated my MapFragment class, currently is not giving any error message though closing as it opens. – Petras Bukelis Nov 17 '19 at 11:47

0 Answers0