Thứ Năm, 26 tháng 7, 2018

Android - Nhà cung cấp nội dung

Thành phần nhà cung cấp nội dung cung cấp dữ liệu từ một ứng dụng cho người khác theo yêu cầu trong lập trình android. Các yêu cầu như vậy được xử lý bằng các phương thức của lớp ContentResolver.

Nhà cung cấp nội dung có thể sử dụng các cách khác nhau để lưu trữ dữ liệu của nó và dữ liệu có thể được lưu trữ trong cơ sở dữ liệu, trong tệp hoặc thậm chí qua mạng.

ảnh minh họa

CONTENTPROVIDER

đôi khi nó là cần thiết để chia sẻ dữ liệu trên các ứng dụng. Đây là nơi các nhà cung cấp nội dung trở nên rất hữu ích.

Nhà cung cấp nội dung cho phép bạn tập trung nội dung vào một nơi và có nhiều ứng dụng khác nhau truy cập nội dung khi cần. Nhà cung cấp nội dung hoạt động rất giống cơ sở dữ liệu nơi bạn có thể truy vấn, chỉnh sửa nội dung, cũng như thêm hoặc xóa nội dung bằng phương thức insert (), update (), delete () và query (). Trong hầu hết các trường hợp, dữ liệu này được lưu trữ trong cơ sở dữ liệu SQlite .

Nhà cung cấp nội dung được triển khai dưới dạng lớp con của lớp ContentProvider và phải triển khai bộ API tiêu chuẩn cho phép các ứng dụng khác thực hiện giao dịch.
public class My Application extends  ContentProvider {
}

URI nội dung

Để truy vấn một nhà cung cấp nội dung, bạn chỉ định chuỗi truy vấn dưới dạng một URI có định dạng sau
<prefix>://<authority>/<data_type>/<id>
Dưới đây là chi tiết về các phần khác nhau của URI -
Sr.NoPhần & Mô tả
1tiếp đầu ngữ

Điều này luôn được đặt thành nội dung: //
2thẩm quyền

Điều này chỉ định tên của nhà cung cấp nội dung, ví dụ như danh bạ, trình duyệt , vv Đối với nhà cung cấp nội dung của bên thứ ba, đây có thể là tên đầy đủ, chẳng hạn như com.tutorialspoint.statusprovider
3loại dữ liệu

Điều này cho biết loại dữ liệu mà nhà cung cấp cụ thể này cung cấp. Ví dụ: nếu bạn đang nhận được tất cả địa chỉ liên hệ từ nhà cung cấp nội dung Danh bạ thì đường dẫn dữ liệu sẽ là người và URI trông giống như nội dung này : // contacts / people
4ID

Điều này quy định cụ thể hồ sơ yêu cầu. Ví dụ: nếu bạn đang tìm số liên lạc 5 trong nhà cung cấp nội dung Danh bạ thì URI sẽ trông giống như nội dung này : // contacts / people / 5 .

Tạo nhà cung cấp nội dung

Điều này liên quan đến số bước đơn giản để tạo nhà cung cấp nội dung của riêng bạn.

Trước hết, bạn cần phải tạo một lớp Nhà cung cấp nội dung mở rộng ContentProviderbaseclass.

Thứ hai, bạn cần xác định địa chỉ URI của nhà cung cấp nội dung sẽ được sử dụng để truy cập nội dung.

Tiếp theo, bạn sẽ cần phải tạo cơ sở dữ liệu của riêng bạn để giữ nội dung. Thông thường, Android sử dụng cơ sở dữ liệu và khung công tác SQLite cần ghi đè phương thức onCreate () sẽ sử dụng phương thức SQLite Open Helper để tạo hoặc mở cơ sở dữ liệu của nhà cung cấp. Khi ứng dụng của bạn được khởi động, trình xử lý onCreate () của mỗi Nhà cung cấp nội dung của nó được gọi trên luồng ứng dụng chính.

Tiếp theo, bạn sẽ phải triển khai các truy vấn Nhà cung cấp nội dung để thực hiện các hoạt động cụ thể của cơ sở dữ liệu khác nhau.

Cuối cùng, hãy đăng ký Nhà cung cấp nội dung của bạn trong tệp hoạt động của bạn bằng cách sử dụng thẻ <provider>.

Dưới đây là danh sách các phương pháp bạn cần ghi đè trong lớp Nhà cung cấp nội dung để Nhà cung cấp nội dung của bạn hoạt động



CONTENTPROVIDER

onCreate () Phương thức này được gọi khi nhà cung cấp được khởi động.

query () Phương thức này nhận được một yêu cầu từ một máy khách. Kết quả được trả về dưới dạng đối tượng Cursor.

insert () Phương thức này chèn một bản ghi mới vào nhà cung cấp nội dung.

delete () Phương thức này xóa một bản ghi hiện có từ nhà cung cấp nội dung.

update () Phương thức này cập nhật một bản ghi hiện có từ nhà cung cấp nội dung.

getType () Phương thức này trả về kiểu MIME của dữ liệu tại URI đã cho.

Thí dụ

Ví dụ này sẽ giải thích cho bạn cách tạo trình ContentProvider của riêng bạn . Vì vậy, hãy làm theo các bước sau để tương tự với những gì chúng tôi đã làm theo trong khi tạo ví dụ Hello World

Bậc thangSự miêu tả
1Bạn sẽ sử dụng Android StudioIDE để tạo ứng dụng Android và đặt tênứng dụng là Ứng dụng của tôi trong gói com.example.MyApplication , với Hoạt động trống.
2Sửa đổi tệp hoạt động chính MainActivity.java để thêm hai phương thức mới onClickAddName () và onClickRetrieveStudents () .
3Tạo một tệp java mới có tên StudentsProvider.java trong góicom.example.MyApplication để xác định nhà cung cấp thực tế của bạn và các phương thức liên quan.
4Đăng ký nhà cung cấp nội dung của bạn trong tệp AndroidManifest.xmlcủa bạn bằng cách sử dụng thẻ <provider ... />
5Sửa đổi nội dung mặc định của tệp res / layout / activity_main.xml để bao gồm GUI nhỏ để thêm bản ghi học sinh.
6Không cần phải thay đổi string.xml.Android studio chăm sóc tệp string.xml.
7Chạy ứng dụng để khởi chạy trình giả lập Android và xác minh kết quả của các thay đổi được thực hiện trong ứng dụng.
Sau đây là nội dung của tệp hoạt động chính đã sửa đổi src / com.example.MyApplication / MainActivity.java .

Tệp này có thể bao gồm từng phương pháp vòng đời cơ bản. Chúng tôi đã thêm hai phương thức mới onClickAddName () và onClickRetrieveStudents () để xử lý tương tác người dùng với ứng dụng.
package com.example.MyApplication;

import android.net.Uri;
import android.os.Bundle;
import android.app.Activity;

import android.content.ContentValues;
import android.content.CursorLoader;

import android.database.Cursor;

import android.view.Menu;
import android.view.View;

import android.widget.EditText;
import android.widget.Toast;

public class MainActivity extends Activity {

   @Override
   protected void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
      setContentView(R.layout.activity_main);
   }
   public void onClickAddName(View view) {
      // Add a new student record
      ContentValues values = new ContentValues();
      values.put(StudentsProvider.NAME,
         ((EditText)findViewById(R.id.editText2)).getText().toString());

      values.put(StudentsProvider.GRADE,
         ((EditText)findViewById(R.id.editText3)).getText().toString());

      Uri uri = getContentResolver().insert(
         StudentsProvider.CONTENT_URI, values);

      Toast.makeText(getBaseContext(),
         uri.toString(), Toast.LENGTH_LONG).show();
   }
   public void onClickRetrieveStudents(View view) {
      // Retrieve student records
      String URL = "content://com.example.MyApplication.StudentsProvider";

      Uri students = Uri.parse(URL);
      Cursor c = managedQuery(students, null, null, null, "name");

      if (c.moveToFirst()) {
         do{
            Toast.makeText(this,
               c.getString(c.getColumnIndex(StudentsProvider._ID)) +
                  ", " +  c.getString(c.getColumnIndex( StudentsProvider.NAME)) +
                     ", " + c.getString(c.getColumnIndex( StudentsProvider.GRADE)),
            Toast.LENGTH_SHORT).show();
         } while (c.moveToNext());
      }
   }
}
Tạo tệp mới StudentsProvider.java trong gói com.example.MyApplication và sau là nội dung của src / com.example.MyApplication / StudentsProvider.java
package com.example.MyApplication;

import java.util.HashMap;

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.SQLException;

import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.database.sqlite.SQLiteQueryBuilder;

import android.net.Uri;
import android.text.TextUtils;

public class StudentsProvider extends ContentProvider {
   static final String PROVIDER_NAME = "com.example.MyApplication.StudentsProvider";
   static final String URL = "content://" + PROVIDER_NAME + "/students";
   static final Uri CONTENT_URI = Uri.parse(URL);

   static final String _ID = "_id";
   static final String NAME = "name";
   static final String GRADE = "grade";

   private static HashMap<String, String> STUDENTS_PROJECTION_MAP;

   static final int STUDENTS = 1;
   static final int STUDENT_ID = 2;

   static final UriMatcher uriMatcher;
   static{
      uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
      uriMatcher.addURI(PROVIDER_NAME, "students", STUDENTS);
      uriMatcher.addURI(PROVIDER_NAME, "students/#", STUDENT_ID);
   }

   /**
      * Database specific constant declarations
   */
   
   private SQLiteDatabase db;
   static final String DATABASE_NAME = "College";
   static final String STUDENTS_TABLE_NAME = "students";
   static final int DATABASE_VERSION = 1;
   static final String CREATE_DB_TABLE =
      " CREATE TABLE " + STUDENTS_TABLE_NAME +
         " (_id INTEGER PRIMARY KEY AUTOINCREMENT, " +
         " name TEXT NOT NULL, " +
         " grade TEXT NOT NULL);";

   /**
      * Helper class that actually creates and manages
      * the provider's underlying data repository.
   */
   
   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 " +  STUDENTS_TABLE_NAME);
         onCreate(db);
      }
   }

   @Override
   public boolean onCreate() {
      Context context = getContext();
      DatabaseHelper dbHelper = new DatabaseHelper(context);

      /**
         * Create a write able database which will trigger its
         * creation if it doesn't already exist.
      */
         
      db = dbHelper.getWritableDatabase();
      return (db == null)? false:true;
   }

   @Override
   public Uri insert(Uri uri, ContentValues values) {
      /**
         * Add a new student record
      */
      long rowID = db.insert( STUDENTS_TABLE_NAME, "", values);

      /**
         * If record is added successfully
      */
      if (rowID > 0) {
         Uri _uri = ContentUris.withAppendedId(CONTENT_URI, rowID);
         getContext().getContentResolver().notifyChange(_uri, null);
         return _uri;
      }
        
      throw new SQLException("Failed to add a record into " + uri);
   }

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

      switch (uriMatcher.match(uri)) {
         case STUDENTS:
            qb.setProjectionMap(STUDENTS_PROJECTION_MAP);
         break;

         case STUDENT_ID:
            qb.appendWhere( _ID + "=" + uri.getPathSegments().get(1));
         break;
         
         default:   
      }

      if (sortOrder == null || sortOrder == ""){
         /**
            * By default sort on student names
         */
         sortOrder = NAME;
      }
      
      Cursor c = qb.query(db, projection, selection, 
         selectionArgs,null, null, sortOrder);
      /**
         * register to watch a content URI for changes
      */
      c.setNotificationUri(getContext().getContentResolver(), uri);
      return c;
   }

   @Override
   public int delete(Uri uri, String selection, String[] selectionArgs) {
      int count = 0;
      switch (uriMatcher.match(uri)){
         case STUDENTS:
            count = db.delete(STUDENTS_TABLE_NAME, selection, selectionArgs);
         break;

         case STUDENT_ID:
            String id = uri.getPathSegments().get(1);
            count = db.delete( STUDENTS_TABLE_NAME, _ID +  " = " + id +
               (!TextUtils.isEmpty(selection) ? " 
               AND (" + selection + ')' : ""), selectionArgs);
            break;
         default:
            throw new IllegalArgumentException("Unknown URI " + uri);
      }

      getContext().getContentResolver().notifyChange(uri, null);
      return count;
   }

   @Override
   public int update(Uri uri, ContentValues values, 
      String selection, String[] selectionArgs) {
      int count = 0;
      switch (uriMatcher.match(uri)) {
         case STUDENTS:
            count = db.update(STUDENTS_TABLE_NAME, values, selection, selectionArgs);
         break;

         case STUDENT_ID:
            count = db.update(STUDENTS_TABLE_NAME, values, 
               _ID + " = " + uri.getPathSegments().get(1) +
               (!TextUtils.isEmpty(selection) ? " 
               AND (" +selection + ')' : ""), selectionArgs);
            break;
         default:
            throw new IllegalArgumentException("Unknown URI " + uri );
      }
        
      getContext().getContentResolver().notifyChange(uri, null);
      return count;
   }

   @Override
   public String getType(Uri uri) {
      switch (uriMatcher.match(uri)){
         /**
            * Get all student records
         */
         case STUDENTS:
            return "vnd.android.cursor.dir/vnd.example.students";
         /**
            * Get a particular student
         */
         case STUDENT_ID:
            return "vnd.android.cursor.item/vnd.example.students";
         default:
            throw new IllegalArgumentException("Unsupported URI: " + uri);
      }
   }
}
Sau đây sẽ là nội dung sửa đổi của tệp AndroidManifest.xml . Ở đây chúng tôi đã thêm thẻ <provider ... /> để bao gồm nhà cung cấp nội dung của chúng tôi:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.MyApplication">

   <application
      android:allowBackup="true"
      android:icon="@mipmap/ic_launcher"
      android:label="@string/app_name"
      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:name="StudentsProvider"
         android:authorities="com.example.MyApplication.StudentsProvider"/>
   </application>
</manifest>
Sau đây sẽ là nội dung của tệp res / layout / activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
   xmlns:tools="http://schemas.android.com/tools"
   android:layout_width="match_parent"
   android:layout_height="match_parent"
   android:paddingBottom="@dimen/activity_vertical_margin"
   android:paddingLeft="@dimen/activity_horizontal_margin"
   android:paddingRight="@dimen/activity_horizontal_margin"
   android:paddingTop="@dimen/activity_vertical_margin"
   tools:context="com.example.MyApplication.MainActivity">

   <TextView
      android:id="@+id/textView1"
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:text="Content provider"
      android:layout_alignParentTop="true"
      android:layout_centerHorizontal="true"
      android:textSize="30dp" />

   <TextView
      android:id="@+id/textView2"
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:text="Tutorials point "
      android:textColor="#ff87ff09"
      android:textSize="30dp"
      android:layout_below="@+id/textView1"
      android:layout_centerHorizontal="true" />

   <ImageButton
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:id="@+id/imageButton"
      android:src="@drawable/abc"
      android:layout_below="@+id/textView2"
      android:layout_centerHorizontal="true" />

   <Button
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:id="@+id/button2"
      android:text="Add Name"
      android:layout_below="@+id/editText3"
      android:layout_alignRight="@+id/textView2"
      android:layout_alignEnd="@+id/textView2"
      android:layout_alignLeft="@+id/textView2"
      android:layout_alignStart="@+id/textView2"
      android:onClick="onClickAddName"/>

   <EditText
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:id="@+id/editText"
      android:layout_below="@+id/imageButton"
      android:layout_alignRight="@+id/imageButton"
      android:layout_alignEnd="@+id/imageButton" />

   <EditText
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:id="@+id/editText2"
      android:layout_alignTop="@+id/editText"
      android:layout_alignLeft="@+id/textView1"
      android:layout_alignStart="@+id/textView1"
      android:layout_alignRight="@+id/textView1"
      android:layout_alignEnd="@+id/textView1"
      android:hint="Name"
      android:textColorHint="@android:color/holo_blue_light" />

   <EditText
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:id="@+id/editText3"
      android:layout_below="@+id/editText"
      android:layout_alignLeft="@+id/editText2"
      android:layout_alignStart="@+id/editText2"
      android:layout_alignRight="@+id/editText2"
      android:layout_alignEnd="@+id/editText2"
      android:hint="Grade"
      android:textColorHint="@android:color/holo_blue_bright" />

   <Button
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:text="Retrive student"
      android:id="@+id/button"
      android:layout_below="@+id/button2"
      android:layout_alignRight="@+id/editText3"
      android:layout_alignEnd="@+id/editText3"
      android:layout_alignLeft="@+id/button2"
      android:layout_alignStart="@+id/button2"
      android:onClick="onClickRetrieveStudents"/>
</RelativeLayout>
Đảm bảo bạn có nội dung sau của tệp res / values ​​/ strings.xml :
<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string name="app_name">My Application</string>
</resources>;
Hãy thử chạy ứng dụng My Application đã sửa đổi mà chúng ta vừa tạo ra. Tôi cho rằng bạn đã tạo AVD của mình trong khi thiết lập môi trường.

Để chạy ứng dụng từ Android Studio IDE, hãy mở một trong các tệp hoạt động của dự án của bạn và nhấp vào Chạy biểu tượng từ thanh công cụ.

Android Studio cài đặt ứng dụng trên AVD của bạn và khởi động ứng dụng và nếu mọi thứ đều ổn với thiết lập và ứng dụng của bạn, nó sẽ hiển thị cửa sổ Trình mô phỏng sau đây, hãy kiên nhẫn vì đôi khi có thể mất thời gian dựa trên tốc độ máy tính của bạn
ảnh minh họa
Bây giờ chúng ta hãy nhập tên và lớp học của học sinh và cuối cùng nhấp vào nút Add Name , điều này sẽ thêm hồ sơ học sinh vào cơ sở dữ liệu và sẽ nháy một thông báo ở phía dưới hiển thị ContentProvider URI cùng với số bản ghi được thêm vào trong cơ sở dữ liệu. 

Thao tác này sử dụng phương thức insert () của chúng ta . Hãy lặp lại quy trình này để thêm vài sinh viên vào cơ sở dữ liệu của nhà cung cấp nội dung của chúng tôi.
ảnh minh họa
Khi bạn đã hoàn tất việc thêm các bản ghi vào cơ sở dữ liệu, bây giờ là lúc để yêu cầu ContentProvider cung cấp cho chúng ta những bản ghi đó, vì vậy hãy nhấn nút Retrieve Students để tìm và hiển thị tất cả các bản ghi từng cái một. phương thức query () .

Bạn có thể viết các hoạt động chống lại các hoạt động cập nhật và xóa bằng cách cung cấp các hàm gọi lại trong tệp MainActivity.java và sau đó sửa đổi giao diện người dùng để có các nút để cập nhật và xóa các hoạt động theo cách tương tự như chúng ta đã thực hiện cho các hoạt động thêm và đọc.

Bằng cách này, bạn có thể sử dụng Nhà cung cấp nội dung hiện có như Address Book hoặc bạn có thể sử dụng khái niệm Nhà cung cấp nội dung để phát triển các ứng dụng theo định hướng cơ sở dữ liệu tốt đẹp nơi bạn có thể thực hiện tất cả các hoạt động cơ sở dữ liệu như đọc, ghi, cập nhật và xóa như đã giải thích ở trên.

Không có nhận xét nào:

Đăng nhận xét

Lập trình Android - RenderScript

Trong chương này, chúng ta sẽ tìm hiểu về Android RenderScript. Thông thường các ứng dụng trên Android được thiết kế để tiêu thụ tài nguyên ...