getPackageName?

Is it possible to get app package name programmatically from an (android) Openfl app?
This is to be able to redirect the user to the url of the app on the playstore with a link like this:

http://play.google.com/store/apps/details?id=” + context.getPackageName()

The only way I know to get something out of project.xml file is like this:

<haxedef name="package" value="project.domain.tld" />

and then

import haxe.macro.Compiler;
...
Compiler.getDefine("package")

If you’re using a project.xml file, then pozirk’s solution is probably best. But if you’re using an include.xml file because you’re making a library or extension, then hard-coding won’t work.

include.xml can look up some variables using ${variableName}, but sadly, the package isn’t one of them.

Instead, you could use Context.getPackageName() to get it. However, this requires making a Java file, and if you’re making a Java file, there’s an easier option.

OpenFL processes Java files as templates, and templates have access to basically every variable. Just type ::META_PACKAGE:: in your Java file, and it’ll be replaced by the package. Add quotes so that Java recognizes it as a string, and return it.

Setting the value in project.xml isn’t a solution. I want to access the value programmaticaly, not to have to set it manually in the project.xml file (or in as a constant in any file)
I guess I would have to make my own extension just for that and make a JNI call…

With a simple tweak to ProjectXMLParser.replaceVariable(), you could skip the Java file entirely. Currently, this function only checks the defines and environment objects (which correspond to <set /> and <setenv />, respectively).

Adding a similar check for the app and/or meta objects would allow you to retrieve this value:

<haxedef name="packageName" value="${packageName}" />

Except that only works in project.xml, not include.xml. A library project will only be able to access its own app and meta objects, not those of the project that imports it.

Fortunately, I implemented a solution last June. Unfortunately, it’s gotten no attention since then. If this is something you want, head over there and voice your support.

Edit: I updated my pull request, and now it solves both parts of your problem. All you’ll have to do is type this:

<haxedef name="packageName" value="${parent:packageName}" />
stage.window.config.packageName

Correction:

stage.application.config.packageName

or

Lib.application.config.packageName

But yes, now that you mention it, this is an easier solution.

1 Like

You’re right, sorry about that :smile:

I’m open to putting more project.xml in config somehow, including the whole parsed project file, but I don’t want to needlessly burden runtime builds with too much data, so open to feedback :slight_smile:

Consider using @:extern inline variables. You can access them at compile-time, but they get removed at runtime. Simple demo:

class Test {
    @:extern public static inline var VAR_0:Int = 0;
    @:extern public static inline var VAR_1:Int = 1;
    public static inline var VAR_2:Int = 2;
    
    static function main() {
        trace(VAR_0);
    }
}
// Generated by Haxe 3.3.0
(function () { "use strict";
var Test = function() { };
Test.main = function() {
	console.log(0);
};
Test.VAR_2 = 2;
Test.main();
})();

VAR_1 is removed from the output regardless of the user’s DCE settings, but VAR_2 is only removed if DCE is enabled.

1 Like

Alternate idea!

As I mentioned above, templates have access to all kinds of information, and you can choose what information to include. That way, you can get what you need without increasing the filesize more than necessary. The hard part is getting the information out of the template; you’d have to implement something different for each platform.

On the other hand, text assets work the same on every platform. If you could put relevant data in, getting it back out would be simple.

Lib.application has no config public field. So trying to call Lib.application.config.packageName makes the app to crash

What version are you using, and are you using legacy mode?

I’m using the latest version and no, I’m not in legacy mode.
The correct solution is Lib.current.stage.application.config.packageName

openfl.Lib.application is an instance of openfl.display.Application.

openfl.display.Application extends lime.app.Application.

lime.app.Application.config is an instance of lime.app.Config.

lime.app.Config has a packageName field.

If you’re encountering a crash, definitely submit a bug report.