Android - Inhaltsanbieter

Eine Inhaltsanbieter-Komponente liefert auf Anfrage Daten von einer Anwendung an andere. Solche Anforderungen werden von den Methoden der ContentResolver-Klasse verarbeitet. Ein Inhaltsanbieter kann seine Daten auf verschiedene Arten speichern, und die Daten können in einer Datenbank, in Dateien oder sogar über ein Netzwerk gespeichert werden.

Inhalt Anbieter

sometimes it is required to share data across applications. This is where content providers become very useful.

Mit Inhaltsanbietern können Sie Inhalte an einem Ort zentralisieren und bei Bedarf von vielen verschiedenen Anwendungen darauf zugreifen lassen. Ein Inhaltsanbieter verhält sich sehr ähnlich wie eine Datenbank, in der Sie ihn abfragen, seinen Inhalt bearbeiten sowie Inhalte mithilfe der Methoden insert (), update (), delete () und query () hinzufügen oder löschen können. In den meisten Fällen werden diese Daten in einem gespeichertSQlite Datenbank.

Ein Inhaltsanbieter ist als Unterklasse von implementiert ContentProvider Klasse und muss einen Standardsatz von APIs implementieren, mit denen andere Anwendungen Transaktionen ausführen können.

public class My Application extends  ContentProvider {
}

Inhalts-URIs

Um einen Inhaltsanbieter abzufragen, geben Sie die Abfragezeichenfolge in Form eines URI an, der das folgende Format hat:

<prefix>://<authority>/<data_type>/<id>

Hier sind die Details verschiedener Teile der URI -

Sr.Nr. Teil & Beschreibung
1

prefix

Dies wird immer auf Inhalt gesetzt: //

2

authority

Dies gibt den Namen des Inhaltsanbieters an, z. B. Kontakte , Browser usw. Bei Inhaltsanbietern von Drittanbietern kann dies der vollständig qualifizierte Name sein, z. B. com.tutorialspoint.statusprovider

3

data_type

Dies gibt die Art der Daten an, die dieser bestimmte Anbieter bereitstellt. Wenn Sie beispielsweise alle Kontakte vom Kontaktinhaltsanbieter erhalten, lautet der Datenpfad Personen, und der URI sieht folgendermaßen aus: // Kontakte / Personen

4

id

Dies gibt den spezifischen angeforderten Datensatz an. Wenn Sie beispielsweise im Inhaltsanbieter für Kontakte nach Kontaktnummer 5 suchen, sieht die URI folgendermaßen aus : // Kontakte / Personen / 5 .

Erstellen Sie einen Inhaltsanbieter

Dies umfasst eine Reihe einfacher Schritte zum Erstellen eines eigenen Inhaltsanbieters.

  • Zunächst müssen Sie eine Content Provider-Klasse erstellen, die die ContentProviderbaseclass erweitert.

  • Zweitens müssen Sie die URI-Adresse Ihres Inhaltsanbieters definieren, über die auf den Inhalt zugegriffen wird.

  • Als nächstes müssen Sie Ihre eigene Datenbank erstellen, um den Inhalt zu behalten. Normalerweise verwendet Android die SQLite-Datenbank und das Framework muss die onCreate () -Methode überschreiben , die die SQLite Open Helper-Methode zum Erstellen oder Öffnen der Datenbank des Anbieters verwendet. Wenn Ihre Anwendung gestartet wird, wird der onCreate () - Handler jedes seiner Inhaltsanbieter im Hauptanwendungsthread aufgerufen.

  • Als Nächstes müssen Sie Content Provider-Abfragen implementieren, um verschiedene datenbankspezifische Vorgänge auszuführen.

  • Registrieren Sie abschließend Ihren Inhaltsanbieter mit dem Tag <provider> in Ihrer Aktivitätsdatei.

Hier ist die Liste der Methoden, die Sie in der Content Provider-Klasse überschreiben müssen, damit Ihr Content Provider funktioniert.

Inhalt Anbieter

  • onCreate() Diese Methode wird beim Starten des Providers aufgerufen.

  • query()Diese Methode empfängt eine Anfrage von einem Client. Das Ergebnis wird als Cursor-Objekt zurückgegeben.

  • insert()Diese Methode fügt einen neuen Datensatz in den Inhaltsanbieter ein.

  • delete() Diese Methode löscht einen vorhandenen Datensatz vom Inhaltsanbieter.

  • update() Diese Methode aktualisiert einen vorhandenen Datensatz vom Inhaltsanbieter.

  • getType() Diese Methode gibt den MIME-Typ der Daten am angegebenen URI zurück.

Beispiel

In diesem Beispiel wird erläutert, wie Sie Ihren eigenen ContentProvider erstellen . Befolgen Sie also die folgenden Schritte, ähnlich wie beim Erstellen von Hello World Example -

Schritt Beschreibung
1 Sie werden Android StudioIDE verwenden, um eine Android-Anwendung zu erstellen und sie unter einem Paket com.example.MyApplication mit leerer Aktivität als Meine Anwendung zu benennen .
2 Ändern Sie die Hauptaktivitätsdatei MainActivity.java , um zwei neue Methoden onClickAddName () und onClickRetrieveStudents () hinzuzufügen .
3 Erstellen Sie eine neue Java-Datei mit dem Namen StudentsProvider.java unter dem Paket com.example.MyApplication , um Ihren tatsächlichen Anbieter und die zugehörigen Methoden zu definieren.
4 Registrieren Sie Ihren Inhaltsanbieter in Ihrer AndroidManifest.xml- Datei mit dem Tag <provider ... />
5 Ändern Sie den Standardinhalt der Datei res / layout / activity_main.xml so , dass eine kleine GUI zum Hinzufügen von Schülerdatensätzen enthalten ist.
6 String.xml muss nicht geändert werden. Android Studio kümmert sich um die Datei string.xml.
7 Führen Sie die Anwendung aus, um den Android-Emulator zu starten, und überprüfen Sie das Ergebnis der in der Anwendung vorgenommenen Änderungen.

Es folgt der Inhalt der geänderten Hauptaktivitätsdatei src/com.example.MyApplication/MainActivity.java. Diese Datei kann jede der grundlegenden Lebenszyklusmethoden enthalten. Wir haben zwei neue Methoden onClickAddName () und onClickRetrieveStudents () hinzugefügt , um die Benutzerinteraktion mit der Anwendung zu handhaben.

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());
      }
   }
}

Erstellen Sie eine neue Datei StudentsProvider.java unter dem Paket com.example.MyApplication und folgen Sie dem Inhalt vonsrc/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);
      }
   }
}

Im Folgenden wird der geänderte Inhalt der Datei AndroidManifest.xml angezeigt . Hier haben wir das Tag <provider ... /> hinzugefügt, um unseren Inhaltsanbieter einzuschließen:

<?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>

Es folgt der Inhalt von res/layout/activity_main.xml Datei−

<?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>

Stellen Sie sicher, dass Sie folgenden Inhalt von haben res/values/strings.xml Datei:

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string name="app_name">My Application</string>
</resources>;

Lassen Sie uns versuchen, unsere modifizierten auszuführen My ApplicationAnwendung, die wir gerade erstellt haben. Ich nehme an, Sie hatten Ihre erstelltAVDwährend der Einrichtung der Umgebung. Um die App über Android Studio IDE auszuführen, öffnen Sie eine der Aktivitätsdateien Ihres Projekts und klicken Sie in der Symbolleiste auf das

Symbol Ausführen . Android Studio installiert die App auf Ihrer AVD und startet sie. Wenn mit Ihrer Einrichtung und Anwendung alles in Ordnung ist, wird sie im folgenden Emulatorfenster angezeigt. Seien Sie geduldig, da dies je nach Computergeschwindigkeit einige Zeit dauern kann.

Lassen Sie uns jetzt Schüler eingeben Name und Grade und schließlich auf klicken Add NameMit dieser Schaltfläche wird ein Schülerdatensatz in die Datenbank eingefügt und unten eine Meldung angezeigt, die den ContentProvider-URI sowie die in der Datenbank hinzugefügte Datensatznummer zeigt. Diese Operation nutzt unsereinsert()Methode. Wiederholen wir diesen Vorgang, um der Datenbank unseres Inhaltsanbieters einige weitere Schüler hinzuzufügen.

Sobald Sie mit dem Hinzufügen von Datensätzen zur Datenbank fertig sind, können Sie ContentProvider bitten, uns diese Datensätze zurückzugeben. Klicken Sie also auf Retrieve Students Schaltfläche, mit der alle Datensätze nacheinander abgerufen und angezeigt werden. Dies entspricht unserer Implementierung unserer query() Methode.

Sie können Aktivitäten gegen Aktualisierungs- und Löschvorgänge schreiben, indem Sie Rückruffunktionen in bereitstellen MainActivity.java Datei und ändern Sie dann die Benutzeroberfläche so, dass Schaltflächen zum Aktualisieren und Löschen von Vorgängen vorhanden sind, wie wir es für das Hinzufügen und Lesen von Vorgängen getan haben.

Auf diese Weise können Sie vorhandene Inhaltsanbieter wie das Adressbuch verwenden oder das Inhaltsanbieter-Konzept bei der Entwicklung netter datenbankorientierter Anwendungen verwenden, bei denen Sie alle Arten von Datenbankoperationen wie Lesen, Schreiben, Aktualisieren und Löschen ausführen können, wie oben im Beispiel erläutert.