Computer >> Hướng Dẫn Máy Tính >  >> Lập Trình >> Android

Cách thực hiện cuộc gọi điện thoại trong Android

Giới thiệu

Hướng dẫn xây dựng ứng dụng cho phép người dùng chọn liên hệ từ danh bạ và thực hiện cuộc gọi, xử lý đầy đủ quyền CALL_PHONE và READ_CONTACTS (runtime permission Android 6.0+).

Các bước thực hiện

Bước 1: AndroidManifest.xml - Khai báo quyền

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

Bước 2: Giao diện (res/layout/activity_main.xml)

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="https://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:padding="16dp">

    <ListView
        android:id="@+id/listContacts"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1" />

</LinearLayout>

Bước 3: MainActivity.java

package com.example.myapplication;

import android.Manifest;
import android.content.ContentResolver;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.database.Cursor;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.provider.ContactsContract;
import android.support.v4.app.ActivityCompat;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.Toast;
import java.util.ArrayList;

public class MainActivity extends AppCompatActivity {

    private static final int REQUEST_CONTACTS = 100;
    private static final int REQUEST_CALL = 101;

    ListView listView;
    ArrayAdapter<String> adapter;
    ArrayList<String> names = new ArrayList<>();
    ArrayList<String> numbers = new ArrayList<>();
    String selectedNumber;

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

        listView = findViewById(R.id.listContacts);
        adapter = new ArrayAdapter<>(this, android.R.layout.simple_list_item_1, names);
        listView.setAdapter(adapter);

        checkContactsPermission();

        listView.setOnItemClickListener((parent, view, position, id) -> {
            selectedNumber = numbers.get(position);
            checkCallPermission();
        });
    }

    private void checkContactsPermission() {
        if (ActivityCompat.checkSelfPermission(this, Manifest.permission.READ_CONTACTS)
                == PackageManager.PERMISSION_GRANTED) {
            loadContacts();
        } else {
            ActivityCompat.requestPermissions(this,
                    new String[]{Manifest.permission.READ_CONTACTS}, REQUEST_CONTACTS);
        }
    }

    private void checkCallPermission() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            if (ActivityCompat.checkSelfPermission(this, Manifest.permission.CALL_PHONE)
                    != PackageManager.PERMISSION_GRANTED) {
                ActivityCompat.requestPermissions(this,
                        new String[]{Manifest.permission.CALL_PHONE}, REQUEST_CALL);
                return;
            }
        }
        makeCall();
    }

    private void makeCall() {
        if (selectedNumber == null || selectedNumber.isEmpty()) return;

        Intent intent = new Intent(Intent.ACTION_CALL);
        intent.setData(Uri.parse("tel:" + selectedNumber));

        if (intent.resolveActivity(getPackageManager()) != null) {
            startActivity(intent);
        } else {
            Toast.makeText(this, "Không tìm thấy ứng dụng gọi điện", Toast.LENGTH_SHORT).show();
        }
    }

    private void loadContacts() {
        ContentResolver cr = getContentResolver();
        String[] projection = {
                ContactsContract.Contacts._ID,
                ContactsContract.Contacts.DISPLAY_NAME,
                ContactsContract.Contacts.HAS_PHONE_NUMBER
        };

        Cursor cursor = cr.query(ContactsContract.Contacts.CONTENT_URI, projection, null, null, null);

        if (cursor != null && cursor.getCount() > 0) {
            while (cursor.moveToNext()) {
                String id = cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts._ID));
                String name = cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME));
                int hasPhone = cursor.getInt(cursor.getColumnIndex(ContactsContract.Contacts.HAS_PHONE_NUMBER));

                if (hasPhone > 0) {
                    Cursor phoneCursor = cr.query(
                            ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
                            new String[]{ContactsContract.CommonDataKinds.Phone.NUMBER},
                            ContactsContract.CommonDataKinds.Phone.CONTACT_ID + " = ?",
                            new String[]{id}, null);

                    if (phoneCursor != null) {
                        while (phoneCursor.moveToNext()) {
                            String phone = phoneCursor.getString(
                                    phoneCursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
                            names.add(name);
                            numbers.add(phone);
                        }
                        phoneCursor.close();
                    }
                }
            }
            cursor.close();
            adapter.notifyDataSetChanged();
        }
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
        if (requestCode == REQUEST_CONTACTS) {
            if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                loadContacts();
            }
        } else if (requestCode == REQUEST_CALL) {
            if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                makeCall();
            } else {
                Toast.makeText(this, "Cần quyền CALL_PHONE để thực hiện cuộc gọi", Toast.LENGTH_LONG).show();
            }
        }
    }
}

Chạy ứng dụng

  1. Nhấn Run → cấp quyền Contacts → danh sách hiển thị.
  2. Nhấn vào một liên hệ → cấp quyền Phone (lần đầu) → cuộc gọi được khởi tạo.

Cách thực hiện cuộc gọi điện thoại trong Android

Cách thực hiện cuộc gọi điện thoại trong Android

Lưu ý quan trọng

  • Intent.ACTION_CALL: Gọi trực tiếp (cần quyền CALL_PHONE).
  • Intent.ACTION_DIAL: Mở keypad với số đã điền, người dùng tự bấm gọi (KHÔNG cần quyền đặc biệt).
  • Google Play hạn chế quyền CALL_PHONE cho app không phải dialer mặc định → cân nhắc dùng ACTION_DIAL.
  • Luôn kiểm tra intent.resolveActivity() trước khi startActivity.
  • Xử lý trường hợp số điện thoại có ký tự đặc biệt (*, #, +) - Uri.parse tự xử lý.