I am working on a school project and need to calculate the time it will take to travel between two locations preferably with the option to specify the mode of transportation inside of an android app.
I have come across the Google Distance Matrix API (documentation here) which seems to have the features that I am looking for, but it warns...
"If you are building a mobile application, you will need to introduce a proxy server to act as intermediary between your mobile application and the Google Maps API Web Services."
I know that this is for the protection of the API key and want to follow this pretty diligently. I'm wonder, is there another way to get the data I need for the app without setting up a proxy server?
I know I could use a service like Heroku to run the code that accesses the API, but this seems like a difficult option given that this is just a school project. Any other ideas on how to get the travel time for my app?
Setting up a proxy server is the best way to secure your API key, but Google also suggests other security techniques such as obfuscation and pinning.
Having said that, if this is a school project and you won't make your API key public in a production environment, then you can just leave your API key unrestricted (and without a proxy server).
But do make sure that you monitor your API usage on a regular basis and that you regenerate your API key periodically and/or as needed. It's also strongly recommended that you set daily quota limits and budget alerts as per this FAQ so that you don't go over budget regardless.
Hope this helps!
I am developing a proof of concept/prototype for an internal tool. The basic premise is, that we have a couple of units that have a GPS on them, and they report their location (with typical GPS accuracy in NMEA format) to a java api I have built in a cloud environment.
[Device GPS] -> [Sends Cellular GSM request to API] -> [API queries Google
Roads] -> [Google Roads returns snapped coordinates] -> [App maps received
coordinates]
The java API takes the reported coordinates, and essentially sends a request to the Google Maps Roads API and uses the Snap-to-road feature (this will essentially take whatever point you gave it along with an optionally traveled path of coordinates, and give you coordinates back that are essentially on the path it believes you are traveling). This is great and all, but with one setback.
IT IS EXPENSIVE.
For two devices reporting their location (similar to the way Uber or Lyft may do it) every few seconds, the cost of running this application essentially makes it a sunk cost. 24,000 queries will cost you $300-500. For one device.
We have taken a few efforts to only accept requests to the API during work hours - but that is still barely scratching the surface.
I am fairly capable at writing whatever I would need (I believe at least), or can find libraries to do what I think needs to be done - but I have no idea what recourse to take. I am thinking of something along the lines of caching requests in another table and querying that first, but I am not certain how reliable that will be.
Has anyone implemented such a solution or something similar? I just need to defray the amount of requests I send to Google Maps' API before I bankrupt this project.
If you have not already I would think you would want to look at the Google Maps API Pricing Sheet ( https://cloud.google.com/maps-platform/pricing/sheet/? ) and talk to Google. They should be able to explain to you the correct architectural approach (caching parts of maps locally, local path processing etc.).
At https://en.wikipedia.org/wiki/Google_Maps#Google_Maps_API they explain the pricing changes and other useful details, but the section also mentions alternatives such as OpenLayers and local map hosting if your use case would allow for that.
It may helpful to better understand the scope of the devices' travel. Are the devices to be put on vehicles that only travel around a factory, or on a personal device that a user can take anywhere in the world?
I'm well aware of how I can communicate with an outside server using Android. Currently I'm using the relatively new AppEngine Connected Android project to do it, and everything works fairly well. The only thing that I'm concerned with is handling downtime for the server (if at all) and internet loss on the client side.
With that in mind, I have the following questions on an implementation:
What is the standard technique for caching values in a SQLite Database for Android while still trying to constantly receive data from the web-application.
How can I be sure that I have the most up-to-date information when that information is available.
How would I wrap up this logic (of determining which one to pull from and whether or not the data is recent) into a ContentProvider?
Is caching the data even that good of an idea? Or should I simply assume that if the user isn't connected to the internet, then the information isn't readily available.
Good news! There's a android construct built just for doing this kind of stuff, its called a SyncAdapter. This is how all the google apps do database syncing. Plus there's a great google IO video all about using it! It's actually one of my favorites. It gives you a nice really high level overview of how to go about keeping remote resources synced with your server using something called REST.
I'm developing an application for Android, and I'm thinking that it's functionality might be useful on other (Java-running) platforms (say a regular desktop app -- although I hope that the other platform(s) involved are immaterial to the question at hand).
It's unlikely that the UI will be in any way portable (there's just too much of a difference between a good touch-capable, 4in screen UI, and a mouse-and-keyboard 19in screen UI), so I'm happy enough reimplementing that separately.
However, the core "business logic" (ugh, horrid word) and model (data storage) classes could, in theory, be reused in managing the core app. I've noticed that there aren't a lot of classes I'm writing that don't end up referencing some Android-specific bits (I've got XML resources files, images, and SQLite databases, as examples). Basically everything I've written so far has at least one Android-related import.
My question is twofold:
What tools are available out there to help me use Android-related classes and features (eg resources, databases) on non-Android platforms; and
What classes, features, etc of the Android platform should I completely avoid using (for the sake of simplicity, let's exclude UI-related items) due to non-portability, and what should I use instead to improve portability.
Answers that consist of "hahahaha, you're doomed" are OK, as long as there's some rationale provided.
(P.S. I'd make this community wiki if that was still available; this seems like a perfect CW question to me -- a list of Android portability tips and tools)
Looks like you have already identified the key point by keeping UI and biz logic / model separate.
Also sqlite itself is used not only in Android. But of course the way you interact with it (e.g. SQLDBOpenHelper) is different again.
So I guess having the biz logic and model as separate as possible is the way to go.
You can then put a wrapper around it (e.g. "Data Access Object " pattern which talks to the specific DB).
Still keep in mind that the users experience is best when you are as specific to a platform as possible on the UI side.
Example: there is an App (Push & Ride) on the Android market, which seems to run in a J2ME emulator. So screen input does not use the normal soft (or hard) keyboard of the device, but a simulated phone keyboard with the "abc" "def" combos on the number keys, which makes data entry a bit strange.
This app is for sure very portable (and its functionality is really great), but it just does not feel right.
When you want to go multi-platform, you may perhaps also look at things like Appcelerator or Adobe AIR
I started off doing something similar - I wanted to write an app for Android, Blackberry and J2ME. Conceptually, you can layer your design such that platform-specific components (UI, network access, data storage) are separated from the core business logic.
In practice, I don't find this satisfactory. The issues I faced all related to the core version of Java being different in the different platforms (in Blackberry it is based on J2Se 1.4, while Android used Java 6 as base). This led to annoyances like
Not able to reuse code that uses generics
My preferred classes not being available uniformly (for example, forced to use Vector over List)
I have opened discussions regarding this on SO (here and here), but couldn't reach a conclusion.
The logging layer can be made portable by using the Simple Logging Facade for Java(SLF4J) which is available for java/log4j and for android.
Also,you can try this out
http://wp7mapping.interoperabilitybridges.com/Home/Library?source=Android
Contains documentation and tools to map your android app to windows phone
Also read this,even though it contains instructions specific to android - windows phone interop,im sure they apply to other platforms as well
http://windowsphone.interoperabilitybridges.com/media/49652/wp7_guide_for_android_application_developers.pdf
What I do is create a web service outside of the android app which can be used by the android app as well as other systems (websites, windows apps, iphone apps etc).
A simple REST web service which supports JSON is a good example to fetch data and also insert/update data. JSON is particularly suitable because its so lightweight, and doesn't require alot of bandwidth which is great for slow mobile connections.
This way you can store your models/data storage outside of the android app, and it can be used by other apps very easily.
The database layer can be made more portable by using android jdbc or by using a database abstraction layer/object relational mapper/ActiveRecord implementation.
Has anyone tried make android.database(.sqlite) runnable on a non android system?
If you carefully separate business logic from UI and android perks you would be able to reuse it in desktop environment. Android is quite different from it in intialisation and application lifecycle - abstracting creation and setup of BL is also necessary.
Usefull pattern for this purpose would be dependency injection. There are different frameworks around, and some are more suited for android (like roboguice) or desktop (spring or picocontainer or guice).
Android appliactions are very constrained in memory, and this puts limits on what frameworks you can use there. So you may need to abstract data storage as well ( hibernate comes handy on desktop / server side , but too heavy for mobile device)
I'm inclined to suggest trying out the new native extensions for Adobe Air. It allows you to create a device-specific chunk of native code, and connect it to the Air framework, accessing it as you would other objects in Air. (cf. http://www.adobe.com/devnet/air/articles/extending-air.html). This allows you to keep the Android-only code as is, and then replace that code with iOS, Windows DLL, etc. code as needed.
This doesn't solve the problem of translating Java code to other languages/platforms, of course. Still, some of the logic you are doing natively may very well exist already cross-platform in Air. For example, you can access the camera in Air in all supported OSes without writing any device-specific code.
You will probably need to go beyond the current Air classes, so some examples may help:
Android speech-recognition
iOS batttery
Windows and Mac tutorial
NE tutorial
I am currently trying to implement a database compatibility layer for Spring-Boot-JPA/Android-Room:
"compatibility layer" means my Service-layer-code is pure-non-android-code that can be used in android and in spring-boot. The Service-layer-code uses a common java-repository-interface that is either implemented in android-room or in JPA.
Currently i am stuck here:
Howto use methods of CrudRepository<T, ID> (or SimpleJpaRepository<T, ID>) in a Spring-Data-Repository-Fragment method?
I plan to go with the free version in order to promote the paid version.
Few questions:
In your experience, is it helps?
After a user has installed the free version, if he wants to install the paid version,
he needs to remove the free version first ?
how it effects downloads rates ?
What is the correct way to do it?
After some research for one of my applications, I have found the following options:
1 - Have all your code in one big library then make two applications using this shared library and have them toggle some flag saying the application is in trial or full mode.
To me, not very nice, because you'll need to handle the fact that the user can have both the free and full applications installed, when the users gets the full application, you'll need to move his data from the trial version to the full version (databases cannot be shared easily)
2 - Have one single application that can be unlocked by buying a code on a particular website
Good thing is you can provide alternate payment options (paypal, ...) and also avoid being limited to the Android Market. Can be nice when dealing with countries that don't have access to it.
3 - Have a single application with all the code plus one small unlock application to unlock the free application limitations
Good thing is you just need to update the free application and all users will get bug corrections. You also take advantage of the Android Market. Downside, is that your users need access to the market to get the full application.
I have personally chosen option 3 but I will add on top of it the option 2 because I intend to distribute my application on countries/devices that do not have access to Android Market
Edit 2/2/2011: I have published an article about that on our website. Your can read it there: http://www.marvinlabs.com/2011/01/sharing-code-full-lite-versions-application/
It's always a good idea to provide a demo (assuming there is incentive to buy the paid version, like a time trial, feature cripple, whatever is best to demonstrate the app without ruining the experience).
Add two versions of your app to the market, one free, one paid.
No, since they're two separate apps, but it would make sense to remove the free one in order to not have two apps installed.
They're two separate apps, so they have two separate counts.
As an alternative, you could use a keyfile to unlock the features of the full version. If you do that, you should probably use Google Checkout for processing (all "fees" must go through Google's processing as per the TOS, IIRC). There's a lot more involved if you go this route (especially coming up with a keyfile system that cannot be easily hacked).