Làm thế nào để thực hiện cuộc gọi điện thoại bằng ý định trong Android?


329

Tôi đang sử dụng mã sau đây để thực hiện cuộc gọi trong Android nhưng nó mang lại cho tôi ngoại lệ bảo mật, vui lòng trợ giúp.

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

quyền

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

ngoại lệ

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)

Câu trả lời:


383

Bạn có thể sử dụng Intent.ACTION_DIALthay vì Intent.ACTION_CALL. Điều này cho thấy trình quay số với số đã nhập, nhưng cho phép người dùng quyết định có thực sự thực hiện cuộc gọi hay không. ACTION_DIALkhông cần sự CALL_PHONEcho phép.


ACTION_DIAL không yêu cầu sự cho phép, đây là một sự khác biệt quan trọng so với mục đích của ACTION_CALL :)
maxwellnewage

237

Bản demo này sẽ hữu ích cho bạn ...

Trên nút gọi bấm:

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

Giấy phép trong Bản kê khai:

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

1
+1 cho "điện thoại:". Tôi đã gọi thay thế và không có ý định ngoại lệ. Tnx
Tina

Điều này chỉ đơn giản là không hoạt động trong nexus của tôi 4. Nó mở trình quay số hiển thị số điện thoại nhưng không bắt đầu cuộc gọi mà không có sự tương tác của người dùng. Bất kỳ đường?
MatheusJardimB

5
Sự khác biệt giữa mã trong câu hỏi và trong câu trả lời này là gì? Làm thế nào để nó giải quyết vấn đề?
Gavriel 3/03/2016

Điều này mở skype cho tôi.
RJB

Vui lòng thêm Quyền gọi điện thoại Thời gian chạy cũng được phép
Raghu Krishnan R

180

Tùy chọn thanh lịch hơn:

String phone = "+34666777888";
Intent intent = new Intent(Intent.ACTION_DIAL, Uri.fromParts("tel", phone, null));
startActivity(intent);

5
Điều này hoạt động mà không cần thêm bất cứ điều gì vào Bản kê khai như câu trả lời trước
Pavlos

4
Không có quyền chạy thời gian cần thiết. +1
kike

81

Sử dụng hành động ACTION_DIAL trong ý định của bạn, theo cách này bạn sẽ không cần bất kỳ sự cho phép nào. Lý do bạn cần sự cho phép với ACTION_CALL là để thực hiện cuộc gọi điện thoại mà không có bất kỳ hành động nào từ người dùng.

Intent intent = new Intent(Intent.ACTION_DIAL);
intent.setData(Uri.parse("tel:0987654321"));
startActivity(intent);

2
Điều này tốt hơn trong trường hợp bạn không cần phải xin phép.
zackygaurav

1
Có một dấu chấm phẩy bị thiếu trong dòng thứ hai của mã. câu trả lời hoàn hảo!
ahmed_khan_89

73

Mọi thứ đều ổn.

tôi chỉ đặt thẻ quyền truy cập trước khi thẻ ứng dụng trong tệp kê khai

và bây giờ mọi thứ đang hoạt động tốt.


2
Xem câu trả lời của tôi dưới đây về cách đạt được gần như giống nhau mà không cần sự cho phép và với cơ hội người dùng không thực sự thực hiện cuộc gọi.
Vô lý

3
Ngoài ra, hãy chú ý đến các thiết bị không có điện thoại: stackoverflow.com/a/9300036/693752
Snicolas

thông tin thêm theo đề xuất của Snicolas londatiga.net/it/programming/android/ triệt
Lorensius WL T

31

LƯU Ý QUAN TRỌNG:

Nếu bạn sử dụng, Intent.ACTION_CALLbạn phải thêm CALL_PHONEquyền.

Chỉ okey nếu bạn không muốn ứng dụng của mình hiển thị trong google play cho máy tính bảng không lấy thẻ SIM hoặc không có GSM.

TRONG HOẠT ĐỘNG CỦA BẠN:

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

RÕ RÀNG:

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

Vì vậy, nếu đó không phải là tính năng quan trọng đối với ứng dụng của bạn, hãy cố gắng tránh xa việc thêm CALL_PHONEquyền.

GIẢI PHÁP KHÁC:

Là để hiển thị ứng dụng Điện thoại với số được ghi trên màn hình, vì vậy người dùng sẽ chỉ cần nhấp vào nút gọi:

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

Không có sự cho phép cần thiết cho việc này.


24

Chỉ cần oneliner đơn giản mà không cần bất kỳ quyền bổ sung nào cần thiết:

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

18

sử dụng mã đầy đủ này

          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
Kỹ thuật này hiệu quả với tôi, mặc dù tôi phải thay đổi Intent.ACTION_DIAL thành Intent.Anction_CALL.
Naeem A. Malik

12

Yêu cầu cấp phép trong bảng kê khai

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

Để gọi sử dụng mã này

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
Tôi nghĩ rằng bạn không cần sự cho phép vì ứng dụng của bạn không tự gọi, nhưng yêu cầu ứng dụng chuyên dụng (có sự cho phép) để làm điều đó.
Mostrapotski

9

Quyền trong AndroidManifest.xml

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

Mã hoàn chỉnh:

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

Quyền:

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

Ý định:

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

6

Bạn cũng có thể sử dụng điều này:

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

5

Để thực hiện một hoạt động cuộc gọi bằng cách sử dụng ý định, bạn nên yêu cầu quyền thích hợp.

Cho rằng bạn bao gồm các quyền sử dụng trong tệp AndroidManifest.xml.

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

Sau đó bao gồm các mã sau trong hoạt động của bạn

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

Đối với cuộc gọi từ trình quay số (Không cần sự cho phép):

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

Đối với cuộc gọi trực tiếp từ ứng dụng (Cần có sự cho phép):

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

Quyền:

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

3

Để tránh điều này - người ta có thể sử dụng GUI để nhập quyền. Eclipse quan tâm đến nơi chèn thẻ quyền và thường thì không chính xác


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

Trong Android đối với một số chức năng nhất định, bạn cần thêm quyền vào tệp Manifest.

  1. Chuyển đến Dự án AndroidManifest.xml
  2. Nhấp vào tab Quyền
  3. Nhấp vào Thêm
  4. Chọn quyền sử dụng
  5. Xem ảnh chụp bên dướinhập mô tả hình ảnh ở đây

6. Lưu tệp kê khai và sau đó chạy dự án của bạn. Dự án của bạn bây giờ sẽ chạy như mong đợi.


1
Bạn đang sử dụng IDE nào?
SHA2NK

1
11-25 14:47:01.681: ERROR/AndroidRuntime(302): blah blah...requires android.permission.CALL_PHONE

^ Câu trả lời nằm ở đầu ra ngoại lệ " 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")));
                }
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.