I have just created a splash screen in my cordova project. I was able to build and run my project initially and my splash screen was displaying. However, when I added in the cordova.jar into the project library to serve as a file dependencies for my webservice function. I kept having this syntax error in my SplashScreen.java:
error: cannot find symbol variable CORDOVA_VERSION
Following is a snippet of my code:
import org.apache.cordova.*;
import org.apache.cordova.CallbackContext;
import org.apache.cordova.CordovaPlugin;
import org.apache.cordova.CordovaWebView;
public class SplashScreen extends CordovaPlugin {
private static final String LOG_TAG = "SplashScreen";
// Cordova 3.x.x has a copy of this plugin bundled with it (SplashScreenInternal.java).
// Enable functionality only if running on 4.x.x.
private static final boolean HAS_BUILT_IN_SPLASH_SCREEN = Integer.valueOf(CordovaWebView.
CORDOVA_VERSION.split("\\.")[0]) < 4;
private static Dialog splashDialog;
private static ProgressDialog spinnerDialog;
private static boolean firstShow = true;
....
Could I receive some help to solve this issue please?
I don't know what you are trying to do exaclty but you can't do that.
You just can't CordovaWebView.CORDOVA_VERSION.
If you really want to know what version you use programmatically, you can use this plugin
Otherwise you can just do that
PackageManager packageManager = this.cordova.getActivity().getPackageManager();
System.out.println(packageManager.versionName);
or
PackageManager packageManager = this.cordova.getActivity().getPackageManager();
packageManager.getPackageInfo(this.cordova.getActivity().getPackageName(), 0).versionName;
Dont forget to surround with try/catch.
Related
I have an app that run as a launcher, in Android 4 in work great but in Android 7 and 8 the select launcher dialog not appear
//
// Decompiled by Procyon v0.5.36
//
package com.r7developers.unityplugin;
import android.os.Build;
import android.annotation.TargetApi;
import android.os.Process;
import android.app.AppOpsManager;
import android.content.Intent;
import com.rvalerio.fgchecker.AppChecker;
import android.content.Context;
public class Plugin
{
static Context mContext;
static String mBundleIdentifier;
static AppChecker mAppChecker;
public static void init(final Context context, final String bundleIdentifier) {
Plugin.mContext = context;
Plugin.mBundleIdentifier = bundleIdentifier;
}
public static void start() {
Plugin.mAppChecker = new AppChecker();
Plugin.mAppChecker.other((AppChecker.Listener)new AppChecker.Listener() {
public void onForeground(final String packageName) {
if (packageName != null && !packageName.contains(Plugin.mBundleIdentifier)) {
final Intent startHomescreen = new Intent("android.intent.action.MAIN");
startHomescreen.addCategory("android.intent.category.HOME");
startHomescreen.setFlags(268435456);
Plugin.mContext.startActivity(startHomescreen);
}
}
}).timeout(1000).start(Plugin.mContext);
}
public static void stop() {
Plugin.mAppChecker.stop();
}
public static void requestUsageStatsPermission() {
if (needsUsageStatsPermission() && !hasUsageStatsPermission()) {
Plugin.mContext.startActivity(new Intent("android.settings.USAGE_ACCESS_SETTINGS"));
}
}
#TargetApi(19)
public static boolean hasUsageStatsPermission() {
final AppOpsManager appOps = (AppOpsManager)Plugin.mContext.getSystemService("appops");
final int mode = appOps.checkOpNoThrow("android:get_usage_stats", Process.myUid(), Plugin.mContext.getPackageName());
final boolean granted = mode == 0;
return granted;
}
public static boolean needsUsageStatsPermission() {
return Build.VERSION.SDK_INT >= 21;
}
public static void openSettings() {
final Intent intent = new Intent("android.settings.SETTINGS");
intent.addFlags(268435456);
Plugin.mContext.startActivity(intent);
}
}
This code is decompiled from a jar plugin from unity project
Is there anything I'm missing?
Your problem must be caused by some missing line in the manifest.
Android evolve really quickly and some application originally made for older version might not work anymore due to changing in the permission system.
That must apply to the Android Manifest as well. By luck you got it working on an older device, but it seems that handling newer ones is problematic.
Have you tried to recompile a way smaller version of the code and test it on multiple version ?
Just by looking at some exemple launcher (but made without the Unity Engine), can help you understand if you have miss something.
Here is a link to an Android Launcher I found (the first one) on GitHub: KISS/app/src/main/AndroidManifest.xml.
Try adding the line that you are missing from your, especially the intent-filter that help Android know what your apps should be aware of when showing it in menus, like the Launcher selector.
I am not an expert, but I know that working with Android can be a pain.
I create the following class:
public class GlobalVariables
{
public static string databasePath = FilesDir.Path;
private GlobalVariables()
{
}
}
But FilesDir.Path is underlined with red and it doesn't allow me to import its namespaces to use it. When I use it in some Activity I'm able to but when I'm trying to use it in a class like that I'm not able to. With that class I'm trying to get the apk folder path of the project.
How to use FilesDir.Path property outside Activity(Xamarin.Android)?
You need using a Context to implement this feature:
public class GlobalVariables
{
public static string databasePath = Android.App.Application.Context.FilesDir.Path;
...
}
Furthermore, you could refer to: What is 'Context' on Android?
I'm running some tests with Roboletric, but I came across a issue that I can't solve.
When I run the test, the following error appears with the "AndroidManifest":
WARNING: No manifest file found at .\AndroidManifest.xml.
Falling back to the Android OS resources only. To remove this warning, annotate
your test class with #Config(manifest=Config.NONE).
No such manifest file: .\AndroidManifest.xml
I've tried these solutions that failed:
#Config (manifest = Config.DEFAULT_MANIFEST_NAME)
#Config(manifest = Config.NONE, constants = BuildConfig.class, sdk = 26)
#Config( constants = BuildConfig.class, manifest="src/main/AndroidManifest.xml", sdk = 26 )
And the other error during execution is:
android.content.res.Resources$NotFoundException: Unable to find
resource ID #0x7f09001b in packages [android, org.robolectric.default]
...
at
com.example.robertoassad.alltestsmerge.MainActivity.onCreate(MainActivity.java:52)
This line that have the error is the following code:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Specifically in: setContentView(R.layout.activity_main);
For me I didn't see sense in this issue ...
DETAILS:
The test class is on the folder: app\src\test\java\com\example\robertoassad
The test is:
#RunWith( RobolectricTestRunner.class)
public class Roboletric {
#Test
public void clickingLogin_shouldStartLoginActivity() {
MainActivity activity = Robolectric.setupActivity(MainActivity.class);
activity.findViewById(R.id.button2).performClick();
Intent expectedIntent = new Intent(activity, SecondActivity.class);
Intent actual = ShadowApplication.getInstance().getNextStartedActivity();
assertEquals(expectedIntent.getComponent(), actual.getComponent());
}
}
I had a similar problem to the one you face. The post by jongerrish on the Robolectric GitHub Issue about this resolved the problem for me.
The aspect of the answer that worked for me was to add a testOptions block in my module's build.gradle file:
testOptions {
unitTests {
includeAndroidResources = true
}
}
After adding this block my tests were able to run and access String resources.
This problem bug me for some time, and here is my note in my test code.
About manifest location
With Gradle build system, Robolectric looks for AndroidManifest.xml in the following order.
Java resource folder
build/intermediates/manifests/[full or fast-start]/[build-type]
So it is a common mistake to specify the location of AndroidManifest.xml according to source code folder organization (e.g. src/main/AndroidManifest.xml) . The specified AndroidManifest.xml location affect how Robolectric look for merged resources as well. So if some resource is not found in test, it is probably due to incorrect setting of AndroidManifest.xml location.
That said, the Android Gradle plugin merge the AndroidManifest.xml and put the result under the above mentioned intermediates directory. So the content of src/main/AndroidManifest.xml affect the test result.
So if you want to specify manifest option in #Config, just use #Config(manifest=“AndroidManifest.xml”) should probably be fine. If you want to use an alternate AndroidManifest.xml, put it in Java resources folder, and specify #Config according to the relative path in resources folder.
I was also facing same problem while testing my library module from app. Now my Receievers and Service are in my library, so to test those , i had to implement custom Test Class, so Roboelectric can point to my library manifest and not the app manifest :
import android.os.Build;
import org.junit.runners.model.InitializationError;
import org.robolectric.manifest.AndroidManifest;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.annotation.Config;
import org.robolectric.res.Fs;
import java.io.File;
import java.io.IOException;
public class RobolectricGradleTestRunner extends RobolectricTestRunner {
private static final String PROJECT_DIR =
"C:/MyProject/";
private static final int MAX_SDK_SUPPORTED_BY_ROBOLECTRIC =
Build.VERSION_CODES.JELLY_BEAN_MR2;
public RobolectricGradleTestRunner(final Class<?> testClass) throws Exception {
super(testClass);
}
private static AndroidManifest getAndroidManifest() {
String manifestPath = PROJECT_DIR+"/src/main/AndroidManifest.xml";
String resPath = PROJECT_DIR+"/src/main/res";
String assetPath = PROJECT_DIR+"/src/main/assets";
System.out.print("manifest path: "+manifestPath);
System.out.print("resPath path: "+resPath);
System.out.print("assetPath path: "+assetPath);
return new AndroidManifest(
Fs.fileFromPath(manifestPath), Fs.fileFromPath(resPath), Fs.fileFromPath(assetPath)) {
#Override public int getTargetSdkVersion() {
return MAX_SDK_SUPPORTED_BY_ROBOLECTRIC;
}
};
}
private static String getProjectDirectory() {
String path = "";
try {
File file = new File("..");
path = file.getCanonicalPath();
path = path + "/app/";
} catch (IOException ex) {}
return path;
}
#Override public AndroidManifest getAppManifest(Config config) {
return getAndroidManifest();
}
}
and use it in your test class like :
#RunWith(RobolectricGradleTestRunner.class)
public class MyClassChangeTest {
}
I just want to test that getting a String resource equals what I think it should equal. My issue seems to be that I have Realm in my project. I know that Robolectric doesn't support Realm (it states it in the documentation), but I'm not invoking Realm at all, so I feel like there might be a way to do this.
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.RuntimeEnvironment;
import org.robolectric.annotation.Config;
import static org.junit.Assert.assertEquals;
#RunWith(RobolectricTestRunner.class)
#Config(constants = BuildConfig.class, sdk = 21, manifest = "app/src/main/AndroidManifest.xml")
public class ResourceTester {
#Test
public void testingString() {
String resourceString = RuntimeEnvironment.application.getString(R.string.app_name);
assertEquals(resourceString, "Yeah");
}
}
It does look like it IS trying to invoke Realm
java.lang.UnsatisfiedLinkError: Can't load library:
/var/folders/3x/ddxtg5fs1hxgqrp6h63vsc140000gp/T/android-tmp-
robolectric3612430387389787158/app_lib/librealm-jni.dylib.3.5.0
EDIT: I tried some more things, and it seems like setting the manifestin the #Config annotation is the issue, but then I get a android.content.res.Resources$NotFoundException: unknown resource 2131362072
Any other thoughts? Can I make another Application class where Realm isn't called? How would the /test directory know that?
EDIT FOR DAVID:
I tried this:
#RunWith(RobolectricGradleTestRunner.class)
#Config(application = TestingApplication.class, constants = BuildConfig.class, sdk = 21)
public class ResourceTester {
#Test
public void newTestingTests() throws Exception {
String appName = RuntimeEnvironment.application.getString(R.string.app_name);
}
}
but I get a:
android.content.res.Resources$NotFoundException: unknown resource 2131362072
If I change it to
#RunWith(RobolectricTestRunner.class)
//#RunWith(RobolectricGradleTestRunner.class)
#Config(application = TestingApplication.class, constants = BuildConfig.class, sdk = 21)
public class ResourceTester {
#Test
public void newTestingTests() throws Exception {
String appName = RuntimeEnvironment.application.getString(R.string.app_name);
}
}
I get
WARNING: No manifest file found at ./AndroidManifest.xml.Falling back to the Android OS resources only.
To remove this warning, annotate your test class with #Config(manifest=Config.NONE).
android.content.res.Resources$NotFoundException: unknown resource 2131362072
If you have a heavyweight Application class (e.g., with dependencies on Realm, Crashlytics etc.) and your unit tests do not refer to these you can use android.app.Application as your Application class in the config:
#RunWith(RobolectricTestRunner.class)
#Config(application = android.app.Application.class, manifest="src/main/AndroidManifest.xml", sdk = 23)
public class ResourceTester {
Also make sure you have Working Directory set to $MODULE_DIR$ if you are using Mac or Linux as per the getting started instructions
When compiling the following example from the robolectric migration guide
package com.jongla.soundmash.robolectric
import org.robolectric.shadows.ShadowApplicationPackageManager
import org.robolectric.annotation.Implements
import android.app.ApplicationPackageManager
#Implements(value = ApplicationPackageManager.class, inheritImplementationMethods = true)
class MyCustomPackageManager extends ShadowApplicationPackageManager {
}
AndroidStudio is giving me Unresolved reference: ApplicationPackageManager. Does anyone know what I need to do to get this example to compile? Do I need some additional testCompile package in gradle?
When I was looking through Roboloectric source code, I ve spotted attribute className to specify class name instead. And it works like magic.
#Implements(className = "android.app.ApplicationPackageManager", inheritImplementationMethods = true)
public class MyCustomPackageManager extends ShadowApplicationPackageManager {
}
Migration document is clearly incorrect, when suggesting to use value as ApplicationPackageManager class is private and not visible for user code.