我正在尝试测试查询内容解析器的类.
我想用MockContentResolver和模拟query方法.
问题是这种方法是最终的.我该怎么办?使用模拟框架?模拟其他课程?提前致谢.
public class CustomClass {
private ContentResolver mContentResolver;
public CustomClass(ContentResolver contentResolver) {
mContentResolver = contentResolver;
}
public String getConfig(String key) throws NoSuchFieldException {
String value = null;
Cursor cursor = getContentResolver().query(...);
if (cursor.moveToFirst()) {
//...
}
//..
}
}
Run Code Online (Sandbox Code Playgroud) 我正在尝试批量删除表中的一些项目.
String ids = { "1", "2", "3" };
mContentResolver.delete(uri, MyTables._ID + "=?", ids);
Run Code Online (Sandbox Code Playgroud)
但是我一直得到以下错误
java.lang.IllegalArgumentException:绑定参数太多.提供了3个参数但声明需要1个参数.
我用这个意图让用户选择一张照片:
Intent intent = new Intent(Intent.ACTION_PICK,
MediaStore.Images.Media.INTERNAL_CONTENT_URI);
startActivityForResult(intent, INTENT_SELECT_PHOTO);
Run Code Online (Sandbox Code Playgroud)
并在onActivityResult:
Uri uri = data.getData();
InputStream inputStream = getContentResolver().openInputStream(uri);
Run Code Online (Sandbox Code Playgroud)
但它会引发FileNotFoundException一些Android设备.
价值uri:
content://media/external/images/media/26467
Run Code Online (Sandbox Code Playgroud)
引发的异常:
java.io.FileNotFoundException: No such file or directory
Run Code Online (Sandbox Code Playgroud)
并且非常奇怪的是它不会在其他一些Android设备上抛出此异常.什么会导致此错误以及如何解决?
我save()在自定义ContentProvider类中有一个自定义方法MyContentProvider,我想通过ContentResolver调用它.目标是将POJO作为Bundle传递给MyContentProvider.
我没有得到任何错误.该方法无法访问.
使用自定义方法的(缩短的)自定义ContentProvider如下所示:
public class MyContentProvider extends ContentProvider {
public void save() {
Log.d("Test method", "called");
}
}
Run Code Online (Sandbox Code Playgroud)
我称之为:
ContentResolver contentResolver = context.getContentResolver();
Bundle bundle = new Bundle();
bundle.putSerializable("pojo", getPojo());
contentResolver.call(Contracts.CONTENT_URI, "save", null, bundle);
Run Code Online (Sandbox Code Playgroud)
为什么这个save方法永远不会被调用,如果我到达这一点,我如何在save()方法中访问被调用的Uri和Bundle ?我无法在SO或网络上找到任何参考资料.
谢谢您的回答!
问题
我有两个我要测试的Android类:
CommentContentProvider,它扩展ContentProvider并由SQLiteDatabase支持.CommentActivity,通过一个间接扩展Activity和访问.CommentContentProviderContentResolver我目前有两个测试类:
CommentContentProviderTest,扩展ProviderTestCase2<CommentContentProvider>和使用MockContentResolver.这很好用.CommentActivityTest,延伸ActivityInstrumentationTestCase2<CommentActivity>.除了CommentActivity访问的部分外,这种方法很好CommentContentProvider.问题是,当CommentActivity访问时CommentContentProvider,它通过标准这样做ContentResolver:
ContentResolver resolver = getContentResolver();
Cursor cursor = resolver().query(...);
Run Code Online (Sandbox Code Playgroud)
因此,当CommentActivityTest运行时,它会启动CommentActivity,访问(读取和写入)生产数据库,如上面两行所示.
我的问题是如何在生产中CommentActivity使用标准ContentResolver,但MockContentResolver在测试期间.
相关问题
Activity.可能的解决方案
如果我可以通过启动的Intent注入ContentResolver(可能是a MockContentResolver或RenamingDelegatingContext),那将是很好的,但我不能这样做,因为s不是.CommentActivityContextParcelable …
android dependency-injection abstract-factory android-contentresolver android-testing
我想问为什么我们得到这个注释:
方法调用getContext.getContentResolver()可能会产生NullPointerException
为什么它在那里而不是在程序碎片/活动的其他部分?这种方法已在Google制作的教程中使用 - 这里是ContentProvider代码的链接https://github.com/udacity/Sunshine-Version-2/blob/sunshine_master/app/src/main/java/com/example/android /sunshine/app/data/WeatherProvider.java即使您只使用空白活动创建一个应用程序,并将该方法放在新创建的ContentProvider中,它就在那里.
我们应该使用getContext().getContentResolver().notifyChange(uri, null);外部ContentProvider获取uri传递,然后更新/插入/删除完成notifyChange?或者我们可以以某种方式解决它?
我有Uri for Image文件.
我使用此代码从Uri获取文件路径:
public String getRealPathFromURI(Uri contentUri) {
Cursor cursor = null;
try {
String[] proj = { MediaStore.Images.Media.DATA };
cursor = mContext.getContentResolver().query(contentUri, proj, null, null, null);
int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
cursor.moveToFirst();
return cursor.getString(column_index);
} catch (Exception e) {
Log.message(e.getMessage());
} finally {
if (cursor != null) {
cursor.close();
}
}
return null;
}
Run Code Online (Sandbox Code Playgroud)
如果我从Gallery应用程序(Android 4.4.2,arm-emu)中选择图像,
uri.getPath = /external/images/media/16 and it work's fine (My file path: /storage/sdcard/Download/0_cf15a_7800a7e5_orig.jpg)
Run Code Online (Sandbox Code Playgroud)
如果我从Documents app(Android 4.4.2,arm-emu)中选择图像,
I have uri.getPath = /document/image:16 and function getRealPathFromURI returns …Run Code Online (Sandbox Code Playgroud) 我在我的项目中使用同步适配器,它将定期同步.要为同步适配器创建帐户,我使用以下代码.
我面临的问题是此代码触发了初始同步.文档中没有提到此代码将使同步最初运行.
事实上即使在谷歌示例项目中也有额外的代码用于触发我已删除的初始同步.
我使用了此示例中的代码:http: //developer.android.com/samples/BasicSyncAdapter/index.html
即使我添加命令ContentResolver.cancelSync(account,null); 同步适配器仍然运行.
如何阻止同步适配器最初同步.它应该在同步间隔周期过去后第一次同步.
Account account = new Account(context.getPackageName(), context.getPackageName());
AccountManager accountManager = (AccountManager) context.getSystemService(Context.ACCOUNT_SERVICE);
if (accountManager.addAccountExplicitly(account, null, null)) {
// Inform the system that this account supports sync
ContentResolver.setIsSyncable(account, context.getPackageName(), 1);
// Inform the system that this account is eligible for auto sync when the network is up
ContentResolver.setSyncAutomatically(account, context.getPackageName(), true);
// Recommend a schedule for automatic synchronization.
// The system may modify this based
// on other scheduled syncs and network utilization. …Run Code Online (Sandbox Code Playgroud) 我正在使用MediaStore 和 ContentResolver API 来保存图像文件 (jpg/png/gif) MediaStore.Images。它可以工作,但问题是所有文件都以 .jpg 扩展名保存,并且文件名始终为“millis.jpg 中的当前时间”。
以下是我在 ContentValues 中放入的内容的示例:
date_added=1575480356 _display_name=2067623.gif date_modified=1575480356 mime_type=image/gif
Run Code Online (Sandbox Code Playgroud)
但将其插入 ContentResolver 并写入文件后,显示名称更改为2067623.jpg,文件名更改为1575480356.jpg.
如何让它保留文件名和扩展名?
代码:
ContentResolver resolver = activity.getContentResolver();
Uri mediaCollection;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
mediaCollection = MediaStore.Images.Media.getContentUri(MediaStore.VOLUME_EXTERNAL_PRIMARY);
} else {
mediaCollection = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
}
ContentValues mediaDetails = new ContentValues();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
final String relativeLocation = Environment.DIRECTORY_PICTURES + File.separator + "my_folder";
mediaDetails.put(MediaStore.Images.Media.DATE_TAKEN, System.currentTimeMillis());
mediaDetails.put(MediaStore.Images.Media.IS_PENDING, 1);
mediaDetails.put(MediaStore.MediaColumns.RELATIVE_PATH, relativeLocation);
}
String mimeType …Run Code Online (Sandbox Code Playgroud) java android mediastore android-contentresolver scoped-storage
更新:我必须彻底改变我的问题,因为我发现了更多与我的问题相关的细节。
问题:我的解决 Content Provider 的应用程序在带有 API 30 的模拟器中不起作用。错误:
java.lang.SecurityException: Failed to find provider com.a52.datafeeder01.MyProvider for user 0; expected to find a valid ContentProvider for this authority
Run Code Online (Sandbox Code Playgroud)
如果我使用 API 26、27、28 和 29,则没有问题。
带有 ContentProvider 的应用程序中的 AndroidManifest.xml:
<manifest>
<permission
android:name="MyProvider._READ_PERMISSION"
android:protectionLevel="normal" />
<application>
<activity>
...
</activity>
<provider android:name=".MyProvider"
android:authorities="com.a52.datafeeder01.MyProvider"
android:enabled="true"
android:exported="true"
android:readPermission="MyProvider._READ_PERMISSION"/>
</application>
</manifest>
Run Code Online (Sandbox Code Playgroud)
客户端应用程序中的 AndroidManifest.xml :
<manifest>
...
<uses-permission android:name="MyProvider._READ_PERMISSION" />
...
</manifest>
Run Code Online (Sandbox Code Playgroud)
如果我尝试在同一个应用程序中解析 Content Provider,它会起作用。
如果我packageManager.getInstalledPackages(PackageManager.GET_PROVIDERS)在我的客户端代码中使用来获取现有提供者的列表,那么对于 API [26,29] 我可以在列表中看到我的提供者。如果我在 API 30 中运行此代码,我的提供者不在列表中。
API 30 中与 …