Android FileProvider class not found in release builds - android

I'm using a FileProvider to get photos from the device. The implementation works just fine in debug builds (minifyEnabled false) but when I'm building the release build (minifyEnabled true) I get an error:
java.lang.RuntimeException: Unable to get provider android.support.v4.content.FileProvider:
java.lang.ClassNotFoundException: Didn't find class "android.support.v4.content.FileProvider"
on path: DexPathList[[zip file "/data/app/com.package.name-2/base.apk"],
nativeLibraryDirectories=[/data/app/om.package.name-2/lib/arm, /vendor/lib, /system/lib]]
So I guess this has someting to do with the proguard setup
I have
compile 'com.android.support:support-v13:23.1.1'
which is a superset of v4 in my gradle file and
minSdkVersion 21
targetSdkVersion 23
and
-keep class android.support.v4.app.** { *; }
-keep class android.support.v4.content.** { *; }
-keep interface android.support.v4.app.** { *; }
-keep interface android.support.v4.content.** { *; }
-keep class * extends android.content.ContentProvider
in my proguard-rules.pro file
I have tested with both Android 5 and 6 and same thing happens.
Any suggestion would be usefull, thanks in advance.

The following worked for me:
In your module build.gradle file:
defaultConfig {
...
multiDexEnabled true
...
}
Then:
dependencies {
...
compile 'com.android.support:multidex:1.0.2'
...
}
And finally, ensure that your application class has one of the following:
A. If you do not extend your application class:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.myapp">
<application
android:name="android.support.multidex.MultiDexApplication" >
...
</application>
</manifest>
B. If you do extend your Application class and but can change the base class:
public class MyApplication extends MultiDexApplication { ... }
C. If you do extend your Application class and cannot change the base class:
public class MyApplication extends SomeOtherApplication {
#Override
protected void attachBaseContext(Context base) {
super.attachBaseContext(base);
MultiDex.install(this);
}
}
For more info:
https://developer.android.com/studio/build/multidex.html#mdex-gradle

I was using androidx library and getting the same error. So, in AndroidManifest.xml, I changed this line:
android:name="android.support.v4.content.FileProvider"
to this:
android:name="androidx.core.content.FileProvider"

After a couple of hours of more googling around I've ended up updating gradle and google services to
dependencies {
classpath 'com.android.tools.build:gradle:1.5.0'
classpath 'com.google.gms:google-services:1.5.0'
}
previously the version ware
classpath 'com.android.tools.build:gradle:1.3.0'
classpath 'com.google.gms:google-services:1.5.0-beta2'
I guess there needs to be something with the google-services library

Related

DexOverflowException after adding com.google.firebase:firebase-firestore:11.4.2

I have a problem after adding compile "com.google.firebase:firebase-firestore:11.4.2" to my build.
As soon as I add that, it also adds com.google.common among other things to my dex file, which is around 27k extra references, thus bursting through the 64k dex limit.
Does anyone know why that is or am I doing something wrong?
Try adding these lines to your build.gradle
android {
defaultConfig {
...
minSdkVersion 21
targetSdkVersion 26
multiDexEnabled true
}
...
}
This will enable multidex mode, which will allow you to exceed the 64k limit. (Read more here)
API below 21
If you're using an API level below 21, then you also need to add the support library
gradle.build:
dependencies {
compile 'com.android.support:multidex:1.0.1'
}
android.manafest
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.myapp">
<application
android:name="android.support.multidex.MultiDexApplication" >
...
</application>
</manifest>
If you use a custom Application class, try using one the of the following
Solution 1
simply override the MultiDexApplication class
public class MyApplication extends MultiDexApplication { ... }
Solution 2
override attachBaseContext and install MultiDex using the install(Application) function
public class MyApplication extends SomeOtherApplication {
#Override
protected void attachBaseContext(Context base) {
super.attachBaseContext(base);
MultiDex.install(this);
}
}
You're not doing anything wrong: the Android API for Cloud Firestore is just big. We'll be working on reducing SDK size on the road to GA.
Meanwhile, you need to enable multidex to build if your application is nontrivial.
We actually use very little of com.google.common, so you may be able to say under the 64k method limit by proguarding your application too.
Updating to 11.6.0 fixes this issue

java.lang.RuntimeException: Unable to instantiate application. ClassNotFoundException: Didn't find class

I know this question has been asked a million times and yet, I couldn't find the answer to my specific situation. I have a library which has all of the code, and a couple of other modules that import the library.
-project
--mylibrary
---sr/main/java
----co/android/mylibrary
----BaseApp (extends MultidexApp)
--Application1
---sr/main/java
----co/android/app2
-----Android Manifest
--Application2
---sr/main/java
----co/android/app2
-----Android Manifest
And both the manifests use the base app like this.
<application
android:name="co.android.mylibrary.BaseApp"
android:allowBackup="false"
android:fullBackupContent="false"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:largeHeap="true"
android:theme="#style/AppTheme"
tools:replace="android:icon,android:theme, android:allowBackup">
And the build dependencies look like this:
dependencies {
releaseCompile project(path: ':mylibrary', configuration: 'release')
debugCompile project(path: ':mylibrary', configuration: 'debug')
}
My base app's method to initialize multidex:
protected void attachBaseContext(Context base) {
super.attachBaseContext(base);
try {
MultiDex.install(this);
}catch (RuntimeException e){}
}
Some of my proguard rules, that I've added at both locations (library and the application). These don't include some rules for 3rd party libraries and some of my own classes.
-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.view.View
-keep public class co.android.mylibrary.data.greendao.**{ *; }
So the app runs fine on my s8, but doesn't on some phones like the moto G. They would also run fine if Proguard is enabled and its shrinking resources, like for release builds. Another strange behavior I noticed is that, when I set my breakpoint on some parts of my code and run the release builds (with debuggable set to true), it would break on the s8, but not on the moto.
Why this strange behavior? Another question that I found super similar is unable to instantiate application - ClassNotFoundException. But still no resolution.
This is the complete log of the error. Ignore the package names.
Edit
After changing the way I compile the library on my application, based on suggestiongs from #Mostafa Anter:
compile project(path: ':mylibrary', configuration: 'debug')
It started giving me this error. I have my instant run turned off.
make base class extend Application
then inside onCreate method call this lineMultiDex.install(this);
Modify the module-level build.gradle file to enable multidex and add the multidex library as a dependency, as shown here:
android {
defaultConfig {
...
minSdkVersion 15
targetSdkVersion 26
multiDexEnabled true
}
...
}
dependencies {
compile 'com.android.support:multidex:1.0.1'
}
if you use JavaVersion.VERSION_1_8 please be sure that you use it in all modules
android {
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
}

SugarORM + Multidex

I downloaded the SugarORM source to use it as a library module (so I could override the aplication's "attachBaseContext" method.
I have already seen the question SugarORM and multidex, Problem is that I can't figure out how to reference the MultiDex library into my new SugarORM library module.
Can someone help me figuring this out?
Error page screenshot
Create a class java file
public class MultiDex extends SugarApp {
#Override
protected void attachBaseContext(Context base) {
super.attachBaseContext(base);
android.support.multidex.MultiDex.install(this);
}
#Override
public void onCreate() {
super.onCreate();
SugarContext.init(this);
}
#Override
public void onTerminate() {
SugarContext.terminate();
super.onTerminate();
}
}
In Manifest, call the java class file.
<application
.......
android:name=".MultiDex"
......>
Check the version of sugar library
and make sure you complie the latest version of sugar library . Using version like 1.3 will throw some errors with multidex.
add this in your gradle
compile 'com.github.satyan:sugar:1.5'
If possible, extend the MultiDexApplication yourself:
public class MyApplication extends MultiDexApplication
Also, ensure you have followed all steps required to configure MultiDex.
Particularly build.gradle:
android {
defaultConfig {
...
multiDexEnabled = true
}
And AndroidManifest.xml:
<application
android:name="android.support.multidex.MultiDexApplication"
.. >
..
</application>

Using AppCompat 'layout_behavior' with '#string/appbar_scrolling_view_behavior' throws exception

I have a strange probem using the AppCompat Lib 22.2 with the new introduced: layout_behavior
If i use it with the value "#string/appbar_scrolling_view_behavior" , as described here Android Design Support Lib the application terminates with the following exception:
Could not inflate Behavior subclass android.support.design.widget.Settings
Caused by: java.lang.RuntimeException: Could not inflate Behavior subclass android.support.design.widget.Settings
Caused by: java.lang.ClassNotFoundException: android.support.design.widget.Settings
Caused by: java.lang.NoClassDefFoundError: android/support/design/widget/Settings
Caused by: java.lang.ClassNotFoundException: android.support.design.widget.Settings
If i change to :
app:layout_behavior="android.support.design.widget.AppBarLayout$ScrollingViewBehavior"
everything works fine.
What i'm missing ?
For others who encounter this exception and use proguard - you need to add following proguard rules:
-keep class android.support.design.widget.** { *; }
-keep interface android.support.design.widget.** { *; }
-dontwarn android.support.design.**
or if you don't want to keep all of the design library components you can use:
-keepattributes *Annotation*
-keep public class * extends android.support.design.widget.CoordinatorLayout.Behavior { *; }
-keep public class * extends android.support.design.widget.ViewOffsetBehavior { *; }
Another reason for this to be happening is when you're extending FloatingActionButton.Behavior and you don't have a (Context, AttributeSet) constructor. That happened to me with design library v. 23.0.1
Just add this constructor to your subclass:
public FloatingActionButtonBehaviorSubclass(Context context, AttributeSet attrs) {
super();
}
You should add design lib for your project.
compile 'com.android.support:design:22.2.0'
Check the sample https://github.com/chrisbanes/cheesesquare
For developers who are using getting this error only when using proguard, just add a single line to proguard rules file :
-keep public class * extends android.support.design.widget.CoordinatorLayout$Behavior { *; }
I encountered this error today after migrating my project to Androidx.
It seems that I had a string in my string.xml file. I had to remove this line.
<string name="appbar_scrolling_view_behavior" translatable="false">android.support.design.widget.AppBarLayout$ScrollingViewBehavior</string>
It should only link to values.xml file and not string.xml file.
app:layout_behavior="#string/appbar_scrolling_view_behavior" should only link to values.xml (Ctrl+B)
<string name="appbar_scrolling_view_behavior" translatable="false">com.google.android.material.appbar.AppBarLayout$ScrollingViewBehavior</string>

Can I write some of the code in Scala (using AndroidStudio)?

I'm using AndroidStudio, and I want to stick to using it because it's the official IDE.
All I want to do is to be able to write some classes in Scala, sounds reasonable to me.
However, all I could find online is a way to create a new project using SBT (+ Android plugins and idea plugin) then load it in AndroidStudio. Of course, I had to deal with all the strange errors and the like until I finally made it compile and run on the emulator. But then I tried to add a fragment drawer and again I ran into problem because I need to add some extra Android libraries and I have no clue to do that.
The sane approach should be to use AndroidStudio as it is (because it's the official IDE) and be able to add Scala files somehow that then get compiled into java bytecode then get treated like normal Java code by the Android compiler. Is there a way to do that?
I use Scala and Gradle (yeah, I know Gradle is written in Groovy). It's a pain to get set up at first, but I like Scala a lot, so it is worth it.
To do it you will need to rely on a groovy plugin. Here is what you do:
1. Add classpath "jp.leafytree.gradle:gradle-android-scala-plugin:1.3.1" to your top-level gradle file like so (also work around the problem with proguard):
build.gradle (top-level):
buildscript {
repositories {
mavenLocal() // Remove this if your repository is not local
jcenter()
}
dependencies {
classpath "com.android.tools.build:gradle:1.0.0"
classpath "jp.leafytree.gradle:gradle-android-scala-plugin:1.3.1"
// Default version of proguard v4.8 (?) and v5.1 fail with ArrayIndexOutOfBoundsException: 4
classpath ('net.sf.proguard:proguard-gradle:5.0') {
force = true
}
...
2. Apply your plugins and set the Scala dependency in the module, like "app" or "wear", level gradle file:
build.gradle (module-level):
...
apply plugin: "jp.leafytree.android-scala"
android {
...
buildTypes {
release {
debuggable false
minifyEnabled true
...
debug {
debuggable true
minifyEnabled true
...
}
dependencies {
...
compile 'org.scala-lang:scala-library:2.11.4'
}
3. Make sure you are using Proguard (Scala code has to be minified to work with Android). Here is the main proguard file I use--you will want to change that "keep public class" line at the top to match your project domain:
proguard-rules.pro:
-dontpreverify
-dontskipnonpubliclibraryclasses
-dontskipnonpubliclibraryclassmembers
-dontusemixedcaseclassnames
# ----
-dontoptimize
# ----
-keep public class com.keithpinson.** { public protected *; }
##
## SCALA SETTINGS
##
-dontwarn scala.**
-dontnote scala.Enumeration
-ignorewarnings
# temporary workaround; see Scala issue SI-5397
-keep class scala.collection.SeqLike {
public protected *;
}
-keep class scala.math.ordering { *; }
-keep class scala.Function1 { *; }
-keep class scala.Function2 { *; }
##
## ANDROID SETTINGS
##
-keep class android.support.v13.** { *; }
-keep interface android.support.v13.** { *; }
-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 *;
}
# Joda Time 2.3
-keep class org.joda.time.** { *; }
-keep interface org.joda.time.** { *; }
If I haven't forgotten something and Gradle is downloading the leafytree plugin and if you have the right versions of Scala and Android, it should work fine.

Categories

Resources