2011-03-25 7 views
44

Tengo varios archivos html en la carpeta de activos. ¿Cómo puedo localizarlos? ¿Es mi única opción poner algún código de hardware para elegir el archivo correcto según la configuración regional?localización de archivos de activos

+1

Necesito usar activos porque emb las imágenes editadas en html no funcionarán desde los recursos sin procesar. Si es un html simple, crudo es el camino a seguir. aquí está tutorial para las personas que podrían ser curioso cómo leer HTML de monocube.com/2011/02/08/android-tutorial-html-file-in-webview prima – mishkin

Respuesta

54

Esto no es directamente compatible pero aquí es lo que he hecho ...

independiente de sus archivos en grupos de código de país (como lo que haría para los archivos normales de recursos) y luego crear una cadena localizada en cada uno de sus archivos string.xml localizados llamó algo así como "prefix" (donde el prefijo sería "en" para inglés, por ejemplo).

Luego, cuando construya sus nombres de archivos de activos, simplemente use algo como getString("prefix") + "-" + "<name-of-asset->.

Al menos alguna variación de lo anterior debería funcionar para usted.

+15

en crudo; gracias! la mejora de su idea un poco, puedo usar Locale.getLanguage(). subcadena (0, 2) .tolowercase() para obtener el prefijo por lo que no es necesario añadir el prefijo var a string.xml – mishkin

+8

Tenga en cuenta que 'getLanguage(). substring (0, 2) 'no es un método de versitle en android porque' zh-rTW' (taiwanese aka chinese tradicional. 'zh' es chino simplificado) no se puede manejar. – Youngjae

+1

Excelente solución. Estoy usando una variación de esto para poner las cosas en assets/en/..., assets/es/..., etc. Algo bueno es que si tienes el prefijo definido en strings.xml, sabes el directorio existirá en los activos (siempre que crea el directorio cada vez que agrega una nueva versión localizada de strings.xml). Estoy usando esto para localizar no solo html sino también otros recursos. – mkasberg

1

Tratando de localizar con assets-ja no funcionará, porque lamentablemente estos no son archivos de recursos. La mejor opción es localizar mediante programación, con la configuración regional correcta. Alternativamente, el contenido de un archivo HTML es simplemente texto sin formato. Si se ajusta a su proyecto, puede intentar almacenar esta cadena como una entrada en el archivo strings.xml (o su propio myHtmlText.xml?) De una nueva carpeta values-ja, por ejemplo.

+4

necesito utilizar activos debido incrustado imágenes en HTML no se trabajar desde crudo pero tienes razón si es un html simple, crudo es el camino a seguir. aquí hay un tutorial para personas que puedan tener curiosidad por leer html desde http://www.monocube.com/2011/02/08/android-tutorial-html-file-in-webview/ – mishkin

30

Si desea localizar un archivo HTML puede simplemente ponerlo bajo res/RAW- < idioma> /filename.html (donde < idioma> = en, es, fr, it, etc), entonces el acceso desde su código con el recurso ID R.raw.nombre de archivo. El marco elegirá el archivo correcto de acuerdo con la configuración regional.

+1

vea mi comentario anterior sobre imágenes incrustadas en HTML - es por eso que no pude usar los recursos – mishkin

+1

Esta solución es ideal para archivos como PDF. Gracias. . – Hong

+0

Perfecta en archivos txt, así ... getResources() openRawResource (R.raw.filename) – Veener

1

Al poner los archivos en la carpeta raw-LOCALE se seleccionará automáticamente la ubicación correcta, pero si carga esos archivos en las rutas de webView se romperá después de la ofuscación con Proguard.

Proguard Breaks Android WebView, Why?

entonces la única solución es utilizar la carpeta activos y utilizar el archivo de configuración regional y recoger archivos de la derecha.

1

Una alternativa al uso de un archivo por cada código de país (como se describe en Andrew White's y PJ_Finnegan's respuestas) es definir el código HTML sólo una vez (por ejemplo, en la carpeta assets) y utilizar @string identificaciones en ella, al igual que

<html> 
<body> 
    <p>@string/message_text</p> 
</body> 
</html> 

Después de cargar el activo en una cadena que podría pasar su contenido a replaceResourceStrings():

/** 
* Regex that matches a resource string such as <code>@string/a-b_c1</code>. 
*/ 
private static final String REGEX_RESOURCE_STRING = "@string/([A-Za-z0-9-_]*)"; 

/** Name of the resource type "string" as in <code>@string/...</code> */ 
private static final String DEF_TYPE_STRING = "string"; 

/** 
* Recursively replaces resources such as <code>@string/abc</code> with 
* their localized values from the app's resource strings (e.g. 
* <code>strings.xml</code>) within a <code>source</code> string. 
* 
* Also works recursively, that is, when a resource contains another 
* resource that contains another resource, etc. 
* 
* @param source 
* @return <code>source</code> with replaced resources (if they exist) 
*/ 
public static String replaceResourceStrings(Context context, String source) { 
    // Recursively resolve strings 
    Pattern p = Pattern.compile(REGEX_RESOURCE_STRING); 
    Matcher m = p.matcher(source); 
    StringBuffer sb = new StringBuffer(); 
    while (m.find()) { 
     String stringFromResources = getStringByName(context, m.group(1)); 
     if (stringFromResources == null) { 
      Log.w(Constants.LOG, 
        "No String resource found for ID \"" + m.group(1) 
          + "\" while inserting resources"); 
      /* 
      * No need to try to load from defaults, android is trying that 
      * for us. If we're here, the resource does not exist. Just 
      * return its ID. 
      */ 
      stringFromResources = m.group(1); 
     } 
     m.appendReplacement(sb, // Recurse 
       replaceResourceStrings(context, stringFromResources)); 
    } 
    m.appendTail(sb); 
    return sb.toString(); 
} 

/** 
* Returns the string value of a string resource (e.g. defined in 
* <code>values.xml</code>). 
* 
* @param name 
* @return the value of the string resource or <code>null</code> if no 
*   resource found for id 
*/ 
public static String getStringByName(Context context, String name) { 
    int resourceId = getResourceId(context, DEF_TYPE_STRING, name); 
    if (resourceId != 0) { 
     return context.getString(resourceId); 
    } else { 
     return null; 
    } 
} 

/** 
* Finds the numeric id of a string resource (e.g. defined in 
* <code>values.xml</code>). 
* 
* @param defType 
*   Optional default resource type to find, if "type/" is not 
*   included in the name. Can be null to require an explicit type. 
* 
* @param name 
*   the name of the desired resource 
* @return the associated resource identifier. Returns 0 if no such resource 
*   was found. (0 is not a valid resource ID.) 
*/ 
private static int getResourceId(Context context, String defType, 
     String name) { 
    return context.getResources().getIdentifier(name, defType, 
      context.getPackageName()); 
} 

lo bueno de este enfoque es que usted tiene que especificar la estructura del HTML solo una vez y usa android's localization mechanism. Además, permite hacer referencia recursivamente a cadenas en strings.xml, que no es compatible con Context.getResources(). Por ejemplo:

<?xml version="1.0" encoding="utf-8"?> 
<resources> 
    <string name="message_text">Some string @string/another_one.</string> 
</resources> 

La desventaja es que el análisis se realiza en tiempo de ejecución, por lo que la especificación de un HTML dedicado para cada idioma tiene un mejor rendimiento cuando se utiliza dentro de la aplicación.

Para un ejemplo que utiliza este código para convertir HTML a partir de un archivo de activos a una "con estilos" CharSequence (usando Kuitsi's TagHandler) que se pueden mostrar en un TextView ver TextUtil.

23

colocar los archivos en la carpeta de activos con el sufijo local. Defina un recurso de cadena 'myLocalizedFileName' para cada archivo y obtenga el nombre de archivo mediante R.string.myLocalizedFileName.

Ejemplo:

estructura de carpetas:

assets/ 
assets/help.html 
assets/help_de.htlm 

Los recursos de cadena para cada idioma en res/valores/strings.xml:

<resource> 
    <string name=helpFile>help.html</string> 
</resource> 

WebView vocación:

public class HelpActivity extends AppCompatActivity { 
    protected void onCreate(Bundle savedInstanceState) { 
    ... 
    findViewById(R.id.helpWebView) 
     .loadUrl("file:///android_asset/" 
     + getString(R.string.helpFile)); 
    } 
} 
+1

Esta parece ser la solución más limpia - gracias! –

+0

Gracias por su enfoque, ruta de almacenamiento –

+0

Buena solución agradable y limpio en recurso de cadena –

Cuestiones relacionadas