I'm using the jexcel api in my android application. It works great on devices running Android 2.2, but any other device just gives a blank String when I try to get the contents of a cell.
I've narrowed the thing thats not working to the Cell.getContents() method in the jexcel api. All android version below 2.2 are able to get the workbook, get the sheets, get the number of sheets, and they can get the cells, but when trying to get the contents within that cell, it return a blank string.
Is there something wrong with the library, or is it an android problem
My guess is that FroYo added in support for some new Apache Harmony class or method (JavaSE-compatible) that JExcel depends on. In earlier versions, JExcel happens to catch the exception that's thrown and quietly fail. However, this is just a guess.
Since JExcel is open source, you could examine the source code to that method and see what turns up. Or, you could temporarily add the JExcel source code to your project (since I'm guessing you're using a JAR right now), and you'll probably get a compile-time error regarding the missing class or method.
This is all a guess, though.
Related
No comments about security concerns please, this is a very specific use case.
I am building an Android app that has two native libraries. We'll call them libFooA.so and libFooB.so. Now, libFooA.so is bundled inside the APK. However, it depends on libFooB.so, which is NOT bundled inside the APK. Instead, it is dynamically loaded from the internal storage at runtime using System.load().
Now, because libFooA.so depends on libFooB.so, I have to load libFooB.so first, (using System.load()) before I can load libFooA.so with System.loadLibrary(). Otherwise, I get this error:
dlopen failed: cannot locate symbol "SOMESYMBOL" referenced by "libFooA.so"...
Anyway so, this works perfectly on every single device running Android 6.0/7.0/8.0 that I have tested. However, it fails on every single KitKat device that I have tested. This led me to suspect that the issue was with Dalvik vs. ART. So I switched a KitKat device to ART through Developer Options and tried again, but it still fails. The perplexing thing is, the error that is thrown is exactly the same error that is thrown if I try to load libFooA.so before libFooB.so on a 6.0/7.0/8.0 device.
Additionally, the problem does not lie with System.load() itself on KitKat, as I have been able to successfully dynamically load and use native libs on KitKat before. The issue here is when trying to System.loadLibrary() a lib that depends on another lib which was loaded with System.load().
I have not yet been able to test on a Lollipop-based device, but I suspect it would work fine. Anyone know why KitKat is having an issue here? Is this a known bug with KitKat?
UPDATE: Fails on 4.4/5.0 ARM Android emulator. Works on 6.0 ARM Android emulator.
UPDATE 2: I think the answer lies on this page, could someone point me to which exact item causes the behavior change that lets this work on >= API 23?
My current phone (Pixel 2 XL) is running the build PQ1A.181105.017.A1. According to source.android.com, that means it was build from branch android-9.0.0_r16. Looking at a source file from that particular branch, for example SignalStrength.java, there is a public method called getWcdmaRscp(). However, it appears this method was added after SDK version 28 was released, so if I try to call it from my app in Android Studio when targeting 28, it doesn't build.
I'm guessing my phone will gladly allow me to call the method in question, so how do I setup my Android Studio to be able to build against that version of the framework?
It appears I would need a new framework.jar, but where can I find that? Please don't tell me I need to download and build the entire AOSP thing locally.
I doubt it was added after API 28 was released. It's annotated with #hide which means, when the SDK was built, it wasn't built in. It's still in the framework itself, but Android Studio doesn't know that.
To get around this, you'll have to use reflection. Something like:
try {
Method getWcdmaRscp = SignalStrength.class.getMethod("getWcdmaRscp");
int rscp = Integer.parseInt(getWcdmaRscp.invoke(signalStrength).toString()); //signalStrength is the instance you have
} catch (Exception ignored) {}
However, that probably won't work. Android Pie introduced restrictions on accessing hidden methods and classes. In Oreo, you could just use reflection. In Pie, most of the classes you try to access will throw a ClassNotFound or NoSuchMethodError exception, because the system prevents third-party apps from accessing them. Certain hidden APIs are still accessible, but there's no definitive list.
You don't need the whole framework.jar
While one way would be to use reflection as TheWanderer suggested, another option is to add the single source file you linked to, SignlaStrength.java, to your project.
You just need to make sure you add it under the original package path /android/telephony
The studio will use it for compilation to resolve method signatures, but when running on the phone the calls will go through to the original framework class.
I didn't see any non public imports in the file, but if it does not compile, you may need to turn it in to a stub, by removing some function internals.
My question is a follow up on: How can I calculate progress with HttpClient PostAsync?
This solution works perfectly. Just remember, if you are using Xamarin, to include the Microsoft.Net.Http nuget package in the .iOS project otherwise you'll get a TypeLoadException when initialising this class – Davide Vosti Oct 27 '15 at 6:47
I'm working with a Xamarin PCL project. This works perfectly on iOS.
I run into problems on droid. I'm targeting 4.4, however, the MSFT HTTP.Net droid package targets 7.1 and I get the expected TypeLoadException. Any workarounds (that keep me at 4.4)?
Thanks, D
Not an answer to the question, but I've hit the same problem here today trying to add upload progress support by extending HttpContent, using Xamarin with a core PCL project and Xamarin Android (there's also an iOS project using the core). I'm adding some extra detail in this post rather than creating a duplicate SO post.
When I'd tried any of the proposed solutions on StackOverflow (including the one the original poster had linked to) that extend from HttpContent, I'm getting an exception of:
System.TypeLoadException: Type Test.Project.FileService+CustomStream has invalid vtable method slot 6 with method none
Which I'm guessing is the same problem they're seeing. I'm not including Microsoft.Net.Http in the PCL/Android project, but we are using System.Net etc.
When I'd tried deriving from StreamContent instead, while that didn't crash, breakpoints were only hit for the contructor and TryComputeLength, but not SerializeToStreamAsync, though the data was successfully uploaded to the server without that being hit.
This is a legacy app I'm working on targetting Android 4.4 too. While I've managed to have this kind of thing working on platform specific (Xamarin.Android) in the past, that would be a much bigger change to this app so ideally would like to be able to get this working in the PCL
Background
I wanted to simplify the usage of DB in an Android app.
For this, I've compared some third party libraries that create a DAO layer.
I've come up with a nice library called "GreenDao" (presentation about it here) . The website shows that it's faster than other competitors (like ORMLite) and is optimized for Android.
The problem
For some reason, on some device (usually old devices, with GB) , I get the next console error when trying to install the app:
Installation error: INSTALL_FAILED_DEXOPT
Please check logcat output for more details.
Launch canceled!
I've searched for the reason of this error, but couldn't find out how to solve it. Many complain about this error, but I can't find out why it occurs, and what can be done.
The error is quite common and known, but it's never mentioned as the result of using this library, yet when I remove the usage of this library, everything works fine...
Also note that on newer devices (like nexus 4) it installs and works just fine, and that the sample itself also works fine no matter which device I test it on.
The question
Why does it occur?
Is it possible that the structure of the classes is just too much for old devices to load, since we use other libraries ?
Could it be that I've reached the limit of code that is supported by android apps?
The jar file itself takes just 87KB ...
How can I solve this?
Ok, I've found the problem and the solution:
It has nothing to do with GreenDao.
It's because the app uses too many jars, so maybe Android has a limitation of code.
The solution is to either delete un-needed jar files or delete a lot of code.
I just started testing my app on android 1.5, and it doesn't want to run at all. I have a breakpoint in onCreate on my main activity, but I get a ClassNotFound exception even before reaching that. The class not found appears to be the class of my main activity. The exception happens in:
ActivityThread.performLaunchActivity
It runs fine on 1.6 and later, so I assume I'm using something that isn't supported on 1.5. But how can I find out what it is? Any tips on how to debug this would be greatly appreciated.
Thanks.
If you have imported jars, verify that they are in the /libs directory and not in the /lib directory and they are imported as jars and not as external jars
I had the same problem today. It's difficult to identify which class is not supported. The stack trace doesn't really shed any light on it, it just gives the somewhat misleading message that your activity class cannot be found. A couple API's that I have used that I know are not in Android 1.5 are:
- Bluetooth (2.0 and up)
- Text to Speech (1.6 and up)
I ran into this issue because I added support for text to speech to my app and didn't think to check the docs first to make sure text to speech is supported on Android 1.5. I was dismayed to learn it was only added in Android 1.6. To work around the problem I had to do a couple things:
Remove the "import android.speech.tts.*" from my activity
Create wrapper classes that mirror the text to speech API and call the real text to speech classes from there.
Put if statements around the calls to my wrapper class to make sure I only call out to it if the Android SDK level is 1.6 or above. You can check the Android SDK level by inspecting android.os.Build.VERSION.SDK
In your Android Market listing, indicate that the text to speech functionality is only available if you have Android 1.6 or higher installed.
The nice thing about this approach is that in the future, when I decide to abandon support for Android 1.5 I can easily change my calls to my wrapper class to just call the text to speech API directly and rip out the wrapper classes.
I did something similar for my Bluetooth code.