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)

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.


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" />

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

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

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.


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.


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

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

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

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

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

6

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

String uri = "tel:" + posted_by.replaceAll("[^0-9|\\+]", "");

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

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>

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


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)

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.


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” :)


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

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")));
                }
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.