2010-01-12 12 views
40

Oggi ho provato a includere il pacchetto apache.commons.codec nella mia applicazione Android e non ho potuto farlo funzionare. Android non riusciva a trovare il metodo ord.apache.commons.codec.binary * e uscita i seguenti errori nel DDMSApache Commons Codec con Android: impossibile trovare il metodo

01-12 08:. 41: 48.161: ERRORE/dalvikvm (457): Impossibile trovare il metodo org .apache.commons.codec.binary.Base64.encodeBase64URLSafeString, richiamati da metodo com.dqminh.app.util.Util.sendRequest

01-12 08: 41: 48,161: WARN/dalvikvm (457): VFY: incapace per risolvere il metodo statico 10146: Lorg/apache/commons/codec/binary/Base64; .encodeBase64URLSafeString ([B) Ljava/lang/String;

1-12 agosto: 41: 48,161: WARN/dalvikvm (457): VFY: rifiutando codice operativo 0x71 a 0x0004

Qualsiasi indizio su come risolvere questo problema? Molte grazie.

+3

Hai una qualsiasi delle classi in 'apache.commons.codec' di lavoro? Quindi è un problema particolare con solo questa classe o pensi che nessuna delle classi sia disponibile? –

risposta

49

Ho avuto un problema simile durante l'utilizzo di Android con uno OAuth library che sto sviluppando.

Ho anche ricevuto da Android che, sebbene avessi incluso apache.commons.codec nel classpath, non è stato trovato un metodo particolare (encodeBase64String).

Controllo delle javadocs, entrambi i metodi sostengono di essere 1.4 e una maggiore solo, quindi la mia ipotesi è che Android include già una versione precedente di commons.codec dove questi metodi sono davvero indefiniti.

La mia soluzione era quella di utilizzare un metodo più vecchio, in questo modo:

String encodedString = new String(Base64.encodeBase64('string to encode')); 

Il metodo che si desidera utilizzare è diverso dal momento che sostituisce + e/con i valori url-safe - e _. Quindi probabilmente potrebbe usare qualcosa come:

String encodedString = new String(Base64.encodeBase64('string to encode')); 
String safeString = encodedString.replace('+','-').replace('/','_'); 

Speranza che aiuta!

+0

Ho lottato con questo per due giorni ora! Solo una domanda però, se dovessi sostituire il + e - come andrei sulla decodifica? Che cosa succede se la stringa codificata originale (prima della sostituzione) già contenuta + e - grazie – jax

+0

Credo che non importa, si dovrebbe fare proprio lo stesso come l'esempio precedente –

+0

il codice funziona .... encodeBase64URLSafeString non funziona –

10

Ho avuto lo stesso identico problema. Così ho iniziato a sfogliare il codice sorgente di Android e, come risulta, l'ipotesi di Pablo Fernandez su Android di avere un'implementazione di org.apache.commons.code.binary è corretta. Tuttavia, la sua versione 1.2 dei commons di apache, non la versione 1.4 o addirittura 1.5. Puoi vedere se stessi nell'androide source.

come nota questo è domanda è un duplicato di this post

+0

Il collegamento per "Origine" è rotto. Potresti aggiustarlo? –

+1

@MichelAyres, fatto. – zarthross

4

Si potrebbe semplicemente copiare questo bit di codice dalla libreria apache (è piuttosto isolato) http://www.java2s.com/Open-Source/Android/Blog-Twitter/twitspeak/org/apache/commons/codec/binary/Base64.java.htm

Edit: Aggiornato collegamento dalla Wayback Machine man mano che l'originale è scomparso: http://web.archive.org/web/20130610025148/http://www.java2s.com/Open-Source/Android/Blog-Twitter/twitspeak/org/apache/commons/codec/binary/Base64.java.htm

+2

Il link è rotto. –

+2

Grazie a @MichelAyres, ho aggiornato il collegamento. –

4

La mia soluzione allo stesso pr oblem doveva rinominare la classe problematica org.apache.commons.codec.binary.Base64.java in org.apache.commons.codec.binary.ApacheBase64.java. L'ho fatto usando il refactoring-rinomina di Eclipse.

In questo modo, la versione più recente soluzione di apache è conservato e utilizzato, e non v'è alcuna possibilità per accidentale problema recidiva quando la mia applicazione è alla fine di essere sollevato da Android 1.6 minimo denominatore.

Nota: l'intero albero dei sorgenti di Apache Commons era già impostato come progetto java Eclipse separato, accanto al mio progetto Android. Il mio progetto Android ha utilizzato molte classi Apache Commons, ma non è riuscito su Base64 a causa di problemi sopra descritti ...

+0

Ho avuto lo stesso identico problema con Hash ed è stato in grado di risolverlo in un modo simile (ho effettivamente rifatto i nomi dei pacchetti per l'intera libreria Codec). – tstaylor7

16

Non è necessario utilizzare apache comuni, su Android è possibile utilizzare android.util.Base64 invece.

+4

Utile, ma richiede il livello API 8 (2.2.x). –

+2

Non funziona se si utilizza una libreria che dipende da Commons-Codec. – William

+6

Si noti che è necessario utilizzare 'Base64.encode (" foobar ".getBytes(), Base64.Base64.NO_WRAP);' per ottenere esattamente lo stesso risultato della libreria di apache commons. Vedi: http://stackoverflow.com/questions/17912119 –

2

Si prega di notare che questa risposta è stata fatta da Dylan Watson nei commenti di cui sopra:

essere consapevoli del fatto che è necessario utilizzare Base64.encode (.getBytes "foobar"(), Base64.Base64.NO_WRAP) ; per ottenere esattamente lo stesso risultato della libreria di apache commons. Vedi: stackoverflow.com/questions/17912119

Questa risposta è stata l'unica che ha funzionato dopo ore di tentativi di comunicare la mia app Android con un'app "desktop" java.

ecco qualche codice sorgente, forse sarà aiutare gli altri:

codice della applet scrivania:

private static String convertToBase64(String s) { 
     byte[] bytes = new byte[0]; 
     try { 
      bytes = (s.getBytes()); 
     } catch (Exception e) { 
      e.printStackTrace(); 
     } 
     return DatatypeConverter.printBase64Binary(bytes); 
    } 

Questo frammento è utilizzato nel applicazione 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; 
    } 
+0

Mi ha aiutato molto. Specialmente quando si utilizza la firma aws che genera la classe java "SignedRequestsHelper" per firmare l'url che utilizza "org.apache.commons.codec.binary.Base64". Ma in Android dobbiamo usare "android.util.Base64" Dovevo sostituire "Base64 encoder = new Base64(); signature = new String (encoder.encode (rawHmac));" con "signature = new String (Base64.encode (rawHmac, Base64.NO_WRAP)," UTF-8 ");" per farlo funzionare. Il commento elaborato è per i futuri richiedenti l'aiuto. Possa aiutare gli altri. Grazie..... – Ashiq

0

Hai incluso Apache lib comuni del progetto, come GAV

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 

il s' commons-codec è

commons-codec:commons-codec 

ma il nome del pacchetto è

org.apache.commons.codec 

questo nome pacchetto sarà in conflitto con le librerie comuni apache progetto, provare a cambiare il nome del pacchetto di commons-codec, quindi generare come un vaso o importare il codice sorgente aveva cambiato il nome del pacchetto;

0

Sapendo che si tratta di una vecchia questione, ma ho affrontato questo problema di recente durante la compilazione per l'API livello , e ha trovato un'altra soluzione per il problema: utilizzare guava progetto.

// 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)); 

La biblioteca guava (18,0) era la versione che ho usato, e il cambiamento era liscia. Il codice funziona come previsto.

soluzione trovata qui: https://memorynotfound.com/encode-decode-base64-string-using-native-java/