Accessing assets of main application inside package - android

i'm currently trying to develop a package for a Flutter App, with Kotlin. My issue is that I need to provide the package with a config file, which should only be defined inside the main App. Since the config differs for the Dev and Prod environment, the app should pass through the path of the File via the Method Channel. The problem is that the package isn't able to access the assets folder of the calling application.
Path: "assets/config.json" (the root being the main application)
Steps I already tried:
Creating the file inside the res/raw & accessing the config file through a ressource id -> Kotlin gives me an "Unresolved reference" error, unless I create the file inside the packages res/raw
Instead of passing through the path, I tried passing through the content of the config & writing it into an empty temporary file. The code in Kotlin like this:
val config = File(applicationContext.filesDir,"config.json")
config.writeText(configContent)
-> This works, but it seems like a weird solution to the problem.
please let me know if I need to provide further information & thank you in advance!
edit:
The Java Method that is called during initialisation:
public static void createMultipleAccountPublicClientApplication(#NonNull final Context context,
#NonNull final File configFile,
#NonNull final IMultipleAccountApplicationCreatedListener listener)

Flutter assets aren't files - they are packaged up and only available through the rootBundle. So, if you want to make a file from a text asset, someone has to load the asset and write it to a file.
As your plugin user will be in charge of the asset, they will have to do the first part (and will end up with a String). The question arises of who should do the writing.
You could make the plugin user use path_provider to find the temporary directory and write it there and then pass you the file path. Eventually, down in the Java, you new File(theTempFilePath). Or they could pass the string to the Dart half of your plugin and you create the temp file in the same way.
It's probably more convenient if they pass your plugin the string, you pass that to the native side and have the native side create a temporary file and write the string there. (BTW, I assume we are talking about this config file: https://learn.microsoft.com/en-us/azure/active-directory/develop/msal-configuration#how-to-use-a-configuration-file )
See this answer for creating temporary files: Creating temporary files in Android
Note that there's actually no reason that your plugin user then needs to use an asset. They could, instead, just hard code the string in their code if the configuration never really changes.
There's an argument that as this is a JSON configuration file, you may not want to bother your user with the details of this JSON configuration file. You may want to default it in your Dart code (why not hard code it as a string, as above, if it never really changes) and then provide some methods to override particular values like the client id and the redirect uri, which may be the only things that users ever change in practice. So rather than making them supply a complete JSON file, they just give you those two strings and you plonk them into your default JSON. Maybe a version 2 feature :)

Related

Add XML Serialized object to APK so it is copied into the app's private files directory

I have a desktop application that produces resource / data files for my android app. These are XML text files that store instances of my custom data class. These objects are serialized using the Simple XML Serialization library. In my android app, I'd like to instantiate objects from this XML serialization class.
I like to add these xml files to Android Studio so they are included in the APK on device install and are placed, for example, in the private app directory "files", to which getFilesDir() is mapped. I can't find a way to do that.
If I add these xml files to the Android XML resource folder, I need to use Android's XML resource parser, and can not use the Simple XML library.
Any tips? I feel I made a wrong design choice seeing how restrictive the resource bundling is.
Thanks, Kind regards,
Harmen
As per CommonsWare's comment: the solution was adding it to the raw resource folder, then you can access it using:
InputStream xmlExerciseInputStream = getResources().openRawResource(R.raw.myresource);
MyClass myClass = serializer.read(MyClass.class, xmlExerciseInputStream);

How to dynamically add stickers in the whatsapp-sticker pack [Android][Unity-Android plugin]?

I have used the repo to make an android plugin for my unity game, wherein I reward the player with some stickers at each level. So basically Im successful in calling the add sticker function from the android plugin and can add the sticker pack according to the desired identifier and name. (Here the contents.json, is already in the aar.)
But since i now need to edit the contents.json (we cant modify .aar files) so i copy the assets file content checkout the content provider code https://pastebin.com/urhXTs7z
And now the contents.json is in my Android/data/packagename/files/
From Unity I deserialize and serialize that json and just add items to the sticker pack list. And then overwrite the contents.json if (Application.platform == RuntimePlatform.Android)
{
System.IO.File.WriteAllText(Application.persistentDataPath + "/contents.json", contents);
}
It works for the original contents.json but after updating the stickerpack, the new items are not read by the ReadContentFile function
But this doesnt work, the plugin just reads the original contents.json. (Because copy assets is called in OnCreate, I tried using sharepreferences of android to call the copyassets function only once. But then my app crashes.)
I found people with similar questions here : https://github.com/WhatsApp/stickers/issues/340
But im not able to figure out what to do.
I dont know even it is possible to handle stickers addition dynamically when the code is inside a plugin.
Please refer to the code in the pastebin link
Would love any suggestions to alternative methods to do this.

Accessing large number of JSON assets with Flutter

I'm working on a prototype app that would read and display data from a large repository of JSON files. I'm currently wondering about the best way to model this behavior in the pubspec.yaml and the in the flutter code itself.
Right now I'm initially loading a catalog file in JSON, this creates a scrollable listview of catalog entries, each of those has its own JSON file in a subdirectory (relative to the catalog file). Do I need to add each new file to the pubspec.yaml, or can I just directly access them.
You could also just access files in the file system without specifying the files in the pubspec.yaml.
Im not sure, if the syntax is still correct, because it is an old project I worked on but it should work in a similar way.
File _themeFile;
Future<Null> _loadThemeFile() async {
String dir = (await PathProvider.getApplicationDocumentsDirectory()).path;
_themeFile = new File('$dir/theme.txt');
if (!await _themeFile.exists()) {
_themeFile.create();
await _themeFile.writeAsString(JSON.encode({
'theme': 'dark',
'colorIndex': 0,
'displayDone': true,
}));
}
}
This snippet looks for the file with the name theme.txt and returns it. If it does not exist, it creates the file. You wouldn't probably need this exactly like that, but I think you can use it as a starting point.

How to store resource file with same name but different extensions in android

I am working on one static custom Android Media Player Application where i have many media files stored in raw folder.
Where as some files have same name but different extensions, here android is giving me
res\raw\then.mp4:0: error: Resource entry then is already defined.
res\raw\then.mp3:0: Originally defined here..
Can anybody please suggest me something on this?
Also there are few media files with java keywords like if, else, return, switch, case,class, else, final, long, new, this,true... where android is giving me error of invalid symbol.
Please suggest me solution for that also.
Thanks in advance...
As #blackbelt said, it's not possible, I'll just add that you can instead put your files in the assets directory instead of res.
You will not be able to use them like R.id.file, but you will get more flexibility.
simply you can't. Raw is build at compile-time inside R.java, and the name key must follow the java convention for naming. Since
if, else, return, switch, case,class, else, final, long, new,
this,true
are reserved keywords you can not use them.
Edit: R.java would look lie:
public static final class raw {
public static final int if=0x70000;

what R.java file actually does and how

I have been working on a simple android tutorial and while browsing through the project folders I found this R.java file in gen folder...
When I opened it seemed to me as a mess...
first R itself is a class.
it had multiple Inner classes defined within eg drawable,id,layout,etc.
and that inner classes had lots of variables declared as below which were assigned with hex values
public static final int addr=0x7f080003;
...
...
and much more
R is auto generated and acts as some pointer for other files
Questions for R.java
what it is basically for
how it works
why
values are in hex
what role did it performs while the actual application is running
"Acts as some pointer to other files" is actually absolutely correct, now the question is which files it points to how it is done.
What does it contain?
R file contains IDs for all the resources in the res folder of your project and also some additional IDs that you define on your own (in the layouts, for example). The IDs are needed for the Android resource management system to retrieve the files from the APK. Each ID is basically a number which corresponds to some resource in the resource management system.
The file itself is needed so you can access or reference the resource from code by giving the ID of the resource to the resource manager. Say, if you want to set the view in the activity, you call
setContentView(R.layout.main);
main in the R file contains the number which is understood by the Android resource management system as the layout file which is called main.
Why is it better than just plain file names?
It's harder to make a mistake with the generated fields. If you write the field name incorrectly, your program won't compile and you will know that there's an error immediately. If you write an incorrect string, however, the application won't fail until it is launched.
If you want to read more on this topic, you should check the Android documentation, especially the Accessing Resources part.
This holds your resource ids. So when you do something like
TextView tv = (TextView) findViewById(R.id.mytextview);
it looks up your id here for that View, layout, etc... This way the app has an easy way to look up your ids while you can use easy to remember names. Anytime you create a resource it automatically creates an id for it and stores it here. That's why you never want to try and edit this file yourself.
One way to think about how valuable R.java is, imagine a world without it. Its amazing how android brings the xml and java world together to help avoid coding the UI manually completely. With legacy java building UI using the java language was a pain. Invaluable.
With Android you can not only build your UI using only xml, but also see it while you build it. Invaluable.
Every element in the xml can be referenced in the java code WITHOUT writing a single line of code to parse the xml :). Just R.id.nameOfElement. Invaluable.
Rapid development is beautifully done in android. Imagine if iPhone would have 5000 screens to fit that one piece of code, they would crumble on their XCode. Google has done a wonderful job with just R.java. Invaluable.

Categories

Resources