I use androidx.camera.camera2 library in my application. This library for SDK 21 and greater. But i want allow users start application for SDK 19 without camera2 support. I check SDK version in my code, but application crash on start. Can i exclude camera2 from dependencies for old SDK?
05-30 12:13:42.318 2000-2000/com.myapp.android E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.myapp.android, PID: 2000
java.lang.NoClassDefFoundError: android.util.Size
at androidx.camera.camera2.impl.Camera2DeviceSurfaceManager.<clinit>(Camera2DeviceSurfaceManager.java:53)
at androidx.camera.camera2.Camera2AppConfig.create(Camera2AppConfig.java:58)
at androidx.camera.camera2.impl.Camera2Initializer.onCreate(Camera2Initializer.java:44)
at android.content.ContentProvider.attachInfo(ContentProvider.java:1591)
at android.content.ContentProvider.attachInfo(ContentProvider.java:1562)
at android.app.ActivityThread.installProvider(ActivityThread.java:4790)
at android.app.ActivityThread.installContentProviders(ActivityThread.java:4385)
at android.app.ActivityThread.handleBindApplication(ActivityThread.java:4325)
at android.app.ActivityThread.access$1500(ActivityThread.java:135)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1256)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:136)
at android.app.ActivityThread.main(ActivityThread.java:5017)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:779)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:595)
at dalvik.system.NativeStart.main(Native Method)
I recently stumbled into the same issue.
Diving deep into the CameraX code I found that CameraX is initialized in app startup through a content provider. Here is the content provider code where CameraX is being initialized.
public final class Camera2Initializer extends ContentProvider {
private static final String TAG = "Camera2Initializer";
#Override
public boolean onCreate() {
Log.d(TAG, "CameraX initializing with Camera2 ...");
CameraX.init(getContext(), Camera2AppConfig.create(getContext()));
return false;
}
}
Im not very familiar with content providers but my first taught was, this is add at the manifest level? And indeed I was right.
Looking at there manifest I found this
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="androidx.camera.camera2">
<application>
<provider
android:name=".Camera2Initializer"
android:authorities="${applicationId}.camerax-init"
android:exported="false"
android:initOrder="100"
android:multiprocess="true" />
</application>
</manifest>
There manifest gets merged into ours which will include this content provider which in the other hand initializes CameraX, we want to avoid this. So one possible way of doing so is creating our own empty content provider and adding it to our manifest with the same name. This will override there content provider.
You can look into
https://developer.android.com/studio/build/manifest-merge
for more detail about manifest merging.
So now with there content provider overriden hopefully you can call
CameraX.init(getContext(), Camera2AppConfig.create(getContext()));
only when the feature gets called and not on app startup.
Im hoping this gets fixed in later versions and allows us to initialize cameraX when we want to.
Related
I need to check if card emulation is enable on a device. I found one method here:
boolean isDefault = CardEmulation
.getInstance(NfcAdapter.getDefaultAdapter(this))
.isDefaultServiceForCategory(
new ComponentName(this, MyPaymentService.class),
CardEmulation.CATEGORY_PAYMENT);
It looks like this works on some devices, but not for all devices.
For example, on the Samsung GT-I9300I (with Android 4.4), there is an NFC module, but it doesn't show the Tap-and-pay options in the settings.
When my app runs on that device I get the following error:
E/CardEmulation: This device does not support card emulation
09-26 16:41:13.592 2625-2625/? E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.android.settings, PID: 2625
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.android.settings/com.android.settings.nfc.PaymentDefaultDialog}: java.lang.UnsupportedOperationException
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2441)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2500)
at android.app.ActivityThread.access$900(ActivityThread.java:171)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1309)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:146)
at android.app.ActivityThread.main(ActivityThread.java:5679)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1291)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1107)
at dalvik.system.NativeStart.main(Native Method)
Caused by: java.lang.UnsupportedOperationException
at android.nfc.cardemulation.CardEmulation.getInstance(CardEmulation.java:159)
at com.android.settings.nfc.PaymentBackend.(PaymentBackend.java:53)
at com.android.settings.nfc.PaymentDefaultDialog.onCreate(PaymentDefaultDialog.java:57)
at android.app.Activity.performCreate(Activity.java:5582)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1093)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2405)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2500)
at android.app.ActivityThread.access$900(ActivityThread.java:171)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1309)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:146)
at android.app.ActivityThread.main(ActivityThread.java:5679)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1291)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1107)
at dalvik.system.NativeStart.main(Native Method)
However, according to the documentation, CardEmulation is available since API level 19 (Android 4.4).
So can anyone explain why I'm getting this exception? How can I overcome this problem?
The error is quite clear in the log output:
E/CardEmulation: This device does not support card emulation
This class can only be used on devices that support card emulation and AID-based routing configuration. This is also documented in the documentation of the class CardEmulation:
Use of this class requires the FEATURE_NFC_HOST_CARD_EMULATION to be present on the device.
Consequently, you must only use the method getInstance() on devices that actually support the HCE feature. Note that host card emulation is a bit misleading here since that feature is also required to manage routing configuration using an OffHostApduService declaration and to use the CardEmulation class for any operations related to OffHostApduService. So this feature applies to both, HCE and management of routing configuration for secure element based card emulation. However, some device manufacturers developed other mechanisms for testing for the availability (and potentailly also for managing the routing) of secure element based card emulation.
You can use the following code to check for the HCE feature before calling the CardEmulation.getInstance() method:
boolean isDefault = false;
if (getPackageManager().hasSystemFeature(PackageManager.FEATURE_NFC_HOST_CARD_EMULATION)) {
isDefault = CardEmulation.getInstance(NfcAdapter.getDefaultAdapter(this))
.isDefaultServiceForCategory(
new ComponentName(this, MyPaymentService.class),
CardEmulation.CATEGORY_PAYMENT);
}
I've modified my build.gradle to use different Application classes based on build-variant (debug / release).
I've added two WrapperApplication classes one in folder "debug", and the second in folder "release", both classes extend some base Application class.
In AndroidManifest I point to com.my.package.WrapperApplication and it indeed uses the correct one.
When releasing a test apk to Play, I got a pre-launch report that my new version crashed on 2 of the 13 devices tested (Moto G and Moto X).
Would love to know why is it crashing, and if something is wrong in the build, how is it working for me and for the other 11 test devices tested.
Here's the stack I received:
FATAL EXCEPTION: main
Process: com.my.package, PID: 16348
java.lang.RuntimeException: Unable to instantiate application com.my.package.WrapperApplication: java.lang.IllegalStateException: Unable to get package info for com.my.package; is package not installed?
at android.app.LoadedApk.makeApplication(LoadedApk.java:516)
at android.app.ActivityThread.handleBindApplication(ActivityThread.java:4398)
at android.app.ActivityThread.access$1500(ActivityThread.java:139)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1270)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:136)
at android.app.ActivityThread.main(ActivityThread.java:5102)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:785)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:601)
at dalvik.system.NativeStart.main(Native Method)
Caused by: java.lang.IllegalStateException: Unable to get package info for com.my.package; is package not installed?
at android.app.LoadedApk.initializeJavaContextClassLoader(LoadedApk.java:376)
at android.app.LoadedApk.getClassLoader(LoadedApk.java:329)
at android.app.LoadedApk.makeApplication(LoadedApk.java:508)
... 11 more
Thanks.
EDIT:
Previously we used the following method, but using the variant-specific folders is cleaner for our build system, so we'd love to switch to it.
Previous method:
AndroidManifest:
<application
android:name="${application}"
... />
build.gradle:
debug {
manifestPlaceholders = [application:".Application1"]
}
release {
manifestPlaceholders = [application: ".Application2"]
}
I don't know what is the reason for the issues. But we are doing a different approach:
We have base Application with common functionality and it also contains protected methods for future behaviour modification:
public class MyApp extends application {
public void onCreate() {
super.onCreate();
initLogging();
}
protected void initLogging() {}
}
We create another app in flavour or build configuration source folder and override behaviour:
public class DebugMyApp extends MyApp {
#Override
protected void initLogging() {
//init Stetho
}
}
We also create another AndroidManifest.xml in flavour or build configuration source folder where we override application name:
<?xml version="1.0" encoding="utf-8"?>
<manifest
package="com.philips.pins.ugrow"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<application
android:name=".DebugMyApp"
android:label="#string/app_name"
tools:replace="android:name,android:label">
<activity android:name="net.hockeyapp.android.UpdateActivity"/>
</application>
</manifest>
Sure extension of the app is not necessary and you can define two different app classes but just correctly define them in manifest files.
I am confused about the permissions section for IBM's MobileFirst GMS Push notifications found here. (Section 5)
https://developer.ibm.com/mobilefirstplatform/documentation/getting-started-7-0/notifications/push-notification-native-android-applications/
I have added all of these permissions verbatim, but im getting an error saying i havn't added manifest permissions. Do i need to modify the package names in these permissions?
Is this activity built in?
<activity
android:name="com.worklight.androidnativepush.AndroidNativePush"
android:label="#string/app_name"
android:theme="#android:style/Theme.Black.NoTitleBar"
android:launchMode="singleTask">
Here is the error logcat
07-25 23:24:48.285 17146-17146/? E/AndroidRuntime﹕ FATAL EXCEPTION: main
Process: com.companyname.hitch.mobilefirsttestapp, PID: 17146
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.companyname.hitch.mobilefirsttestapp/com.companyname.hitch.mobilefirsttestapp.push.PushActivity}: java.lang.RuntimeException: Your manifest is not allowed to work with push. Android Manifest Error: Missing permission in manifest: com.companyname.hitch.mobilefirsttestapp.permission.C2D_MESSAGE
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2184)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2233)
at android.app.ActivityThread.access$800(ActivityThread.java:135)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1196)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:136)
at android.app.ActivityThread.main(ActivityThread.java:5001)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:785)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:601)
at dalvik.system.NativeStart.main(Native Method)
Caused by: java.lang.RuntimeException: Your manifest is not allowed to work with push. Android Manifest Error: Missing permission in manifest: com.companyname.hitch.mobilefirsttestapp.permission.C2D_MESSAGE
at com.worklight.wlclient.api.WLPush.<init>(WLPush.java:180)
at com.worklight.wlclient.api.WLClient.getPush(WLClient.java:957)
at com.companyname.hitch.mobilefirsttestapp.push.PushActivity.onCreate(PushActivity.java:19)
at android.app.Activity.performCreate(Activity.java:5231)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1087)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2148)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2233)
at android.app.ActivityThread.access$800(ActivityThread.java:135)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1196)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:136)
at android.app.ActivityThread.main(ActivityThread.java:5001)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:785)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:601)
at dalvik.system.NativeStart.main(Native Method)
When creating a MobileFirst-based Hybrid app with the Android environment, MobileFirst will be creating it based on a template with a set of predefined permissions and activities.
In a native application, you are the one creating it. MobileFirst only supplies you with the SDK and a set of integration instructions.
The activity that you mentioned in the question (taken from the tutorial page) is the activity of the sample application included in the tutorial. In your own app's AndroidManifest.xml you will see your app's name instead of "androidnativepush" (or rather need to create it).
Make sure not to use "androidnativepush" anywhere unless that is your app name.
I'm seeing the following exception under Crashes in the dev console from time to time.
Whats puzzling about it is that google maps shows up in the call stack as if its calling or creating my app class - very confusing. Whats further weird is the "MyApp-2.apk" in the call stack - where it appends the "-2".
I do include the android.maps.jar file in the libs.
I would like to know how to recreate this if possible and how to prevent this from happening?
java.lang.RuntimeException: Unable to instantiate application com.MyApp.MyCustomApp:
java.lang.ClassNotFoundException: Didn't find class "com.MyApp.MyCustomApp"
on path: /system/framework/com.google.android.maps.jar:/data/app/com.MyApp-2.apk
at android.app.LoadedApk.makeApplication(LoadedApk.java:503)
at android.app.ActivityThread.handleBindApplication(ActivityThread.java:4405)
at android.app.ActivityThread.access$1400(ActivityThread.java:141)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1327)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:5059)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:792)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:555)
at dalvik.system.NativeStart.main(Native Method)
Caused by: java.lang.ClassNotFoundException: Didn't find class "com.MyApp.MyCustomApp" on path: /system/framework/com.google.android.maps.jar:/data/app/com.MyApp-2.apk
at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:61)
at java.lang.ClassLoader.loadClass(ClassLoader.java:501)
at java.lang.ClassLoader.loadClass(ClassLoader.java:461)
at android.app.Instrumentation.newApplication(Instrumentation.java:967)
at android.app.LoadedApk.makeApplication(LoadedApk.java:498)
... 11 more
Manifest Application Tag:
<application
android:name=".MyApp"
android:hardwareAccelerated="true"
android:icon="#drawable/app_icon"
android:label="#string/app_name"
android:theme="#style/AppBaseTheme" >
I'm using these JARS: android-support-v4-r2-googlemaps.jar + android-support-v4.jar
The prime reason why a Class within your application would be present on your test devices but missing at runtime on some others would be if your class has a dependency on some external feature which is missing on those devices. For example, if you used some Google API which is not part of AOSP and so missing on a plain AOSP build, or a vendor build which does not license these, then your class will be pruned at install time as its dependencies cannot be resolved.
A common reason for your app finding its way into such circumstances might be someone running an inconsistently assembled "custom ROM" on their device.
I use my library Projects ActiveAndroid for which you want to create a class:
import com.activeandroid.app.Application;
public class App extends Application {
#Override
public void onCreate()
{
super.onCreate();
}
}
on the emulator everything works fine, the data stored in the database and so on. but when you start the phone, the application crashes. and immediately.
Error:
01-29 12:55:19.027 14098-14098/com.skip.client.customer E/AndroidRuntime﹕ FATAL EXCEPTION: main
Process: com.skip.client.customer, PID: 14098
java.lang.NoClassDefFoundError: android.support.v4.app.ActivityCompat21$SharedElementCallbackImpl
at java.lang.Class.classForName(Native Method)
at java.lang.Class.forName(Class.java:305)
at com.activeandroid.ReflectionUtils.getModelClasses(ReflectionUtils.java:83)
at com.activeandroid.DatabaseHelper.onCreate(DatabaseHelper.java:46)
at android.database.sqlite.SQLiteOpenHelper.getDatabaseLocked(SQLiteOpenHelper.java:252)
at android.database.sqlite.SQLiteOpenHelper.getWritableDatabase(SQLiteOpenHelper.java:164)
at com.activeandroid.Registry.openDatabase(Registry.java:149)
at com.activeandroid.Registry.initialize(Registry.java:107)
at com.activeandroid.ActiveAndroid.initialize(ActiveAndroid.java:8)
at com.activeandroid.app.Application.onCreate(Application.java:9)
at com.skip.client.customer.App.onCreate(App.java:12)
at android.app.Instrumentation.callApplicationOnCreate(Instrumentation.java:1007)
at android.app.ActivityThread.handleBindApplication(ActivityThread.java:4473)
at android.app.ActivityThread.access$1500(ActivityThread.java:144)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1265)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:136)
at android.app.ActivityThread.main(ActivityThread.java:5146)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:732)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:566)
It looks like getModelClasses() in active android is trying to find a java class in your code that matches the model classes you would have specified in your AndroidManifest.xml. Can you please post your manifest? Specifically, I'm looking for a line like this:
<meta-data
android:name="AA_MODELS"
android:value="
com.example.myapp.Book,
com.example.myapp.Chapter,
com.example.myapp.Library
"/>
If classes Book, Chapter, and Library are not defined in your code, then you'd get the no-class-def-found exception.
Also, I'd recommend changing your app to have your custom app class derive from android.app.Application instead of from the ActiveAndroid app base class. And then explicitly initialize ActiveAndroid. This will allow you to have your own exception handling around ActiveAndroid.initialize() and then explore why your exception is being thrown. You can also use the debugger to step into the initialize() method and see where the exception is coming from.
import com.activeandroid.ActiveAndroid;
public class App extends android.app.Application {
#Override
public void onCreate()
{
super.onCreate();
// add your own exception handling around this. Not that you can do much
// in your app without a database, but at least you'd be able to log a
// meaningful error to the log so you can know details about the exception
// being thrown.
ActiveAndroid.initialize(this);
}
}