Basic summary: reading and writing short messages of ContentProvider, and downloading SDK by fluent

mb61ab4a9335a30 2022-01-15 03:39:45 阅读数:450

basic summary reading writing short
  1. package?com.scott.provider;??

  2. import?java.text.SimpleDateFormat;??

  3. import?android.content.ContentResolver;??

  4. import?android.database.Cursor;??

  5. import?android.database.CursorWrapper;??

  6. import?android.net.Uri;??

  7. import?android.test.AndroidTestCase;??

  8. import?android.util.Log;??

  9. public?class?SMSTest?extends?AndroidTestCase?{??

  10. ????private?static?final?String?TAG?=?"SMSTest";??

  11. ????// conversation ??

  12. ????private?static?final?String?CONVERSATIONS?=?"content://sms/conversations/";??

  13. ????// Query contact ??

  14. ????private?static?final?String?CONTACTS_LOOKUP?=?"content://com.android.contacts/phone_lookup/";??

  15. ????// All SMS ??

  16. ????private?static?final?String?SMS_ALL???=?"content://sms/";??

  17. ????// inbox ??

  18. //??private?static?final?String?SMS_INBOX?=?"content://sms/inbox";??

  19. ????// Has been sent ??

  20. //??private?static?final?String?SMS_SENT??=?"content://sms/sent";??

  21. ????// Draft box ??

  22. //??private?static?final?String?SMS_DRAFT?=?"content://sms/draft";??

  23. ????private?SimpleDateFormat?dateFormat?=?new?SimpleDateFormat("yyyy-MM-dd?HH:mm:ss");??

  24. ????/**?

  25. ?????*? Read session information ?

  26. ?????*/??

  27. ????public?void?testReadConversation()?{??

  28. ????????ContentResolver?resolver?=?getContext().getContentResolver();??

  29. ????????Uri?uri?=?Uri.parse(CONVERSATIONS);??

  30. ????????String[]?projection?=?new?String[]{"groups.group_thread_id?AS?group_id",?"groups.msg_count?AS?msg_count",??

  31. ????????????????????????"groups.group_date?AS?last_date",?"sms.body?AS?last_msg",?"sms.address?AS?contact"};??

  32. ????????Cursor?thinc?=?resolver.query(uri,?projection,?null,?null,?"groups.group_date?DESC");???// Query and reverse by date ??

  33. ????????Cursor?richc?=?new?CursorWrapper(thinc)?{???// Yes Cursor To deal with , Get the corresponding contact name after encountering the number ??

  34. ????????????@Override??

  35. ????????????public?String?getString(int?columnIndex)?{??

  36. ????????????????if(super.getColumnIndex("contact")?==?columnIndex){??

  37. ????????????????????String?contact?=?super.getString(columnIndex);??

  38. ????????????????????// Read contacts , Query the corresponding name ??

  39. ????????????????????Uri?uri?=?Uri.parse(CONTACTS_LOOKUP?+?contact);??

  40. ????????????????????Cursor?cursor?=?getContext().getContentResolver().query(uri,?null,?null,?null,?null);??

  41. ????????????????????if(cursor.moveToFirst()){??

  42. ????????????????????????String?contactName?=?cursor.getString(cursor.getColumnIndex("display_name"));??

  43. ????????????????????????return?contactName;??

  44. ????????????????????}??

  45. ????????????????????return?contact;??

  46. ????????????????}??

  47. ????????????????return?super.getString(columnIndex);??

  48. ????????????}??

  49. ????????};??

  50. ????????while?(richc.moveToNext())?{??

  51. ????????????String?groupId?=?"groupId:?"?+?richc.getInt(richc.getColumnIndex("group_id"));??

  52. ????????????String?msgCount?=?"msgCount:?"?+?richc.getLong(richc.getColumnIndex("msg_count"));??

  53. ????????????String?lastMsg?=?"lastMsg:?"?+?richc.getString(richc.getColumnIndex("last_msg"));??

  54. ????????????String?contact?=?"contact:?"?+?richc.getString(richc.getColumnIndex("contact"));??

  55. ????????????String?lastDate?=?"lastDate:?"?+?dateFormat.format(richc.getLong(richc.getColumnIndex("last_date")));??

  56. ????????????printLog(groupId,?contact,?msgCount,?lastMsg,?lastDate,?"---------------END---------------");??

  57. ????????}??

  58. ????????richc.close();??

  59. ????}??

  60. ????/**?

  61. ?????*? Read SMS ?

  62. ?????*/??

  63. ????public?void?testReadSMS()?{??

  64. ????????ContentResolver?resolver?=?getContext().getContentResolver();??

  65. ????????Uri?uri?=?Uri.parse(SMS_ALL);??

  66. ????????String[]?projection?=?{"thread_id?AS?group_id",?"address?AS?contact",?"body?AS?msg_content",?"date",?"type"};??

  67. ????????Cursor?c?=?resolver.query(uri,?projection,?null,?null,?"date?DESC");????// Query and reverse by date ??

  68. ????????while?(c.moveToNext())?{??

  69. ????????????String?groupId?=?"groupId:?"?+?c.getInt(c.getColumnIndex("group_id"));??

  70. ????????????String?contact?=?"contact:?"?+?c.getString(c.getColumnIndex("contact"));??

  71. ????????????String?msgContent?=?"msgContent:?"?+?c.getString(c.getColumnIndex("msg_content"));??

  72. ????????????String?date?=?"date:?"?+?dateFormat.format(c.getLong(c.getColumnIndex("date")));??

  73. ????????????String?type?=?"type:?"?+?getTypeById(c.getInt(c.getColumnIndex("type")));??

  74. ????????????printLog(groupId,?contact,?msgContent,?date,?type,?"---------------END---------------");??

  75. ????????}??

  76. ????????c.close();??

  77. ????}??

  78. ????private?String?getTypeById(int?typeId)?{??

  79. ????????switch?(typeId)?{??

  80. ????????case?1:?return?"receive";??

  81. ????????case?2:?return?"send";??

  82. ????????case?3:?return?"draft";??

  83. ????????default:?return?"none";??

  84. ????????}??

  85. ????}??

  86. ????private?void?printLog(String...strings)?{??

  87. ????????for?(String?s?:?strings)?{??

  88. ????????????Log.i(TAG,?s?==?null???"NULL"?:?s);??

  89. ????????}??

  90. ????}??

  91. }??

package com.scott.provider;

import java.text.SimpleDateFormat;

import android.content.ContentResolver;

import android.database.Cursor;

import android.database.CursorWrapper;

import android.net.Uri;

import android.test.AndroidTestCase;

import android.util.Log;

public class SMSTest extends AndroidTestCase {

private static final String TAG = "SMSTest";

// conversation

private static final String CONVERSATIONS = "content://sms/conversations/";

// Query contact

private static final String CONTACTS_LOOKUP = "content://com.android.contacts/phone_lookup/";

// All SMS

private static final String SMS_ALL = "content://sms/";

// inbox

// private static final String SMS_INBOX = "content://sms/inbox";

// Has been sent

// private static final String SMS_SENT = "content://sms/sent";

// Draft box

// private static final String SMS_DRAFT = "content://sms/draft";

private SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

/**

  • Read session information

*/

public void testReadConversation() {

ContentResolver resolver = getContext().getContentResolver();

Uri uri = Uri.parse(CONVERSATIONS);

String[] projection = new String[]{"groups.group_thread_id AS group_id", "groups.msg_count AS msg_count",

"groups.group_date AS last_date", "sms.body AS last_msg", "sms.address AS contact"};

Cursor thinc = resolver.query(uri, projection, null, null, "groups.group_date DESC"); // Query and reverse by date

Cursor richc = new CursorWrapper(thinc) { // Yes Cursor To deal with , Get the corresponding contact name after encountering the number

@Override

public String getString(int columnIndex) {

if(super.getColumnIndex("contact") == columnIndex){

String contact = super.getString(columnIndex);

// Read contacts , Query the corresponding name

Uri uri = Uri.parse(CONTACTS_LOOKUP + contact);

Cursor cursor = getContext().getContentResolver().query(uri, null, null, null, null);

if(cursor.moveToFirst()){

String contactName = cursor.getString(cursor.getColumnIndex("display_name"));

return contactName;

}

return contact;

}

return super.getString(columnIndex);

}

};

while (richc.moveToNext()) {

String groupId = "groupId: " + richc.getInt(richc.getColumnIndex("group_id"));

String msgCount = "msgCount: " + richc.getLong(richc.getColumnIn

《Android Summary of learning notes + Latest mobile architecture video + Big Android interview questions + Project actual combat source code handout 》

【docs.qq.com/doc/DSkNLaERkbnFoS0ZF】 Open source sharing of complete information

dex("msg_count"));

String lastMsg = "lastMsg: " + richc.getString(richc.getColumnIndex("last_msg"));

String contact = "contact: " + richc.getString(richc.getColumnIndex("contact"));

String lastDate = "lastDate: " + dateFormat.format(richc.getLong(richc.getColumnIndex("last_date")));

printLog(groupId, contact, msgCount, lastMsg, lastDate, "---------------END---------------");

}

richc.close();

}

/**

  • Read SMS

*/

public void testReadSMS() {

ContentResolver resolver = getContext().getContentResolver();

Uri uri = Uri.parse(SMS_ALL);

String[] projection = {"thread_id AS group_id", "address AS contact", "body AS msg_content", "date", "type"};

Cursor c = resolver.query(uri, projection, null, null, "date DESC"); // Query and reverse by date

while (c.moveToNext()) {

String groupId = "groupId: " + c.getInt(c.getColumnIndex("group_id"));

String contact = "contact: " + c.getString(c.getColumnIndex("contact"));

String msgContent = "msgContent: " + c.getString(c.getColumnIndex("msg_content"));

String date = "date: " + dateFormat.format(c.getLong(c.getColumnIndex("date")));

String type = "type: " + getTypeById(c.getInt(c.getColumnIndex("type")));

printLog(groupId, contact, msgContent, date, type, "---------------END---------------");

}

c.close();

}

private String getTypeById(int typeId) {

switch (typeId) {

case 1: return "receive";

case 2: return "send";

case 3: return "draft";

default: return "none";

}

}

private void printLog(String...strings) {

for (String s : strings) {

Log.i(TAG, s == null ? "NULL" : s);

}

}

}

Let's analyze it testReadConversation() Method , It is used to read all session information , according to “content://sms/conversations/” This URI Read session data , When you get the data , Further packaging of data , The specific method is to meet the number according to “content://com.android.contacts/phone_lookup/” Find the corresponding name in the contact , If present, the name is displayed instead of the number . We noticed that... Was used when querying sessions projection, What are these based on ? This requires us to take a look at the source code .

We find TelephonyProvider Medium com/android/providers/telephony/SmsProvider.java file , Let's see what :

[java] [view plain]( ) [copy]( ) [print]( ) [?]( )

  1. @Override??

  2. public?Cursor?query(Uri?url,?String[]?projectionIn,?String?selection,??

  3. ????????String[]?selectionArgs,?String?sort)?{??

  4. ????SQLiteQueryBuilder?qb?=?new?SQLiteQueryBuilder();??

  5. ????//?Generate?the?body?of?the?query.??

  6. ????int?match?=?sURLMatcher.match(url);??

  7. ????switch?(match)?{??

  8. ????...??

  9. ????case?SMS_CONVERSATIONS:??

  10. ????????qb.setTables("sms,?(SELECT?thread_id?AS?group_thread_id,?MAX(date)AS?group_date,"??

  11. ???????????????+?"COUNT(*)?AS?msg_count?FROM?sms?GROUP?BY?thread_id)?AS?groups");??

  12. ????????qb.appendWhere("sms.thread_id?=?groups.group_thread_id?AND?sms.date?="??

  13. ???????????????+?"groups.group_date");??

  14. ????????qb.setProjectionMap(sConversationProjectionMap);??

  15. ????????break;??

  16. ????????...??

  17. ????}??

  18. ????String?orderBy?=?null;??

  19. ????if?(!TextUtils.isEmpty(sort))?{??

  20. ????????orderBy?=?sort;??

  21. ????}?else?if?(qb.getTables().equals(TABLE_SMS))?{??

  22. ????????orderBy?=?Sms.DEFAULT_SORT_ORDER;??

  23. ????}??

  24. ????SQLiteDatabase?db?=?mOpenHelper.getReadableDatabase();??

  25. ????Cursor?ret?=?qb.query(db,?projectionIn,?selection,?selectionArgs,??

  26. ??????????????????????????null,?null,?orderBy);??

  27. ????//?TODO:?Since?the?URLs?are?a?mess,?always?use?content://sms??

  28. ????ret.setNotificationUri(getContext().getContentResolver(),??

  29. ????????????NOTIFICATION_URI);??

  30. ????return?ret;??

  31. }??

@Override

public Cursor query(Uri url, String[] projectionIn, String selection,

String[] selectionArgs, String sort) {

SQLiteQueryBuilder qb = new SQLiteQueryBuilder();

// Generate the body of the query.

int match = sURLMatcher.match(url);

switch (match) {

...

case SMS_CONVERSATIONS:

qb.setTables("sms, (SELECT thread_id AS group_thread_id, MAX(date)AS group_date,"

  • "COUNT(*) AS msg_count FROM sms GROUP BY thread_id) AS groups");

qb.appendWhere("sms.thread_id = groups.group_thread_id AND sms.date ="

  • "groups.group_date");

qb.setProjectionMap(sConversationProjectionMap);

break;

...

}

String orderBy = null;

if (!TextUtils.isEmpty(sort)) {

orderBy = sort;

} else if (qb.getTables().equals(TABLE_SMS)) {

orderBy = Sms.DEFAULT_SORT_ORDER;

}

SQLiteDatabase db = mOpenHelper.getReadableDatabase();

Cursor ret = qb.query(db, projectionIn, selection, selectionArgs,

null, null, orderBy);

// TODO: Since the URLs are a mess, always use content://sms

ret.setNotificationUri(getContext().getContentResolver(),

NOTIFICATION_URI);

return ret;

}

We see , stay query Methodical case In the sentence , If it is SMS_CONVERSATIONS Type words , for SQLiteQueryBuilder Instance object qb Set the corresponding query table and where sentence , In addition, a basic query mapping will be set for it map namely sConversationProjectionMap, This variable is embodied in the following code :

[java] [view plain]( ) [copy]( ) [print]( ) [?]( )

  1. static?{??

  2. ????...??

  3. ????sURLMatcher.addURI("sms",?"conversations",?SMS_CONVERSATIONS);??

  4. ????sURLMatcher.addURI("sms",?"conversations/*",?SMS_CONVERSATIONS_ID);??

  5. ????...??

  6. ????sConversationProjectionMap.put(Sms.Conversations.SNIPPET,??

  7. ????????"sms.body?AS?snippet");??

  8. ????sConversationProjectionMap.put(Sms.Conversations.THREAD_ID,??

  9. ????????"sms.thread_id?AS?thread_id");??

  10. ????sConversationProjectionMap.put(Sms.Conversations.MESSAGE_COUNT,??

  11. ????????"groups.msg_count?AS?msg_count");??

  12. ????sConversationProjectionMap.put("delta",?null);??

  13. }??

static {

...

sURLMatcher.addURI("sms", "conversations", SMS_CONVERSATIONS);

sURLMatcher.addURI("sms", "conversations/*", SMS_CONVERSATIONS_ID);

...

sConversationProjectionMap.put(Sms.Conversations.SNIPPET,

"sms.body AS snippet");

sConversationProjectionMap.put(Sms.Conversations.THREAD_ID,

"sms.thread_id AS thread_id");

sConversationProjectionMap.put(Sms.Conversations.MESSAGE_COUNT,

"groups.msg_count AS msg_count");

sConversationProjectionMap.put("delta", null);

}

What is the use of these data ? If we query projection by null Words ,sConversationProjectionMap It will be converted to the default projection, Finally, the query result contains only these three basic fields :snippet、thread_id、msg_count, The most concise information that can represent a conversation , Friends can try it themselves .

Of course , If you want to run the above test case , Two permissions need to be configured : Read SMS permission and read contact permission , as follows :

[html] [view plain]( ) [copy]( ) [print]( ) [?]( )

  1. <!--? Read SMS ?-->??

  2. <uses-permission?android:name\="android.permission.READ_SMS"?/>??

  3. <!--? Read contacts ?-->??

  4. <uses-permission?android:name\="android.permission.READ_CONTACTS"/>??

<!-- Read SMS -->

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

<!-- Read contacts -->

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

Then let's run the test case , give the result as follows :

 Basic summary :ContentProvider Read and write short messages ,flutter download sdk

That's all about reading the session , Now let's introduce one of them testReadSMS() Method . In this method, we try to get all short messages , Used “content://sms/” The query , This query is relatively simple . In addition, there are several unused in the code URI, They are inbox 、 Sent and drafts , These queries are “content://sms/” Subset , Different selection conditions are used to query the short message table , Let's take a look at the specific source code :

[java] [view plain]( ) [copy]( ) [print]( ) [?]( )

  1. ??@Override??

  2. ??public?Cursor?query(Uri?url,?String[]?projectionIn,?String?selection,??

  3. ??????????String[]?selectionArgs,?String?sort)?{??

  4. ??????SQLiteQueryBuilder?qb?=?new?SQLiteQueryBuilder();??

  5. ??????//?Generate?the?body?of?the?query.??

  6. ??????int?match?=?sURLMatcher.match(url);??

  7. ??????switch?(match)?{??

  8. ??????case?SMS_ALL:??

  9. ??????????constructQueryForBox(qb,?Sms.MESSAGE_TYPE_ALL);??

  10. ??????????break;??

  11. ??????case?SMS_INBOX:??

  12. ??????????constructQueryForBox(qb,?Sms.MESSAGE_TYPE_INBOX);??

  13. ??????????break;??

  14. ??????case?SMS_SENT:??

  15. ??????????constructQueryForBox(qb,?Sms.MESSAGE_TYPE_SENT);??

  16. ??????????break;??

  17. ??????case?SMS_DRAFT:??

  18. ??????????constructQueryForBox(qb,?Sms.MESSAGE_TYPE_DRAFT);??

  19. ??????????break;??

  20. ??????}??

  21. ...??

  22. ??}??

@Override

public Cursor query(Uri url, String[] projectionIn, String selection,

String[] selectionArgs, String sort) {

SQLiteQueryBuilder qb = new SQLiteQueryBuilder();

// Generate the body of the query.

int match = sURLMatcher.match(url);

switch (match) {

case SMS_ALL:

constructQueryForBox(qb, Sms.MESSAGE_TYPE_ALL);

break;

case SMS_INBOX:

constructQueryForBox(qb, Sms.MESSAGE_TYPE_INBOX);

break;

case SMS_SENT:

constructQueryForBox(qb, Sms.MESSAGE_TYPE_SENT);

break;

case SMS_DRAFT:

constructQueryForBox(qb, Sms.MESSAGE_TYPE_DRAFT);

break;

}

...

}

You can see , They all called constructQueryForBox Method , What is this method for ?

[java] [view plain]( ) [copy]( ) [print]( ) [?]( )

  1. private?void?constructQueryForBox(SQLiteQueryBuilder?qb,?int?type)?{??

  2. ????qb.setTables(TABLE_SMS);??

  3. ????if?(type?!=?Sms.MESSAGE_TYPE_ALL)?{??

  4. ????????qb.appendWhere("type="?+?type);??

  5. ????}??

  6. }??

private void constructQueryForBox(SQLiteQueryBuilder qb, int type) {

qb.setTables(TABLE_SMS);

if (type != Sms.MESSAGE_TYPE_ALL) {

qb.appendWhere("type=" + type);

}

}

We found that it actually adds filter conditions , If not all , Then add type filter information , Therefore, query different SMS sets . Friends can also try different types of queries in person .

in addition , If we want to query the corresponding SMS collection according to the session , We can do it in two ways :

1.“content://sms/”(selection:“thread_id=3”)

2.“content://sms/conversations/3”

The first one is easier to think of the query process , That is to add... To the above “thread_id=3” This article where Sentence can be used ; The second is in conversation path Follow the conversation id that will do , The specific logic is as follows :

[java] [view plain]( ) [copy]( ) [print]( ) [?]( )

  1. case?SMS_CONVERSATIONS_ID:??

  2. int?threadID;??

  3. try?{??

  4. ????threadID?=?Integer.parseInt(url.getPathSegments().get(1));??

  5. ????if?(Log.isLoggable(TAG,?Log.VERBOSE))?{??

  6. ????????Log.d(TAG,?"query?conversations:?threadID="?+?threadID);??

  7. ????}??

  8. }??

  9. catch?(Exception?ex)?{??

  10. ????Log.e(TAG,??

  11. ??????????"Bad?conversation?thread?id:?"??

  12. ??????????+?url.getPathSegments().get(1));??

  13. ????return?null;??

  14. }??

  15. qb.setTables(TABLE_SMS);??

  16. qb.appendWhere("thread_id?=?"?+?threadID);??

  17. break;??

case SMS_CONVERSATIONS_ID:

int threadID;

try {

threadID = Integer.parseInt(url.getPathSegments().get(1));

if (Log.isLoggable(TAG, Log.VERBOSE)) {

Log.d(TAG, "query conversations: threadID=" + threadID);

}

}

catch (Exception ex) {

Log.e(TAG,

"Bad conversation thread id: "

  • url.getPathSegments().get(1));

return null;

}

qb.setTables(TABLE_SMS);

qb.appendWhere("thread_id = " + threadID);

break;

We can see , It finally went the same way as the first way , There is no essential difference between the two . But in terms of simplicity and ease of use , This way is better , Friends can compare .

The above is to get all the information about the conversation content and SMS content , Let's introduce the writing operation of SMS .

Send and write SMS

On certain occasions , We need to send text messages , And write the SMS to the data source , At this time, we need to understand the sending SMS mechanism and writing SMS mechanism .

We will try to send a text message to the specified address , At the same time, the content of the short message is written to the short message data source , After the SMS is sent successfully , We inform the user that the transmission is successful , After the other party receives the message , We inform the user that the other party has received successfully .

To implement these functions , We need to understand the following key contents :

1. Use android.telephony.SmsManager Of API Send a text message

2. Use ContentProvider The mechanism is right “content://sms/sent” This URI Write operation

3. register “SENT_SMS_ACTION” This broadcast address , Receive this broadcast after the SMS is successfully sent

4. register “DELIVERED_SMS_ACTION” This broadcast address , When the other party receives the message, it receives the broadcast

Let's use code to realize these functions , Create a file called SMSActivity Of Activity, as follows :

[java] [view plain]( ) [copy]( ) [print]( ) [?]( )

  1. package?com.scott.provider;??

  2. import?java.util.List;??

  3. import?android.app.Activity;??

  4. import?android.app.PendingIntent;??

  5. import?android.content.BroadcastReceiver;??

  6. import?android.content.ContentValues;??

  7. import?android.content.Context;??

  8. import?android.content.Intent;??

  9. import?android.content.IntentFilter;??

  10. import?android.net.Uri;??

  11. import?android.os.Bundle;??

  12. import?android.telephony.SmsManager;??

  13. import?android.view.View;??

  14. import?android.widget.EditText;??

  15. import?android.widget.Toast;??

  16. public?class?SMSActivity?extends?Activity?{??

  17. ????private?SendReceiver?sendReceiver?=?new?SendReceiver();??

  18. ????private?DeliverReceiver?deliverReceiver?=?new?DeliverReceiver();??

  19. ????private?EditText?address;??

  20. ????private?EditText?body;??

  21. ????@Override??

  22. ????protected?void?onCreate(Bundle?savedInstanceState)?{??

  23. ????????super.onCreate(savedInstanceState);??

  24. ????????setContentView(R.layout.sms);??

  25. ????????address?=?(EditText)?findViewById(R.id.address);??

  26. ????????body?=?(EditText)?findViewById(R.id.body);??

  27. ????????// Register to send a successful broadcast ??

  28. ????????registerReceiver(sendReceiver,?new?IntentFilter("SENT_SMS_ACTION"));??

  29. ????????// Register to receive successful broadcasts ??

  30. ????????registerReceiver(deliverReceiver,?new?IntentFilter("DELIVERED_SMS_ACTION"));??

  31. ????}??

  32. ????@Override??

  33. ????protected?void?onDestroy()?{??

  34. ????????super.onDestroy();??

  35. ????????unregisterReceiver(sendReceiver);??

  36. ????????unregisterReceiver(deliverReceiver);??

  37. ????}??

  38. ????public?void?sendSMS(View?view)?{??

  39. ????????String?address?=?this.address.getText().toString();??

  40. ????????String?body?=?this.body.getText().toString();??

  41. ????????//android.telephony.SmsManager,?not?[android.telephony.gsm.SmsManager]??

  42. ????????SmsManager?smsManager?=?SmsManager.getDefault();??

  43. ????????// A message will be generated after successful or failed SMS sending SENT_SMS_ACTION Broadcast of ??

  44. ????????PendingIntent?sendIntent?=?PendingIntent.getBroadcast(this,?0,?new?Intent("SENT_SMS_ACTION"),?0);??

  45. ????????// After receiving the message successfully , The sender will generate a message DELIVERED_SMS_ACTION radio broadcast ??

  46. ????????PendingIntent?deliveryIntent?=?PendingIntent.getBroadcast(this,?0,?new?Intent("DELIVERED_SMS_ACTION"),?0);??

  47. ????????if?(body.length()?>?70)?{????// If the number of words exceeds 70, It needs to be split into multiple SMS messages to send ??

  48. ????????????List<String>?msgs?=?smsManager.divideMessage(body);??

  49. ????????????for?(String?msg?:?msgs)?{??

  50. ????????????????smsManager.sendTextMessage(address,?null,?msg,?sendIntent,?deliveryIntent);??????????????????????????

  51. ????????????}??

  52. ????????}?else?{??

  53. ????????????smsManager.sendTextMessage(address,?null,?body,?sendIntent,?deliveryIntent);??

  54. ????????}??

  55. ????????// Write to SMS data source ??

  56. ????????ContentValues?values?=?new?ContentValues();??

  57. ????????values.put("address",address);??// Sending address ??

  58. ????????values.put("body",?body);???// The message content ??

  59. ????????values.put("date",?System.currentTimeMillis());?// Creation time ??

  60. ????????values.put("read",?0);??//0: unread ;1: read ??

  61. ????????values.put("type",?2);??//1: receive ;2: send out ??

  62. ????????getContentResolver().insert(Uri.parse("content://sms/sent"),?values);???// insert data ??

  63. ????}??

  64. ????private?class?SendReceiver?extends?BroadcastReceiver?{??

  65. ????????@Override??

The end of the

If you want to be a good Android Developer , Please focus on , Do in-depth research on basic and important things .

For many primary and intermediate Android For Engineers , Want to improve skills , Often is oneself gropes for growth , Unsystematic learning is inefficient, long and helpless . I hope that these architecture technologies can be applied to Android Development of friends have reference and less detours , The point of this article is whether you have gained and grown up , The rest is unimportant , I hope readers will keep this in mind .

here , The author shares a video and data from the perspective of architecture philosophy to share with you the experience of many years of architecture , Near preparation 6 The latest recording of , I believe this video can give you different inspiration 、 Harvest . Basic summary :ContentProvider Read and write short messages ,flutter download sdk

PS: Because of the Internet's second line collection Android The real question of the interview ( contain BAT、 millet 、 Huawei 、 Meituan 、 sound of dripping water ) And I sort it out myself Android Review notes ( contain Android Basic knowledge points 、Android Expand your knowledge 、Android The source code parsing 、 Design pattern summary 、Gradle Knowledge point 、 Summary of common algorithm questions .)

 Basic summary :ContentProvider Read and write short messages ,flutter download sdk

Architecture

《Jetpack The whole family bucket creates a new Google Standard architecture mode 》
 Basic summary :ContentProvider Read and write short messages ,flutter download sdk

This article has been  CODING Open source project :《Android Summary of learning notes + Mobile architecture video + The real interview question of Dachang + Project source code 》 Included

版权声明:本文为[mb61ab4a9335a30]所创,转载请带上原文链接,感谢。 https://javamana.com/2021/12/202112122318461766.html