R8 and Proguard Rules - android

I am using https://github.com/amalChandran/trail-android this library in my android project. The animation was working perfectly fine. But, after enabling R8, the animation is not working. The library does not have any Proguard suggestion. I added the following block in one of my method,
googleMap.setOnMapLoadedCallback(() -> {
Route normalOverlayPolyline = new Route.Builder(mRouteOverlayView)
.setRouteType(RouteType.PATH)
.setCameraPosition(mMap.getCameraPosition())
.setProjection(mMap.getProjection())
.setLatLngs(mRoute)
.setBottomLayerColor(Color.YELLOW)
.setTopLayerColor(Color.RED)
.create();
map.setOnCameraMoveListener(() -> mRouteOverlayView.onCameraMove(map.getProjection(), map.getCameraPosition()));
Where I have two global variables defined,
public Route route;
public RouteOverlayView mRouteOverlayView;
Now, I have some details in my usage.txt
public void onCameramove(com.google.android.gms.maps.GoogleMap,com.obhai.polyline.trail.RouteOverlayView)
Is there any way to write something in proguard-rules.pro so that R8 doesn't remove this part?

Thanks to #sgjesse for his hint. I finally got my narrowed down proguard rule to keep my feature functioning.
-keep class com.amalbit.trail.AnimationRouteHelper { *;}
adding this rule served my purpose.

Related

After migrating to AndroidX: Cannot instantiate class: androidx.appcompat.widget.ShareActionProvider

I migrated to AndroidX (using the wizard in Android Studio), and I'm having problems with the share action provider. The wizard changed (among many other things) app:actionProviderClass="android.support.v7.widget.ShareActionProvider" to app:actionProviderClass="androidx.appcompat.widget.ShareActionProvider", in my detailactivity.xml file.
The app compiles fine, and runs fine, too -- so long as I install it on my device over USB. However, if I compile a signed APK, and install that, I get the following runtime error (when starting the detailfragment):
W/SupportMenuInflater: Cannot instantiate class: androidx.appcompat.widget.ShareActionProvider
I didn't notice this problem while developing, since I run/test the app on my device through USB. However, when I'm now testing the (signed/minified) APK, the SHARE button does not work. How can I troubleshoot and fix this? For instance, why does it fail on the signed/minified APK fail, while it works fine when installing on same device through USB?
It's hard to tell specifically where (in the code) the warning occurs, since the code in the APK is minified. Perhaps I could create an APK where the code is not minified, so I'd get proper references to lines in the source code (in Android Studio LogCat)?
For reference, here is an excerpt from the class where the warning occurs. I'm assuming the warning occurs somewhere here, as this is what's referencing the shareActionProvider?
import androidx.appcompat.widget.ShareActionProvider;
public class ScreenSlidePageFragment extends Fragment implements LoaderManager.LoaderCallbacks<Cursor> {
private ShareActionProvider mShareActionProvider;
public ScreenSlidePageFragment() {
setHasOptionsMenu(true); // only the share button
}
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
inflater.inflate(R.menu.detailfragment, menu);
MenuItem menuItem = menu.findItem(R.id.action_share);
mShareActionProvider = (ShareActionProvider) MenuItemCompat.getActionProvider(menuItem);
if (mShareActionProvider != null && mImageData != null) {
mShareActionProvider.setShareIntent(createShareImageIntent());
}
}
}
I got some help on #android-dev (IRC), and it seems the problem was that the minifier (for some reason) removes the androidx.appcompat.widget.ShareActionProvider class. Turning off minification produced a working APK.
The fix was to update my proguard-rules.pro file with a new "keep" line, to prevent it from removing the class. From before, I had a similar rule for the old Android Support Library, so I added the second line below and now it works.
-keep class android.support.v7.widget.** { *; }
-keep class androidx.appcompat.widget.** { *; }
thanks #melatonina!

How to add below mentioned Mapbox plugins to Android App

I happen unable to add LocationLayerPlugin to my Android project and cannot find any documentation to demonstrate how. Also, I can't find NavigationMapRoute inside package com.mapbox.services.android.navigation.ui.v5. Any help, please?
EDIT:
That's my build.gradle below and when typing LocationLayerPlugin, Android Studio cannot resolve it.
compile('com.mapbox.mapboxsdk:mapbox-android-sdk:5.1.0#aar') {
transitive = true
}
compile('com.mapbox.mapboxsdk:mapbox-android-services:2.1.3#aar') {
transitive = true
}
compile 'com.mapbox.mapboxsdk:mapbox-android-navigation:0.3.1'
For the LocationLayerPlugin you can use it with two lines of code:
locationLayerPlugin = new LocationLayerPlugin(mapView, mapboxMap, locationEngine);
locationLayerPlugin.setLocationLayerEnabled(LocationLayerMode.TRACKING);
You'll need to make sure to also call the lifecycles in the appropriate methods onStart and onStop. If you are using with navigation and want to use location snapping to the route, you will need to pass in null for the locationEngine and than use forceLocationUpdate inside onProgressChange.
A few examples are available here which show different ways to use the plugin. Documentation will be avliable soon once we release the first final version (currently just producing nightly builds).
For the NavigationMapRoute you'll need to make sure you are using the 0.4.0-snapshot of the Navigation SDK. you'll find it here com.mapbox.services.android.navigation.ui.v5.NavigationMapRoute

Adding cast button to ActionBar using the CastCompanionLibrary

I am trying to add the cast icon to the ActionBar using the CastCompanionLibrary's helper method:
#Override
public boolean onCreateOptionsMenu(Menu menu) {
super.onCreateOptionsMenu(menu);
getMenuInflater().inflate(R.menu.main, menu);
mDataCastManager.addMediaRouterButton(menu, R.id.media_route_menu_item); // This one
return true;
}
I have this as my menu.xml as specified by the PDF that is included with the companion library:
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:id="#+id/media_route_menu_item"
android:title="#string/media_route_menu_title"
app:actionProviderClass="android.support.v7.app.MediaRouteActionProvider"
app:showAsAction="always"/>
</menu>
However, nothing shows up in the ActionBar. No errors are thrown, nothing at all is visible. If I add a different menu item just to see if everything with my menu is set up correctly, that item shows up fine - it is just this cast action menu item that isn't showing up.
I have tried changing the "app" prefixes to "android", but then I get a NullPointerException somewhere deep in the library, and I have tried giving the menu item a different, visible icon. Nothing helps.
In AndroidStudio, the menu preview shows a menu item with the title "Play on...", so it seems like this should work.
What am I doing wrong?
You have to register your chrome-cast as a testing devise for you to be able to detect the chromecast devise from the Android.
Check the full SDK guide
Check the developer console registration. You have to register you chromecast devise in the console here, or else it is not detectable
Update: If nothing works, you may try to publish your app in the chromecast dev console as a last resort.
As mentioned by one of the chromecast developer try to access http://<chromecast-ip>:9222 from browser and see if you are able to see any thing.
Sometimes, these types of errors happen because proguard changes the name of the object and/or functions.
One possible solution is to add these to your progaurd configuration files:
-dontwarn android.support.v7.**
-keep class android.support.v7.internal.** { *; }
-keep interface android.support.v7.internal.** { *; }
-keep class android.support.v7.** { *; }
-keep interface android.support.v7.** { *; }
I actually had this exact error on the exact line and I didn't have my proguard configured properly for the support library.
In my case after device registration I forgot reboot chromecast device
CastCompanionLibrary and MediaRouteActionProvider are written for AppCompat ActionBar and not Sherlock ActionBar. It is strongly recommended to move your project to AppCompat since Sherlock ActionBar is deprecated so moving to AppCompat is generally a good move for your project; making that move is not difficult (see, e.g. this article)

Android java.lang.VerifyError with exp4j Libraries

I tried to make my own small calculator, but I don't want to make all the business logic by myself. So I tried to use the javax.script since I heard that the javax.script needs a real JVM and is a JavaScriptParser. Then, I searched for other libraries with the functions I needed and found the project "exp4j". First, I made a small normal Java Project with JDK 1.7, and yes, it works with the source code:
public static void main(String[] args) throws UnknownFunctionException, UnparsableExpressionException {
ExpressionBuilder builder=new ExpressionBuilder("34*2");
Calculable calc=builder.build();
System.out.println(calc.calculate());
}
Then, I tried the same code in my model (MVC Pattern) of my calculator:
public void berechnen() throws UnknownFunctionException, UnparsableExpressionException {
ExpressionBuilder builder=new ExpressionBuilder("34*2");
Calculable calc=builder.build();
setErgebnis(calc.calculate());
}
But every time I got the same exception:
"AndroidRuntime(630): java.lang.VerifyError",
after I started the app. I can't click on the button that runs the method berechnen() because the app crashes after I start it.
I'm confused why my program doesn't work. When I delete all imports of exp4j and delete the source for the calculation, my calculator works fine.
My only idea is that the exp4j libaries is using a class or method that does not exist in Android.
Thank you.
You may have include jars twice, check once in libs folder and libraries in properties, I have faced same in the past What you need to do is to
Remove that in the libraries and paste freshly in your res/lib folder of android application project and then clear your project

Android: Cant find .html file in res/raw after obfuscation

I have some html files in res/raw which I open in WebView. But after obfuscation they are unable to load.
I ran into exactly this same issue. I have my help html file in raw and after obfuscation I run my app and get an error that the file could not be found.
Here is my HelpActivity class:
public class HelpActivity extends BaseActivity
{
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
// requesting to turn the title OFF
//requestWindowFeature(Window.FEATURE_NO_TITLE);
// making it full screen
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
setContentView(R.layout.help);
setTitle(getString(R.string.help_title));
WebView webView = (WebView) findViewById(R.id.webView);
webView.loadUrl("file:///android_" + getString(R.raw.how_to_play_zeewee));
}
}
I fixed this issue by adding the following to my proguard.cfg file:
-keepclassmembers class **.R$* {public static <fields>;}
-keep class **.R$*
You probably already have the first line, but this does not prevent the issue. Adding the second line eliminated the issue completly. I don't think the first line is still needed, but I have not tested that yet -- and since it currently works... ;).
Suggested in an answer in this question -
-keep class **.R$*
isn't the most elegant solution since it instructs ProGuard to preserve all of the R classes regardless of the package they are in.
Having the same problem with WebView, the error I see in my Logcat:
... E/AndroidProtocolHandler: Unable to open resource URL:file:///android_res/raw/$MISSING_RESOURCE_NAME.css
java.lang.ClassNotFoundException: Didn't find class
"my.app.package.R$raw" on path: DexPathList[[...
The instruction with maximum restrictions I added to my proguard-rules.pro file:
-keepnames class my.app.package.R$raw { public static <fields>; }
Obviously Since R class contains only fields and all of these fields have public static type, in practice, there should no be the difference between the one above and
-keepnames class my.app.package.R$raw { *; }
However, here I'm
NOT disabling shrinking and obfuscation for all of the rest inner classes in R other than raw.
targeting R in one specific package only.
That approach should be better in case if you have more than one module in your project that provides its own resources that may not be needed for the one particular APK you are building (having, let's say, more than one android_application modules – APK sources – in your project as well).
To understand the difference between -keepnames and -keep, please, refer to the following.
Distinguishing between the different ProGuard -keep directives - Tue May 29 04:10:50 MSK 2018
Create a file in raw folder
keep.xml
<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:tools="http://schemas.android.com/tools"
tools:keep="#raw/*">
</resources>
That's it! It will keep all the files in raw folder, If you want to restrict it to only one particular file you can use
tools:keep="#raw/fileName"
Note that you should not add file extension in the end so it shouldn't be filename.html

Categories

Resources