Кодек Apache Commons с Android: не удалось найти метод
Сегодня я попытался включить пакет apache.commons.codec в свое приложение для Android и не смог его запустить. Android не смог найти метод ord.apache.commons.codec.binary.* И вывел следующие ошибки в DDMS
01-12 08: 41: 48.161: ОШИБКА /dalvikvm(457): не удалось найти метод org.apache.commons.codec.binary.Base64.encodeBase64URLSafeString, на который ссылается метод com.dqminh.app.util.Util.sendRequest
01-12 08: 41: 48.161: WARN /dalvikvm(457): VFY: невозможно разрешить статический метод 10146: Lorg / apache / commons / codec / binary / Base64;.encodeBase64URLSafeString ([B) Ljava / lang / String;
01-12 08: 41: 48.161: WARN /dalvikvm(457): VFY: отклонение кода операции 0x71 в 0x0004
Любая подсказка о том, как решить эту проблему? Большое спасибо.
11 ответов
У меня была похожая проблема при использовании Android с библиотекой OAuth, которую я разрабатываю.
Я также получил от Android, хотя я включил apache.commons.codec
в пути к классу, конкретный метод (encodeBase64String
) не был найден.
Проверяя javadocs, оба метода утверждают, что они имеют версию 1.4 и выше, поэтому я предполагаю, что Android уже включает в себя более старую версию commons.codec
где эти методы действительно не определены.
Моим решением было использовать более старый метод, например так:
String encodedString = new String(Base64.encodeBase64('string to encode'));
Метод, который вы хотите использовать, отличается тем, что заменяет + и / на URL-безопасные значения - и _. Таким образом, вы, вероятно, можете использовать что-то вроде:
String encodedString = new String(Base64.encodeBase64('string to encode'));
String safeString = encodedString.replace('+','-').replace('/','_');
Надеюсь, это поможет!
Вам не нужно использовать Apache Commons, на Android вы можете использовать вместо Android.util.Base64.
Я испытал точно такую же проблему. Поэтому я начал просматривать исходный код Android, и, как оказалось, предположение Пабло Фернандеса о том, что Android имеет реализацию org.apache.commons.code.binary, является правильным. Тем не менее, его версия 1.2 Apache Commons, а не версия 1.4 или даже 1.5. Вы можете убедиться сами в источнике Android.
как примечание, это вопрос является дубликатом этого поста
Вы можете использовать следующую функцию:
private static String encodeBase64URLSafeString(byte[] binaryData) {
return android.util.Base64.encodeToString(binaryData, Base64.URL_SAFE);
}
источник + список других возможных флагов: http://developer.android.com/reference/android/util/Base64.html
Моим решением той же проблемы было переименование проблемного класса org.apache.commons.codec.binary.Base64.java
в org.apache.commons.codec.binary.ApacheBase64.java
, Я сделал это с помощью Eclipse refactor-rename.
Таким образом, самое последнее и лучшее решение Apache сохраняется и используется, и нет никаких шансов для случайного повторения проблемы, когда мое приложение в конечном итоге поднимается с Android 1.6 наименьшего знаменателя.
Заметьте, что все дерево исходников apache commons уже установлено как отдельный Java-проект Eclipse, рядом с моим проектом Android. Мой проект Android использовал много классов Apache Commons, но потерпел неудачу на Base64 из-за вышеописанных проблем...
Вы можете просто скопировать этот бит кода из библиотеки apache (он довольно изолирован) http://www.java2s.com/Open-Source/Android/Blog-Twitter/twitspeak/org/apache/commons/codec/binary/Base64.java.htm
Редактировать: Обновленная ссылка с Wayback Machine исчезла, поскольку оригинал пропал: http://web.archive.org/web/20130610025148/http://www.java2s.com/Open-Source/Android/Blog-Twitter/twitspeak/org/apache/commons/codec/binary/Base64.java.htm
Обратите внимание, что этот ответ был сделан Dylan Watson в комментариях выше:
Имейте в виду, что вам нужно использовать Base64.encode("foobar".getBytes(), Base64.Base64.NO_WRAP); чтобы получить точно такой же результат, как библиотека Apache Commons. Смотрите: stackru.com/questions/17912119
Этот ответ был единственным, который сработал после нескольких часов попыток связать мое приложение для Android с Java-приложением для рабочего стола.
Итак, вот некоторый исходный код, может быть, он поможет другим:
Код из настольного апплета:
private static String convertToBase64(String s) {
byte[] bytes = new byte[0];
try {
bytes = (s.getBytes());
} catch (Exception e) {
e.printStackTrace();
}
return DatatypeConverter.printBase64Binary(bytes);
}
Этот фрагмент используется в приложении Android:
public static String convertToBase64(String password) {
byte[] bPwd = new byte[0];
try {
bPwd = (password.getBytes("UTF-8"));
} catch (Exception e) {
e.printStackTrace();
}
try {
password = new String(Base64.encode(bPwd, Base64.NO_WRAP), "UTF-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
return password;
}
Вы можете просто импортировать следующую библиотеку в зависимости от Gradle
dependencies {
implementation "commons-codec:commons-codec:1.11"
}
Это сработает
Зная, что это старый вопрос, но я недавно столкнулся с этой проблемой при компиляции для API уровня 23 и нашел другое решение этой проблемы: используйте проект guava.
// Encoding
String encodedString = BaseEncoding.base64().encode(text.getBytes(UTF_8));
System.out.println("encodedString: " + encodedString);
// Decoding
byte[] decodedString = BaseEncoding.base64().decode(encodedString);
System.out.println("decodedString: " + new String(decodedString, UTF_8));
Библиотека guava (18.0) была версией, которую я использовал, и изменение было гладким. Код работает как положено.
Решение находится здесь: https://memorynotfound.com/encode-decode-base64-string-using-native-java/
Вы включили Apache Commons Project Lib, как
org.apache.commons:commons-compress
org.apache.commons:commons-email
org.apache.commons:commons-io
org.apache.commons:commons-lang3
org.apache.commons:commons-parent
org.apache.commons:commons-pool2
GAV общего кодека является
commons-codec:commons-codec
но это имя пакета
org.apache.commons.codec
это имя пакета будет конфликтовать с библиотеками проекта apache commons, попробуйте изменить имя пакета commons-codec, затем сгенерировать его как jar или импортировать исходный код, изменивший имя пакета;
Это работает для меня:
import org.apache.commons.codec.binary.Base64;
/**
* This is used to get the base64 from the bytes
*
* @param rawBytes the raw bytes
* @return the base64 encoded string
*/
public static String getBase64String(byte[] rawBytes) {
String base64Str = "";
if (rawBytes!= null) {
base64Str= new String(Base64.encodeBase64(rawBytes));
}
return base64Str;
}
public static byte[] getBase64DecodedString(String base64EncodedStr) {
byte[] base64Bytes = Base64.decodeBase64(base64EncodedStr.getBytes());
return bitmap;
}