2011-03-08 14 views
9

Estoy tratando de leer los nombres de contacto, números de teléfono y correos electrónicos del URI ContactsContract, y obtengo un SecurityException cuando intento ejecutar el programa. Yo he dado la autorización en el archivo AndroidManifest.xml:java.lang.SecurityException tratando de leer desde URI de Contactos Android

<manifest xmlns:android="http://schemas.android.com/apk/res/android" 
     package="edu.smumn.cs394" 
     android:versionCode="1" 
     android:versionName="1.0"> 
    <uses-sdk android:minSdkVersion="8" /> 
    **<uses-permission android:name="android.pemission.READ_CONTACTS"/>** 
    <application android:icon="@drawable/icon" android:label="@string/app_name"> 
     <activity android:name=".ReadPhoneNumbers" 
        android:label="@string/app_name"> 
      <intent-filter> 
       <action android:name="android.intent.action.MAIN" /> 
       <category android:name="android.intent.category.LAUNCHER" /> 
      </intent-filter> 
     </activity> 
    </application> 
</manifest>` 

El siguiente es el código de la aplicación:

@Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.contact_list);  
     ContentResolver resolver = getContentResolver(); 
     Cursor c = resolver.query(ContactsContract.Contacts.CONTENT_URI, null, null, null, null); 
//[...] Work through data here` 

me sale una excepción de seguridad en la última línea (resolver.query()):

`03-08 07:41:40.812: ERROR/AndroidRuntime(416): FATAL EXCEPTION: main 
03-08 07:41:40.812: ERROR/AndroidRuntime(416): java.lang.RuntimeException: Unable to start activity ComponentInfo{edu.smumn.cs394/edu.smumn.cs394.ReadPhoneNumbers}: java.lang.SecurityException: Permission Denial: reading com.android.providers.contacts.ContactsProvider2 uri content://com.android.contacts/contacts from pid=416, uid=10037 requires android.permission.READ_CONTACTS 
[...] 
03-08 07:41:40.812: ERROR/AndroidRuntime(416): Caused by: java.lang.SecurityException: Permission Denial: reading com.android.providers.contacts.ContactsProvider2 uri content://com.android.contacts/contacts from pid=416, uid=10037 requires android.permission.READ_CONTACTS 
[...] 
03-08 07:41:40.812: ERROR/AndroidRuntime(416):  at edu.smumn.cs394.ReadPhoneNumbers.onCreate(ReadPhoneNumbers.java:30) 

[...] `

Me falta algo, pero no puedo averiguar qué.

+0

Tiene un error de sintaxis en su archivo AndroidManifest.xml. En la línea ** ** android.permission se escribe mal sin R y debe parecer "permiso" en lugar de "pemission". – technik

Respuesta

9

Asegúrese de agregar fuera de la etiqueta de aplicación. Mientras desarrollaba para una plataforma meta de 2.3.3 usando Eclipse en Ubuntu, tuve fallas de permisos en el archivo de registro que indicaban que necesitaba esta línea exacta mientras trabajaba en algo similar. No fue hasta que moví la línea * uses-permission ... READ_CONTACTS * a fuera de la etiqueta de la aplicación que funcionó todo.

+0

OMG .... Fue eso ... ¡Gracias! – cesards

+0

+1: Este fue también el caso para mí en el sistema Windows 7 (api v10 a v19). Agregué el permiso con la GUI y con la etiqueta . Lo reemplacé con la etiqueta . – Dexter

6

Hola Steven la traza de registro de depuración que indica que necesita ... requiere android.permission.READ_CONTACTS

por lo que sólo probar algo mediante la edición del Manifest.xml como la adición de otro permiso, vamos a ver si no es correcta leído.

y comprobar esta línea sin **

<uses-permission android:name="android.permission.READ_CONTACTS" /> 

dan

5

con la API 23, el permiso <uses-permission android:name="android.pemission.READ_CONTACTS"/> no trabajan, cambiar el nivel de API en el emulador de la API 22 (paleta) o menor

+3

Entonces, ¿cuál es la alternativa? – NicoJuicy

+5

¡La API de bajada no debería ser una solución! – Shumin

+0

La alternativa es codificar un permiso de solicitud explícito para la API 23+ como se muestra en la documentación, también tuve que degradar la versión de destino de mi SDK a 22 para evitar hacer un trabajo tan tedioso – zozelfelfo

2

Si el dispositivo ejecuta Android 6.0 o superior, y el SDK objetivo de la aplicación es de 23 o más: la aplicación tiene que enumerar los permisos en el manifiesto, y debe solicitar cada permiso peligroso que necesita mientras se ejecuta la aplicación. El usuario puede otorgar o denegar cada permiso, y la aplicación puede seguir ejecutándose con capacidades limitadas incluso si el usuario niega una solicitud de permiso.

Ejemplo:

//thisActivity is the running activity 


if (ContextCompat.checkSelfPermission(thisActivity, 
       Manifest.permission.READ_CONTACTS) 
       != PackageManager.PERMISSION_GRANTED) { 

      // Should we show an explanation? 
      if (ActivityCompat.shouldShowRequestPermissionRationale(thisActivity, 
        Manifest.permission.READ_CONTACTS)) { 

       // Show an expanation to the user *asynchronously* -- don't block 
       // this thread waiting for the user's response! After the user 
       // sees the explanation, try again to request the permission. 

      } else { 

       // No explanation needed, we can request the permission. 

       ActivityCompat.requestPermissions(thisActivity, 
         new String[]{Manifest.permission.READ_CONTACTS}, 
         MY_PERMISSIONS_REQUEST_READ_CONTACTS); 

       // MY_PERMISSIONS_REQUEST_READ_CONTACTS is an 
       // app-defined int constant. The callback method gets the 
       // result of the request. 
      } 
     } 

http://developer.android.com/training/permissions/requesting.html

15

permisos que solicitan en tiempo de ejecución

A partir de Android 6.0 (API de nivel 23), los usuarios otorgan permisos para aplicaciones mientras la aplicación está corriendo, no cuando instalan la aplicación.

Si el permiso que necesita agregar no aparece en la lista bajo los permisos normales, deberá tratar con "Permisos de tiempo de ejecución". Los permisos de tiempo de ejecución son permisos que se solicitan a medida que se necesitan mientras se ejecuta la aplicación.Estos permisos se mostrará un cuadro de diálogo para el usuario, similar a la siguiente:

enter image description here

El primer paso cuando se añade un "Permiso Runtime" es para añadirlo a la AndroidManifest:

<manifest xmlns:android="http://schemas.android.com/apk/res/android" 
    package="com.codepath.androidpermissionsdemo" > 

    <uses-permission android:name="android.permission.READ_CONTACTS" /> 
    ... 
</manifest> 

A continuación, deberá iniciar la solicitud de permiso y manejar el resultado. El siguiente código muestra cómo hacerlo en el contexto de una actividad, pero esto también es posible desde dentro de un fragmento.

// MainActivity.java 
public class MainActivity extends AppCompatActivity { 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_main); 

     // In an actual app, you'd want to request a permission when the user performs an action 
     // that requires that permission. 
     getPermissionToReadUserContacts(); 
    } 

    // Identifier for the permission request 
    private static final int READ_CONTACTS_PERMISSIONS_REQUEST = 1; 

    // Called when the user is performing an action which requires the app to read the 
    // user's contacts 
    public void getPermissionToReadUserContacts() { 
     // 1) Use the support library version ContextCompat.checkSelfPermission(...) to avoid 
     // checking the build version since Context.checkSelfPermission(...) is only available 
     // in Marshmallow 
     // 2) Always check for permission (even if permission has already been granted) 
     // since the user can revoke permissions at any time through Settings 
     if (ContextCompat.checkSelfPermission(this, Manifest.permission.READ_CONTACTS) 
       != PackageManager.PERMISSION_GRANTED) { 

      // The permission is NOT already granted. 
      // Check if the user has been asked about this permission already and denied 
      // it. If so, we want to give more explanation about why the permission is needed. 
      if (shouldShowRequestPermissionRationale(
        Manifest.permission.READ_CONTACTS)) { 
       // Show our own UI to explain to the user why we need to read the contacts 
       // before actually requesting the permission and showing the default UI 
      } 

      // Fire off an async request to actually get the permission 
      // This will show the standard permission request dialog UI 
      requestPermissions(new String[]{Manifest.permission.READ_CONTACTS}, 
        READ_CONTACTS_PERMISSIONS_REQUEST); 
     } 
    } 

    // Callback with the request from calling requestPermissions(...) 
    @Override 
    public void onRequestPermissionsResult(int requestCode, 
              @NonNull String permissions[], 
              @NonNull int[] grantResults) { 
     // Make sure it's our original READ_CONTACTS request 
     if (requestCode == READ_CONTACTS_PERMISSIONS_REQUEST) { 
      if (grantResults.length == 1 && 
        grantResults[0] == PackageManager.PERMISSION_GRANTED) { 
       Toast.makeText(this, "Read Contacts permission granted", Toast.LENGTH_SHORT).show(); 
      } else { 
       Toast.makeText(this, "Read Contacts permission denied", Toast.LENGTH_SHORT).show(); 
      } 
     } else { 
      super.onRequestPermissionsResult(requestCode, permissions, grantResults); 
     } 
    } 
} 
Cuestiones relacionadas