I am very new to eclipse and android developing in general and need help with the following. I have built two android projects in Eclipse with the android SDK:
"ORF401 Project" - targets Android 2.2 platform
"Map Project" - targets Google APIs 2.2 platform
I have followed the steps as specified by the standard Hello World Google Maps for android tutorial and have gotten the Google map to display on the emulator when I run the second project.
I have a menu set up in the 1st project for which one of the options is to load the map. However, I'm not sure how to load the map within this project since only one build target can be specified for each project, and so I cannot specify the Google Maps API as a (additional) build target. Is there a way to call the main .java class from the second project within the first project? I see where a reference can be made to the 2nd project under the project properties, but I'm not sure how to make use of this. One possible solution I found on the web was to add the following code under the switch case in the first project:
Intent intent = new Intent(this, {googleMap}.class);
startActivity(intent);
I presume this would require an additional googleMap.java class in the first project and also another activity, but I can't get it to work. Can anyone make a suggestion as to how I can accomplish this?
If the code for either or both projects would help, I'll be happy to post it. Thanks
The main idea with projects is to have one project per application that does some thing.
I assume your application needs to do something with maps, as well as something else. There is no need to split those ideas. Keep them in one project, because they make up one single application that you develop.
First thing I would suggest - read carefully about activities and intents. Head to http://developer.android.com - everything's clearly explained.
With that all cleared up you will see the point in making some button, which, being tapped, opens a new screen with the map feature that you've developed. And then let's you go back or do something else, like open a new screen, a browser, etc.
And give up trying to call the other project from a different one :) It's not the way I think you want to do stuff.
Just to make sure I'm not misunderstood - of course you might want to have two projects. But those will most probably result in two separate applications. Luckily, applications may also interact by intents, or content providers, or a couple more. Just see how Contacts app takes you to GMail app if you want to send a mail. If that's what you want to achieve - still need to read about intents.
edit:
Here's the link I mentioned about in the comments:
http://android-developers.blogspot.com/2010/07/how-to-have-your-cupcake-and-eat-it-too.html
It explains how to achieve the 'additional target' that you would like to have.
There are ways to call a class from one project in another project, but there are bigger problems here. The first project can run on any Android device. The second, however, requires Google Maps APIs. You won't be able to invoke it anyway, because it can't be installed unless you're in an environment that supports Google APIs. There really is no benefit to doing this, unless you have additional functionality in project 1 such that it can exist without project 2.
I would suggest using the Intent method rather than trying to hack something together that allows you to access another class. Regardless, though coupling these two together like this seems overly complicated and error prone. I would suggest simply embedding the mapping functionality in project 1 and requiring Google APIs. Most mainstream device support them anyway.
If you're married to the idea of having two separate projects with different build targets, I would suggest looking into using BroadcastReceivers with a custom intent that you broadcast from application 1. I don't believe startActivity will work across application boundaries because of class loader issues, but I could be wrong about that.
Related
My scenario
I have to implement a "modular" android app. There is a core module from which I should be able to invoke other modules. Each module provides a different feature to the user. Imagine I am making a city guide, then one module may contain a map with POIs, another one an event calendar and a third one pre-defined city guides. The modules contain views to be loaded in activities of the core module (like dashboards where each module puts its item/picture). They also contain activities which should be invoked (like when a user taps an item on the dashboard). As far as I know, I will need a database and/or preferences only in the core module. The "plug-in modules" use classes (utilities) of the core module, e.g. when connecting to the backend.
My solution on iOS
For iOS, I achieved this with targets in XCode. I have one project and depending on the customer's needs I compile only the relevant modules. It would be even better if the user can install modules whenever he wants, without the need of reinstalling the "core" application.
My problems on Android
In SO, I already found various solutions like library project, switching from Eclipse to Android Studio + something, using package manager and broadcast receiver... But I still don't understand... How is the modularity of an android application to be achieved?
Here are some concrete problems that I see:
Libraries: My modules all use classes of the core module, so they are not independent. I achieve the modularity by using interfaces/inheritance depending on the flexibility that I need.
Broadcast receiver: This seems to be everything else than recommended. See, for example, here or here.
What I need is, at least, to be able to use the same code for delivering app with features A and B to one customer and with B and C to another one. And, until now, I have no idea how to achieve it.
PS: I don't want to use scripting, I am not familiar with that.
I don't see this "modular" app as anything different from one app, with several packages, each containing discrete functionality, that is adapted to some list of settings or external parameter (either provided by the user or you).
My approach would be to have a "main" package. That package would contain the shared functionality you mention above and serve as the hub for your application. I would then create separate sub-packages for the different "add on" functionality. This allows you to still use the code in your main package with a simple import statement. From your description these additional functions should probably be implemented as a Fragment. A Fragment is almost a stand alone application with the exception that it is "hosted" by an Activity. Depending on how these add on functions are used (I cannot tell if they relate to the UI, just background processing etc) you could easily have 3 of 4 different fragments and choose to load only 1 or 3 or 2 of them at runtime.
To control which parts of the code are used I would just set up a simple switching class (it could even be part of the first activity launched, I cant tell from your description above). Here I would check for some setting indicating which parts of the app will be "active." This could be easily defined using SharedPreferences to store a specific configuration, e.g. use A and B, prior to delivering the final project. You would then just initialize the fragments you need and display them either (1) individually in a Fragment layout element or FrameLayout; (2) collectively in some other view structure like a ViewPager.
I follows your links on the BroadcastReceiver and I am still not sure why they are "everything else than recommended." Used correctly a BroadcastReceiver is very useful. I tend to use a LocalBroadcastManager along with a BroadcastReceiver to notify other sections of the app when some AsyncTask, e.g. downloading a lot of data, is complete. These parts of the app can then access a local database or process the information downloaded on their own time. I wouldn't use a BroadcastReceiver to modulate parts of the app if that is what you're looking for. I would instead just use a SharedPreference file to set the configuration at runtime.
If you need modules like facebook sdk or something like that better use library project. If you use Idea or Android Studio there is such thing like Module. If I need some modeles in one app I prefer just put in different packages like com.appname.model, com.appname.ui and so on. Broadcast Receiver isn't about modules. As I know there isn't analog of ios target.
Some time ago I created and Android app. Then I needed to create very similar app (functionality-wise) with some cosmetic, branding and small-scale functionality changes. I refactored the original app as a library project, created an app that used this library project and recreated the original functionality. Then I created a new app that used that same library project and also implemented the small-scale changes required for the second app. This worked perfectly fine. Now if a change is needed, it's very easy to implemented it in multiple apps: I just change the library project and recompile all the apps.
I also had the original application available for iOS - and need to make the second app available for iOS. I could, naturally, copy the project, make the changes and create another apps. However this would mean double work if I needed to change something in the core functionality. I'd like to be able to refactor the iOS project/app similarly to the Android one, but not sure how to go about it - or if such functionality is even available. Any suggestions are much appreciated.
You can create a Single project with differents targets.
Then, you will have target A, and B for example and CoreFile files that are common for all targets.
Let's suppose you have HomeViewController with some slightly differences.
You can create a single interface HomeViewController.h and two implementation AHomeViewController and BHomeViewController, both extending BaseViewController.
Then open AHomeViewController, and on FileInspector at 'Target Membership' mark only target A. On BHomeViewController you do the same. Image 1, illustrate what you have to do (names are differents from the example because it's a real example from one of my projects).
If for some reason you have need to know what's targets are you using you can define it using Preprocessor Macros on Target -> Build Settings. As illustrate by Image 2.
Then you can use #ifdef APP_CB to check the current target.
As was mentioned you can really regulate target membership[About] of every file which you add. But in my opinion is better to create a separate framework(library) and add it as dependency
[Swift consumer -> Swift dynamic framework]
In short: Is there a supported way to create an Android project for eclipse (as you would get via the new Android project wizard) programmatically? Or if not supported, then is there any way at all? (this is being done within an eclipse plugin)
I've been trying to do this for a while, and it is turning out to be much more difficult than expected. I took a look at the source for both the New and the Import wizards for Android projects, and found that they both use the NewProjectCreator class. There seem to be two ways to use this class; one is via the static "create" method, and the other is to construct an instance of NewProjectCreator and call "createAndroidProjects". However, I'm having trouble getting ahold of all the necessary parameters for either of these. The static method requires both an IAndroidTarget and a ProjectPopulator, neither of which I can find implementations of (There is an anonymous implementation of ProjectPopulator in the NewProjectWizard class, but pasting this into my code is disastrous in the number of classes and fields it can't find). The instance method on the other hand requires an IWizardContainer, but I would like to be able to do this without bringing up a wizard.
At the other end of the spectrum, I've tried simply adding and Android nature to the project, but this causes all sorts of build errors, since it doesn't actually change the setup of the project to reflect whatever the Android standards are. I guess another option is to take this route and try to set up the whole project manually, but I don't know if there are any guidelines for this, or whether the project standards are likely to change.
Does anyone know how to do this? Thanks in advance!
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.
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).