您好,无论谁读到这篇文章,我在我的应用程序上遇到了一个大问题,我无法理解为什么! 我的应用程序名为FireFiles不会在Android 8.0上启动,但它可以在17-25的所有其他API级别上完美运行 这是我在Genymotion Android 8.0模拟器上运行它时的logcat
02-18 08:02:02.749 2425-2462/com.gigabytedevelopersinc.app.explorer E/AndroidRuntime: FATAL EXCEPTION: AsyncTask #1
Process: com.gigabytedevelopersinc.app.explorer, PID: 2425
java.lang.RuntimeException: An error occured while executing doInBackground()
at com.gigabytedevelopersinc.app.explorer.misc.AsyncTask$3.done(AsyncTask.java:326)
at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:383)
at java.util.concurrent.FutureTask.setException(FutureTask.java:252)
at java.util.concurrent.FutureTask.run(FutureTask.java:271)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1162)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:636)
at java.lang.Thread.run(Thread.java:764)
Caused by: java.lang.SecurityException: Permission Denial: opening provider com.gigabytedevelopersinc.app.explorer.provider.RecentsProvider from ProcessRecord{bd0f8f5 2425:com.gigabytedevelopersinc.app.explorer/u0a83} (pid=2425, uid=10083) requires that you obtain access using ACTION_OPEN_DOCUMENT or related APIs
at android.os.Parcel.readException(Parcel.java:1942)
at android.os.Parcel.readException(Parcel.java:1888)
at android.content.IContentService$Stub$Proxy.registerContentObserver(IContentService.java:768)
at android.content.ContentResolver.registerContentObserver(ContentResolver.java:1924)
at android.content.ContentResolver.registerContentObserver(ContentResolver.java:1913)
at com.gigabytedevelopersinc.app.explorer.misc.RootsCache.loadRootsForAuthority(RootsCache.java:267)
at com.gigabytedevelopersinc.app.explorer.misc.RootsCache.access$900(RootsCache.java:51)
at com.gigabytedevelopersinc.app.explorer.misc.RootsCache$UpdateTask.handleDocumentsProvider(RootsCache.java:252)
at com.gigabytedevelopersinc.app.explorer.misc.RootsCache$UpdateTask.doInBackground(RootsCache.java:208)
at com.gigabytedevelopersinc.app.explorer.misc.RootsCache$UpdateTask.doInBackground(RootsCache.java:164)
at com.gigabytedevelopersinc.app.explorer.misc.AsyncTask$2.call(AsyncTask.java:313)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1162)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:636)
at java.lang.Thread.run(Thread.java:764)
以下是github存储库FireFiles-Github
的链接以下是一些代码。 AsyncTask.java (第326行)
public AsyncTask() {
mWorker = new WorkerRunnable<Params, Result>() {
public Result call() throws Exception {
mTaskInvoked.set(true);
Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
//noinspection unchecked
return postResult(doInBackground(mParams));
}
};
mFuture = new FutureTask<Result>(mWorker) {
@Override
protected void done() {
try {
postResultIfNotInvoked(get());
} catch (InterruptedException e) {
android.util.Log.w(LOG_TAG, e);
} catch (ExecutionException e) {
throw new RuntimeException("An error occured while executing doInBackground()",
e.getCause());
} catch (CancellationException e) {
postResultIfNotInvoked(null);
}
}
};
}
RootsCache.java (第164-267行)
private class UpdateTask extends AsyncTask<Void, Void, Void> {
private final String mAuthority;
private final MultiMap<String, RootInfo> mTaskRoots = new MultiMap<>();
private final ArraySet<String> mTaskStoppedAuthorities = new ArraySet<>();
/**
* Update all roots.
*/
public UpdateTask() {
this(null);
}
/**
* Only update roots belonging to given authority. Other roots will
* be copied from cached {@link #mRoots} values.
*/
public UpdateTask(String authority) {
mAuthority = authority;
}
@TargetApi(Build.VERSION_CODES.KITKAT)
@Override
protected Void doInBackground(Void... params) {
final long start = SystemClock.elapsedRealtime();
if (mAuthority != null) {
// Need at least first load, since we're going to be using
// previously cached values for non-matching packages.
waitForFirstLoad();
}
mTaskRoots.put(mHomeRoot.authority, mHomeRoot);
mTaskRoots.put(mConnectionsRoot.authority, mConnectionsRoot);
mTaskRoots.put(mRecentsRoot.authority, mRecentsRoot);
final ContentResolver resolver = mContext.getContentResolver();
final PackageManager pm = mContext.getPackageManager();
// Pick up provider with action string
if(Utils.hasKitKat()){
final Intent intent = new Intent(DocumentsContract.PROVIDER_INTERFACE);
final List<ResolveInfo> providers = pm.queryIntentContentProviders(intent, 0);
for (ResolveInfo info : providers) {
handleDocumentsProvider(info.providerInfo);
}
}
else{
List<ProviderInfo> providers = pm.queryContentProviders(mContext.getPackageName(),
mContext.getApplicationInfo().uid, 0);
for (ProviderInfo providerInfo : providers) {
handleDocumentsProvider(providerInfo);
}
}
final long delta = SystemClock.elapsedRealtime() - start;
Log.d(TAG, "Update found " + mTaskRoots.size() + " roots in " + delta + "ms");
synchronized (mLock) {
mRoots = mTaskRoots;
mStoppedAuthorities = mTaskStoppedAuthorities;
}
mFirstLoad.countDown();
resolver.notifyChange(sNotificationUri, null, false);
return null;
}
private void handleDocumentsProvider(ProviderInfo info) {
// Ignore stopped packages for now; we might query them
// later during UI interaction.
if ((info.applicationInfo.flags & ApplicationInfo.FLAG_STOPPED) != 0) {
if (LOGD) Log.d(TAG, "Ignoring stopped authority " + info.authority);
mTaskStoppedAuthorities.add(info.authority);
return;
}
// Try using cached roots if filtering
boolean cacheHit = false;
if (mAuthority != null && !mAuthority.equals(info.authority)) {
synchronized (mLock) {
if (mTaskRoots.putAll(info.authority, mRoots.get(info.authority))) {
if (LOGD) Log.d(TAG, "Used cached roots for " + info.authority);
cacheHit = true;
}
}
}
// Cache miss, or loading everything
if (!cacheHit) {
mTaskRoots.putAll(info.authority,
loadRootsForAuthority(mContext.getContentResolver(), info.authority));
}
}
}
/**
* Bring up requested provider and query for all active roots.
*/
private Collection<RootInfo> loadRootsForAuthority(ContentResolver resolver, String authority) {
if (LOGD) Log.d(TAG, "Loading roots for " + authority);
synchronized (mObservedAuthorities) {
if (mObservedAuthorities.add(authority)) {
// Watch for any future updates
final Uri rootsUri = DocumentsContract.buildRootsUri(authority);
mContext.getContentResolver().registerContentObserver(rootsUri, true, mObserver);
}
}
final List<RootInfo> roots = new ArrayList<>();
final Uri rootsUri = DocumentsContract.buildRootsUri(authority);
ContentProviderClient client = null;
Cursor cursor = null;
try {
client = DocumentsApplication.acquireUnstableProviderOrThrow(resolver, authority);
cursor = client.query(rootsUri, null, null, null, null);
while (cursor.moveToNext()) {
final RootInfo root = RootInfo.fromRootsCursor(authority, cursor);
roots.add(root);
}
} catch (Exception e) {
Log.w(TAG, "Failed to load some roots from " + authority + ": " + e);
} finally {
IoUtils.closeQuietly(cursor);
ContentProviderClientCompat.releaseQuietly(client);
}
return roots;
}