美文网首页
android14-release版本DocumentsUI移植

android14-release版本DocumentsUI移植

作者: 梧叶已秋声 | 来源:发表于2024-05-30 10:14 被阅读0次

本文主要是受了https://github.com/siren-ocean/DocumentsUI 的启发。由于DocumentsUI依赖较少,所有拿来入门练手。

运行环境:

Android Studio Jellyfish | 2023.3.1
Build #AI-233.14808.21.2331.11709847, built on April 13, 2024
Runtime version: 17.0.10+0-17.0.10b1087.21-11572160 amd64
gradle plugin version:8.4.1
gradle version:8.6
gradle JDK:17.0.10

最终完整版可运行代码会在整理好后上传github。
一开始我是想使用低版本gradle,但是由于framework.jar下的android/content/Context.class 使用的是JDK17编译的,会导致编译报错:类文件具有错误的版本 61.0, 应为 52.0。所以就使用的JDK17(后面发现其实还是可以使用低版本的gradle和android studio 去引用高版本JDK的framework.jar)。
以下为过程简单记录。
1.新建工程,package命名为com.android.documentsui。
2.删除默认activity和res,将aosp 中packages/apps/DocumentsUI/src中的源码,res和manifestcopy到此工程。
3.minSdk修改为26,解决编译报错问题
4.添加依赖库

diff --git a/app/build.gradle b/app/build.gradle
--- a/app/build.gradle  (revision 1524766154bf21ffcb0738b7901e8d21a299013d)
+++ b/app/build.gradle  (revision 60b5398ef261ade6a1160d542027d9c8c7317e7b)
@@ -27,8 +27,24 @@
         targetCompatibility JavaVersion.VERSION_1_8
     }
 }
-
+configurations.all {
+    resolutionStrategy.eachDependency { DependencyResolveDetails details ->
+        if (details.requested.group == 'com.google.guava' && details.requested.name == 'listenablefuture') {
+            details.useTarget 'com.google.guava:guava:31.0.1-jre'
+        }
+    }
+}
 dependencies {
+    compileOnly files('libs/framework.jar')
+
+    implementation libs.legacy.support.v4
+    implementation libs.commons.compress
+    // 添加 guava 依赖并排除 listenablefuture
+    implementation ('com.google.guava:guava:31.0.1-jre') {
+        exclude group: 'com.google.guava', module: 'listenablefuture'
+    }
+    implementation libs.recyclerview
+    implementation libs.recyclerview.selection
 
     implementation libs.appcompat
     implementation libs.material
@@ -37,4 +53,30 @@
     testImplementation libs.junit
     androidTestImplementation libs.ext.junit
     androidTestImplementation libs.espresso.core
-}
\ No newline at end of file
+}
+
+
+gradle.projectsEvaluated {
+    tasks.withType(JavaCompile) {
+        options.compilerArgs.add("-Xbootclasspath/p:$rootProject.rootDir/app/libs/framework.jar")
+    }
+}
+
+preBuild {
+    doLast {
+        // 注意:iml的路径要根据自己的实际情况来写
+        def imlFile = file("../.idea/modules/app/DocumentsUI.app.main.iml")
+        try {
+            def parsedXml = (new XmlParser()).parse(imlFile)
+            def jdkNode = parsedXml.component[1].orderEntry.find { it.'@type' == 'jdk' }
+            parsedXml.component[1].remove(jdkNode)
+            def sdkString = "Android API " + android.compileSdkVersion.substring("android-".length()) + " Platform"
+            new groovy.util.Node(parsedXml.component[1], 'orderEntry', ['type': 'jdk', 'jdkName': sdkString, 'jdkType': 'Android SDK'])
+            groovy.xml.XmlUtil.serialize(parsedXml, new FileOutputStream(imlFile))
+        } catch (FileNotFoundException e) {
+
+        }
+    }
+
+}
+
Index: gradle/libs.versions.toml
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml
--- a/gradle/libs.versions.toml (revision 1524766154bf21ffcb0738b7901e8d21a299013d)
+++ b/gradle/libs.versions.toml (revision 60b5398ef261ade6a1160d542027d9c8c7317e7b)
@@ -7,6 +7,10 @@
 material = "1.12.0"
 activity = "1.9.0"
 constraintlayout = "2.1.4"
+recyclerview = "1.2.1"
+recyclerviewSelection = "1.1.0"
+legacySupportV4 = "1.0.0"
+commonsCompress = "1.26.2"
 
 [libraries]
 junit = { group = "junit", name = "junit", version.ref = "junit" }
@@ -16,6 +20,10 @@
 material = { group = "com.google.android.material", name = "material", version.ref = "material" }
 activity = { group = "androidx.activity", name = "activity", version.ref = "activity" }
 constraintlayout = { group = "androidx.constraintlayout", name = "constraintlayout", version.ref = "constraintlayout" }
+recyclerview = { group = "androidx.recyclerview", name = "recyclerview", version.ref = "recyclerview" }
+recyclerview-selection = { group = "androidx.recyclerview", name = "recyclerview-selection", version.ref = "recyclerviewSelection" }
+legacy-support-v4 = { group = "androidx.legacy", name = "legacy-support-v4", version.ref = "legacySupportV4" }
+commons-compress = { group = "org.apache.commons", name = "commons-compress", version.ref = "commonsCompress" }
 

5.解決编译报错:元素值必须为常量表达式

diff --git a/gradle.properties b/gradle.properties
--- a/gradle.properties (revision 60b5398ef261ade6a1160d542027d9c8c7317e7b)
+++ b/gradle.properties (revision bbea8c3f04c21ac89801d301f162f787a1002c91)
@@ -18,4 +18,6 @@
 # Enables namespacing of each library's R class so that its R class includes only the
 # resources declared in the library itself and none from the library's dependencies,
 # thereby reducing the size of the R class for that library
-android.nonTransitiveRClass=true
\ No newline at end of file
+android.nonTransitiveRClass=true
+
+android.nonFinalResIds=false

6.把缺少的java/com/android/modules/utils/build 下的SdkLevel和UnboundedSdkLevel放入android studio工程。
7.解决缺少id问题。
部分id存在于
out/soong/.intermediates/packages/apps/DocumentsUI/DocumentsUI/android_common/R.txt 这个文件中。可以在android studio中新建ids.xml 文件。

diff --git a/app/src/main/res/values/ids.xml b/app/src/main/res/values/ids.xml
new file mode 100644
--- /dev/null   (revision e64969f8df18fe4f2a8200c70a1a7e5ab1ce153c)
+++ b/app/src/main/res/values/ids.xml   (revision e64969f8df18fe4f2a8200c70a1a7e5ab1ce153c)
@@ -0,0 +1,20 @@
+<resources>
+    <item type="id" name="search_src_text" />
+    <item type="id" name="search_close_btn" />
+    <item type="id" name="action_mode_bar" />
+    <item type="id" name="option_menu_show_hidden_files" />
+    <item type="id" name="sub_menu_grid" />
+    <item type="id" name="sub_menu_list" />
+    <item type="id" name="dir_menu_create_dir" />
+
+    <item type="id" name="option_menu_create_dir" />
+    <item type="id" name="option_menu_search" />
+    <item type="id" name="option_menu_select_all" />
+    <item type="id" name="option_menu_debug" />
+
+    <item type="id" name="option_menu_sort" />
+
+    <item type="id" name="action_mode_close_button" />
+
+
+</resources>
\ No newline at end of file

8.添加DocumentsStatsLog文件
DocumentsStatsLog位于out/soong/.intermediates/packages/apps/DocumentsUI/statslog-docsui-java-gen/gen/com/android/documentsui/DocumentsStatsLog.java,把此文件copy至app/src/main/java/com/android/documentsui/DocumentsStatsLog.java。
9.解决其他编译语法报错

diff --git a/app/src/main/java/com/android/documentsui/DirectoryLoader.java b/app/src/main/java/com/android/documentsui/DirectoryLoader.java
--- a/app/src/main/java/com/android/documentsui/DirectoryLoader.java    (revision 0e3dfb4862f2129032c0d387b3e089e3426e418d)
+++ b/app/src/main/java/com/android/documentsui/DirectoryLoader.java    (revision d3a6a73d79a22f891e1f9a263687a2296b29afad)
@@ -100,7 +100,7 @@
         mPhotoPicking = state.isPhotoPicking();
     }
 
-    @Override
+    //@Override
     protected Executor getExecutor() {
         return ProviderExecutor.forAuthority(mRoot.authority);
     }
Index: app/src/main/java/com/android/documentsui/archives/WriteableArchive.java
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/app/src/main/java/com/android/documentsui/archives/WriteableArchive.java b/app/src/main/java/com/android/documentsui/archives/WriteableArchive.java
--- a/app/src/main/java/com/android/documentsui/archives/WriteableArchive.java  (revision 0e3dfb4862f2129032c0d387b3e089e3426e418d)
+++ b/app/src/main/java/com/android/documentsui/archives/WriteableArchive.java  (revision d3a6a73d79a22f891e1f9a263687a2296b29afad)
@@ -298,7 +298,7 @@
         synchronized (mEntries) {
             for (final String path : mPendingEntries) {
                 try {
-                    mZipOutputStream.putArchiveEntry(mEntries.get(path));
+                    mZipOutputStream.putArchiveEntry((ZipArchiveEntry)mEntries.get(path));
                     mZipOutputStream.closeArchiveEntry();
                 } catch (IOException e) {
                     Log.e(TAG, "Failed to flush empty entries.", e);
Index: app/src/main/java/com/android/documentsui/inspector/KeyValueRow.java
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/app/src/main/java/com/android/documentsui/inspector/KeyValueRow.java b/app/src/main/java/com/android/documentsui/inspector/KeyValueRow.java
--- a/app/src/main/java/com/android/documentsui/inspector/KeyValueRow.java  (revision 0e3dfb4862f2129032c0d387b3e089e3426e418d)
+++ b/app/src/main/java/com/android/documentsui/inspector/KeyValueRow.java  (revision d3a6a73d79a22f891e1f9a263687a2296b29afad)
@@ -98,8 +98,8 @@
     public void setOnClickListener(OnClickListener callback) {
         TextView clickable = ((TextView) findViewById(R.id.table_row_value));
         mDefaultTextColor = clickable.getTextColors();
-        TypedArray ta = getContext().obtainStyledAttributes(R.styleable.TextAppearance);
-        int linkColor = ta.getColor(R.styleable.TextAppearance_android_textColorLink,
+        TypedArray ta = getContext().obtainStyledAttributes(android.R.styleable.TextAppearance);
+        int linkColor = ta.getColor(android.R.styleable.TextAppearance_textColorLink,
                 mDefaultTextColor.getDefaultColor());
         ta.recycle();
         clickable.setTextColor(linkColor);

10.使用系统签名
这里可以直接使用https://github.com/siren-ocean/DocumentsUI
这里的文件
11.修改versionCode,改成35.
12.解决运行时错误,注释部分代码

diff --git a/app/src/main/java/com/android/documentsui/roots/ProvidersCache.java b/app/src/main/java/com/android/documentsui/roots/ProvidersCache.java
--- a/app/src/main/java/com/android/documentsui/roots/ProvidersCache.java   (revision 900dbfa600a2c680e08016ba0371ba545c0d7e17)
+++ b/app/src/main/java/com/android/documentsui/roots/ProvidersCache.java   (revision a390c75512f2515fa2a7410efcef9ce80dfe36f6)
@@ -207,7 +207,7 @@
             assert (recentRoot.rootId == null);
             assert (recentRoot.derivedIcon == R.drawable.ic_root_recent);
             assert (recentRoot.derivedType == RootInfo.TYPE_RECENTS);
-            assert (recentRoot.flags == (Root.FLAG_LOCAL_ONLY | Root.FLAG_SUPPORTS_IS_CHILD));
+        //    assert (recentRoot.flags == (Root.FLAG_LOCAL_ONLY | Root.FLAG_SUPPORTS_IS_CHILD));
             assert (recentRoot.availableBytes == -1);
         }

相关文章

网友评论

      本文标题:android14-release版本DocumentsUI移植

      本文链接:https://www.haomeiwen.com/subject/ezclqjtx.html