1. Introduction to ContentProvider
The client operation contentResolver and ContentProvider are the same
Auxiliary operation class ContentUris of Uri
2.ContentProvider database operation
Project class structure
1. Create MetaData
2. Define a subclass of SQLiteOpenHelper class to create and delete member tables
3,
Give up first
3. Use ContentProvider to access contacts
1. Create dynamic access to contacts (may be omitted)
Create permissionutils class
public class PermisionUtils { private static final int REQUEST_READ_CONTACTS = 1; private static String[] PERMISSIONS_CONTACTS = { Manifest.permission.READ_CONTACTS, Manifest.permission.WRITE_CONTACTS}; public static void verifyContactsPermissions(Activity activity) {//Check authority int permission = ActivityCompat.checkSelfPermission(activity, Manifest.permission.WRITE_CONTACTS); if (permission != PackageManager.PERMISSION_GRANTED) {//No authority ActivityCompat.requestPermissions(activity, PERMISSIONS_CONTACTS, REQUEST_READ_CONTACTS);//Dynamic empowerment } } }
2. Create listview layout page contacts.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="horizontal" android:layout_width="match_parent" android:layout_height="wrap_content"> <TextView android:id="@+id/_id" android:layout_marginLeft="10dp" android:textSize="14sp" android:layout_width="30sp" android:layout_height="35dp"/> <TextView android:id="@+id/name" android:text="Contacts" android:textSize="14sp" android:layout_width="wrap_content" android:layout_height="35dp"/> </LinearLayout>
3. Manifest file
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.fengray.myex004contactperson"> <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/AppTheme"> <activity android:name=".MainActivity"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application> <uses-permission android:name="android.permission.READ_CONTACTS"/> <uses-permission android:name="android.permission.WRITE_CONTACTS"/> </manifest>
4. Main layout page
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent"> <TextView android:textSize="14sp" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Mobile contact list" /> <ListView android:id="@+id/contactsList" android:layout_width="match_parent" android:layout_height="wrap_content"/> </LinearLayout>
5. activity page
public class MainActivity extends AppCompatActivity { private ListView contactsList=null; private List<Map<String,Object>> allContacts=null; private SimpleAdapter simpleadpter=null; private Cursor result=null; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); //PermisionUtils.verifyContactsPermissions(this); contactsList=findViewById(R.id.contactsList); //query result=getContentResolver().query(ContactsContract.Contacts.CONTENT_URI,null,null,null,null); //Submit result set to container management startManagingCursor(result); //Instantiate List collection allContacts=new ArrayList<Map<String, Object>>(); //Loop through the data in the result set, put it into the map, and finally add it to the list table for (result.moveToFirst();!result.isAfterLast();result.moveToNext()){ Map<String,Object> map=new HashMap<String,Object>(); //Take out each content in the result set above map.put("_id",result.getInt(result.getColumnIndex(ContactsContract.Contacts._ID))); map.put("name",result.getString(result.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME))); allContacts.add(map); } //Create adapter simpleadpter=new SimpleAdapter(this,allContacts,R.layout.contacts,new String[]{"_id","name"},new int[]{R.id._id,R.id.name}); contactsList.setAdapter(simpleadpter);//Set adpate registerForContextMenu(this.contactsList); } //Create action context menu @Override public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) { //super.onCreateContextMenu(menu, v, menuInfo); menu.setHeaderTitle("operation"); menu.add(menu.NONE, Menu.FIRST+1,1,"see information"); menu.add(menu.NONE, Menu.FIRST+2,1,"Delete information"); } @Override public boolean onContextItemSelected(@NonNull MenuItem item) { AdapterView.AdapterContextMenuInfo info= (AdapterView.AdapterContextMenuInfo) item.getMenuInfo(); int position=info.position;//Get the location of the context action menu String contactsID=allContacts.get(position).get("_id").toString(); switch (item.getItemId()){ case Menu.FIRST+1: String phoneSelection= ContactsContract.CommonDataKinds.Phone.CONTACT_ID+"=?"; String [] phoneSelectionArgs=new String[]{contactsID}; Cursor cursor=getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI,null, phoneSelection,phoneSelectionArgs,null); StringBuffer stringBuffer=new StringBuffer(); stringBuffer.append("phone number:"); for (cursor.moveToFirst(); !cursor.isAfterLast();cursor.moveToNext()){ stringBuffer.append(cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER))); } Toast.makeText(this, stringBuffer, Toast.LENGTH_SHORT).show(); break; case Menu.FIRST+2: getContentResolver().delete(Uri.withAppendedPath(ContactsContract.Contacts.CONTENT_URI,contactsID),null,null); allContacts.remove(position);//Output collection data items simpleadpter.notifyDataSetChanged();//Notification change Toast.makeText(this, "Data deleted", Toast.LENGTH_SHORT).show(); break; } return super.onContextItemSelected(item); } }
Result:
4. Use ContentProvider to access call records
1. Create dynamic access contact call & log permission (may be omitted)
Create permissionutils class
First execution asked
public class PermisionUtils { private static final int REQUEST_CALLLOG = 1; private static String[] PERMISSIONS_CALLLOG = { Manifest.permission.READ_CALL_LOG, Manifest.permission.WRITE_CALL_LOG}; public static void verifyCallLogPermissions(Activity activity) {//Check authority int permission = ActivityCompat.checkSelfPermission(activity, Manifest.permission.WRITE_CALL_LOG); if (permission != PackageManager.PERMISSION_GRANTED) {//No authority ActivityCompat.requestPermissions(activity, PERMISSIONS_CALLLOG, REQUEST_CALLLOG);//Dynamic empowerment } } }
2. adapter layout file
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="horizontal" android:layout_width="match_parent" android:layout_height="wrap_content"> <TextView android:id="@+id/_id" android:layout_marginLeft="10dp" android:textSize="14sp" android:layout_width="15sp" android:layout_height="35dp"/> <TextView android:id="@+id/name" android:text="Contacts" android:textSize="14sp" android:layout_width="wrap_content" android:layout_height="35dp"/> <TextView android:id="@+id/number" android:text="Phone number" android:textSize="14sp" android:layout_marginLeft="10dp" android:layout_width="wrap_content" android:layout_height="35dp"/> </LinearLayout>
3. Main layout file
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <ListView android:id="@+id/callist" android:layout_width="wrap_content" android:layout_height="wrap_content"/> </LinearLayout>
4. Manifest file
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.fengray.myex005tonghua"> <uses-permission android:name="android.permission.READ_CALL_LOG" /> <uses-permission android:name="android.permission.WRITE_CALL_LOG" /> <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/AppTheme"> <activity android:name=".MainActivity"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application> </manifest>
5. Main activity file
public class MainActivity extends AppCompatActivity { private ListView callist; private Cursor result = null;//Result pointer private List<Map<String, Object>> allCalls = null; private SimpleAdapter adapter = null; @RequiresApi(api = Build.VERSION_CODES.O) @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); PermisionUtils.verifyCallLogPermissions(this); callist = findViewById(R.id.callist); if (ActivityCompat.checkSelfPermission(this, Manifest.permission.READ_CALL_LOG) != PackageManager.PERMISSION_GRANTED) { return; } result = getContentResolver().query(CallLog.Calls.CONTENT_URI, null, null, null,null);//Query call records startManagingCursor(result);//Submit result set to manager for execution //Create List allCalls=new ArrayList<>(); for (result.moveToFirst();!result.isAfterLast();result.moveToNext()){ Map<String ,Object> contact=new HashMap<>(); contact.put("_id",result.getInt(result.getColumnIndex(CallLog.Calls._ID))); String tempString=result.getString(result.getColumnIndex(CallLog.Calls.CACHED_NAME));//This value is not taken in the operation Log.d("jian", "onCreate: "+tempString); if (tempString==null || "".equals(tempString)){ tempString="Unknown"; } contact.put("name",tempString); contact.put("number",result.getInt(result.getColumnIndex(CallLog.Calls.NUMBER))); allCalls.add(contact); } adapter=new SimpleAdapter(this,allCalls,R.layout.contacts,new String[]{"_id","name","number"},new int[]{R.id._id,R.id.name,R.id.number}); callist.setAdapter(adapter); } }
Result: name could not be read all the time, I don't know why
4.SimpleCursorAdapter
Create permissionutils class
First execution asked
public class PermisionUtils { private static final int REQUEST_CALLLOG = 1; private static String[] PERMISSIONS_CALLLOG = { Manifest.permission.READ_CALL_LOG, Manifest.permission.WRITE_CALL_LOG}; public static void verifyCallLogPermissions(Activity activity) {//Check authority int permission = ActivityCompat.checkSelfPermission(activity, Manifest.permission.WRITE_CALL_LOG); if (permission != PackageManager.PERMISSION_GRANTED) {//No authority ActivityCompat.requestPermissions(activity, PERMISSIONS_CALLLOG, REQUEST_CALLLOG);//Dynamic empowerment } } }
2. adapter layout file
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="horizontal" android:layout_width="match_parent" android:layout_height="wrap_content"> <TextView android:id="@+id/_id" android:layout_marginLeft="10dp" android:textSize="14sp" android:layout_width="15sp" android:layout_height="35dp"/> <TextView android:id="@+id/name" android:text="Contacts" android:textSize="14sp" android:layout_width="wrap_content" android:layout_height="35dp"/> <TextView android:id="@+id/number" android:text="Phone number" android:textSize="14sp" android:layout_marginLeft="10dp" android:layout_width="wrap_content" android:layout_height="35dp"/> </LinearLayout>
3. Main layout file
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <ListView android:id="@+id/callist" android:layout_width="wrap_content" android:layout_height="wrap_content"/> </LinearLayout>
4. Manifest file
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.fengray.myex005tonghua"> <uses-permission android:name="android.permission.READ_CALL_LOG" /> <uses-permission android:name="android.permission.WRITE_CALL_LOG" /> <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/AppTheme"> <activity android:name=".MainActivity"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application> </manifest>
5. Main activity file
public class MainActivity extends AppCompatActivity { private ListView callist; private Cursor result = null;//Result pointer private ListAdapter listAdapter=null; @RequiresApi(api = Build.VERSION_CODES.O) @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); PermisionUtils.verifyCallLogPermissions(this); callist = findViewById(R.id.callist); if (ActivityCompat.checkSelfPermission(this, Manifest.permission.READ_CALL_LOG) != PackageManager.PERMISSION_GRANTED) { return; } result = getContentResolver().query(CallLog.Calls.CONTENT_URI, null, null, null,null);//Query call records startManagingCursor(result);//Submit result set to manager for execution String [] columns=new String[] {CallLog.Calls._ID, CallLog.Calls.CACHED_NAME, CallLog.Calls.NUMBER}; int [] entries=new int[]{R.id._id,R.id.name,R.id.number}; listAdapter=new SimpleCursorAdapter(this,R.layout.contacts,result,columns,entries);//Turn the adpater into data that can be displayed directly callist.setAdapter(listAdapter); } }
Result: still unable to read the name attribute