I am including a class in my app that another developer has made freely available. His class has a different package.
Will this cause any issues on Android, the market, etc? Does every single class in the app need to be my own package?
Despite this being a very old question, I'd like to clarify: Java-level "packages" (which the question is about) and Android .APK "packages" are two different beasts. Java-level "packages" are namespaces to organize classes within your app, whereas the Android "package" name provides a globally unique identifier for your entire app.
Usually at least part of the Java sources in a project is in a Java-level "package" (namespace) matching the Android package name of the app, but that is just for convenience and is not at all required. It is very common to have several Java packages within your app project. Adding to the project 3-rd party Java classes with different namespaces does not affect the name of the resulting Android package. The entire project must have a globally unique Android package name defined in the Manifest, which is later used to identify your app within Google Play.
You are allowed to use other packages, sources and libraries. Eclipse makes that all very easy to do in the properties page of the project.
The main issue is usually making sure you obey the licences and agreements of the code you are using. Make sure you understand the implications and include credit to the developers, as well as references to the agreements as they state. If you don't, it could cause problems down the line.
It doesn't have to by in Your own package. Also You can use external jars, or external eclipse projects or external source folders for easier project maintenance.
Related
I'm building an app from github source, and I need two different versions of it on the same device.
What's the minimum an app must differ, to be a different app?
I'd like a small change, and not rename packages everywhere.
NB: No gradle. I'm doing it on the device itself (using termux), which lacks gradle.
The app itself has some native code, and a few different packages.
It seems the package name in the AndroidManifest.xml must differ, and of course any classes referenced explicitly referenced in the AndroidManifest.xml must also exist.
But is that enough? Specifically, can the following be the same:
everything else in AndroidManifest.xml?
all other classes in the main package?
other packages in the app?
native libraries?
I'm guessing that all the other names in the manifest are just decoration, and don't identify the app. So that e.g. different apps could have the same name on the homescreen.
The package name is used to name the directory the app is installed in, so all its other data - dex classes, native libraries etc - are distinct.
It would be sensible for android to load each app with a different classloader, so different apps can have the same packages. This avoids clashes in the common scenario of different apps using the same (popular) library, that uses static/class fields.
My guesses are derived from this answer:
https://android.stackexchange.com/a/20793/108921
If so... I could just make one new package, move the classes referenced into it, and use this new package name in the AndroidManifest.xml. (There might be issues with these classes accessing other classes which were formerly in the same one package, but I suppose that's a different issue).
its hard to believe... package name is like ID i think... google play store also use package name as ID... every app has to unique ID in every device, and finally i can say its impossible you can install 2 app have same package name in 1 device
You just need to change the package attribute in the AndroidManifest.xml (manifest package). This can differ from the java packages of your codebase.
There's some caveats. The aapt tool uses the manifest package to generate R.java. Any relative names (of Activities etc) in the AndroidManifest.xml are completed into absolute names using the manifest package. To avoid this, just use absolute names.
As a convenience, the --rename-manifest-package option of the aapt tool does that. i.e. completes any relative names, then changes the manifest package to the argument given.
I've tested this with a simple project, and confirmed it works to install different versions of the same app on the same device.
I haven't tested more complex projects... There may be further caveats, with aspects of the AndroidManifest.xml that constitute a public API, and Activities, Services, ContentProviders and BroadcastReceivers that are referenced with explicit Intents. Things That Cannot Change
20 June 2011
The docs confirm you can change your java packages from the original; and that you can create different versions (flavors) of the same app. Unfortunately, it's discussed in terms of an extra layer of how gradle reads and updates the AndroidManifest.xml, not doing it yourself directly:
Set the application ID
I have an Android app that's downloaded primarily from Android Market (now, Google Play). We made a few tweaks to the source and also submitted to the Amazon App Store to see what sort of traction it gets. I'm now looking for a sustainable way to develop from a common code base and yet build so that I can submit to either/both.
Amazon's store has some restrictions about available APIs, and hence I'd like to conditionally remove/modify features from that version. Since Java doesn't support traditional conditional compilation, and conditionally including files in Eclipse doesn't seem trivial (is it even possible?), I wanted to ask what others are doing to solve this.
Admittedly, I'm no Eclipse/Java expert so feel free to school me.
What I'm looking for in a solution:
Building/debugging using Eclipse.
Static code files, with environment/settings toggles to control what to build.
No duplicate code or conditional logic in code to pick code flow at runtime
Is this something you've solved for Android apps specifically, or for other Java/Eclipse based projects? Suggestions for where to begin?
It's quite easy to do in the newest versions of ADT (version 17), though I do find it makes compilation a bit longer:
Create a new Android project (proj-A)
Go to Project->Properties, select Android, and check "Is Library"
Move all your common code to proj-A, import all the necessary libraries
Create a new Android project for Google Play (proj-B)
Go to Project->Properties, select Android, and add Proj-A to the Library
Repeat #4&5 for the Amazon version
If you have some variables that should be set differently for each sub project (i.e. boolean GOOGLE_PLAY_VERSION to enable Google Play specific functions), you have to create another project to contain these values since you can't have projects that reference one-another in a circular fashion. You can solve this by adding the following steps:
Pull all of your sub-project specific variables into one or more Classes that just serves as container(s) for these variables
Create a "dummy" Java project (dummy)
Config proj-A to add a new Source link to the bin directory of dummy
Add the config Classes in each sub-project with project-specific changes
Profits!
Note that the variables in dummy should not be set as final, otherwise it will override sub-project's setting.
This may seem like quite a bit of up-front work, but has worked quite well for me as far as version control goes.
Edit:
Now with Google's move to Android Studio & Gradle, it may be better to move to that if you are starting a new project if you want to support multiple APKs, see Android dev site's Building Your Project with Gradle#Work with build variants. It definitely doesn't hurt to evaluate that option before deciding.
Unfortunately, it's sort of a convention in Android to change flow at runtime based on what would be in C/C++-land conditional compilation.
Our app has to maintain different behavior for different API levels, so we've created some application-level constants that are initialized statically based on API-level information available to us, and used throughout the code. This is the way that Google does things in their examples (for example, see the ActionBarCompat compatibility library, and in particular the factory method used here).
You could create an interface CustomBuild, and implement it in AmazonBuild and GooglePlayBuild, then use a static getBuild() method to switch functionality as necessary:
if(getBuild().shouldEnableFeatureX()){
doStuff();
} else {
doDifferentStuff();
}
Then all you've got to worry about switching between builds is a line or two of code in the factory along with maintaining which things you want enabled in which versions. Or you could include a different version of a static class CustomBuild for each build.
I'm going to second the suggestion of others above re: switching to something like Maven for building; it should make your life much easier once you have it set up.
I'm also going to say you should make the core of the app a library as suggested above, and have two different modules (one for amazon, one for play store) that depend on the library but each only contain the one custom factory file (or just a static class for each type of build that contains the same "should I do this thing?" methods... once you have the infrastructure it's just a matter of preference).
I haven't actually tried this yet, but it's something I've thought about.
How about using Eclipse's ability to link to files from a directory outside your workspace?
Start with one Eclipse project: for the sake of argument, say it's the Google Play version.
Now build a second project, beginning with asking Eclipse to link (not copy) the source files from your first project.
To develop the second project, add classes that subclass ones from the original project to realize your modifications. For resources, you can use some combination of includes, attribute overrides, and selectors.
Where it's not possible to subclass or extend, then obviously you'll have to just copy the original source file and hack on it. If you're really OCD about it, you can probably just maintain a patch set rather than a whole redundant set of files.
What do you think, will it work?
You may create manually two projects in Eclipse pointing to the same source folders but with different inclusion/exclusion filters and different target directories.
Then two Ant targets using properties to switch excluded files from javac fileset are enough to generate corresponding jar files.
The aim is to get a clean application for each target, without any code from the other one.
With features listed as pluggable behaviors in a property file or XML configuration, your runtime will adapt itself with the addition of menu entries.
Since it's popular to have both a free and a paid version in the android market of the same app, I had decided to do the same. Initially I just duplicated the complete codebase and adapted some code here and there (added ads, built in some limitations etc) since there was no option to do library projects at that time, but that left me with two projects that are horrific to manage fixes to bugs as I need to do those twice.
Since r14 we can use library projects with resources, so that would be a great solution to this particular problem as far as I can tell. Therefore I've read up on library projects and conciderations, and I'm curious to know what the minimum amount of files needed in the projects of the different versions are. My questions therefore are;
Could I have all of the code in the shared project, and have bare bone project with basically just a manifest?
If so, should I? is this the optimal way conceptually? (so apart from the fact that it depends on my code base)
How should I deal with library package naming, are there specific rules?
Are there tools about that can compare code from two different projects and perhaps merge them auto-magically or auto-manually, and which one is preferred?
If I understand your problem correctly, you want to create multiple Android apps that are similar to one another (i.e., have a lot of the same source code), but which are different in particular (minor) ways, and you want each of these apps to have a distinct package, so that it can be separately uploaded and distributed on an app store such as Google Play. A Project Library is an excellent facility for accomplishing those goals.
I'm assuming that the differences between your various versions are minor, involving things like resources and the app name and package, and a switch that turns on certain features for a paid version while leaving them off for a free version.
Even if that is not the case, by using polymorphism in the ways described below, your various apps could differ in significant ways and still share a common Project Library.
A Project Library can be defined in Eclipse in the same way as any Android project can be defined, but it is marked as a Project Library (by checking the "Is Library" box near the bottom of the Android page of the library's Project Properties dialog) and cannot be compiled and run on its own. Instead, it is intended to be included by reference in one or more other projects which are actual apps (by adding a reference to it on the Android page of each such app's Project Properties dialog). These apps will use the Project Library, and thus will share its code and capabilities.
Each such referencing app will have its own manifest file (where their respective, different packages can be declared), and they can also define their own classes (including classes derived from the Activity and/or Application classes of the Project Library), so that these classes can be specialized polymorphically for each app that uses the Project Library (e.g., by overriding methods or by providing definitions for methods that are defined as abstract within the Project Library's Activity- or Application-derived classes), although you can also use those Library classes without modification (provided that they are not abstract) by simply referencing them within the manifest file (e.g., in an activity or application tag) of each app that uses the Library, just as you would reference Activity or Application-derived classes defined within the app itself.
If you decided to use this approach, then you would put your main source files in a Project Library, and would create a separate project for each app you want to produce, each of which would reference the Project Library. The manifest file of the Project Library would be overridden by the manifest of whatever project is being created using that Library (actually, I think that the Project Library's own manifest is completely ignored, not just overridden, but nonetheless it is useful to create a manifest for the Library, so that you can manually template - copy and edit - the manifest of each project that uses it from the Library's own manifest).
I have used this approach to create multiple android apps that share some of the same capabilities, and it has worked very well for me.
Regarding package naming, any old package name will work for a library project, but of course it makes sense to use the same prefix for the Library Project's package as you use for your various individual (e.g., free vs. paid) apps that use it, with something like ".library" as the last part of the name, while the various apps could have endings like ".myappfree" and ".myapppaid". Naturally, you would want to use your reverse domain name convention for the library's package prefix to prevent conflicts, just as you would for a package name of a released app.
In Windows, a nice, open-source tool for comparing code bases is WinMerge:
http://winmerge.org/
If I were in your position, however, I would only use this tool to manually identify differences, and would not attempt to use it to automate the refactoring of your code into a Library Project. That would be best done under your own (manual) control.
Finally, as an alternative, you might consider using a single app that is free and that has your free app's capabilities by default, with an option to upgrade to your full app's capabilities (delivered within the same APK) via an in-app payment, rather than having separate free and paid apps. In-app payments have improved a great deal in the past several months (with the release of version 3 of IAB), and although there are still some glitches, they have become a more practical alternative to the free/full dichotomy than they were at first.
Yes, you can have a project that is basically just a manifest specifying app name, name space, icon etc, with all the actual code and 99% of the resources in the library project.
Yes, I think you should use this approach. It's very common to use library projects to deal with the Free/Paid app problem.
I've not had any problems with naming, though you should be careful with any resources in separate projects to avoid using the same names.
I'm not aware of any tools, and if it were me I'd want to do it manually to be sure I'm merging what needs merging and keeping separate what needs to be separate. you've one significant refactor to do, but once all the duplication is removed I'm sure it'll be much easier.
I have an app that, for release, needs building as two apps. The app will self-reconfigure based on the app's namespace, so I just need to build two versions, each with its own slightly different namespace.
I obviously want to avoid changing source code package names, and would like to change the name space in one place so building either version is quick and easy.
Can I simply change the package name in the <manifest> tag in the Android manifest, making sure my references are fully qualified? Are there any gotchas with doing this?
Have two separate application projects, with separate package names, and have the common functionality - the bulk of your code - in a shared library project.
I would like an Android build system procedure, command line or Eclipse, to generate several .apk files from a single source codebase. Some common reasons for this - having specific versions for markets with different requirements or a free and paid version.
This question IS NOT ABOUT:
Packaging shared code into Android libraries or into external Java jars
Producing a debug vs. signed release .apk
Google says "you probably need to create separate Android projects for each APK you intend to publish so that you can appropriately develop them separately. You can do this by simply duplicating your existing project and give it a new name." Then they kindly suggest using libraries, which I understand. Then, they mention in passing exactly what I do want: "a build system that can output different resources based on the build configuration"
I know that to accomplish conditional compilation in JAVA one can key off a 'public static final' variable. There is an example of tweaking such a value in build.xml. Any more complete example of an Android Ant build configuration for this or a link to an OSS project doing that now, please? BTW, build.xml is auto-generated, but I have seen people hacking it, so how does that work?
With the package name declared in Manifest.xml as package="com.example.appname", if one needs to emit multiple .apks that vary that name, is one stuck with a separate project for each?
I'm generating 2 different APK's (demo and production) from one single source tree with 3 small modifications:
1) I have public static final DEMO=true; //false; in my Application class and depending on that value I used to switch code between demo/production features
2) There are 2 main activities, like:
package mypackage;
public class MyProduction extends Activity
{
//blah-blah
}
package mypackage.demo;
public class MyDemoActivity extends mypackage.MyProductionActivity
{
//blah-blah
}
3) And in the end 2 separate AndroidManifest.xml files which points to different launcher activities depending on demo/production switch
I'm switching between 2 APK's manually, but see nothing difficult in writing small ANT task to switch between them automatically
One way to do it would be to maintain two separate AndroidManifest.xml, one for each configuration. You can switch back and forth between the two either manually (copying) or automatically (build script).
[edit] This person here has a system to do this kind of thing: http://blog.elsdoerfer.name/2010/04/29/android-build-multiple-versions-of-a-project/
The answer to this screams Gradle, as explained on this website. It's officially built into Android Studio and is encouraged.
It's amazing; I've built 3 separate apps using the same source code, with customized text and graphics, with no special coding whatsoever. Just some directory and Gradle setup is required, and other posts of mine can be found with answers to both.
It seems to explain all the basics really well. For the answer to your specific question, look for the section Product Flavors under Build Variants, where it describes specifying different flavors.
As the website explains, part of the purpose behind this design was to make it more dynamic and more easily allow multiple APKs to be created with essentially the same code, which sounds exactly like what you're doing.
I probably didn't explain it the best, but that website does a pretty good job.
Despite your insistence that this is not about packaging shared code into Android libraries, it sort of is. You've stated that markets may have different requirements or having a free and a paid version. In each of these examples, your two final output APKs have different behavior and/or resources. You can put the vast majority of your code in a shared Android library, and then maintain the differences in your actual projects.
For example, I've worked on apps where they need to be released both to the Android Market and the Amazon AppStore. The Amazon AppStore requires that if you link to a market page for the app, it must be Amazon's (as opposed to the Android Market page). You can store a URL in a resource in the library and use that in your code, but then override that resource in the Amazon project to point to the appropriate Amazon URL.
If you structure it right, you can do similar things in code because your starting point is your Application object which you can subclass and do different things with.
That said, if you want to add an Ant step that changes the package name in the manifest, it is just XML. It shouldn't be hard to modify as a precompilation step.
This article has a good walk-through with examples of how to amend config files at build time; see in particular the Customizing the build and Using a Java configuration file sections. Note that some of the information about build.xml and ant is a little bit out-of-date now.
Here's our situation: we have a single codebase from which we release for several clients. Each of them has various requirements regarding titles, backgrounds and other resources in the application (let alone package names).
Build is handled by a Ruby script that modifies AndroidManifest, copies/replaces certain resources from client-specific folders and then moves on to Android's standart build routine. After the build is done, script resets changed files back to their original, 'default' state.
Well... Maybe it's not optimal and definitely not Android-specific, but that's how we do it.
I had the same problem but packing all in one project with flags is no solution for me. I wrote an example how to do that with Maven:
How to create multiple Android apk files from one codebase organized by a Maven multi module project.
My team build 2 different build using single code base + additional code.
As android build is based on ant script, I use ant script to do this work.
I used xmltask to manipulate manifest xml file and many ant task ( regexp , copy..) to edit source code.
I prepared template project template ( including build.xml , default.properties, local.properties) and copied new source code into those project templates. when copy completed, run build.xml parallel to shorten build time. when build finished, I get multiple apk files.
It's easily to achieve your goal by using Android Studio build variants which use graddle as the build system.
Check here for more detailed information.
I think that the best way remain to use libray for common sources and two different Android project for demo and production package. This because in Java it is very simple to make a reverse engeneering from apk to sources. If you use the same sources for demo and production, someone could hacking your apk downloading the demo package, extracting the java sources and unlock the sources changing the variable to use it as production version.
With library you can preserve part of sources in the production package, in this way there is no way to use demo package as production package.