Android development course of molet technology - Li Xinghua - 02ContentProvider

Posted by erme on Sat, 14 Mar 2020 18:26:02 +0100

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

Published 44 original articles, won praise 1, visited 561
Private letter follow

Topics: Android xml encoding Database