Edit: following is the official solution from Google (link)
Google Maps SDK thread crashes App (ArrayIndexOutOfBoundsException) - Solution Offered
On April 23 2020 starting at 11:30 PDT, Google served for 4 hours an update to the configuration of a Maps mobile component, triggering crashes in Maps SDKs for Android and iOS. Applications on devices that downloaded this version of the configuration (during the outage period) were vulnerable to the crash. Workaround solutions are offered for Maps SDKs for Android and iOS.
Maps SDK for Android v2 (included in Google Play Services)
The updates to Google Play Services to fix the crash has been published to all devices with Google Play Services version 17.4.55 and newer. There is no change to the version number of Google Play Services on the device after the update is installed. No action is required from developers or end users to receive the updated Maps module; however, developers can verify that the module is present on a given device with the following adb command:
adb shell dumpsys activity provider com.google.android.gms.chimera.container.GmsModuleProvider
You should see the line Module Set ID: maps
listed in the Module Sets
section.
Module Set ID: maps, Module Set Version: 2015120015120000
The crash rates of Maps SDK for Android v2 are back to normal.
As of now, if you have not updated your app with the client-side code workarounds mentioned below, you do not need to take further action.
If you have already updated your app with the workarounds, you can remove the workaround in a subsequent update of your app (but keeping the workaround is safe).
Premium Plan Maps SDK for Android v2 or Maps SDK for Android v3 beta (static libraries)
If your app uses the Premium Plan Maps SDK for Android v2 or Maps SDK for Android v3 beta (static libraries), and is still experiencing crashes, we still highly recommend you to roll out the workarounds below via an update to your app. As your application is loading a static version of the SDK which is vulnerable to the bad data being stored on some devices, only an update to your application can solve the problem.
Play Store review approvals
If you update your app but experience Play Store review approvals delays, please file a support case with your app’s Package ID: Contact the support team. Our Support Team will internally escalate your request and expedite the approval.
Negative reviews in the Google Play Store
Some application developers inquired about 1-star reviews in the Google Play Store left by end-users due to crashes. Only comments that violate Google Play's policy [ 1 ] can be removed. You can also flag abusive reviews in the Play Console [ 2 ]. Applications will not be automatically removed from the Google Play store due to negative reviews. It's also worth noting that the calculation of your overall app review rating favors recent reviews, which means that your rating will recover to pre-incident levels over time.
[ 1 ] Ratings & Review on the Play Store
[ 2 ] Report inappropriate reviews
Crash rates on iOS are back to normal. If your application is still experiencing crashes, you need to update and publish your app with the code workarounds communicated here.
For questions about deploying or expediting your application in the Apple App Store, please contact Apple directly.
With this update, we are closing this issue. Thank you to everyone for your patience. Our team is performing an in-depth internal investigation of this incident; as soon as possible, we will publish our analysis (in approximately a week). In the meantime, if you have any questions, or are still experiencing problems, please file a support case.
End users on Android can clear the affected app's data (not just the cache).
End users on iOS can uninstall then reinstall the affected app(s).
App Developers can apply the code workarounds below in order to solve the issue for all their end users.
Code workaround for iOS:
Recommended placement for the code is before GMSServices initialization in the application(_:didFinishLaunchingWithOptions:) (Swift) or application:didFinishLaunchingWithOptions: (Objective-C) method. Specifically:
Swift:
let key = "GoogleMapsServerControlledParamsKey_bug_154855417"
if !UserDefaults.standard.bool(forKey: key) {
let urls = FileManager.default.urls(for: .applicationSupportDirectory, in: .userDomainMask)
if urls.count > 0 {
let paramUrl = urls[0].appendingPathComponent("com.google.GoogleMaps/ServerControlledParams", isDirectory: false)
try? FileManager.default.removeItem(at: paramUrl)
}
UserDefaults.standard.set(true, forKey: key)
}
Objective-C:
NSString *key = @"GoogleMapsServerControlledParamsKey_bug_154855417";
BOOL keyExists = [[NSUserDefaults standardUserDefaults] boolForKey:key];
if (!keyExists) {
NSArray<NSURL *> *array =
[[NSFileManager defaultManager] URLsForDirectory:NSApplicationSupportDirectory
inDomains:NSUserDomainMask];
if (array.count > 0) {
NSURL *url =
[array[0] URLByAppendingPathComponent:@"com.google.GoogleMaps/ServerControlledParams"
isDirectory:NO];
if (url) {
[[NSFileManager defaultManager] removeItemAtURL:url error:NULL];
}
}
[[NSUserDefaults standardUserDefaults] setBool:YES forKey:key];
}
Code workaround for Android:
The recommended placement for the code is in Application.onCreate():
Java
try {
SharedPreferences hasFixedGoogleBug154855417 = getSharedPreferences("google_bug_154855417", Context.MODE_PRIVATE);
if (!hasFixedGoogleBug154855417.contains("fixed")) {
File corruptedZoomTables = new File(getFilesDir(), "ZoomTables.data");
File corruptedSavedClientParameters = new File(getFilesDir(), "SavedClientParameters.data.cs");
File corruptedClientParametersData =
new File(
getFilesDir(),
"DATA_ServerControlledParametersManager.data."
+ getBaseContext().getPackageName());
File corruptedClientParametersDataV1 =
new File(
getFilesDir(),
"DATA_ServerControlledParametersManager.data.v1."
+ getBaseContext().getPackageName());
corruptedZoomTables.delete();
corruptedSavedClientParameters.delete();
corruptedClientParametersData.delete();
corruptedClientParametersDataV1.delete();
hasFixedGoogleBug154855417.edit().putBoolean("fixed", true).apply();
}
} catch (Exception e) {
}
Kotlin
try {
val sharedPreferences = getSharedPreferences("google_bug_154855417", Context.MODE_PRIVATE)
if (!sharedPreferences.contains("fixed")) {
val corruptedZoomTables = File(filesDir, "ZoomTables.data")
val corruptedSavedClientParameters = File(filesDir, "SavedClientParameters.data.cs")
val corruptedClientParametersData = File(filesDir, "DATA_ServerControlledParametersManager.data.${packageName}")
val corruptedClientParametersDataV1 = File(filesDir, "DATA_ServerControlledParametersManager.data.v1.${packageName}")
corruptedZoomTables.delete()
corruptedSavedClientParameters.delete()
corruptedClientParametersData.delete()
corruptedClientParametersDataV1.delete()
sharedPreferences.edit().putBoolean("fixed", true).apply()
}
} catch (exception: Exception) {
}
The workarounds provided here covers all available flavors and versions of our SDKs for Android. To clarify further (in case you released an earlier version of the workaround that did not delete as many files):
Applications that use Maps Android SDK v3 beta should only need to delete one file, either
DATA_ServerControlledParametersManager.data.v1. + getBaseContext().getPackageName()) or
DATA_ServerControlledParametersManager.data. + getBaseContext().getPackageName())
Seems in every app Google Map creates ZoomTables.data file.
This file was malformed, malformed version of it that could be downloaded from comment. To reproduce the issue remove ZoomTables.data from the app packages on the device and insert malformed one. The app should crash.
Currently, the issue was solved on google's side, but the apps still contain a cached version of that data file. To fix the issue we should remove that file right on the app start in Application onCreate Method.
private void fixGoogleMapBug() {
try {
SharedPreferences hasFixedGoogleBug154855417 = getSharedPreferences("google_bug_154855417", Context.MODE_PRIVATE);
if (!hasFixedGoogleBug154855417.contains("fixed")) {
File corruptedZoomTables = new File(getFilesDir(), "ZoomTables.data");
File corruptedSavedClientParameters = new File(getFilesDir(), "SavedClientParameters.data.cs");
File corruptedClientParametersData =
new File(
getFilesDir(),
"DATA_ServerControlledParametersManager.data."
+ getBaseContext().getPackageName());
File corruptedClientParametersDataV1 =
new File(
getFilesDir(),
"DATA_ServerControlledParametersManager.data.v1."
+ getBaseContext().getPackageName());
corruptedZoomTables.delete();
corruptedSavedClientParameters.delete();
corruptedClientParametersData.delete();
corruptedClientParametersDataV1.delete();
hasFixedGoogleBug154855417.edit().putBoolean("fixed", true).apply();
}
} catch (Exception e) {
}
}
Update 1
I've updated workaround, base on the latest google developers comment:
The workarounds provided here covers all available flavors and versions of our SDKs for Android. To clarify further (in case you released an earlier version of the workaround that did not delete as many files):
Applications that use Maps Android SDK v2 should only need to delete one file: ZoomTables.data. Applications that use Maps Android SDK v3 beta should only need to delete one file, either DATA_ServerControlledParametersManager.data.v1. + getBaseContext().getPackageName()) or DATA_ServerControlledParametersManager.data. + getBaseContext().getPackageName())
This solution worked for me
First open "App Info"
Choose "Storage"
Click "Clear data"
Open app again and check if the issue fixed.
Below are suggestions just to help your customers.
Send an email to your all users for the inconvenience and describe them the issue they faced and give them above mentioned steps to resolve their issue.
You can also send Push Notification to all your users with Firebase Push Notifications, if your app have the push notifications service.
Screenshots demonstration:
Drawbacks of solutions above:
Drawbacks of my solution:
My solution catches the Exception thrown by the Maps SDK, call this in onCreate of the Application class:
public static void catchGoogleMapsException(final Context context)
{
final Thread.UncaughtExceptionHandler defaultHandler =
Thread.getDefaultUncaughtExceptionHandler();
Thread.setDefaultUncaughtExceptionHandler(
(@NonNull final Thread thread, @NonNull final Throwable ex) ->
{
if (thread.getName().contains("ZoomTableManager"))
{
new File(context.getFilesDir(), "ZoomTables.data").delete();
Log.w("Maps Bug 154855417", "Caught exception and deleted ZoomTables.data");
}
else
if (defaultHandler!=null)
defaultHandler.uncaughtException(thread, ex);
else
throw new RuntimeException(
"No default uncaught exception handler.", ex);
});
}
For Android, multiple developers mentioned a workaround consisting in deleting the ZoomTable.data file directly from their application. After review, this fix seems safe, and you could try it in your application.
Please refer to https://issuetracker.google.com/154855417#comment179
If you want your users to continue using your app without re-installing, The sample code is copy-pasted here for your convenience. In Application.onCreate():
SharedPreferences googleBug = getSharedPreferences("google_bug_154855417", Context.MODE_PRIVATE);
if (!googleBug.contains("fixed")) {
File corruptedZoomTables = new File(getFilesDir(), "ZoomTables.data");
corruptedZoomTables.delete();
googleBug.edit().putBoolean("fixed", true).apply();
}
reference: Google Maps SDK is crashing -- partially resolved
https://issuetracker.google.com/issues/154855417#comment509
The updates to Google Play Services to fix the crash has been published to all devices with Google Play Services version 17.4.55 and newer. There is no change to the version number of Google Play Services on the device after the update is installed. No action is required from developers or end users to receive the updated Maps module; however, developers can verify that the module is present on a given device with the following adb command:
adb shell dumpsys activity provider com.google.android.gms.chimera.container.GmsModuleProvider
You should see the line Module Set ID: maps
listed in the Module Sets
section.
Module Set ID: maps, Module Set Version: 2015120015120000
The crash rates of Maps SDK for Android v2 are back to normal.
As of now, if you have not updated your app with the client-side code workarounds mentioned below, you do not need to take further action.
If you have already updated your app with the workarounds, you can remove the workaround in a subsequent update of your app (but keeping the workaround is safe).
The productive version was fixed (on google's side) but if you still have problems with your emulator you have to run the following code only once.
The recommended placement for the code is in Application.onCreate():
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
fixGoogleMapBugTemp() //TODO: Then clean this line
// ...
}
/**
* Observation: Invoke this method only once
*/
private fun fixGoogleMapBugTemp() {
val googleBug = getSharedPreferences("google_bug_154855417", Context.MODE_PRIVATE)
if (!googleBug.contains("fixed")) {
val corruptedZoomTables = File(filesDir, "ZoomTables.data");
corruptedZoomTables.delete();
googleBug.edit().putBoolean("fixed", true).apply();
}
}
Workaround: Clear application data (not just the cache).
Note: A copy of the problematic file from the app packages on the device if anyone needs it for repro.
Source
GL
Complete & official answer for all :
Diagnosis: Crash of the Google Maps Platform mobile SDKs (iOS & Android) at load.
Workaround: * Clear the affected app's data (not just the cache), or uninstall then reinstall the affected app(s).
Recommended placement for the code is before GMSServices initialization in the application(_:didFinishLaunchingWithOptions:) (Swift) or application:didFinishLaunchingWithOptions: (Objective-C) method. Specifically:
let key = "GoogleMapsServerControlledParamsKey_bug_154855417"
if !UserDefaults.standard.bool(forKey: key) {
let urls = FileManager.default.urls(for: .applicationSupportDirectory, in: .userDomainMask)
if urls.count > 0 {
let paramUrl = urls[0].appendingPathComponent("com.google.GoogleMaps/ServerControlledParams", isDirectory: false)
try? FileManager.default.removeItem(at: paramUrl)
}
UserDefaults.standard.set(true, forKey: key)
}
NSString *key = @"GoogleMapsServerControlledParamsKey_bug_154855417";
BOOL keyExists = [[NSUserDefaults standardUserDefaults] boolForKey:key];
if (!keyExists) {
NSArray<NSURL *> *array =
[[NSFileManager defaultManager] URLsForDirectory:NSApplicationSupportDirectory
inDomains:NSUserDomainMask];
if (array.count > 0) {
NSURL *url =
[array[0] URLByAppendingPathComponent:@"com.google.GoogleMaps/ServerControlledParams"
isDirectory:NO];
if (url) {
[[NSFileManager defaultManager] removeItemAtURL:url error:NULL]);
}
}
[[NSUserDefaults standardUserDefaults] setBool:YES forKey:key];
}
Once you have deployed it in your app, you can file a Maps Support case if you would like us to help expedite its approval. Please make sure to include your application's ID, Bundle ID, and the version you want reviewed in your case.
Code workaround for Android:
The recommended placement for the code is in Application.onCreate():
try {
SharedPreferences hasFixedGoogleBug154855417 = getSharedPreferences("google_bug_154855417", Context.MODE_PRIVATE);
if (!hasFixedGoogleBug154855417.contains("fixed")) {
File corruptedZoomTables = new File(getFilesDir(), "ZoomTables.data");
File corruptedSavedClientParameters = new File(getFilesDir(), "SavedClientParameters.data.cs");
File corruptedClientParametersData =
new File(
getFilesDir(),
"DATA_ServerControlledParametersManager.data.v1."
+ getBaseContext().getPackageName());
corruptedZoomTables.delete();
corruptedSavedClientParameters.delete();
corruptedClientParametersData.delete();
hasFixedGoogleBug154855417.edit().putBoolean("fixed", true).apply();
}
} catch (Exception e) {
}
try {
val sharedPreferences = getSharedPreferences("google_bug_154855417", Context.MODE_PRIVATE)
if (!sharedPreferences.contains("fixed")) {
val corruptedZoomTables = File(filesDir, "ZoomTables.data")
val corruptedSavedClientParameters = File(filesDir, "SavedClientParameters.data.cs")
val corruptedClientParametersData = File(filesDir, "DATA_ServerControlledParametersManager.data.v1.${packageName}")
corruptedZoomTables.delete()
corruptedSavedClientParameters.delete()
corruptedClientParametersData.delete()
sharedPreferences.edit().putBoolean("fixed", true).apply()
}
} catch (exception: Exception) {
}
Source : https://issuetracker.google.com/issues/1548554
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With