Cordova 和 proguard:takePicture 上的相机插件 NPE
Posted
技术标签:
【中文标题】Cordova 和 proguard:takePicture 上的相机插件 NPE【英文标题】:Cordova and proguard : Camera Plugin NPE on takePicture 【发布时间】:2018-02-06 20:37:07 【问题描述】:对不起,如果有人已经要求这个。 我是 Stack 的新手,但我没有找到解决方案。
这是我缩小应用程序后从应用程序的使用中得到的堆栈。
08-29 13:27:30.330 10037-10192/? E/PluginManager: Uncaught exception from plugin
java.lang.NullPointerException: Attempt to invoke virtual method 'android.content.res.XmlResourceParser android.content.pm.PackageItemInfo.loadXmlMetaData(android.content.pm.PackageManager, java.lang.String)' on a null object reference
at android.support.v4.content.FileProvider.parsePathStrategy(Unknown Source)
at android.support.v4.content.FileProvider.getPathStrategy(Unknown Source)
at android.support.v4.content.FileProvider.getUriForFile(Unknown Source)
at org.apache.cordova.camera.CameraLauncher.takePicture(Unknown Source)
at org.apache.cordova.camera.CameraLauncher.callTakePicture(Unknown Source)
at org.apache.cordova.camera.CameraLauncher.execute(Unknown Source)
at org.apache.cordova.CordovaPlugin.execute(Unknown Source)
at org.apache.cordova.PluginManager.exec(Unknown Source)
at org.apache.cordova.CordovaBridge.jsExec(Unknown Source)
at org.apache.cordova.engine.SystemExposedJsApi.exec(Unknown Source)
at org.chromium.base.SystemMessageHandler.nativeDoRunLoopOnce(Native Method)
at org.chromium.base.SystemMessageHandler.handleMessage(SystemMessageHandler.java:7)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:154)
at android.os.HandlerThread.run(HandlerThread.java:61)
这是我的 proguard 文件:
# ionic
-keep class org.apache.cordova.** *;
-keep class org.apache.cordova.camera.** *;
-keep public class * extends org.apache.cordova.CordovaPlugin
-keep class com.ionic.keyboard.IonicKeyboard.** *;
-keep public class com.google.android.gms.common.internal.safeparcel.SafeParcelable
public static final *** NULL;
-keepnames @com.google.android.gms.common.annotation.KeepName class *
-keepclassmembernames class *
@com.google.android.gms.common.annotation.KeepName *;
-keepnames class * implements android.os.Parcelable
public static final ** CREATOR;
# Not sure if needed, found it in several documentations
-keep class * extends java.util.ListResourceBundle
protected Object[][] getContents();
-keep public class com.google.android.gms.common.internal.safeparcel.SafeParcelable
public static final *** NULL;
-keepnames @com.google.android.gms.common.annotation.KeepName class *
-keepclassmembernames class *
@com.google.android.gms.common.annotation.KeepName *;
-keepnames class * implements android.os.Parcelable
public static final ** CREATOR;
-keep public class * extends android.app.Activity
-keep public class * extends android.app.Application
-keep public class * extends android.app.Service
-keep public class * extends android.content.BroadcastReceiver
-keep public class * extends android.content.ContentProvider
-keep public class * extends android.app.backup.BackupAgentHelper
-keep public class * extends android.preference.Preference
-keep public class com.android.vending.licensing.ILicensingService
#-libraryjars ./libs/android-support-v4.jar
-dontwarn android.support.v4.**
-keep class android.support.v4.** *;
-keep interface android.support.v4.** *;
-keep public class * extends android.support.v4.**
-keep public class * extends android.app.Fragment
-keep class android.support.v4.content.FileProvider
-keepclasseswithmembernames class *
native <methods>;
-keepclasseswithmembers class *
public <init>(android.content.Context, android.util.AttributeSet);
-keepclasseswithmembers class *
public <init>(android.content.Context, android.util.AttributeSet, int);
-keepclassmembers class * extends android.app.Activity
public void *(android.view.View);
-keepclassmembers enum *
public static **[] values();
public static ** valueOf(java.lang.String);
-keep class * implements android.os.Parcelable
public static final android.os.Parcelable$Creator *;
-dontwarn com.worklight.common.internal.WLTrusteerInternal*
-dontwarn com.worklight.jsonstore.**
-dontwarn org.codehaus.jackson.map.ext.*
-dontwarn com.worklight.androidgap.push.GCMIntentService
-dontwarn com.worklight.androidgap.plugin.WLInitializationPlugin
-dontwarn android.net.SSLCertificateSocketFactory
-dontwarn android.net.http.*
-keepattributes *Annotation*
如果我使用“从图库中选择”项目,一切正常,但每次我尝试使用相机时都会出现此错误。
对于 android manifest 我有这个:
<?xml version='1.0' encoding='utf-8'?>
<manifest android:hardwareAccelerated="true" android:versionCode="24" android:versionName="2.4" package="" xmlns:android="http://schemas.android.com/apk/res/android">
<supports-screens android:anyDensity="true" android:largeScreens="true" android:normalScreens="true" android:resizeable="true" android:smallScreens="true" android:xlargeScreens="true" />
<uses-permission android:name="android.permission.INTERNET" />
<application android:hardwareAccelerated="true" android:icon="@mipmap/icon" android:label="@string/app_name" android:supportsRtl="true">
<activity android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale" android:label="@string/activity_name" android:launchMode="singleTop" android:name="MainActivity" android:screenOrientation="portrait" android:theme="@android:style/Theme.DeviceDefault.NoActionBar" android:windowSoftInputMode="adjustResize">
<intent-filter android:label="@string/launcher_name">
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<provider
android:authorities="$applicationId.provider"
android:exported="false"
android:grantUriPermissions="true"
android:name="android.support.v4.content.FileProvider">
<meta-data android:name="android.support.FILE_PROVIDER_PATHS" android:resource="@xml/provider_paths" />
</provider>
</application>
<uses-sdk android:minSdkVersion="16" android:targetSdkVersion="22" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.CAMERA"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
</manifest>
请注意,我从清单中删除了包名称(仅适用于堆栈上的这篇文章,在我的构建中有名称)
如果我使用 minifyenabled false 删除 proguard,则该应用程序正常并且可以处理相机。
我不知道缩小了什么,我应该添加以保留? 或者也许你有提示/提示来发现我的方法有什么问题?
谢谢。
【问题讨论】:
【参考方案1】:如果还有人卡在这个问题上
将此行添加到您的 proguard 规则中
-keep class com.abc.xyz.BuildConfig *;
com.abc.xyz 是你的包名
就是这样......
稍后谢谢我...
快乐编码
【讨论】:
我确实阅读了您的帖子,但在您的 proguard 文件中找不到,我遇到了同样的错误,解决方案对我有用.....@JolyVincent 好的,非常感谢,确实如此。我很惊讶这部分代码链接到相机插件,但就是这样! 我测试了这个解决方案和Shica Kumar H R 的answer below 并且都可以工作。显然,Shiva 的答案将适用于更动态的项目,其中各种平台不是项目专用/永久的一部分,并且需要临时生成,而 MSD 的答案将适用于项目中的永久 android 平台。 【参考方案2】:我也遇到了同样的问题,下面为我解决了这个问题:
更新 config.xml 文件。
打开项目文件夹中的 config.xml 文件。 在
<preference name="applicationId" value="PACKAGE_ID"/>
其中 PACKAGE_ID 替换为您项目的 Android 包 ID。参考:https://www.ibm.com/support/knowledgecenter/SSHS8R_7.1.0/com.ibm.worklight.dev.doc/dev/t_android_cam_api_24.html#t_android_cam_api_24
【讨论】:
这也适用于我,但我将偏好元素作为子元素添加到小部件元素中,在 android 平台元素之外。 这解决了我在 build-extras.gradle 中添加 applicationIdSuffix 配置引起的相同问题,例如:android buildTypes debug applicationIdSuffix ".dev"
【参考方案3】:
嗨,我解决了同样的问题。有没有classnotfounderror?在我的问题中,NPE 底部有一个 classnotfoundexception 。在我在 proguard-rules 中添加了那个未找到的类后,问题就解决了。
我的问题日志喜欢 java.lang.ClassNotFoundException: com.xyz.XYZ.BuildConfig
Uncaught exception from plugin java.lang.NullPointerException:
Attempt to invoke virtual method 'android.content.res.XmlResourceParser
android.content.pm.ProviderInfo.loadXmlMetaData(android.content.pm.PackageManager, java.lang.String)' on a null object reference
at android.support.v4.content.FileProvider.parsePathStrategy(Unknown Source)
at android.support.v4.content.FileProvider.getPathStrategy(Unknown Source)
at android.support.v4.content.FileProvider.getUriForFile(Unknown Source)
at org.apache.cordova.camera.CameraLauncher.takePicture(Unknown Source)
at org.apache.cordova.camera.CameraLauncher.callTakePicture(Unknown Source)
at org.apache.cordova.camera.CameraLauncher.execute(Unknown Source)
at org.apache.cordova.CordovaPlugin.execute(Unknown Source)
at org.apache.cordova.PluginManager.exec(Unknown Source)
at org.apache.cordova.CordovaBridge.jsExec(Unknown Source)
at org.apache.cordova.engine.SystemExposedJsApi.exec(Unknown Source)
at org.chromium.base.SystemMessageHandler.nativeDoRunLoopOnce(Native Method)
at org.chromium.base.SystemMessageHandler.handleMessage(SystemMessageHandler.java:7)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:145)
at android.os.HandlerThread.run(HandlerThread.java:61)
09-03 11:38:37.630 6926-6926/com.xyz.XYZ D/SystemWebChromeClient: file:///android_asset/www/js/bundles/fileUploadMobile_bundle.js: Line 1 : Failed because: Attempt to invoke virtual method 'android.content.res.XmlResourceParser android.content.pm.ProviderInfo.loadXmlMetaData(android.content.pm.PackageManager, java.lang.String)' on a null object reference
09-03 11:38:37.630 6926-6926/com.xyz.XYZ I/chromium: [INFO:CONSOLE(1)] "Failed because: Attempt to invoke virtual method 'android.content.res.XmlResourceParser android.content.pm.ProviderInfo.loadXmlMetaData(android.content.pm.PackageManager, java.lang.String)' on a null object reference", source: file:///android_asset/www/js/bundles/fileUploadMobile_bundle.js (1)
09-03 11:38:37.690 6926-9554/com.xyz.XYZ D/BuildHelper: Unable to get the BuildConfig, is this built with ANT?
09-03 11:38:37.690 6926-9554/com.xyz.XYZ W/System.err: **java.lang.ClassNotFoundException: com.xyz.XYZ.BuildConfig**
然后在 proguard-rules 中添加该行
-keep public class com.xyz.XYZ.BuildConfig
-keepclassmembers class com.xyz.XYZ.BuildConfig
public *;
【讨论】:
不,后面没有堆栈。事实上,当我使用cordova并且他生成了一些内省类时,我认为它没有提供比我之前粘贴的堆栈更多的信息。【参考方案4】:将此添加到清单文件中,在应用程序标记内。我试过了,效果很好
这是我的 Manifest xml 文件中的提供程序部分:
<provider
android:name="android.support.v4.content.FileProvider"
android:authorities="$applicationId.provider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/provider_paths" />
</provider>
【讨论】:
抱歉,您看过我的帖子吗?我将我的 android 清单放入其中,而您所说的已经在我的清单中。以上是关于Cordova 和 proguard:takePicture 上的相机插件 NPE的主要内容,如果未能解决你的问题,请参考以下文章
添加proguard后用于cordova的相机插件中的java NullPointerException