One of several thousand customers reported an error in one of my apps. The error is:
java.lang.NoClassDefFoundError - android.security.MessageDigest
<
I have found simple work around! Just create in src directory package android\security and place MessageDigest.java inside.
package android.security;
import java.security.NoSuchAlgorithmException;
public class MessageDigest
{
private java.security.MessageDigest instance;
public MessageDigest() {}
private MessageDigest(java.security.MessageDigest instance)
{
this.instance = instance;
}
public static MessageDigest getInstance(String algorithm) throws NoSuchAlgorithmException
{
if (algorithm == null) return null;
try
{
if (algorithm.equals("SHA-1"))
return (MessageDigest) Class.forName("android.security.Sha1MessageDigest").newInstance();
else if (algorithm.equals("MD5"))
return (MessageDigest) Class.forName("android.security.Md5MessageDigest").newInstance();
}
catch (Exception e) {}
return new MessageDigest(java.security.MessageDigest.getInstance(algorithm));
}
public void update(byte[] input)
{
instance.update(input);
}
public byte[] digest()
{
return instance.digest();
}
public byte[] digest(byte[] input)
{
return instance.digest(input);
}
}
It is works, but may accrue other exceptions because of map library not match android version!
The MessageDigest class is a helper class used to encode/decode keys, using common methods such as MD5 or SHA-1.
It seems that the class android.security.MessageDigest was removed from Honeycomb and later releases of Android, and must be replaced by java.security.MessageDigest (see this page)
Try downloading the latest version of the Google Maps API and rebuild your application with targetSDK set to the highest available (as of today it should be 16 / Jelly Bean).
I spent some time looking into this problem, and I'm documenting what I've found here in the hopes that it saves other people some trouble.
The error is the result of a device manufacturer or ROM creator using an older maps library with a new version of Android. Typically, this is isolated to obscure tablets, but it could theoretically appear in other situations. It's possible to recreate this problem in an emulator using following these steps:
adb pull /system/framework/com.google.android.maps.jar <destination_folder>
You can close the emulator once you've done this.adb remount
adb push <destination_folder>/com.google.android.maps.jar /system/framework
adb reboot
but that just hung the emulator. Instead, you'll need to kill a particular process which has the same effect. In Eclipse/DDMS it will be called system_process
and you can kill it there. Alternatively, you can run this command:adb shell ps | grep system_server | awk '{print $2}' | xargs adb shell kill
This process isn't permanent. Restarting the emulator reverts it to its normal working state.
It's possible to detect this problem by getting the KeyHelper.getSignatureFingerprint()
method in the maps library via reflection and invoking it - passing a PackageManager
and your package name as arguments. Alternatively, you can trap the error in onCreate()
and load a new activity instead.