| পদ্ধতি | বিবরণ | পারমিশন | সুপারিশ |
| Intent.ACTION_INSERT | সিস্টেম UI খুলে, ইউজার কনফার্ম করে | দরকার নেই | ✅ সাধারণ অ্যাপের জন্য |
| ContentResolver.insert() | সিলেন্ট्ली যোগ করে (ব্যাকগ্রাউন্ড) | READ_CONTACTS, WRITE_CONTACTS | সিঙ্ক অ্যাপ, ব্যাকআপ টুলের জন্য |
ধাপ ১: প্রজেক্ট সেটআপ
Package: com.example.addcontact
ধাপ ২: লেআউট (activity_main.xml)
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="https://schemas.android.com/apk/res/android"
xmlns:tools="https://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:padding="16dp"
tools:context=".MainActivity">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="নতুন কন্ট্যাক্ট যোগ করুন"
android:textSize="24sp"
android:textStyle="bold"
android:layout_gravity="center_horizontal"
android:layout_marginBottom="24dp"/>
<com.google.android.material.textfield.TextInputLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="নাম">
<com.google.android.material.textfield.TextInputEditText
android:id="@+id/etName"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="textPersonName" />
</com.google.android.material.textfield.TextInputLayout>
<com.google.android.material.textfield.TextInputLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:hint="ফোন নম্বর">
<com.google.android.material.textfield.TextInputEditText
android:id="@+id/etPhone"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="phone" />
</com.google.android.material.textfield.TextInputLayout>
<com.google.android.material.textfield.TextInputLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:hint="ইমেইল (ঐচ্ছিক)">
<com.google.android.material.textfield.TextInputEditText
android:id="@+id/etEmail"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="textEmailAddress" />
</com.google.android.material.textfield.TextInputLayout>
<Button
android:id="@+id/btnAddContact"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="24dp"
android:text="কন্ট্যাক্ট যোগ করুন"
android:onClick="addContact"/>
<TextView
android:id="@+id/tvStatus"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:gravity="center"
android:textSize="14sp"
android:textColor="#666"/>
</LinearLayout>
ধাপ ৩: MainActivity.java
package com.example.addcontact;
import android.app.Activity;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.provider.ContactsContract;
import android.view.View;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;
import androidx.appcompat.app.AppCompatActivity;
public class MainActivity extends AppCompatActivity {
private static final int REQUEST_ADD_CONTACT = 1001;
private EditText etName, etPhone, etEmail;
private TextView tvStatus;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
etName = findViewById(R.id.etName);
etPhone = findViewById(R.id.etPhone);
etEmail = findViewById(R.id.etEmail);
tvStatus = findViewById(R.id.tvStatus);
}
public void addContact(View view) {
String name = etName.getText().toString().trim();
String phone = etPhone.getText().toString().trim();
String email = etEmail.getText().toString().trim();
if (name.isEmpty() && phone.isEmpty() && email.isEmpty()) {
tvStatus.setText("দয়া করে অন্তত একটি ফিল্ড পূরণ করুন");
return;
}
Intent intent = new Intent(ContactsContract.Intents.Insert.ACTION);
intent.setType(ContactsContract.RawContacts.CONTENT_TYPE);
if (!name.isEmpty()) {
intent.putExtra(ContactsContract.Intents.Insert.NAME, name);
}
if (!phone.isEmpty()) {
intent.putExtra(ContactsContract.Intents.Insert.PHONE, phone);
// ফোন টাইপ সেট করুন (ঐচ্ছিক)
intent.putExtra(ContactsContract.Intents.Insert.PHONE_TYPE,
ContactsContract.CommonDataKinds.Phone.TYPE_MOBILE);
}
if (!email.isEmpty()) {
intent.putExtra(ContactsContract.Intents.Insert.EMAIL, email);
intent.putExtra(ContactsContract.Intents.Insert.EMAIL_TYPE,
ContactsContract.CommonDataKinds.Email.TYPE_WORK);
}
// অতিরিক্ত ফিল্ডও যোগ করা যায়:
// intent.putExtra(ContactsContract.Intents.Insert.COMPANY, "Company Name");
// intent.putExtra(ContactsContract.Intents.Insert.JOB_TITLE, "Job Title");
// intent.putExtra(ContactsContract.Intents.Insert.POSTAL, "Address");
// intent.putExtra(ContactsContract.Intents.Insert.NOTES, "Notes");
if (intent.resolveActivity(getPackageManager()) != null) {
startActivityForResult(intent, REQUEST_ADD_CONTACT);
} else {
tvStatus.setText("কন্ট্যাক্ট অ্যাপ পাওয়া যায়নি");
}
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == REQUEST_ADD_CONTACT) {
if (resultCode == Activity.RESULT_OK) {
tvStatus.setText("✅ কন্ট্যাক্ট সফলভাবে যোগ হয়েছে");
Toast.makeText(this, "কন্ট্যাক্ট যোগ করা হয়েছে", Toast.LENGTH_SHORT).show();
clearFields();
} else if (resultCode == Activity.RESULT_CANCELED) {
tvStatus.setText("❌ কন্ট্যাক্ট যোগ করা বাতিল হয়েছে");
}
}
}
private void clearFields() {
etName.setText("");
etPhone.setText("");
etEmail.setText("");
}
}
ধাপ ৪: AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="https://schemas.android.com/apk/res/android"
package="com.example.addcontact">
<!-- Intent.ACTION_INSERT ব্যবহার করলে কোনো পারমিশন লাগে না -->
<!-- ContentResolver.insert() ব্যবহার করলে নিচের দুটি লাগে -->
<!-- <uses-permission android:name="android.permission.READ_CONTACTS" /> -->
<!-- <uses-permission android:name="android.permission.WRITE_CONTACTS" /> -->
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/Theme.AddContact">
<activity
android:name=".MainActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
উন্নত: ContentResolver দিয়ে সিলেন্ট ইনসার্ট (অ্যাডভান্সড)
যদি ব্যবহারকারীকে UI না দেখিয়ে সরাসরি কন্ট্যাক্ট যোগ করতে চান (পারমিশন দরকার):
// build.gradle dependencies
implementation "androidx.core:core:1.12.0"
// MainActivity-এ মেথড যোগ
private void insertContactSilently(String name, String phone, String email) {
// পারমিশন চেক
if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_CONTACTS)
!= PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(this,
new String[]{Manifest.permission.WRITE_CONTACTS}, 2001);
return;
}
// RawContact ইনসার্ট
ContentValues values = new ContentValues();
Uri rawContactUri = getContentResolver().insert(ContactsContract.RawContacts.CONTENT_URI, values);
long rawContactId = ContentUris.parseId(rawContactUri);
// নাম যোগ
values.clear();
values.put(ContactsContract.Data.RAW_CONTACT_ID, rawContactId);
values.put(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE);
values.put(ContactsContract.CommonDataKinds.StructuredName.DISPLAY_NAME, name);
getContentResolver().insert(ContactsContract.Data.CONTENT_URI, values);
// ফোন যোগ
if (!phone.isEmpty()) {
values.clear();
values.put(ContactsContract.Data.RAW_CONTACT_ID, rawContactId);
values.put(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE);
values.put(ContactsContract.CommonDataKinds.Phone.NUMBER, phone);
values.put(ContactsContract.CommonDataKinds.Phone.TYPE, ContactsContract.CommonDataKinds.Phone.TYPE_MOBILE);
getContentResolver().insert(ContactsContract.Data.CONTENT_URI, values);
}
// ইমেইল যোগ
if (!email.isEmpty()) {
values.clear();
values.put(ContactsContract.Data.RAW_CONTACT_ID, rawContactId);
values.put(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.Email.CONTENT_ITEM_TYPE);
values.put(ContactsContract.CommonDataKinds.Email.ADDRESS, email);
values.put(ContactsContract.CommonDataKinds.Email.TYPE, ContactsContract.CommonDataKinds.Email.TYPE_WORK);
getContentResolver().insert(ContactsContract.Data.CONTENT_URI, values);
}
runOnUiThread(() -> tvStatus.setText("✅ সিলেন্টলি কন্ট্যাক্ট যোগ হয়েছে (ID: " + rawContactId + ")"));
}
পরীক্ষা পদ্ধতি
- অ্যাপ চালু করুন → নাম, ফোন, ইমেইল লিখুন
- "কন্ট্যাক্ট যোগ করুন" চাপুন
- সিস্টেম কন্ট্যাক্ট অ্যাপ খুলবে → "Save" চাপুন
- আপনার অ্যাপে ফিরে "কন্ট্যাক্ট সফলভাবে যোগ হয়েছে" দেখুন
- কন্ট্যাক্ট অ্যাপে যাচাই করুন
সাধারণ সমস্যা ও সমাধান
| সমস্যা | সমাধান |
| কন্ট্যাক্ট অ্যাপ খুলছে না | intent.resolveActivity() null চেক করুন, ডিভাইসে কন্ট্যাক্ট অ্যাপ আছে কিনা |
| ফোন নম্বর ফরম্যাট ভুল | inputType="phone" ব্যবহার করুন,'util-normalizeNumber()' দিয়ে নরমালাইজ করুন |
| Duplicate কন্ট্যাক্ট তৈরি হচ্ছে | ইনসার্ট করার আগে কোয়েরি করে চেক করুন (ContentResolver.query) |
| Permission denied (Silent insert) | WRITE_CONTACTS পারমিশন manifest + runtime দুটোই দিন |
সেরা অনুশীলন
- ব্যবহারকারীর গোপনীয়তা রক্ষা: শুধু জরুরি ফিল্ডই চাইये
- Intent.ACTION_INSERT ব্যবহার করুন — ব্যবহারকারী কন্ট্রোল পায়
- ফোন নম্বর E.164 ফরম্যাটে (+88017...) স্টোর করুন আন্তর্জাতিক কম্প্যাটিবিলিটির জন্য
- বড় পরিমাণ কন্ট্যাক্ট যোগ করলে
applyBatch() ব্যবহার করুন