The project I'm working on requires that N stand-alone applications can be built but also an extra big application with a selection menu that will execute one of those.
The difference between these applications is mainly resources and XML, so they all use a common library which reacts to assets and the information provided in the XML.
The problem is regarding the "mother" application. It has to be able to use the common library using one of the stand-alone resources set. I realized I can access another application resources using:
Resources R2 = getPackageManager().getResourcesForApplication("com.example.appa");
int id = R2.getIdentifier("image", "drawable", "com.example.appa");
Drawable myDrawable = R2.getDrawable(id);
And this actually solves the issue, I can supply a package string to the library so it will know where to look for the resources.
Problem is, in order for this to work, I need to have those stand-alone applications installed on the device, and that's something I cannot do (think of it as a quiz application, the stand-alone apps are only one topic while the "mother" app allows access to all different topics and, as far as I'm aware, Android Market won't allow downloading all apps and installing them just so I can access their resources).
Conceptually speaking, this issue would be solved if I could make those stand-alone applications as libraries and adding them to the mother app. The mother app would then use a package string depending on user choice and then use the library. So far I haven't been able to work this out and I can't find information about this so I'm afraid this can't be done.
Each topic application has, for example, an intro.png with an image regarding the topic of the app (for example a roman or a greek image) and the idea is to access package_string.intro.png so it will automatically access the right one depending on user choice.
After struggling to do this I finally found out resources are indexed which means only one "intro.png" exists in one application, no matter how many libraries you try to link, you can't create a reference to lib1.intro.png or lib2.intro.png. I finally built a resource manager system which works with "lib1_intro" or "lib2_intro" on demand. Not the cleanest of solutions but, meh, it works I guess...
Moving my edit to an answer as I read about accepting answers and this is how it should have been done instead of just editing my first post
Related
This is more of a fundamental question I suppose. I currently have in the market one app that I have separated in two projects. One project (with it's unique package name, obviously) does not have Google Ads and is not free. The other project has Google Ads and it's free.
Both projects are exactly the same. Same functionalities.
When I want to add a new functionality, I have to work on both projects, making then the release of my app slower, since I am basically control-c/control-v what I did in one project onto another. And sometimes I just forget something, so I have to fix the issues...
So, basically, I am wondering if there's a better way I have to manage that?
Maybe creating a rather intelligent script that will build the application depending on what I want (i.e: if it's ad based version, should use the AndroidManifest that declares the AdMob Activity)
Or maybe create a library? But I don't think this approach would work.
Looking forward for inputs.
Regards,
Felipe Caldas
Yes, a library project is exactly what you want. Put all the functionality in a library, and have two very thin shells for each of your app types that make calls into the library. As you noticed, duplicating the code is error prone and at best just extra work you shouldn't have to do.
See: Managing Projects for details. That page even mentions your exact scenario:
If you are creating an application that exists in both free and paid
versions. You move the part of the application that is common to both
versions into a library project. The two dependent projects, with
their different package names, will reference the library project and
provide only the difference between the two application versions.
I have a single android app with a custom logo, some custom json service endpoints, occasional custom text, and possibly a custom color scheme.
For my client this particular app will need to be rebranded and distributed as an entirely different app about 5-10 times over. So I'm looking for way to reuse the most amount of code - the activities and services will be identical except for the custom things I mentioned.
First off, how can I share projects in the sense that one project will hold all code (including activities), and the others just modify a few values. I can't think of a smart way to share both service code and activity code with the occasional value thrown in via properties.
Do android layout/string resource files have the ability to pull from properties? Can activities be bundled inside a jar and shared with other projects?
You can use Android library project to share the common code. Start by reading this article
You do not have to have different java namespaces, they can be common for all projects. All you need is to replace resources and modify manifest to contain different namespace for each application. There is no problem with several applications having the same name of classes inside. Unless you want to rebrand it all the way user could not find it is actually the same code, of course.
I would like to add two versions of my app to the Android Market, one for a few cents, and one free version, with ads. That's a very common practice.
I'm currently building AdMod into my app, and it seems I'll have to change quite a few files, so it seems best to make a separate version of my app for this.
How do you achieve that? A branch? A different repository? Has anyone found a way to keep both apps in the same repository in a reasonable manner?
The title is not misspelled, I do mean "realise", i.e. how people manage the two versions, not how they add them to the Market.
This kind of thing is a complete nightmare - unfortunately the Android build system doesn't really support it in any good way.
We do it by having 99% of the code of our application in a library project. We then create one application project for each different version of the app, each of which use that library.
Where we need different versions of the app to behave differently, we currently achieve that by having different resources that are queried at runtime. We are in the process of moving to using Dependency Injection via RoboGuice, however.
There are elements of this that work reasonably well, and others that don't. It's necessary, for example, to duplicate the AndroidManifest.xml file, which can be error-prone (it's easy, for example, to add a new activity to one manifest and forget to do so in the others). It's a mess, unfortunately, but the least-bad solution we've found.
Personally speaking, I would strongly advise against using branches to achieve this effect. They can work well initially, but will rapidly become a maintenance nightmare.
One side benefit of using a library is that we've found that it makes testing considerably easier. For an example of how to set this up, see:
http://www.paulbutcher.com/2010/09/android-library-project-with-tests-step-by-step/
People usually upload them twice(like two different programs) and just modify the title for adding something like Ad-Free, Donate and things like that. And on the free version just add the Free label and also put on the description that it's Ad-Supported.
Here is an example with the SMS Popup application:
For the Android Market, they are considered different programs, but for us it's the same, but one is Ad-Supported and the other isn't.
I have a fully functioning program that worked. However it had two dialogs that I know I'll be reusing every time I write a program, or potentially multiple times per program. They are a EULA and an info page. So I've moved the two activities to their own project, however I don't want to have a standard EULA and info page obviously. So I have the resource on the projects I'm working on. (If using Assets will work better, I could change that.)
For the EULA I have a static function checkEULA to see if it's already been accepted and that works because I pass in an activity and the resource ID.
However for the InfoActivity I am trying to do it as a pure Intent.. I can pass in the id into the bundle, but is there a way to get the activity or resources from the intent with out adding it into the bundle?
Or if not, what is there a best practice, or a smart way to pass a resource into a intent to get it out on the other end?
You can probably do this using the PackageManager class. I believe it will allow you to access the resources from any package on the system.
http://developer.android.com/reference/android/content/pm/PackageManager.html#getResourcesForApplication(java.lang.String)
That being said, I'm curious how you plan to distribute this. Are you going to tell the user to download two different packages from the Android Market?
You might want to consider looking into the library project support that was added in the latest version for the Android SDK tools:
http://developer.android.com/guide/developing/eclipse-adt.html#libraryProject
http://developer.android.com/guide/developing/other-ide.html#libraryProject
If I needed to build an android SDK that other developers can integrate into their android apps, is jarring my SDK the only way to go about it? As far as I have learnt, jarring has the following considerations:
If your app uses a layout, then you have to create it programmatically. Since jar files cant carry any resources.
The jar will needs to be placed in the lib/assets folder and added to the build path (in Eclipse) -- Learnt here: Android - Invoke activity from within jar
The main app will have to create an Intent object and specify the package and class name in the jar to start the activity.
Any one have other ideas of going about any of the above steps?
Thanks
George
Creating a JAR is, in my opinion, a very bad decision. Android has specific features just for the kind of thing you're looking for. If your JAR:
provides some sort of (structured) data to be used in other applications, use a ContentProvider;
does some backround processing and makes that processing's results available to other applications, use a Service;
provides an Activity that gets some input from the user (or shows some information about something), eventually processes it and returns it to the calling Activity, just create that Activity and any application will be able to start your Activity as long as it's installed on the phone.
If you use one of the three solutions above, third party apps will be able to probe for whether your application is installed and, if not, prompt the user to install it. Only if your application does not fall into one of the three bullet points mentioned above should you use a JAR. Otherwise, using a ContentProvider, Service or Activity provides:
More standardized interaction between components
Better maintainability -- if you update your SDK you won't have to call everyone who uses it and tell them to upgrade.
No duplication -- if you were to provide a JAR and multiple applications that use it would be installed on a device, multiple copies of the JAR would be present on that device, thus using more memory than it has to. If you provide one of the three components mentioned above, one copy will satisfy all applications that need to use it.
Again, these components are specifically designed and provided by the Android OS for creating such SDKs. Please, only use a JAR if you really, really have to. Otherwise, provide a standardized ContentProvider, Service or Activity and document the way it's supposed to be used (i.e. how to use/query/integrate it).