Jak nawiązać połączenie telefoniczne przy użyciu zamiaru w systemie Android?

329

Korzystam z następującego kodu, aby wykonać połączenie w Androidzie, ale daje mi wyjątek bezpieczeństwa, proszę o pomoc.

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

uprawnienia

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

Wyjątek

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
źródło

Odpowiedzi:

383

Możesz użyć Intent.ACTION_DIALzamiast Intent.ACTION_CALL. To pokazuje dialer z już wprowadzonym numerem, ale pozwala użytkownikowi zdecydować, czy rzeczywiście wykonać połączenie, czy nie. ACTION_DIALnie wymaga CALL_PHONEpozwolenia.

Ridcully
źródło
ACTION_DIAL nie wymaga pozwolenia, to ważna różnica w porównaniu z intencją ACTION_CALL :)
maxwellnewage
237

To demo pomoże ci ...

Kliknij przycisk połączenia:

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

Zezwolenie na manifest:

 <uses-permission android:name="android.permission.CALL_PHONE" />
Denny Sharma
źródło
1
+1 dla „tel:”. Zamiast tego zadzwoniłem i nie dostałem żadnego wyjątkowego zamiaru. Tnx
Tina
To po prostu nie działa w moim nexusie 4. Otwiera dialer pokazujący numer telefonu, ale nie rozpoczyna połączenia bez interakcji użytkownika. Wszelkie sugestie?
MatheusJardimB
5
Jaka jest różnica między kodem w pytaniu a tą odpowiedzią? Jak to rozwiązuje problem?
Gavriel
To otwiera dla mnie Skype.
RJB
Proszę również dodać zezwolenie na wykonanie połączenia telefonicznego
Raghu Krishnan R
180

Bardziej elegancka opcja:

String phone = "+34666777888";
Intent intent = new Intent(Intent.ACTION_DIAL, Uri.fromParts("tel", phone, null));
startActivity(intent);
cprcrack
źródło
5
Działa to bez dodawania niczego do Manifestu, jak poprzednia odpowiedź
Pavlos,
4
Nie są wymagane żadne uprawnienia do wykonywania. +1
kike
82

Użyj akcji ACTION_DIAL w swoim zamiarze, w ten sposób nie będziesz potrzebować żadnego pozwolenia. Powodem, dla którego potrzebujesz uprawnień w ACTION_CALL, jest wykonywanie połączeń telefonicznych bez żadnych działań ze strony użytkownika.

Intent intent = new Intent(Intent.ACTION_DIAL);
intent.setData(Uri.parse("tel:0987654321"));
startActivity(intent);
wheeliez
źródło
2
Jest to lepsze w przypadku, gdy nie musisz pytać o pozwolenie.
zackygaurav
1
W drugim wierszu kodu brakuje średnika. idealna odpowiedź!
ahmed_khan_89
73

Wszystko w porządku.

właśnie umieściłem tag uprawnień do połączeń przed tagiem aplikacji w pliku manifestu

a teraz wszystko działa dobrze.

UMAR
źródło
2
Zobacz moją odpowiedź poniżej, w jaki sposób osiągnąć prawie to samo bez konieczności uzyskania pozwolenia i z możliwością, że użytkownik nie wykona połączenia.
Ridcully,
3
Pamiętaj także o urządzeniach bez telefonu: stackoverflow.com/a/9300036/693752
Snicolas 24.04.13
dalsze informacje sugerowane przez Snicolasa londatiga.net/it/programming/android/…
Lorensius WL T
31

WAŻNA UWAGA:

Jeśli używasz Intent.ACTION_CALL, musisz dodać CALL_PHONEpozwolenie.

Jest w porządku, tylko jeśli nie chcesz, aby Twoja aplikacja wyświetlała się w Google Play na tabletach, które nie biorą karty SIM lub nie mają GSM.

W TWOJEJ DZIAŁALNOŚCI:

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

OCZYWISTY:

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

Jeśli więc nie jest to krytyczna funkcja dla Twojej aplikacji, staraj się unikać dodawania CALL_PHONEuprawnień.

INNE ROZWIĄZANIE:

Ma wyświetlać aplikację Telefon z numerem wpisanym na ekranie, aby użytkownik musiał tylko kliknąć przycisk połączenia:

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

Nie wymaga na to zgody.

MBH
źródło
24

Po prostu prosty oneliner bez żadnych dodatkowych uprawnień:

private void dialContactPhone(final String phoneNumber) {
    startActivity(new Intent(Intent.ACTION_DIAL, Uri.fromParts("tel", phoneNumber, null)));
}
Artemiy
źródło
18

użyj tego pełnego kodu

          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
źródło
1
Ta technika działała dla mnie, chociaż musiałem zmienić Intent.ACTION_DIAL na Intent.Anction_CALL.
Naeem A. Malik
12

Poproś o zezwolenie w manifeście

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

Do połączeń użyj tego kodu

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
źródło
3
Myślę, że nie potrzebujesz pozwolenia, ponieważ aplikacja nie dzwoni sama, ale prosi o to dedykowaną aplikację (która ma pozwolenie).
Mostrapotski,
9

Licencja w AndroidManifest.xml

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

Pełny kod:

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
źródło
8

Uprawnienia:

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

Zamiar:

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

źródło
6

Możesz również użyć tego:

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

Aby wykonać połączenie za pomocą zamiarów, należy poprosić o odpowiednie uprawnienia.

Do tego należy dołączyć uprawnienia w pliku AndroidManifest.xml.

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

Następnie dołącz następujący kod do swojej aktywności

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
źródło
4

W przypadku połączenia z dialera (bez konieczności uzyskania pozwolenia):

   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()
        }
    }

W przypadku bezpośredniego połączenia z aplikacji (wymagane zezwolenie):

  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()
        }
    }

Pozwolenie:

<uses-permission android:name="android.permission.CALL_PHONE"></uses-permission>
Shohan Ahmed Sijan
źródło
3

Aby tego uniknąć - można użyć GUI do wprowadzania uprawnień. Zaćmienie dbają o to, gdzie wstawić znacznik uprawnień, a częściej nie jest poprawne

SaKet
źródło
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
źródło
1

W Androidzie dla niektórych funkcji musisz dodać uprawnienie do pliku manifestu.

  1. Przejdź do Projekty AndroidManifest.xml
  2. Kliknij kartę Uprawnienia
  3. Kliknij Dodaj
  4. Wybierz wykorzystuje uprawnienia
  5. Zobacz migawkę poniżejwprowadź opis zdjęcia tutaj

6. Zapisz plik manifestu, a następnie uruchom projekt. Twój projekt powinien teraz działać zgodnie z oczekiwaniami.

MindBrain
źródło
1
Z którego IDE korzystasz?
SHA2NK,
1
11-25 14:47:01.681: ERROR/AndroidRuntime(302): blah blah...requires android.permission.CALL_PHONE

^ Odpowiedź leży w wyjściu wyjątku „ requires android.permission.CALL_PHONE” :)

Charlie Scott-Skinner
źródło
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
źródło
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
źródło