CĂN BẢN
INTENTS
GIAO DIỆN
CÁC KHÁI NIỆM
VÍ DỤ
TÀI LIỆU
HỌC LẬP TRÌNH ANDROID
CÁC CHỦ ĐỀ
BÀI MỚI NHẤT
MỚI CẬP NHẬT

Content Providers trong Android

Bài này chúng ta sẽ tìm hiểu về content provider trong Android, nó đóng vai trò là một kho cung cấp nội dung cho ứng dụng Android.

test php

banquyen png
Bài viết này được đăng tại freetuts.net, không được copy dưới mọi hình thức.

Trong Android, content provider sẽ hoạt động như một kho lưu trữ trung tâm để lưu trữ dữ liệu ứng dụng ở một nơi và cung cấp dữ liệu đó cho các ứng dụng khác nhau để truy cập bất cứ khi nào nó yêu cầu.

Chúng ta có thể định cấu hình content provider để cho phép các ứng dụng khác truy cập an toàn và sửa đổi dữ liệu ứng dụng.

Nói chung, content provider là một phần của ứng dụng Android và nó sẽ hoạt động giống như cơ sở dữ liệu quan hệ dùng để lưu trữ dữ liệu ứng dụng. Chúng ta có thể thực hiện nhiều thao tác như chèn, cập nhật, xóa và chỉnh sửa dữ liệu được lưu trữ trong content provider bằng các phương thức insert (), update (), delete ()query ().

Bài viết này được đăng tại [free tuts .net]

Trong Android, có thể sử dụng content provider bất cứ khi nào chúng ta muốn chia sẻ dữ liệu ứng dụng với các ứng dụng khác, và nó cho phép sửa đổi dữ liệu ứng dụng mà không ảnh hưởng đến các ứng dụng khác phụ thuộc vào ứng dụng đó.

Content provider có nhiều cách khác nhau để lưu trữ dữ liệu ứng dụng. Dữ liệu ứng dụng có thể được lưu trữ trong cơ sở dữ liệu [SQLite] hoặc trong các file, hoặc thậm chí qua mạng dựa trên các yêu cầu. Bằng cách sử dụng các content provider, chúng ta có thể quản lý dữ liệu như âm thanh, video, hình ảnh và thông tin liên hệ cá nhân.

Có nhiều loại truy cập khác có sẵn trong content provider để chia sẻ dữ liệu. Ta có thể đặt quyền hạn chế quyền truy cập trong content provider để hạn chế quyền truy cập dữ liệu giới hạn trong ứng dụng,
và có thể cấu hình các permissions khác nhau để đọc hoặc ghi dữ liệu.

1. Truy cập dữ liệu từ content provider

Để truy cập dữ liệu từ content provider, ta cần sử dụng đối tượng ContentResolver trong ứng dụng để liên lạc với provider với tư cách là khách hàng. Đối tượng ContentResolver sẽ giao tiếp với đối tượng provider (ContentProvider) được triển khai theo instance của lớp.

Nói chung, để gửi yêu cầu từ UI đến ContentResolver, chúng ta có một đối tượng khác gọi là CursorLoader, được sử dụng để chạy truy vấn không đồng bộ trong background. Trong ứng dụng Android, các component UI như Activity hoặc Fragment sẽ gọi CursorLoader để truy vấn và nhận dữ liệu cần thiết từ ContentProvider bằng ContentResolver.

Đối tượng ContentProvider sẽ nhận được yêu cầu dữ liệu từ máy khách, thực hiện các hành động được yêu cầu (tạo, cập nhật, xóa, truy xuất) và trả về kết quả.

Sau đây là hình ảnh minh họa việc yêu cầu một thao tác từ UI bằng Activity hoặc Fragment để lấy dữ liệu từ đối tượng ContentProvider.

1 png

Đây là cách tương tác sẽ xảy ra giữa UI ứng dụng Android và content provider để thực hiện các hành động cần thiết để lấy dữ liệu.

2. Content URI

Trong Android, Content URI là một URI được sử dụng để truy vấn content provider để lấy dữ liệu cần thiết. Các content URI sẽ chứa tên của toàn bộ provider (authority) và tên trỏ đến một bản ghi(path).

Nói chung, định dạng của URI trong các ứng dụng Android sẽ giống như dưới đây

content://authority/path

Sau đây là chi tiết về các phần khác nhau của một URI .

  • content: // - luôn có trong URI và nó được sử dụng để thể hiện đây là content URI.
  • authority - đại diện cho tên của content provider, ví dụ phone, contacts, v.v. và cần sử dụng tên đủ điều kiện cho các content provider bên thứ ba như com.tutlane.contactprovider
  • path - đại diện cho đường dẫn bản ghi.

Đối tượng ContentResolver sử dụng authority URI, để tìm provider phù hợp và gửi các đối tượng truy vấn đến provider. Sau đó, ContentProvider sử dụng đường dẫn của content URI để chọn đúng bản ghi để truy cập.

Sau đây là ví dụ về ví dụ đơn giản về URI trong các ứng dụng Android.

content://contacts_info/users

Ở đây, chuỗi content:// được sử dụng để thể hiện URI là một content URI, chuỗi contact_info là tên quyền hạn của provider và chuỗi user là đường dẫn bản ghi.

3. Tạo content provider

Để tạo một content provider trong các ứng dụng Android, chúng ta nên làm theo các bước dưới đây.

  • Cần tạo một lớp content provider kế thừa lớp ContentProvider.
  • Cần xác định content provider URI để truy cập content.
  • Lớp ContentProvider định nghĩa sáu phương thức trừu tượng (insert (), update (), delete (), query (), getType ()) mà chúng ta cần thực hiện tất cả các phương thức này như là một phần của lớp con.
  • Cần đăng ký content provider trong AndroidManifest.xml bằng cách sử dụng thẻ <provider>.

Sau đây là danh sách các phương thức cần triển khai.

2 png

  • query() - Nhận một yêu cầu từ khách hàng. Bằng cách sử dụng các đối số, nó sẽ nhận được dữ liệu từ bản ghi và trả về dữ liệu dưới dạng đối tượng Cursor.
  • insert() - Phương thức này sẽ chèn một hàng mới vào content provider và nó sẽ trả về content URI cho hàng mới được chèn.
  • update() - Phương thức này sẽ cập nhật một hàng hiện có trong content provider và nó trả về số lượng hàng được cập nhật.
  • delete() - Phương thức này sẽ xóa các hàng trong content provider và nó trả về số lượng hàng đã xóa.
  • getType() - Phương thức này sẽ trả về loại dữ liệu MIME cho content URI đã cho.
  • onCreate() - Phương thức này sẽ khởi tạo provider . Hệ thống Android sẽ gọi phương thức này ngay lập tức sau khi nó tạo ra provider .

4. Ví dụ về content provider Android

Sau đây là ví dụ về việc sử dụng content provider trong các ứng dụng Android. Ở đây chúng ta sẽ tạo content provider để chèn và truy cập dữ liệu trong ứng dụng Android.

Tạo một ứng dụng Android và đặt tên là ContentProvider.

Bây giờ chúng ta cần tạo file content provider tên là UserProvider.java trong đường dẫn \ src \ main \ java \ com.tutlane.contentprovider để xác định provider thực tế và các phương thức được liên kết bằng cách: nhấp chuột phải vào folder ứng dụng của bạn -> New -> chọn Java Class và đặt tên là UserProvider.java.

Khi tạo một file mới UserProvider.java, hãy nhập code như dưới đây

UserProvider.java

package com.tutlane.contentprovider;

import android.content.ContentProvider;
import android.content.ContentUris;
import android.content.ContentValues;
import android.content.Context;
import android.content.UriMatcher;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteException;
import android.database.sqlite.SQLiteOpenHelper;
import android.database.sqlite.SQLiteQueryBuilder;
import android.net.Uri;
import java.util.HashMap;

/**
 * Created by sureshdasari on 29-07-2017.
 */

public class UsersProvider extends ContentProvider {
    static final String PROVIDER_NAME = "com.tutlane.contentprovider.UserProvider";
    static final String URL = "content://" + PROVIDER_NAME + "/users";
    static final Uri CONTENT_URI = Uri.parse(URL);

    static final String id = "id";
    static final String name = "name";
    static final int uriCode = 1;
    static final UriMatcher uriMatcher;
    private static HashMap<String, String> values;
    static {
        uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
        uriMatcher.addURI(PROVIDER_NAME, "users", uriCode);
        uriMatcher.addURI(PROVIDER_NAME, "users/*", uriCode);
    }

   @Override
    public String getType(Uri uri) {
        switch (uriMatcher.match(uri)) {
            case uriCode:
                return "vnd.android.cursor.dir/users";
            default:
                throw new IllegalArgumentException("Unsupported URI: " + uri);
        }
    }

    @Override
    public boolean onCreate() {
        Context context = getContext();
        DatabaseHelper dbHelper = new DatabaseHelper(context);
        db = dbHelper.getWritableDatabase();
        if (db != null) {
            return true;
        }
        return false;
    }

    @Override
    public Cursor query(Uri uri, String[] projection, String selection,
                        String[] selectionArgs, String sortOrder) {
        SQLiteQueryBuilder qb = new SQLiteQueryBuilder();
        qb.setTables(TABLE_NAME);

        switch (uriMatcher.match(uri)) {
            case uriCode:
                qb.setProjectionMap(values);
                break;
            default:
                throw new IllegalArgumentException("Unknown URI " + uri);
        }
        if (sortOrder == null || sortOrder == "") {
            sortOrder = id;
        }
        Cursor c = qb.query(db, projection, selection, selectionArgs, null,
                null, sortOrder);
        c.setNotificationUri(getContext().getContentResolver(), uri);
        return c;
    }
    @Override
    public Uri insert(Uri uri, ContentValues values) {
        long rowID = db.insert(TABLE_NAME, "", values);
        if (rowID > 0) {
            Uri _uri = ContentUris.withAppendedId(CONTENT_URI, rowID);
            getContext().getContentResolver().notifyChange(_uri, null);
            return _uri;
        }
        throw new SQLiteException("Failed to add a record into " + uri);
    }
    @Override
    public int update(Uri uri, ContentValues values, String selection,
                      String[] selectionArgs) {
        int count = 0;
        switch (uriMatcher.match(uri)) {
            case uriCode:
                count = db.update(TABLE_NAME, values, selection, selectionArgs);
                break;
            default:
                throw new IllegalArgumentException("Unknown URI " + uri);
        }
        getContext().getContentResolver().notifyChange(uri, null);
        return count;
    }
    @Override
    public int delete(Uri uri, String selection, String[] selectionArgs) {
        int count = 0;
        switch (uriMatcher.match(uri)) {
            case uriCode:
                count = db.delete(TABLE_NAME, selection, selectionArgs);
                break;
            default:
                throw new IllegalArgumentException("Unknown URI " + uri);
        }
        getContext().getContentResolver().notifyChange(uri, null);
        return count;
    }
    private SQLiteDatabase db;
    static final String DATABASE_NAME = "EmpDB";
    static final String TABLE_NAME = "Employees";
    static final int DATABASE_VERSION = 1;
    static final String CREATE_DB_TABLE = " CREATE TABLE " + TABLE_NAME
            + " (id INTEGER PRIMARY KEY AUTOINCREMENT, "
            + " name TEXT NOT NULL);";

    private static class DatabaseHelper extends SQLiteOpenHelper {
        DatabaseHelper(Context context) {
            super(context, DATABASE_NAME, null, DATABASE_VERSION);
        }

        @Override
        public void onCreate(SQLiteDatabase db) {
            db.execSQL(CREATE_DB_TABLE);
        }

        @Override
        public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
            db.execSQL("DROP TABLE IF EXISTS " + TABLE_NAME);
            onCreate(db);
        }
    }
}

Bây giờ mở file Activity_main.xml từ đường dẫn \ src \ main \ res \ layout và nhập code như dưới đây.

activity_main.xml

<?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:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Name"
        android:layout_marginLeft="100dp"
        android:layout_marginTop="100dp"/>
    <EditText
        android:id="@+id/txtName"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginLeft="100dp"
        android:ems="10"/>
    <Button
        android:id="@+id/btnAdd"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:onClick="onClickAddDetails"
        android:layout_marginLeft="100dp"
        android:text="Add User"/>

    <Button
        android:id="@+id/btnRetrieve"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:onClick="onClickShowDetails"
        android:layout_marginLeft="100dp"
        android:text="Show Users"/>
    <TextView
        android:id="@+id/res"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginLeft="100dp"
        android:clickable="false"
        android:ems="10"/>
</LinearLayout>

Bây giờ mở file MainActivity.java và nhập code như dưới đây

MainActivity.java

package com.tutlane.contentprovider;

import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.net.Uri;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.MotionEvent;
import android.view.View;
import android.view.inputmethod.InputMethodManager;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }
    @Override
    public boolean onTouchEvent(MotionEvent event) {
        InputMethodManager imm = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE);
        imm.hideSoftInputFromWindow(getCurrentFocus().getWindowToken(), 0);
        return true;
    }
    public void onClickAddDetails(View view) {
        ContentValues values = new ContentValues();
        values.put(UsersProvider.name, ((EditText) findViewById(R.id.txtName)).getText().toString());
        getContentResolver().insert(UsersProvider.CONTENT_URI, values);
        Toast.makeText(getBaseContext(), "New Record Inserted", Toast.LENGTH_LONG).show();
    }

    public void onClickShowDetails(View view) {
        // Retrieve employee records
        TextView resultView= (TextView) findViewById(R.id.res);
        Cursor cursor = getContentResolver().query(Uri.parse("content://com.tutlane.contentprovider.UserProvider/users"), null, null, null, null);
        if(cursor.moveToFirst()) {
            StringBuilder strBuild=new StringBuilder();
            while (!cursor.isAfterLast()) {
                strBuild.append("\n"+cursor.getString(cursor.getColumnIndex("id"))+ "-"+ cursor.getString(cursor.getColumnIndex("name")));
                cursor.moveToNext();
            }
            resultView.setText(strBuild);
        }
        else {
            resultView.setText("No Records Found");
        }
    }
}

Chúng ta cần đưa content provider mới được tạo này vào file manifest (ActivityManifest.xml) bằng cách sử dụng thuộc tính <provider> như được hiển thị bên dưới.

AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.tutlane.contentprovider">
    <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>
        <provider
            android:authorities="com.tutlane.contentprovider.UserProvider"
            android:name=".UsersProvider">
            </provider>
    </application>
</manifest>

5. Kết quả của ví dụ về content provider Android

Khi chạy ví dụ trên trong trình giả lập Android sẽ nhận được kết quả như hiển thị bên dưới

3 gif

Đây là cách sử dụng các content provider trong ứng dụng Android để lưu trữ dữ liệu ở một vị trí để cho phép các ứng dụng khác truy cập.

Cùng chuyên mục:

Tìm hiểu về vòng đời của Activity trong Android

Tìm hiểu về vòng đời của Activity trong Android

AlarmManager trong Android

AlarmManager trong Android

Menu trong Android

Menu trong Android

Fragments trong Android

Fragments trong Android

SearchView trong Android

SearchView trong Android

TabLayout trong Android

TabLayout trong Android

ViewStub trong Android

ViewStub trong Android

Image Slider trong Android

Image Slider trong Android

Trình chuyển đổi hình ảnh (Image Switcher) trong Android

Trình chuyển đổi hình ảnh (Image Switcher) trong Android

ScrollView trong Android

ScrollView trong Android

ProgressBar trong Android

ProgressBar trong Android

Đồng hồ Analog và đồng hồ kỹ thuật số trong Android

Đồng hồ Analog và đồng hồ kỹ thuật số trong Android

Cách dùng TimePicker trong Android

Cách dùng TimePicker trong Android

Cách dùng DatePicker trong Android

Cách dùng DatePicker trong Android

Cách dùng SeekBar trong Android

Cách dùng SeekBar trong Android

Cách dùng WebView trong Android

Cách dùng WebView trong Android

Cách dùng RatingBar trong Android

Cách dùng RatingBar trong Android

Cách dùng ListView trong Android

Cách dùng ListView trong Android

AutoCompleteTextView trong Android

AutoCompleteTextView trong Android

Spinner trong Android

Spinner trong Android

Top