我有 2 个 Xamarin Forms 应用程序。其中一个实现了 ContentProvider,而另一个我使用了 ContentResolver。在 Android 版本 10 (API 29) 上一切正常,但是在更高版本上(我在 12.1 和 14 上测试) - ContentResolver 中的应用程序给出以下错误: Java.Lang.IllegalArgumentException: 'Unknown URL content://com .nts.user_screen_provider/products' 这是提供商代码:
[ContentProvider(new string[] {AUTHORITIES}, Exported = true)]
public class ProductProvider : ContentProvider
{
public const string NAME = "ProductProvider";
public const string PRODUCT_PATH = "products";
public const string AUTHORITIES = "com.nts.user_screen_provider";
public static readonly Android.Net.Uri PRODUCTS_URI = Android.Net.Uri.Parse("content://" + AUTHORITIES + "/" + PRODUCT_PATH);
public const int PRODUCTS_URI_ID = 1;
UriMatcher uriMatcher;
public static class ColumnNames
{
public const string Name = "Name";
public const string Price = "Price";
public const string Weight = "Weight";
public const string Barcode = "Barcode";
public const string Type = "Type";
}
public override Android.Net.Uri Insert(Android.Net.Uri uri, ContentValues values)
{
System.Diagnostics.Debug.WriteLine("Insert provider");
int uriType = uriMatcher.Match(uri);
int id = 0;
switch (uriType)
{
case PRODUCTS_URI_ID:
id = IndexOf(values);
break;
default:
throw new IllegalArgumentException("Unknown URI: " + uri);
}
Context.ContentResolver.NotifyChange(uri, null);
return Android.Net.Uri.Parse(PRODUCTS_URI + "/" + id.ToString());
}
public int IndexOf(ContentValues values)
{
int result = -1;
string name = (string)values.Get(ColumnNames.Name);
string priceS = (string)values.Get(ColumnNames.Price);
string weightS = (string)values.Get(ColumnNames.Weight);
string barcodeS = (string)values.Get(ColumnNames.Barcode);
string typeS = (string)values.Get(ColumnNames.Type);
double price = 0;
double weight = 0;
long barcode = 0;
if (!double.TryParse(priceS, out price) || !double.TryParse(weightS, out weight) || !long.TryParse(barcodeS, out barcode)) return result;
Product.CountType type = 0;
try
{
type = typeS switch
{
"Counted" => Product.CountType.Counted,
"Weighted" => Product.CountType.Weighted,
_ => throw new NotImplementedException()
};
}
catch { return result; }
result = AppManager.UserPage.AddProductInt(name, price, weight, barcode, type);
return result;
}
//implement other ovveride voids
}
内容解析器:
public class ProductSender : IProductSender
{
public const string NAME = "ProductProvider";
public const string PRODUCT_PATH = "products";
public const string AUTHORITIES = "com.nts.user_screen_provider";
public static readonly Android.Net.Uri PRODUCTS_URI = Android.Net.Uri.Parse("content://" + AUTHORITIES + "/" + PRODUCT_PATH);
public void Add(Product product)
{
ContentResolver resolver = Android.App.Application.Context.ContentResolver;
ContentValues values = new ContentValues();
values.Put("Name", product.Name);
values.Put("Price", product.Price.ToString());
values.Put("Weight", product.Weight.ToString());
values.Put("Barcode", product.Barcode.ToString());
values.Put("Type", product.Type.ToString());
Android.Net.Uri uri = resolver.Insert(PRODUCTS_URI, values);
}
}
第一个应用程序 AndroidManifest:
<application android:label="UserScreen.Android" android:theme="@style/MainTheme" android:icon="@mipmap/icon">
<service android:name=".user_screen_service" />
<provider
android:name="com.nts.user_screen.ProductProvider"
android:authorities="com.nts.user_screen_provider"
android:enabled="true"
android:exported="true"
android:grantUriPermissions="true"
android:readPermission="android.permission.BIND_DIRECTORY_SEARCH"
android:writePermission="true"
/>
</application>
第二:
<application android:label="TestProductDataBase.Android" android:theme="@style/MainTheme" android:icon="@mipmap/icon"></application>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_USER_DICTIONARY" />
我尝试在 AndroidManifest 中添加和更改权限 - 没有运气,在其他设备上进行了测试(Android 10 - 有效,Android 14 - 无效)。
我用这个替换了实现 ContentProvider 的类的命名空间
namespace com.nts.user_screen
{
[ContentProvider(new string[] {AUTHORITIES}, Exported = true)]
public class ProductProvider : ContentProvider
{
//...