【Android】讀取手機簡訊 顯示到自己的 APP 上 範例
在Android中,content://sms/inbox 是一個URI,它表示手機收件箱中的所有短信消息。開發者可以使用此URI來讀取手機上的短信消息,例如用於短信備份、消息提醒等應用場景。
使用此URI,開發者可以查詢收件箱中的所有短信消息,並讀取每個消息的發送者、接收者、時間戳和消息內容等信息。例如,可以使用以下代碼讀取收件箱中的短信消息。
文章目錄
- Manifest 申請權限
- 讀取簡訊
- 簡訊 projection
- 顯示所有簡訊
- SMSReadDemo Github
1.Manifest 申請權限
<uses-permission android:name="android.permission.RECEIVE_SMS" />
<uses-permission android:name="android.permission.READ_SMS" />
build.gradle
buildFeatures {
viewBinding true
}
MainActivity.kt
class MainActivity : AppCompatActivity() {
private lateinit var binding: ActivityMainBinding
private val readPermission = registerForActivityResult(ActivityResultContracts.RequestMultiplePermissions()) {}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
readPermission.launch(
arrayOf(
android.Manifest.permission.RECEIVE_SMS,
android.Manifest.permission.READ_SMS
)
)
}
}
2.讀取簡訊
MainActivity.kt
private fun querySMS(): MutableList<SMS> {
val uri = Uri.parse("content://sms/inbox")
val projection = arrayOf("_id", "address", "body", "date")
val smsList = mutableListOf<SMS>()
contentResolver.query(uri, projection, null, null, null)?.apply {
if (moveToFirst()) {
do {
val id = getInt(getColumnIndexOrThrow("_id"))
val sender = getString(getColumnIndexOrThrow("address"))
val body = getString(getColumnIndexOrThrow("body"))
val timestamp = getLong(getColumnIndexOrThrow("date"))
val dateFormat = SimpleDateFormat("yyyy/MM/dd HH:mm:ss", Locale.TAIWAN)
val dateTime = dateFormat.format(Date(timestamp))
smsList.add(SMS(id, sender, body, dateTime))
} while (moveToNext())
}
close()
}
return smsList
}
3.簡訊 projection
_id:短信 ID
thread_id:與該條短信相關聯的會話 ID
address:發送者或接收者的電話號碼
person:發送者或接收者在聯系人列表中的 ID
date:短信的時間戳,以毫秒為單位
date_sent:短信發送的時間戳,以毫秒為單位
protocol:短信協議
read:短信是否已讀
status:短信狀態
type:短信類型,1 表示收到的短信,2 表示發送的短信
body:短信內容
4.顯示所有簡訊
MainActivity.kt
class MainActivity : AppCompatActivity() {
private lateinit var binding: ActivityMainBinding
private val readPermission = registerForActivityResult(ActivityResultContracts.RequestMultiplePermissions()) {}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
readPermission.launch(
arrayOf(
android.Manifest.permission.RECEIVE_SMS,
android.Manifest.permission.READ_SMS
)
)
binding.recyclerView.apply {
layoutManager = LinearLayoutManager(this@MainActivity)
setHasFixedSize(true)
adapter = SMSAdapter(querySMS())
val divider = DividerItemDecoration(this@MainActivity, DividerItemDecoration.VERTICAL)
addItemDecoration(divider)
}
}
private fun querySMS(): MutableList<SMS> {
val uri = Uri.parse("content://sms/inbox")
val projection = arrayOf("_id", "address", "body", "date")
val smsList = mutableListOf<SMS>()
contentResolver.query(uri, projection, null, null, null)?.apply {
if (moveToFirst()) {
do {
val id = getInt(getColumnIndexOrThrow("_id"))
val sender = getString(getColumnIndexOrThrow("address"))
val body = getString(getColumnIndexOrThrow("body"))
val timestamp = getLong(getColumnIndexOrThrow("date"))
val dateFormat = SimpleDateFormat("yyyy/MM/dd HH:mm:ss", Locale.TAIWAN)
val dateTime = dateFormat.format(Date(timestamp))
smsList.add(SMS(id, sender, body, dateTime))
} while (moveToNext())
}
close()
}
return smsList
}
}
SMSAdapter.kt
class SMSAdapter(private var smsList: List<SMS>) : RecyclerView.Adapter<SMSAdapter.SMSHolder>() {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): SMSHolder {
return SMSHolder(SmsItemBinding.inflate(LayoutInflater.from(parent.context), parent, false))
}
override fun onBindViewHolder(holder: SMSHolder, position: Int) {
holder.onBind(position)
}
override fun getItemCount() = smsList.size
inner class SMSHolder(private val smsItemBinding: SmsItemBinding) : RecyclerView.ViewHolder(smsItemBinding.root) {
fun onBind(position: Int) {
smsItemBinding.sender.text = smsList[position].sender
smsItemBinding.body.text = smsList[position].body
smsItemBinding.date.text = smsList[position].dateTime
}
}
}
SMS.kt
data class SMS(
val id: Int,
val sender: String,
val body: String,
val dateTime: String
)
sms_item.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:background="#C4E1FF"
android:padding="5dp"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_marginBottom="10dp"
android:id="@+id/smsLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/sender"
android:layout_width="0dp"
android:textColor="#008000"
android:textStyle="bold"
android:layout_height="wrap_content"
android:gravity="center"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:text="sender" />
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/body"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:textColor="@color/black"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="@+id/sender"
app:layout_constraintTop_toBottomOf="@+id/date"
tools:text="body" />
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/date"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:textColor="#9FA2A4"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:text="date" />
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recyclerView"
android:layout_width="0dp"
android:layout_height="0dp"
android:background="#C4E1FF"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:listitem="@layout/sms_item" />
</androidx.constraintlayout.widget.ConstraintLayout>
5.SMSReadDemo Github
SMSReadDemo Github