CREATING A NEW CONTENT PROVIDER

Creating a new Content Provider

import android.content.*;
import android.database.Cursor;
import android.net.Uri;
import android.database.SQLException;
public class MyProvider extends ContentProvider {
@Override
public boolean onCreate() {
// TODO Construct the underlying database.
return true;
}
}

 

 The general form for defining a Content Provider’s URI is:
content://com.<CompanyName>.provider.<ApplicationName>/<DataPath>
For example:
content://com.paad.provider.myapp/elements
Content URIs can represent either of two forms. The previous URI represents a request for all values of
that type (in this case all elements).
A trailing /<rownumber>, as shown in the following code, represents a request for a single record
(in this case the fifth element).
content://com.paad.provider.myapp/elements/5
It’s good practice to support access to your provider for both of these forms.

 

The simplest way to do this is to use a UriMatcher. Create and configure a Uri Matcher to parse
URIs and determine their forms. This is particularly useful when you’re processing Content Resolver
requests

public class MyProvider extends ContentProvider {
private static final String myURI = "content://com.paad.provider.myapp/items";
public static final Uri CONTENT_URI = Uri.parse(myURI);
@Override
public boolean onCreate() {
// TODO: Construct the underlying database.
return true;
}
// Create the constants used to differentiate between the different URI
// requests.
private static final int ALLROWS = 1;
private static final int SINGLE_ROW = 2;
private static final UriMatcher uriMatcher;
// Populate the UriMatcher object, where a URI ending in ‘items’ will
// correspond to a request for all items, and ‘items/[rowID]’
// represents a single row.
static {
uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
uriMatcher.addURI("com.paad.provider.myApp", "items", ALLROWS);
uriMatcher.addURI("com.paad.provider.myApp", "items/#", SINGLE_ROW);
}
}

 

Exposing Access to the Data Source

Expose queries and transactions on your Content Provider by implementing the delete, insert,
update,and query methods.

 

Implementing queries and transactions within a Content Provider

@Override
public Cursor query(Uri uri,
String[] projection,
String selection,
String[] selectionArgs,
String sort) {
// If this is a row query, limit the result set to the passed in row.
switch (uriMatcher.match(uri)) {
case SINGLE_ROW :
// TODO: Modify selection based on row id, where:
// rowNumber = uri.getPathSegments().get(1));
}
return null;
}
@Override
public Uri insert(Uri _uri, ContentValues _initialValues) {
long rowID = [ ... Add a new item ... ]
// Return a URI to the newly added item.
if (rowID > 0) {
return ContentUris.withAppendedId(CONTENT_URI, rowID);
}
throw new SQLException("Failed to add new item into " + _uri);
}

 

@Override
public int delete(Uri uri, String where, String[] whereArgs) {
switch (uriMatcher.match(uri)) {
case ALLROWS:
case SINGLE_ROW:
default: throw new IllegalArgumentException("Unsupported URI:" + uri);
}
}
@Override
public int update(Uri uri, ContentValues values, String where, String[]
whereArgs) {
switch (uriMatcher.match(uri)) {
case ALLROWS:
case SINGLE_ROW:
default: throw new IllegalArgumentException("Unsupported URI:" + uri);
}
}

 

➤ Single item vnd.<companyname>.cursor.item/<contenttype>
➤ All items vnd.<companyName>.cursor.dir/<contenttype>

 

@Override
public String getType(Uri _uri) {
switch (uriMatcher.match(_uri)) {
case ALLROWS: return "vnd.paad.cursor.dir/myprovidercontent";
case SINGLE_ROW: return "vnd.paad.cursor.item/myprovidercontent";
default: throw new IllegalArgumentException("Unsupported URI: " + _uri);
}
}

 

Registering Your Provider

<provider android:name="MyProvider"
android:authorities="com.paad.provider.myapp"/>

 

USING CONTENT PROVIDERS

ContentResolver cr = getContentResolver();

 

Querying for Content

ContentResolver cr = getContentResolver();
// Return all rows
Cursor allRows = cr.query(MyProvider.CONTENT_URI, null, null, null, null);
// Return all columns for rows where column 3 equals a set value
// and the rows are ordered by column 5.
String where = KEY_COL3 + "=" + requiredValue;
String order = KEY_COL5;
Cursor someRows = cr.query(MyProvider.CONTENT_URI,
null, where, null, order);

 

Adding, Updating, and Deleting Content

To perform transactions on Content Providers, use the delete, update,and insert methods on the
ContentResolver object.

 

// Get the Content Resolver
ContentResolver cr = getContentResolver();
// Create a new row of values to insert.
ContentValues newValues = new ContentValues();
// Assign values for each row.
newValues.put(COLUMN_NAME, newValue);
[ ... Repeat for each column ... ]
Uri myRowUri = cr.insert(MyProvider.CONTENT_URI, newValues);
// Create a new row of values to insert.
ContentValues[] valueArray = new ContentValues[5];
// TODO: Create an array of new rows
int count = cr.bulkInsert(MyProvider.CONTENT_URI, valueArray);

 

ContentResolver cr = getContentResolver();
// Remove a specific row.
cr.delete(myRowUri, null, null);
// Remove the first five rows.
String where = "_id < 5";
cr.delete(MyProvider.CONTENT_URI, where, null);

 

// Create a new row of values to insert.
ContentValues newValues = new ContentValues();
// Create a replacement map, specifying which columns you want to
// update, and what values to assign to each of them.
newValues.put(COLUMN_NAME, newValue);
// Apply to the first 5 rows.
String where = "_id < 5";
getContentResolver().update(MyProvider.CONTENT_URI, newValues, where, null);

 

 

 NATIVE ANDROID CONTENT PROVIDERS

Android exposes several native databases using Content Providers.
You can access these Content Providers directly using the techniques described earlier in this chapter.
Alternatively, the android.provider package includes classes that can simplify access to many of the
most useful providers, including:
➤ Browser Use the browser Content Provider to read or modify bookmarks, browser history,
or web searches.
➤ CallLog View or update the call history, including both incoming and outgoing calls,
together with missed calls and call details like caller ID and call durations.
➤ ContactsContract Use the Contacts Contract provider to retrieve, modify, or store your
contacts’ details. This Content Provider replaces the Contact Content Provider.
➤ MediaStore The Media Store provides centralized, managed access to the multimedia on
your device, including audio, video, and images. You can store your own multimedia within
the media store and make it globally available, as shown in Chapter 11.
➤ Settings You can access the device’s preferences using the Settings provider.
You can view most system settings and modify some of them. More usefully, the
android.provider.Settings class includes a collection of Intent actions that can be used to
open the appropriate settings screen to let users modify their own settings.
➤ UserDictionary Access (or add to) the user defined words added to the dictionary for use in
IME predictive text input.

 

Using the Media Store Provider

// Get a cursor over every piece of audio on the external volume.
Cursor cursor =
getContentResolver().query(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI,
null, null, null, null);
// Let the activity manage the cursor lifecycle.
startManagingCursor(cursor);
// Use the convenience properties to get the index of the columns
int albumIdx = cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.ALBUM);
int titleIdx = cursor. getColumnIndexOrThrow(MediaStore.Audio.Media.TITLE);
String[] result = new String[cursor.getCount()];
if (cursor.moveToFirst())
do {
// Extract the song title.
String title = cursor.getString(titleIdx);
// Extract the album name.
String album = cursor.getString(albumIdx);
result[cursor.getPosition()] = title + " (" + album + ")";
} while(cursor.moveToNext());

 

Using the Contacts Provider

// Get a cursor over every aggregated contact.
Cursor cursor =
getContentResolver().query(ContactsContract.Contacts.CONTENT_URI,
null, null, null, null);
// Let the activity manage the cursor lifecycle.
startManagingCursor(cursor);
// Use the convenience properties to get the index of the columns
int nameIdx =
cursor.getColumnIndexOrThrow(ContactsContract.Contacts.DISPLAY_NAME);
int idIdx = cursor. getColumnIndexOrThrow(ContactsContract.Contacts._ID);
String[] result = new String[cursor.getCount()];
if (cursor.moveToFirst())
do {
// Extract the name.
String name = cursor.getString(nameIdx);
// Extract the phone number.
String id = cursor.getString(idIdx);
result[cursor.getPosition()] = name + " (" + id + ")";
} while(cursor.moveToNext());
stopManagingCursor(cursor);

 

The ContactsContract.Data Content Provider is used to store all the contact details — such as
addresses, phone numbers, and e-mail addresses — making it the best approach when searching for
one of these details.

 

To simplify this lookup, Android provides the ContactsContract.Contacts.CONTENT_FILTER_URI
query URI. Append the full or partial name to lookup as an additional path segment to the URI. To
extract the associated contact details, find the _ID value from the returned Cursor and use it to create a
query on the Data table.

 

Finding contact details after finding a contact

// Find a contact using a partial name match
Uri lookupUri =
Uri.withAppendedPath(ContactsContract.Contacts.CONTENT_FILTER_URI, "kristy");
Cursor idCursor = getContentResolver().query(lookupUri, null, null, null,
null);
String id = null;
if (idCursor.moveToFirst()) {
int idIdx = idCursor.getColumnIndexOrThrow(ContactsContract.Contacts._ID);
id = idCursor.getString(idIdx);
}
idCursor.close();
if (id != null) {
// Return all the contact details of type PHONE for the contact we found
String where = ContactsContract.Data.CONTACT_ID + " = " + id + " AND " +
ContactsContract.Data.MIMETYPE + " = ‘" +
ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE +
"’";

Cursor dataCursor =
getContentResolver().query(ContactsContract.Data.CONTENT_URI,
null, where, null, null);
// Use the convenience properties to get the index of the columns
int nameIdx =
dataCursor.getColumnIndexOrThrow(ContactsContract.Data.DISPLAY_NAME);
int phoneIdx =
dataCursor.getColumnIndexOrThrow(ContactsContract.CommonDataKinds.Phone.NUMBER)
;
String[] result = new String[dataCursor.getCount()];
if (dataCursor.moveToFirst())
do {
// Extract the name.
String name = dataCursor.getString(nameIdx);
// Extract the phone number.
String number = dataCursor.getString(phoneIdx);
result[dataCursor.getPosition()] = name + " (" + number + ")";
} while(dataCursor.moveToNext());
dataCursor.close();

 

Performing a caller-ID lookup

String incomingNumber = "5551234";
Uri lookupUri =
Uri.withAppendedPath(ContactsContract.PhoneLookup.CONTENT_FILTER_URI,
incomingNumber);
Cursor idCursor = getContentResolver().query(lookupUri, null, null, null,
null);
if (idCursor.moveToFirst()) {
int nameIdx =
idCursor.getColumnIndexOrThrow(ContactsContract.Contacts.DISPLAY_NAME);
String caller = idCursor.getString(nameIdx);
Toast.makeText(getApplicationContext(), caller, Toast.LENGTH_LONG).show();
}
idCursor.close();

 

 

要在 Android Studio 中调用相机并保存到相册,可以按照以下步骤进行操作: 1. 添加相机权限 在 AndroidManifest.xml 文件中添加相机权限: ```xml <uses-permission android:name="android.permission.CAMERA" /> ``` 2. 添加文件写入权限 在 AndroidManifest.xml 文件中添加文件写入权限: ```xml <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> ``` 3. 创建一个 FileProvider 在 AndroidManifest.xml 文件中添加一个 FileProvider: ```xml <provider android:name="androidx.core.content.FileProvider" android:authorities="${applicationId}.fileprovider" android:grantUriPermissions="true" android:exported="false"> <meta-data android:name="android.support.FILE_PROVIDER_PATHS" android:resource="@xml/file_paths" /> </provider> ``` 4. 创建 file_paths.xml 文件 在 res/xml 目录下创建一个 file_paths.xml 文件,并添加以下内容: ```xml <?xml version="1.0" encoding="utf-8"?> <paths xmlns:android="http://schemas.android.com/apk/res/android"> <external-path name="my_images" path="Pictures" /> </paths> ``` 5. 创建一个 Intent 并启动相机 在你想要启动相机的地方,创建一个 Intent 并启动相机: ```java private static final int REQUEST_IMAGE_CAPTURE = 1; private String currentPhotoPath; private void dispatchTakePictureIntent() { Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); if (takePictureIntent.resolveActivity(getPackageManager()) != null) { File photoFile = null; try { photoFile = createImageFile(); } catch (IOException ex) { // Error occurred while creating the File ex.printStackTrace(); } if (photoFile != null) { Uri photoURI = FileProvider.getUriForFile(this, BuildConfig.APPLICATION_ID + ".fileprovider", photoFile); takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, photoURI); startActivityForResult(takePictureIntent, REQUEST_IMAGE_CAPTURE); } } } private File createImageFile() throws IOException { // Create an image file name String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date()); String imageFileName = "JPEG_" + timeStamp + "_"; File storageDir = getExternalFilesDir(Environment.DIRECTORY_PICTURES); File image = File.createTempFile( imageFileName, /* prefix */ ".jpg", /* suffix */ storageDir /* directory */ ); // Save a file: path for use with ACTION_VIEW intents currentPhotoPath = image.getAbsolutePath(); return image; } ``` 这个代码会启动相机,并将拍摄的照片保存到一个指定的文件中。 6. 处理结果 在 onActivityResult 方法中处理相机返回的结果: ```java @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { if (requestCode == REQUEST_IMAGE_CAPTURE && resultCode == RESULT_OK) { // GalleryAddPic(currentPhotoPath); Intent mediaScanIntent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE); File f = new File(currentPhotoPath); Uri contentUri = Uri.fromFile(f); mediaScanIntent.setData(contentUri); this.sendBroadcast(mediaScanIntent); } } ``` 这个代码会将拍摄的照片添加到相册中。 注意:为了使照片可以被其他应用访问,你需要将照片添加到 MediaStore 中。可以使用以下代码将照片添加到 MediaStore 中: ```java private void GalleryAddPic(String currentPhotoPath) { Intent mediaScanIntent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE); File f = new File(currentPhotoPath); Uri contentUri = Uri.fromFile(f); mediaScanIntent.setData(contentUri); this.sendBroadcast(mediaScanIntent); } ```
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值