¿Cómo hacer una llamada telefónica con intención en Android?

329

Estoy usando el siguiente código para hacer una llamada en Android, pero me está dando una excepción de seguridad, por favor ayuda.

 posted_by = "111-333-222-4";

 String uri = "tel:" + posted_by.trim() ;
 Intent intent = new Intent(Intent.ACTION_CALL);
 intent.setData(Uri.parse(uri));
 startActivity(intent);

permisos

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

Excepción

11-25 14:47:01.661: ERROR/AndroidRuntime(302): Uncaught handler: thread main exiting due to uncaught exception
11-25 14:47:01.681: ERROR/AndroidRuntime(302): java.lang.SecurityException: Permission Denial: starting Intent { act=android.intent.action.CALL dat=tel:111-333-222-4 cmp=com.android.phone/.OutgoingCallBroadcaster } from ProcessRecord{43d32508 302:com.Finditnear/10026} (pid=302, uid=10026) requires android.permission.CALL_PHONE
11-25 14:47:01.681: ERROR/AndroidRuntime(302):     at android.os.Parcel.readException(Parcel.java:1218)
11-25 14:47:01.681: ERROR/AndroidRuntime(302):     at android.os.Parcel.readException(Parcel.java:1206)
11-25 14:47:01.681: ERROR/AndroidRuntime(302):     at android.app.ActivityManagerProxy.startActivity(ActivityManagerNative.java:1214)
11-25 14:47:01.681: ERROR/AndroidRuntime(302):     at android.app.Instrumentation.execStartActivity(Instrumentation.java:1373)
11-25 14:47:01.681: ERROR/AndroidRuntime(302):     at android.app.Activity.startActivityForResult(Activity.java:2749)
11-25 14:47:01.681: ERROR/AndroidRuntime(302):     at android.app.Activity.startActivity(Activity.java:2855)
11-25 14:47:01.681: ERROR/AndroidRuntime(302):     at com.Finditnear.PostDetail$2$1$1$1.onClick(PostDetail.java:604)
11-25 14:47:01.681: ERROR/AndroidRuntime(302):     at com.android.internal.app.AlertController$AlertParams$3.onItemClick(AlertController.java:884)
11-25 14:47:01.681: ERROR/AndroidRuntime(302):     at android.widget.AdapterView.performItemClick(AdapterView.java:284)
11-25 14:47:01.681: ERROR/AndroidRuntime(302):     at android.widget.ListView.performItemClick(ListView.java:3285)
11-25 14:47:01.681: ERROR/AndroidRuntime(302):     at android.widget.AbsListView$PerformClick.run(AbsListView.java:1640)
UMAR
fuente

Respuestas:

383

Puedes usar en Intent.ACTION_DIALlugar de Intent.ACTION_CALL. Esto muestra el marcador con el número ya ingresado, pero le permite al usuario decidir si realmente hace la llamada o no. ACTION_DIALNo requiere el CALL_PHONEpermiso.

Ridículo
fuente
ACTION_DIAL no requiere permiso, esta es una diferencia importante en comparación con la intención ACTION_CALL :)
maxwellnewage
237

Esta demostración será útil para usted ...

Al hacer clic en el botón de llamada:

Intent intent = new Intent(Intent.ACTION_CALL, Uri.parse("tel:" + "Your Phone_number"));
startActivity(intent);

Permiso en manifiesto:

 <uses-permission android:name="android.permission.CALL_PHONE" />
Denny Sharma
fuente
1
+1 para "tel:". En su lugar, llamé y no obtuve ninguna excepción intencional. Tnx
Tina
Esto simplemente no funciona en mi nexus 4. Abre el marcador que muestra el número de teléfono pero no inicia la llamada sin la interacción del usuario. ¿Alguna sugerencia?
MatheusJardimB
55
¿Cuál es la diferencia entre el código en la pregunta y en esta respuesta? ¿Cómo resuelve el problema?
Gavriel
Esto abre Skype para mí.
RJB
Agregue también el permiso de tiempo de ejecución del teléfono de llamada
Raghu Krishnan R
180

Opción más elegante:

String phone = "+34666777888";
Intent intent = new Intent(Intent.ACTION_DIAL, Uri.fromParts("tel", phone, null));
startActivity(intent);
cprcrack
fuente
55
Esto funciona sin agregar nada al Manifiesto como la respuesta anterior
Pavlos
44
No se requieren permisos de tiempo de ejecución. +1
kike
82

Use la acción ACTION_DIAL en su intento, de esta manera no necesitará ningún permiso. La razón por la que necesita el permiso con ACTION_CALL es para hacer una llamada telefónica sin ninguna acción del usuario.

Intent intent = new Intent(Intent.ACTION_DIAL);
intent.setData(Uri.parse("tel:0987654321"));
startActivity(intent);
wheeliez
fuente
2
Esto es mejor en caso de que no necesite pedir permiso.
zackygaurav
1
Falta un punto y coma en la segunda línea del código. ¡Respuesta perfecta!
ahmed_khan_89
73

Todo esta bien.

Acabo de colocar la etiqueta de permisos de llamadas antes de la etiqueta de la aplicación en el archivo de manifiesto

y ahora todo funciona bien.

UMAR
fuente
2
Vea mi respuesta a continuación sobre cómo lograr casi lo mismo sin la necesidad de un permiso y con la posibilidad de que el usuario no realice la llamada.
Ridcully
3
Además, tenga en cuenta los dispositivos sin telefonía: stackoverflow.com/a/9300036/693752
Snicolas el
más información según lo sugerido por Snicolas londatiga.net/it/programming/android/…
Lorensius WL T
31

NOTA IMPORTANTE:

Si usa Intent.ACTION_CALLdebe agregar CALL_PHONEpermiso.

Solo funciona si no desea que su aplicación aparezca en Google Play para tabletas que no tienen tarjeta SIM o no tienen GSM.

EN TU ACTIVIDAD:

            Intent callIntent = new Intent(Intent.ACTION_CALL);
            callIntent.setData(Uri.parse("tel:" + Constants.CALL_CENTER_NUMBER));
            startActivity(callIntent);

MANIFIESTO:

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

Entonces, si no es una función crítica para su aplicación, trate de evitar agregar CALL_PHONEpermisos.

OTRA SOLUCIÓN:

Es mostrar la aplicación del teléfono con el número escrito en la pantalla, por lo que el usuario solo tendrá que hacer clic en el botón de llamada:

            Intent dialIntent = new Intent(Intent.ACTION_DIAL);
            dialIntent.setData(Uri.parse("tel:" + Constants.CALL_CENTER_NUMBER));
            startActivity(dialIntent);

No se necesita permiso para esto.

MBH
fuente
24

Solo el simple oneliner sin necesidad de permisos adicionales:

private void dialContactPhone(final String phoneNumber) {
    startActivity(new Intent(Intent.ACTION_DIAL, Uri.fromParts("tel", phoneNumber, null)));
}
Artemiy
fuente
18

usa este código completo

          Intent callIntent = new Intent(Intent.ACTION_DIAL);
          callIntent.setData(Uri.parse("tel:"+Uri.encode(PhoneNum.trim())));
          callIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
          startActivity(callIntent);     
Osama Ibrahim
fuente
1
Esta técnica funcionó para mí, aunque tuve que cambiar Intent.ACTION_DIAL a Intent.Anction_CALL.
Naeem A. Malik
12

Solicitar permiso en manifiesto

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

Para llamar utiliza este código

Intent in = new Intent(Intent.ACTION_CALL, Uri.parse("tel:99xxxxxxxx"));
try {
    startActivity(in);
} catch (android.content.ActivityNotFoundException ex) {
    Toast.makeText(mcontext, "Could not find an activity to place the call.", Toast.LENGTH_SHORT).show();
}
Abhay Anand
fuente
3
Creo que no necesita el permiso ya que su aplicación no se llama a sí misma, sino que le pide a la aplicación dedicada (que tiene el permiso) que lo haga.
Mostrapotski
9

Permiso en AndroidManifest.xml

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

Código completo:

private void onCallBtnClick(){
    if (Build.VERSION.SDK_INT < 23) {
        phoneCall();
    }else {

        if (ActivityCompat.checkSelfPermission(mActivity,
                Manifest.permission.CALL_PHONE) == PackageManager.PERMISSION_GRANTED) {

            phoneCall();
        }else {
            final String[] PERMISSIONS_STORAGE = {Manifest.permission.CALL_PHONE};
            //Asking request Permissions
            ActivityCompat.requestPermissions(mActivity, PERMISSIONS_STORAGE, 9);
        }
    }
}

@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
    boolean permissionGranted = false;
    switch(requestCode){
        case 9:
            permissionGranted = grantResults[0]== PackageManager.PERMISSION_GRANTED;
            break;
    }
    if(permissionGranted){
        phoneCall();
    }else {
        Toast.makeText(mActivity, "You don't assign permission.", Toast.LENGTH_SHORT).show();
    }
}

private void phoneCall(){
    if (ActivityCompat.checkSelfPermission(mActivity,
            Manifest.permission.CALL_PHONE) == PackageManager.PERMISSION_GRANTED) {
        Intent callIntent = new Intent(Intent.ACTION_CALL);
        callIntent.setData(Uri.parse("tel:12345678900"));
        mActivity.startActivity(callIntent);
    }else{
        Toast.makeText(mActivity, "You don't assign permission.", Toast.LENGTH_SHORT).show();
    }
}
Atif Mahmood
fuente
8

Permisos:

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

Intención:

Intent callIntent = new Intent(Intent.ACTION_CALL);
callIntent.setData(Uri.parse("tel:0377778888"));
startActivity(callIntent);

fuente
6

También puedes usar esto:

String uri = "tel:" + posted_by.replaceAll("[^0-9|\\+]", "");
Áron Pável
fuente
5

Para realizar una actividad de llamada utilizando intentos, debe solicitar los permisos adecuados.

Para eso incluye permisos de uso en el archivo AndroidManifest.xml.

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

Luego incluya el siguiente código en su actividad

if (ActivityCompat.checkSelfPermission(mActivity,
        Manifest.permission.CALL_PHONE) == PackageManager.PERMISSION_GRANTED) {
    //Creating intents for making a call
    Intent callIntent = new Intent(Intent.ACTION_CALL);
    callIntent.setData(Uri.parse("tel:123456789"));
    mActivity.startActivity(callIntent);

}else{
    Toast.makeText(mActivity, "You don't assign permission.", Toast.LENGTH_SHORT).show();
}
Codemaker
fuente
4

Para llamadas del marcador (no se necesita permiso):

   fun callFromDailer(mContext: Context, number: String) {
        try {
            val callIntent = Intent(Intent.ACTION_DIAL)
            callIntent.data = Uri.parse("tel:$number")
            mContext.startActivity(callIntent)
        } catch (e: Exception) {
            e.printStackTrace()
            Toast.makeText(mContext, "No SIM Found", Toast.LENGTH_LONG).show()
        }
    }

Para llamadas directas desde la aplicación (se necesita permiso):

  fun callDirect(mContext: Context, number: String) {
        try {
            val callIntent = Intent(Intent.ACTION_CALL)
            callIntent.data = Uri.parse("tel:$number")
            mContext.startActivity(callIntent)
        } catch (e: SecurityException) {
            Toast.makeText(mContext, "Need call permission", Toast.LENGTH_LONG).show()
        } catch (e: Exception) {
            e.printStackTrace()
            Toast.makeText(mContext, "No SIM Found", Toast.LENGTH_LONG).show()
        }
    }

Permiso:

<uses-permission android:name="android.permission.CALL_PHONE"></uses-permission>
Shohan Ahmed Sijan
fuente
3

Para evitar esto, se puede usar la GUI para ingresar permisos. Eclipse se encarga de dónde insertar la etiqueta de permiso y, a menudo, no es correcto

SaKet
fuente
2
// Java
String mobileNumber = "99XXXXXXXX";
Intent intent = new Intent();
intent.setAction(Intent.ACTION_DIAL); // Action for what intent called for
intent.setData(Uri.parse("tel: " + mobileNumber)); // Data with intent respective action on intent
startActivity(intent);

// Kotlin
val mobileNumber = "99XXXXXXXX"
val intent = Intent()
intent.action = Intent.ACTION_DIAL // Action for what intent called for
intent.data = Uri.parse("tel: $mobileNumber") // Data with intent respective action on intent
startActivity(intent)
Sumit Jain
fuente
1

En Android para ciertas funcionalidades, debe agregar el permiso al archivo Manifiesto.

  1. Vaya a Proyectos AndroidManifest.xml
  2. Haga clic en la pestaña Permisos
  3. Haga clic en Agregar
  4. Seleccione el permiso de usos
  5. Vea la instantánea a continuacióningrese la descripción de la imagen aquí

6. Guarde el archivo de manifiesto y luego ejecute su proyecto. Su proyecto ahora debería ejecutarse como se esperaba.

MindBrain
fuente
1
¿Qué IDE estás usando?
SHA2NK
1
11-25 14:47:01.681: ERROR/AndroidRuntime(302): blah blah...requires android.permission.CALL_PHONE

^ La respuesta se encuentra en la salida de excepción " requires android.permission.CALL_PHONE" :)

Charlie Scott-Skinner
fuente
1
    final public void Call(View view){

    try {

        EditText editt=(EditText)findViewById(R.id.ed1);
        String str=editt.getText().toString();
        Intent intent = new Intent(Intent.ACTION_DIAL, Uri.parse("tel:"+str));
        startActivity(intent);
    }
    catch (android.content.ActivityNotFoundException e){

        Toast.makeText(getApplicationContext(),"App failed",Toast.LENGTH_LONG).show();
    }
Deepak Singh
fuente
1
 if(ContextCompat.checkSelfPermission(
        mContext,android.Manifest.permission.CALL_PHONE) != 
              PackageManager.PERMISSION_GRANTED) {
                    ActivityCompat.requestPermissions((Activity) mContext, new 
                  String[]{android.Manifest.permission.CALL_PHONE}, 0);
                } else {
                    startActivity(new Intent(Intent.ACTION_CALL, Uri.parse("tel:" + "Your Number")));
                }
Mohsinali
fuente