Friday, March 5, 2021

Tìm hiểu Content Providers Andoid

 Trong Android Content Provides sẽ hoạt động như một kho lưu trữ trung tâm để lưu trữ dữ liệu của ứ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 được yêu cầu.

Trong android, chúng tôi có thể định cấu hình Nhà cung cấp nội dung để cho phép các ứng dụng khác truy cập và sửa đổi dữ liệu ứng dụng một cách an toàn dựa trên yêu cầu của chúng tôi.

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ư một cơ sở dữ liệu quan hệ để 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 trên dữ liệu được lưu trữ trong trình cung cấp nội dung bằng cách sử dụng các phương thức insert () , update () , delete () và query () .

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

Trong android, content provider trong Android đang có các 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 tệp hoặc thậm chí qua mạng dựa trên yêu cầu của chúng tôi. Bằng cách sử dụng các nhà cung cấp nội dung, chúng tôi 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.

Chúng tôi có các loại quyền truy cập khác nhau có sẵn trong nhà cung cấp nội dung để chia sẻ dữ liệu. Chúng tôi có thể đặt giới hạn quyền truy cập trong nhà cung cấp nội dung để hạn chế quyền truy cập dữ liệu chỉ giới hạn trong ứng dụng của chúng tôi và chúng tôi có thể định cấu hình các quyền khác nhau để đọc hoặc ghi dữ liệu.

Truy cập dữ liệu từ Content provider

Để truy cập dữ liệu từ nhà cung cấp nội dung, chúng tôi cần sử dụng ContentResolver đối tượng trong ứng dụng của mình để giao tiếp với nhà cung cấp với tư cách là khách hàng. Đối  ContentResolver tượng sẽ giao tiếp với đối tượng nhà cung cấp ( ContentProvider) được thực hiện bởi một thể hiện của lớp.

Nói chung, trong android để gửi một yêu cầu từ UI tới Content Resolver chúng ta có một đối tượng khác có tên là CursorLoader được sử dụng để chạy truy vấn không đồng bộ trong nền. Trong ứng dụng android, các thành phần giao diện người dùng như Activity hoặc Fragment sẽ gọi một CursorLoader để truy vấn và lấy dữ liệu cần thiết từ Content Provider việc sử dụng Content Resolver.

Đối Content Provider tượng sẽ nhận 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à biểu diễn bằng hình ảnh củ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ừ Content Provider đối tượng.


Content URIs.

Trong android, Content URI là một URI được sử dụng để truy vấn nhà cung cấp nội dung để lấy dữ liệu cần thiết. URI nội dung sẽ chứa tên của toàn bộ nhà cung cấp ( cơ quan ) và tên trỏ đến một bảng ( đường dẫn ).

Nói chung định dạng của URI trong các ứng dụng android sẽ như hình dưới đây.
content://authority/path

Sau đây là thông tin chi tiết về các phần khác nhau của URI trong ứng dụng Android. 

  • content:// Luôn có trong URI và nó được sử dụng để biểu thị URI đã cho là URI nội dung.
  • authority : Nó đại diện cho tên của nhà cung cấp nội dung, ví dụ: điện thoại, danh bạ, v.v. và chúng tôi cần sử dụng tên đủ điều kiện cho các nhà cung cấp nội dung bên thứ ba như com.anhttvn.contactprovider
  • path: Nó đại diện cho đường dẫn của bảng.

Đối ContentResolver tượng sử dụng quyền của URI để tìm nhà cung cấp thích hợp và gửi các đối tượng truy vấn đến đúng nhà cung cấp. Sau đó ContentProvider sử dụng URI đường dẫn của nội dung để chọn bảng phù hợp để truy cập.

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

content: // contact_info / users

Cách tạo content providers

Để tạo một nhà cung cấp nội dung trong các ứng dụng Android, chúng ta nên làm theo các bước sau.

  • Chúng ta cần tạo một lớp cung cấp nội dung để mở rộng lớp cơ sở ContentProvider.
  • Chúng tôi cần xác định URI nhà cung cấp nội dung của mình để truy cập nội dung.
  • Các ContentProviderlớp định nghĩa một sáu phương pháp trừu tượng (insert (), cập nhật (), delete (), truy vấn (), getType ()) mà chúng ta cần phải thực hiện tất cả các phương pháp này như một phần của lớp con của chúng tôi.
  • Chúng tôi cần đăng ký nhà cung cấp nội dung của mình trong AndroidManifest.xml bằng thẻ <provider> .

Sau đây là danh sách các phương thức cần triển khai như một phần của ContentProviderlớp.

  • query () - Nó nhận được một yêu cầu từ máy khách. Bằng cách sử dụng các đối số, nó sẽ lấy dữ liệu từ bảng được yêu cầu và trả về dữ liệu dưới dạng đối tượng Con trỏ . 
  • insert () - Phương thức này sẽ chèn một hàng mới vào trình cung cấp nội dung của chúng tôi và nó sẽ trả về URI nội dung cho hàng mới được chèn. 
  • update () - Phương thức này sẽ cập nhật các hàng hiện có trong trình cung cấp nội dung của chúng tôi 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 trình cung cấp nội dung của chúng tôi và nó trả về số hàng đã bị xóa. 
  • getType () - Phương thức này sẽ trả về kiểu dữ liệu MIME cho URI nội dung đã cho. 
  • onCreate () - Phương thức này sẽ khởi tạo trình cung cấp của chúng tôi. Hệ thống Android sẽ gọi phương thức này ngay lập tức sau khi nó tạo nhà cung cấp của chúng tôi. 

Tạo Content provider example Android

Sau đây là ví dụ về việc sử dụng Content provider trong các ứng dụng Android. Ở đây chúng tôi sẽ tạo nhà cung cấp nội dung của riêng mình để chèn và truy cập dữ liệu trong ứng dụng android.

Tạo một ứng dụng android mới bằng cách sử dụng studio android và đặt tên là ContentProvider. Trong trường hợp nếu bạn chưa biết cách tạo ứng dụng trong android studio, hãy xem bài viết này Ứng dụng Android Hello World .

Bây giờ chúng ta cần tạo tệp trình cung cấp nội dung của riêng mình UserProvider.java trong đường dẫn \ src \ main \ java \ com.tutlane.contentprovider để xác định nhà cung cấp thực tế của chúng ta và các phương thức liên quan cho nhấp chuột phải vào thư mục ứng dụng của bạn  à  Đi tới Mới  à  chọn Lớp Java và đặt tên là UserProvider.java .

Sau khi chúng tôi tạo một tệp mới UserProvider.java , hãy mở nó và viết mã như hình dưới đây.
UserProvider.java
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);
        }
    }
}

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> 

MainActivity.java

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");

        }

    }

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.anhttvn.contentprovider.UserProvider"

            android:name=".UsersProvider">

            </provider>

    </application>

</manifest> 

Kết quả:

No comments:

Post a Comment