2011-06-23 9 views
17

Tengo un ContentProvider en mi manifiesto, cuando los defino plenamente con cadenas codificadas que trabaja. P.ej.@string para android: las autoridades en un ContentProvider

<provider android:name="com.myprovider" android:authorities="com.myprovider"/> 

funciona perfecto, sin embargo los ContentProviders están en una biblioteca que es utilizada por múltiples proyectos, y no quieren conflictos de autoridad, por lo que intentaron hacer lo siguiente.

<provider android:name="com.myprovider" android:authorities="@string/myProviderAuthority"> 

De esta manera yo debería ser capaz de definir todas las autoridades de mi país en un solo archivo strings.xml y no tener conflictos entre aplicaciones, ya que debería ser capaz de cambiar el uso de cada sistema de aplicaciones de anulación de recursos.

Sin embargo, parece que cuando intento de construir con @string, me da un error manifiesto malformados y dice "Proveedor no incude (sí dice incude) Las autoridades Tribute"

¿Puedo utilizar un no cadena de recursos para el tributo de las autoridades, me siento enfermo cada vez que necesito mantener constantes en dos lugares. Los conflictos de autoridad pueden ser difíciles de atrapar por nuestro departamento de control de calidad, y no quiero que las cosas se desincronicen o podría causar confusión. ¿Alguien tiene alguna idea de por qué mi código no funciona?

+1

Me acabo de topar con este problema yo mismo, y encontré que esto funciona muy bien 2.2+. Por supuesto, sería genial si alguien señala cómo hacer que esto funcione en 2.1 y antes. – dmon

+0

Me he pasado a las cadenas, pero quizás puedas usar una API más reciente como objetivo de compilación mientras configuras android: minSdkVersion en 7 o lo que quieras, similar a hacer que appsToSd se compile en aplicaciones compatibles con 2.1. – HaMMeReD

+0

No creo que funcione, porque son los teléfonos reales que se quejan cuando se instalan, no falla al compilar. Terminé reemplazando la cadena "manualmente" con Maven. Apesta, pero funciona, por ahora. Supongo que puedo recuperarlo una vez que 2.1 llegue al final de la vida :) – dmon

Respuesta

11

que se enfrentaron a un problema similar, pero con el atributo android:versionCode. Cuando traté de definir el código de la versión en recursos y usar una referencia en el manifiesto Android Market, incluso me prohibió publicar la aplicación. La razón de tal comportamiento resultó ser bastante simple. Los recursos pueden cambiar dependiendo de la configuración actual y este valor debe ser el mismo en cualquier caso.

Probablemente, esta es la razón por la cual los proveedores de contenido con referencias de autoridad no funcionan demasiado. Y me parece que no es una buena idea usar dicha referencia porque no hay garantía de que haya el único valor para un recurso de autoridad en una aplicación. Entiendo que puede ser lo suficientemente cuidadoso como para mantener una sola instancia de este recurso, pero no hay un compilador especial o el sistema lo comprueba para que no sea confiable.

+0

Este es un buen motivo para no habilitarlo, pero claramente funciona en versiones posteriores, simplemente no 2.1, por lo que la "consistencia" no es la razón por la que no funciona. – dmon

+0

Fue solo una suposición. – Michael

6

Muchos atributos manifiestos no se pueden especificar como una referencia a una cadena - que deben ser especificados como valores de cadena explícitos.

El código que analiza el manifiesto se encuentra en: marcos/base/core/java/androide/content/pm/PackageParser.java. Esa clase llama, entre otros, getNonConfigurationString() y getNonResourceString() (que se implementan en: frameworks/base/core/java/android/content/res/TypedArray.java).

getNonConfigurationString() se describe como:

Retrieve the string value of an attribute that is not allowed to change with the given configurations. 

getNonResourceString() se describe como:

Retrieve the string value for an attribute, but only if that string comes from an immediate value in an XML file. That is, this does not allow references to string resources, string attributes, or conversions from other types. As such, this method will only return strings that come from attributes in an XML file. 

El manifiesto atributos que PackageParser no permite ser tomada de recursos o de diferentes configuraciones están enlistados debajo.

Estos atributos se definen en com.android.internal.R.styleable El nombre del atributo del elemento manifest.xml suele ser la parte del nombre después de la última '_' en el nombre formal. Por ejemplo, el atributo android: authorities en un elemento en manifest.xml es AndroidManifestProvider_authorities, o com.android.internal.R.styleable.AndroidManifestProvider_authorities. (El número en las listas de nombres de atributos a continuación es el número de línea del código relevante en la versión 4.1.1 de PackageParser.java)

Atributos leído por getNonConfigurationString:

917: AndroidManifest_versionName 
922: AndroidManifest_sharedUserId 
2057: AndroidManifestActivity_parentActivityName 
2071: AndroidManifestActivity_permission 
2079: AndroidManifestActivity_taskAffinity 
2247: AndroidManifestActivityAlias_targetActivity 
2330: AndroidManifestActivityAlias_permission 
2336: AndroidManifestActivityAlias_parentActivityName 
1672: AndroidManifestApplication_name 
1683: AndroidManifestApplication_manageSpaceActivity 
1697: AndroidManifestApplication_backupAgent 
1795: AndroidManifestApplication_permission 
1800: AndroidManifestApplication_taskAffinity 
1815: AndroidManifestApplication_process 
3005: AndroidManifestData_mimeType 
3017: AndroidManifestData_scheme 
3023: AndroidManifestData_host 
3025: AndroidManifestData_port 
3031: AndroidManifestData_path 
3037: AndroidManifestData_pathPrefix 
3043: AndroidManifestData_pathPattern 
2527: AndroidManifestGrantUriPermission_path 
2533: AndroidManifestGrantUriPermission_pathPrefix 
2539: AndroidManifestGrantUriPermission_pathPattern 
2579: AndroidManifestPathPermission_permission 
2581: AndroidManifestPathPermission_readPermission 
2586: AndroidManifestPathPermission_writePermission 
2615: AndroidManifestPathPermission_path 
2622: AndroidManifestPathPermission_pathPrefix 
2629: AndroidManifestPathPermission_pathPattern 
2434: AndroidManifestProvider_authorities 
2441: AndroidManifestProvider_permission 
2443: AndroidManifestProvider_readPermission 
2454: AndroidManifestProvider_writePermission 
2713: AndroidManifestService_permission 
2832: AndroidManifestMetaData_name 
1225: AndroidManifestOriginalPackage_name 
1981: (parsePackageItemInfo -- I can't tell list of all names) 
3258: (Component constructor args.nameres -- I can't tell list of all names) 

atributos leídos por getNonResourceString:

1806: AndroidManifestApplication_taskAffinity 
1821: AndroidManifestApplication_process 
1632: AndroidManifestInstrumentation_targetPackage 
2891: AndroidManifestPackageVerifier_name 
2894: AndroidManifestPackageVerifier_publicKey 
1512: AndroidManifestPermission_permissionGroup 
1200: AndroidManifestProtectedBroadcast_name 
1927: AndroidManifestUsesLibrary_name 
1054: AndroidManifestUsesFeature_name 
1004: AndroidManifestUsesPermission_name 
3308: (Component constructor args.processRes -- I can't tell list of all names) 

Por lo tanto, una gran cantidad de atributos en el archivo manifest.xml debe especificarse como valores de cadena explícita (es decir, entre comillas) en lugar de referencias a cadenas en strings.xml.

+0

Lo entiendo. El diseño evita el uso de cadenas de recursos en ciertos casos. Si utilizo una cadena explícita en el manifiesto para AndroidManifestProvider_authorities, ¿hay alguna manera en la aplicación de poder acceder a esa cadena, principalmente con el fin de definir la cadena en un lugar y usar una cadena consistente en todo momento? – Les

Cuestiones relacionadas