Search code examples
javaandroidhere-api

cannot resolve getSupportFragmentManager() in helper class


I'm trying to learn java by following a tutorial on here maps api to make an android app. In the tutorial, there is a helper class MapInitializer that is called in the Main Activity. The function initializeMap had a MapFragment and getFragmentManager(), which I learned have been deprecated. When I tried to change it to getSupportFragmentManager() to get the fragment, it says the method cannot be resolved. I think it has to do with the activity prefix, because I used getSupportFragmentManager in another tutorial and it worked. I have tried extending the class with FragmentActivity and AppCompatActivity, but it does not work. Here is the helper class:

package helper;
import smart.wheels.R;

import android.app.Activity;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.support.annotation.NonNull;
import android.support.v4.app.ActivityCompat;
import android.support.v4.app.FragmentActivity;
import android.support.v4.content.ContextCompat;
import android.util.Log;

import com.here.android.mpa.mapping.SupportMapFragment;
import com.here.android.mpa.common.MapSettings;
import com.here.android.mpa.common.OnEngineInitListener;
import com.here.android.mpa.mapping.Map;
import com.here.android.mpa.mapping.MapFragment;

import java.io.File;
import java.util.ArrayList;

public class MapInitializer {

    private static final String LOG_TAG = MapInitializer.class.getName();
    private static final int PERMISSIONS_REQUEST_CODE = 42;
    private static final String MAP_SERVICE_INTENT_NAME = "com.here.msdkui.example.MapService";

    private final ResultListener resultListener;
    private final Activity activity;

    public interface ResultListener {
        void onMapInitDone(Map map);
    }

    public MapInitializer(@NonNull Activity activity, @NonNull ResultListener resultListener) {
        this.activity = activity;
        this.resultListener = resultListener;

        String[] missingPermissions = getPermissionsToRequest();
        if (missingPermissions.length == 0) {
            initializeMap();
        } else {
            ActivityCompat.requestPermissions(activity, missingPermissions, PERMISSIONS_REQUEST_CODE);
        }
    }

    private void initializeMap() {
        String cacheLocation =
                activity.getApplicationContext().getFilesDir().getPath() + File.separator + "example_maps_cache";
        if (MapSettings.setIsolatedDiskCacheRootPath(cacheLocation, MAP_SERVICE_INTENT_NAME)) {
            SupportMapFragment mapFragment = (SupportMapFragment) activity.getSupportFragmentManager().findFragmentById(R.id.mapfragment);
            mapFragment.init(error -> {
                if (error == OnEngineInitListener.Error.NONE) {
                    mapFragment.getPositionIndicator().setVisible(true);
                    resultListener.onMapInitDone(mapFragment.getMap());
                } else {
                    Log.e(LOG_TAG, "Cannot initialize Map Fragment: " + error.getDetails());
                }
            });
        } else {
            Log.e(LOG_TAG, "Unable to set isolated disk cache path.");
        }
    }

    private String[] getPermissionsToRequest() {
        ArrayList<String> permissionList = new ArrayList<>();
        try {
            PackageInfo packageInfo = activity.getPackageManager().getPackageInfo(
                    activity.getPackageName(), PackageManager.GET_PERMISSIONS);
            if (packageInfo.requestedPermissions != null) {
                for (String permission : packageInfo.requestedPermissions) {
                    if (ContextCompat.checkSelfPermission(
                            activity, permission) != PackageManager.PERMISSION_GRANTED) {
                        permissionList.add(permission);
                    }
                }
            }
        } catch (Exception e) {
            Log.e(LOG_TAG, "Cannot read permissions from manifest: " + e.getMessage());
        }
        return permissionList.toArray(new String[permissionList.size()]);
    }

    public void onRequestPermissionsResult(int requestCode, @NonNull int[] grantResults) {
        if (requestCode == PERMISSIONS_REQUEST_CODE) {
            boolean allGranted = true;
            for (int result : grantResults) {
                allGranted &= result == PackageManager.PERMISSION_GRANTED;
            }

            if (allGranted) {
                initializeMap();
            } else {
                Log.e(LOG_TAG, "Required Android permissions denied by user.");
            }
        }
    }
}

and the layout:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">

<com.here.msdkui.routing.WaypointList
    android:id="@+id/waypointList"
    android:layout_width="match_parent"
    android:layout_height="wrap_content" />

<com.here.msdkui.routing.TransportModePanel
    android:id="@+id/transportModePanel"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"/>

<fragment
    class="com.here.android.mpa.mapping.SupportMapFragment"
    android:id="@+id/mapfragment"
    android:layout_width="match_parent"
    android:layout_height="0dp"
    android:layout_weight="1"/>

<Button
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:text="Show route details"
    android:onClick="onRouteDetailsButtonClick"/>

How can I get the fragment? Any help will be greatly appreciated!


Solution

  • You get this error because your variable private final Activity activity; is type of Activity, getSupportFragmentManager() is only available for FragmentActivity and AppCompatActivity subclasses.

    If your sure that the instance pass to your MapInitializer constructor is type of AppCompatActivity, you should change the signature of the constructor :

    private final AppCompatActivity activity;
    
    public MapInitializer(@NonNull AppCompatActivity activity, @NonNull ResultListener resultListener) {
        this.activity = activity;
    
        // your code
    }
    

    Hope this helps.