Android Views appear different when accessed via a JAR in libs - java

I'm working on a reusable library for Android. The library will include an Activity that developers can use in their apps.
The plan is to distribute the library as a JAR. Consequently, I'm laying out views at runtime in my Activity onCreate(), as I can't use XML resources.
However, I'm noticing this weird behavior where there are subtle size differences between my Activity in two contexts:
I'm running my project, directly launching the Activity (Manifest LAUNCHER definition).
I zip my project classes into a JAR, and import that JAR into another Android project (testing what other developers will do). This wrapping project fires an intent for my Activity.
Why would this be?
What I see is that the imported lib version (2) looks smaller. It's some kind of scaling factor that's being applied to the direct launch case (1) that isn't being applied to the imported lib.
I have tried:
making sure all my dimensions are in DiPs
converting my DiPs values to scaled View dimensions using getWindowManager().getDefaultDisplay().getMetrics() and TypedValue.applyDimension()

Related

How can I keep corresponding code in one place for several versions of the same app?

I am developing several song book apps with basically the same functionality. I have developed "Evening Light Songs" and "Wahrheits Lieder". The main things that change between the two apps are the images and the database.
Right now I have them in separate projects. When I find a bug or make an update, I have to go to each project and change my code. Is there a way to bundle the code that is the same in both apps into one place so I only have to change it once? Then I could have other classes specific to each app that I would change separately.
Thanks!

Create a symbolic link from inside the Android app's assets folder to its storage

I'm working on an android app in which the user can play multiple Unity games. However, achieving this simple aspect has proven to be too complicated with Unity, if even possible.
After analyzing how Unity on Android works, I understood that it uses a bunch of libraries (called libmain.so, libunity.so and libmono.so), these three libraries refer to the code of the actual game which is stored inside the apk of the android app, specifically in "assets/bin/Data/" directory. The directory is hard-coded inside the code of the libraries, and everything in the libraries is legally prevented from being changed.
So, in order to allow the users to play multiple games, I thought that I could place the game that the user currently wants to play inside the "assets/bin/Data" directory, and so when the Unity libraries want to start the game, they will find it in "assets/bin/Data" and will start it. And then when the user wants to play another game, I simply replace the files of the old game in "asseets/bin/Data" with the files of the new game, and the Unity libraries will thus play the other game, and so on.
However, this wouldn't work, because an android app is not allowed to modify its own apk.
So, to solve this problem, I thought that I could put the files of the game to be played somewhere in the external or internal storage of the app, and then add a symbolic link (shortcut) to those files inside "assets/bin/Data".
That way, when the libraries of Unity want to play the game, they will go to the "assets/bin/Data" directory, where they will find shortcuts to the actual game in the app's storage, and since I can freely change the content of the app's storage, then I will be able to replace the game on demand.
My question is: Is it possible to create a symbolic link (shortcut) from the app's assets to the app's storage?? If yes, how??
If anything is unclear please ask me to elaborate
Thank you
No, it's not possible to do this. The assets included in the APK are not expanded to be on the device filesystem. They are accessed in-place via the AssetManager APIs.
It would be an enormous security hole to allow an app to replace itself without the user knowing or bypassing the package installation path provided by the framework. If all you need to do is push down asset type updates (graphics, levels, sounds, etc.) then consider using an OBB or other downloadable asset to extend the app.

implementing android library project without subclassing all activities

I have created an Android project and set it as a library project in order to support a free and paid version of the App. The library project is set as a "...base" project and actually the paid version simply calls the base app including its Main Activity.
I need to make some changes to limit the Free version and I can easily override layout resources, but I'd like to know the simplest way to extend/override some of the Activities. Ideally, what I'd like to do is only subclass Activities where changes which limit functionality are required, but I'm hitting a few problems. My activities redirect to other activities within the App navigation and I'm finding that the error below is being generated:
03-11 13:54:10.068: E/AndroidRuntime(21264): android.content.ActivityNotFoundException: Unable to find explicit activity class {package.free/package.base.MainActivity}; have you declared this activity in your AndroidManifest.xml?
Obviously, I can add these to the manifest or I can abstract the redirects, but the 2nd option means that I need to subclass anything that can trigger a redirect or anything which can be the target of a redirect. Is there a simpler way?
I managed to get this all working as I wanted. It does mean you need to be quite specific with projects which are using a library project in terms of which object you want to instantiate (and the activities or fragments that are declared in the manifest). I posted this question purely because there's not enough information out there on how to actually implement this stuff. If there's sufficient interest I'll try to pull together a tutorial/blog to show the steps that I took to get this all up and running.

Allow my Android view to be embedded in other apps

In web-based development and Windows-based development it is possible to develop applets or components that other applications can embed in their own UI seamlessly. I have a component (derived from View) that does some real-time animation that I'd like other apps to be able to embed in their own views or activities. Is it possible to allow other apps to embed this component in them in such a way that, when my app is updated, the other apps will automatically exhibit the updated behavior in their embedded component?
If this is possible, I'm having a hard time figuring out the search terms to use to look up how to do this. How would one app go about embedding a view from another app, and what happens if that other app isn't installed?
You cannot directly allow embeding in the way of an iframe.
However, you could make your View a library project that other developers can include in their app, much like they include another company's SDK. To allow updating automatically, you will need to have your app installed in addition to theirs, and when making the library project, you will have to make a BroadcastReceiver that can react to broadcasts you send from your app to update the Views in other apps.
Your SDK can then receive these Broadcasts, and update your View accordingly.
You can make your current project as Library project. You add the Library project to the project you want use the custom View. Your custom View will be accessible in that project.
You can mark a project as Library project by going to Project Properties > Android and checking the appropriate checkbox.
You can create an app widget for your application, and that widget can be used by any application that acts as a widget host - which few do - but at least you could have it on your home screen. I wonder why this is not done more - that would be a killer feature for many applications.
https://developer.android.com/guide/topics/appwidgets/index.html
Gives more information.

Rendering an Android XML layout in Java

I'm building a Java application that is some sort of Android applications (APK files) analyzer.
One of the main features that the app will offer is a "preview" of an Android layout, hence I need an API that receives an Android layout XML and a few configuration arguments such as screen resolution and theme, and returns the rendered layout as it would appear on a device running the application (graphical consistency with the real Android platform is important) along with position data of the View objects (in order to allow the user to select a view by clicking it). At the first stage, I don't expect the feature to reflect layout changes that are made programmatically, but only the View objects and resource graphics defined in the XML.
The idea I have in mind is to use the source code of a layout editor, such as ADT's editor or DroidDraw, and integrate it into my framework, but then I was wondering - maybe a better way would be to use the android API itself to render the layout for me (this is better mainly because I won't need to rewrite my code for later versions of the OS).
So my question is: does the API allows such operations? Or is there an even better way?
Any suggestions and insights are welcomed :)
does the API allows such operations?
If by "java application" you mean an app that runs on your PC, then no. There's no straightforward way to even call anything in the Android API. I'd recommend you go with the first approach of integrating some existing source code.
That said, this is not a straightforward task either. Also, if you're analyzing an APK, you'll be working with binary XML files, not the easy-to-read plain text ones that you see when developing (which assumedly are what ADT/DroidDraw use). There may be source code out there to deal with that too.
You could also consider looking at the source for Android itself, but I imagine you'd have to re-implement a bunch of rendering code, so that's no easy way out either.
At the first stage, I don't expect the feature to reflect layout changes that are made programmatically, but only the View objects and resource graphics defined in the XML.
Reflecting the layout changes made programmatically will be virtually impossible to do in a reasonable way.
This task is definitely possible, however, it's not straightforward at all. I would suggest taking a look and Android Studio's source code, more specifically there is a tool called LayoutLib.
This is the tool that the IDE's layout preview/editor uses to render layouts. You can use this to render layouts and views that you have the source code for. Unfortunately, it's not very well documented, so you have to figure out the usage from IDE's sources.
The open source Itsnat has a way to render loaded XML Android Layout files directly. it has a sample app that compares the standard (binary compiled) versions with the dynamic. My work with it shows that it does a good job reproducing all the quirks of LinearLayout/Relativelayout, etc. https://github.com/jmarranz/itsnat

Categories