I am trying to implement a google map into a contact list app I am building. I have ran the debugger it seems to be going to an exception at setContentView(R.layout.activity_contact_map);. I am unsure why or how to fix this. any advice would be greatly appreciated. It must be coded like this due to being a school project.
package com.example.mycontactlist;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import android.Manifest;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.location.Location;
import android.os.Build;
import android.os.Bundle;
import android.view.View;
import android.widget.ImageButton;
import android.widget.Toast;
import com.google.android.gms.location.FusedLocationProviderClient;
import com.google.android.gms.location.LocationCallback;
import com.google.android.gms.location.LocationRequest;
import com.google.android.gms.location.LocationResult;
import com.google.android.gms.location.LocationServices;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.OnMapReadyCallback;
import com.google.android.gms.maps.SupportMapFragment;
import com.google.android.material.snackbar.Snackbar;
import java.io.IOException;
import java.util.List;
public class ContactMapActivity extends AppCompatActivity implements OnMapReadyCallback {
final int PERMISSION_REQUEST_LOCATION = 101;
GoogleMap gMap;
FusedLocationProviderClient fusedLocationProviderClient;
LocationRequest locationRequest;
LocationCallback locationCallback;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_contact_map);
fusedLocationProviderClient = LocationServices.getFusedLocationProviderClient(this);
SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map);
mapFragment.getMapAsync(this);
createLocationRequest();
createLocationCallback();
initListButton();
initSettingsButton();
}
private void initListButton() {
ImageButton contactList = findViewById(R.id.imageButtonList);
contactList.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
Intent intent = new Intent(ContactMapActivity.this, ContactListActivity.class); // A mew Intent is created, the Intent's constructors requires reference to the current activity and know what activity to start
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);
}
});
}
private void initSettingsButton() {
ImageButton contactList = findViewById(R.id.imageButtonSettings);
contactList.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
Intent intent = new Intent(ContactMapActivity.this, ContactSettingsActivity.class); // A mew Intent is created, the Intent's constructors requires reference to the current activity and know what activity to start
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);
}
});
}
@Override
public void onRequestPermissionsResult(int requestCode,
String permissions[], int[] grantResults) {
switch (requestCode) {
case PERMISSION_REQUEST_LOCATION: {
System.out.println(grantResults.length);
System.out.println(grantResults[0]);
System.out.println(PackageManager.PERMISSION_GRANTED);
if (grantResults.length > 0 &&
grantResults[0] == PackageManager.PERMISSION_GRANTED) {
startLocationUpdates();
} else {
Toast.makeText(ContactMapActivity.this,
"MyContactList will not locate your contacts.",
Toast.LENGTH_LONG).show();
}
}
}
}
@Override
public void onPause() {
super.onPause();
if (Build.VERSION.SDK_INT >= 23 &&
ContextCompat.checkSelfPermission(getBaseContext(),
android.Manifest.permission.ACCESS_FINE_LOCATION) !=
PackageManager.PERMISSION_GRANTED &&
ContextCompat.checkSelfPermission(getBaseContext(),
Manifest.permission.ACCESS_COARSE_LOCATION) !=
PackageManager.PERMISSION_GRANTED) {
return;
}
}
private void createLocationRequest() {
locationRequest = LocationRequest.create();
locationRequest.setInterval(10000);
locationRequest.setFastestInterval(5000);
locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
}
private void createLocationCallback() {
locationCallback = new LocationCallback() {
@Override
public void onLocationResult (LocationResult locationResult) {
if (locationResult == null) {
return;
}
for (Location location : locationResult.getLocations()) {
Toast.makeText(getBaseContext(), "Lat: " + location.getLatitude() +
" Long: " + location.getLongitude() +
"Accuracy: " + location.getAccuracy(),Toast.LENGTH_LONG).show();
}
};
};
}
private void startLocationUpdates() {
if ( Build.VERSION.SDK_INT >= 23 && ContextCompat.checkSelfPermission(getBaseContext(),
Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED
&& ContextCompat.checkSelfPermission( getBaseContext(),
Manifest.permission.ACCESS_COARSE_LOCATION) !=
PackageManager.PERMISSION_GRANTED) {
return;
}
fusedLocationProviderClient.requestLocationUpdates(locationRequest, locationCallback, null);
gMap.setMyLocationEnabled(true);
}
private void stopLocationUpdates() {
if ( Build.VERSION.SDK_INT >= 23 && ContextCompat.checkSelfPermission(getBaseContext(),
Manifest.permission.ACCESS_FINE_LOCATION) !=PackageManager.PERMISSION_GRANTED &&
ContextCompat.checkSelfPermission( getBaseContext(),
Manifest.permission.ACCESS_COARSE_LOCATION) !=
PackageManager.PERMISSION_GRANTED)
{
return;
}
fusedLocationProviderClient.removeLocationUpdates(locationCallback);
}
@Override
public void onMapReady(GoogleMap googleMap) {
gMap = googleMap;
gMap.setMapType(GoogleMap.MAP_TYPE_NORMAL);
try {
if (Build.VERSION.SDK_INT >= 23) {
if (ContextCompat.checkSelfPermission(ContactMapActivity.this,
android.Manifest.permission.ACCESS_FINE_LOCATION) !=
PackageManager.PERMISSION_GRANTED) {
if (ActivityCompat.shouldShowRequestPermissionRationale
(ContactMapActivity.this,
android.Manifest.permission.ACCESS_FINE_LOCATION)) {
Snackbar.make(findViewById(R.id.activity_contact_map),
"MyContactList requires this permission to locate " +
"your contacts", Snackbar.LENGTH_INDEFINITE)
.setAction("OK", new View.OnClickListener() {
@Override
public void onClick(View view) {
ActivityCompat.requestPermissions(
ContactMapActivity.this,
new String[]{
Manifest.permission.ACCESS_FINE_LOCATION},
PERMISSION_REQUEST_LOCATION);
}
})
.show();
} else {
ActivityCompat.requestPermissions(ContactMapActivity.this, new
String[]{Manifest.permission.ACCESS_FINE_LOCATION},
PERMISSION_REQUEST_LOCATION);
}
} else {
startLocationUpdates();
}
} else {
startLocationUpdates();
}
} catch (Exception e) {
Toast.makeText(getBaseContext(), "ERROR requesting permission", Toast.LENGTH_LONG).show();
}
}
}
here is the xml for activity_contact_map
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/activity_contact_map"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".ContactMapActivity">
<LinearLayout
android:id="@+id/linearLayout"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:background="@color/navbar_background"
android:orientation="horizontal"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent">
<ImageButton
android:id="@+id/imageButtonList"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:contentDescription="@string/button_to_display_a_list_of_contacts"
app:srcCompat="@drawable/paperclip" />
<ImageButton
android:id="@+id/imageButtonMap"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:contentDescription="@string/show_map_of_contact_location"
app:srcCompat="@drawable/placeholder" />
<ImageButton
android:id="@+id/imageButtonSettings"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:contentDescription="@string/show_settings"
app:srcCompat="@drawable/settings" />
</LinearLayout>
<fragment
android:id="@+id/map"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_alignParentTop="true"
app:layout_constraintBottom_toTopOf="@+id/linearLayout"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
/>
</androidx.constraintlayout.widget.ConstraintLayout>
This is some of the errors I am getting
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.mycontactlist, PID: 8885
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.mycontactlist/com.example.mycontactlist.ContactMapActivity}: android.view.InflateException: Binary XML file line #45 in com.example.mycontactlist:layout/activity_contact_map: Binary XML file line #45 in com.example.mycontactlist:layout/activity_contact_map: Error inflating class fragment
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3449)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3601)
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:85)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2066)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:223)
at android.app.ActivityThread.main(ActivityThread.java:7656)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:947)
Caused by: android.view.InflateException: Binary XML file line #45 in com.example.mycontactlist:layout/activity_contact_map: Binary XML file line #45 in com.example.mycontactlist:layout/activity_contact_map: Error inflating class fragment
Caused by: android.view.InflateException: Binary XML file line #45 in com.example.mycontactlist:layout/activity_contact_map: Error inflating class fragment
Caused by: java.lang.NullPointerException
at java.lang.VMClassLoader.findLoadedClass(Native Method)
at java.lang.ClassLoader.findLoadedClass(ClassLoader.java:738)
at java.lang.ClassLoader.loadClass(ClassLoader.java:363)
at java.lang.ClassLoader.loadClass(ClassLoader.java:312)
at android.app.Fragment.instantiate(Fragment.java:536)
at android.app.FragmentContainer.instantiate(FragmentContainer.java:53)
at android.app.FragmentManagerImpl.onCreateView(FragmentManager.java:3553)
at android.app.FragmentController.onCreateView(FragmentController.java:104)
at android.app.Activity.onCreateView(Activity.java:7112)
at androidx.fragment.app.FragmentActivity.onCreateView(FragmentActivity.java:338)
at android.view.LayoutInflater.tryCreateView(LayoutInflater.java:1067)
at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:995)
at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:959)
at android.view.LayoutInflater.rInflate(LayoutInflater.java:1121)
at android.view.LayoutInflater.rInflateChildren(LayoutInflater.java:1082)
at android.view.LayoutInflater.inflate(LayoutInflater.java:680)
at android.view.LayoutInflater.inflate(LayoutInflater.java:532)
at android.view.LayoutInflater.inflate(LayoutInflater.java:479)
at androidx.appcompat.app.AppCompatDelegateImpl.setContentView(AppCompatDelegateImpl.java:696)
at androidx.appcompat.app.AppCompatActivity.setContentView(AppCompatActivity.java:170)
at com.example.mycontactlist.ContactMapActivity.onCreate(ContactMapActivity.java:43)
at android.app.Activity.performCreate(Activity.java:8000)
at android.app.Activity.performCreate(Activity.java:7984)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1309)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3422)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3601)
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:85)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2066)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:223)
at android.app.ActivityThread.main(ActivityThread.java:7656)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:947)
This is the exception it is jumping to:
private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
ActivityInfo aInfo = r.activityInfo;
if (r.packageInfo == null) {
r.packageInfo = getPackageInfo(aInfo.applicationInfo, r.compatInfo,
Context.CONTEXT_INCLUDE_CODE);
}
ComponentName component = r.intent.getComponent();
if (component == null) {
component = r.intent.resolveActivity(
mInitialApplication.getPackageManager());
r.intent.setComponent(component);
}
if (r.activityInfo.targetActivity != null) {
component = new ComponentName(r.activityInfo.packageName,
r.activityInfo.targetActivity);
}
ContextImpl appContext = createBaseContextForActivity(r);
Activity activity = null;
try {
java.lang.ClassLoader cl = appContext.getClassLoader();
activity = mInstrumentation.newActivity(
cl, component.getClassName(), r.intent);
StrictMode.incrementExpectedActivityCount(activity.getClass());
r.intent.setExtrasClassLoader(cl);
r.intent.prepareToEnterProcess();
if (r.state != null) {
r.state.setClassLoader(cl);
}
} catch (Exception e) {
if (!mInstrumentation.onException(activity, e)) {
throw new RuntimeException(
"Unable to instantiate activity " + component
+ ": " + e.toString(), e);
}
}
try {
Application app = r.packageInfo.makeApplication(false, mInstrumentation);
if (localLOGV) Slog.v(TAG, "Performing launch of " + r);
if (localLOGV) Slog.v(
TAG, r + ": app=" + app
+ ", appName=" + app.getPackageName()
+ ", pkg=" + r.packageInfo.getPackageName()
+ ", comp=" + r.intent.getComponent().toShortString()
+ ", dir=" + r.packageInfo.getAppDir());
if (activity != null) {
CharSequence title = r.activityInfo.loadLabel(appContext.getPackageManager());
Configuration config = new Configuration(mCompatConfiguration);
if (r.overrideConfig != null) {
config.updateFrom(r.overrideConfig);
}
if (DEBUG_CONFIGURATION) Slog.v(TAG, "Launching activity "
+ r.activityInfo.name + " with config " + config);
Window window = null;
if (r.mPendingRemoveWindow != null && r.mPreserveWindow) {
window = r.mPendingRemoveWindow;
r.mPendingRemoveWindow = null;
r.mPendingRemoveWindowManager = null;
}
// Activity resources must be initialized with the same loaders as the
// application context.
appContext.getResources().addLoaders(
app.getResources().getLoaders().toArray(new ResourcesLoader[0]));
appContext.setOuterContext(activity);
activity.attach(appContext, this, getInstrumentation(), r.token,
r.ident, app, r.intent, r.activityInfo, title, r.parent,
r.embeddedID, r.lastNonConfigurationInstances, config,
r.referrer, r.voiceInteractor, window, r.configCallback,
r.assistToken);
if (customIntent != null) {
activity.mIntent = customIntent;
}
r.lastNonConfigurationInstances = null;
checkAndBlockForNetworkAccess();
activity.mStartedActivity = false;
int theme = r.activityInfo.getThemeResource();
if (theme != 0) {
activity.setTheme(theme);
}
activity.mCalled = false;
if (r.isPersistable()) {
mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
} else {
mInstrumentation.callActivityOnCreate(activity, r.state);
}
if (!activity.mCalled) {
throw new SuperNotCalledException(
"Activity " + r.intent.getComponent().toShortString() +
" did not call through to super.onCreate()");
}
r.activity = activity;
mLastReportedWindowingMode.put(activity.getActivityToken(),
config.windowConfiguration.getWindowingMode());
}
r.setState(ON_CREATE);
// updatePendingActivityConfiguration() reads from mActivities to update
// ActivityClientRecord which runs in a different thread. Protect modifications to
// mActivities to avoid race.
synchronized (mResourcesManager) {
mActivities.put(r.token, r);
}
} catch (SuperNotCalledException e) {
throw e;
} catch (Exception e) {
if (!mInstrumentation.onException(activity, e)) {
throw new RuntimeException(
"Unable to start activity " + component
+ ": " + e.toString(), e);
}
}
return activity;
}