MapSettings.setIsolatedDiskCacheRootPath() is unclear - android

I'm assessing HERE Android SDK Premium v3.13.2_86.
In the turn-by-turn-navigation sample there is a call MapSettings.setIsolatedDiskCacheRootPath(). However the API doc says the method is deprecated:
Deprecated. As of SDK 3.13. This method will be replaced with new one once shared map service feature is removed.
Method to allow switching of the disk cache to a separate service process and disk cache path.
So I am not sure whether I should use this method or not. What happens if I don't call it?
Of course, I'd like to have a map data cache in my app. And ideally it should be private to my app, so other apps (even those using HERE SDK) do not have access to the cache. How can I achieve this?

From the documentation and from the except you quoted, SDK 3.13 still supports shared map service so you have to keep using the MapSettings.setIsolatedDiskCacheRootPath() method until in a later release when shared map service feature is removed and a new method introduced.

With SDK 3.16 it is proposed to use setDiskCacheRootPath instead
val diskCacheRoot = (Environment.getExternalStorageDirectory().path
+ File.separator + ".isolated-here-maps")
MapSettings.setDiskCacheRootPath(diskCacheRoot)

Related

Android: Check if Current User is a guest

I had a read through UserManager and UserHandle docs and couldn't find any method which would return a boolean answering the question. Anyone have an idea how to determine this?
UserInfo class has “isGuest()” method returning a Boolean and UserManager.getUsers() returns a list, of UserInfo type. BUT, all these methods are hidden and not supported for 3rd party apps.
Additionally, the getUsers() method requires “android.Manifest.permission.MANAGE_USERS” permission, which is meant for only system (or any apps that have the platform key, or if your app only runs on Android emulator, as it gets a default platform key). So, even if you find any way to sign your application with the platform signature, it would definitely break on one or more Android versions.
Although You can try with reflection to get the access for getUsers() like below:
UserManager manager = (UserManager)getSystemService(USER_SERVICE);
Method method = manager.getClass().getMethod("getUsers", null);
Object users = method.invoke(manager, null);
But, again there seem no guarantees you will get what you want here.

How to directly invoke AWS Lambda function from an Android app?

I'm trying to invoke one AWS Lambda function from my Android application.
If I understand correctly, I have to start with something like this:
BasicAWSCredentials creds = new BasicAWSCredentials(keyId, secret);
AWSLambdaClientBuilder builder = AWSLambdaClientBuilder.standard()
.withCredentials(new AWSStaticCredentialsProvider(creds))
.withRegion(regionName);
AWSLambda lambdaClient = builder.build();
and then the rest of the code with InvokeRequest etc.
Problem is in the above code, after it app crashes. I can't find the correct set of libs to make this work in Android.
If I use
implementation 'com.amazonaws:aws-java-sdk-lambda:1.11.782'
then it compiles fine and executes up to the "builder.build()" and then crashes and if I use
implementation 'com.amazonaws:aws-android-sdk-lambda:2.16.12'
(which is supposed to be used for Android???) Then "import com.amazonaws.services.lambda.AWSLambdaClientBuilder;" is red cause there's no such thing in the lib..
I get that AWSLambdaClient is deprecated and AWSLambda should be used, then what about AWSLambdaClientBuilder? What should I use?
Basically, if everything above is wrong, how do I get to call AWS Lambda function (by the way, this is without using API Gateway) from an Android app? What libs (with versions) would work for it?
I tried to follow https://docs.aws.amazon.com/lambda/latest/dg/with-android-example.html tutorial, but they also have deprecated stuff, plus it wants to involve Cognito and I was under the impression that I could call a function directly with a key and secret of a user with specific policy..
A different approach, but you can use the API gateway or application load balancer and call the configured endpoint from the android application.
Benefit with this, you will not need to configure the application to have the client id, and client secret set up, and even if restart, it would be simple api gateway call.
Lambda can work with both API Gateway as well as Application Load Balancer, and it is pretty easy to configure. Refer this page for details on ALB with Lambda.

Maps Android API doesn't work offline without online initialization

I'm using Maps Android API in the offline mode extensively in travel apps I build. On the first app launch, I download all the tiles I need so that they're available later in the field without the Internet. Everything works great, but I noticed that the Maps API does require Internet connection on its first use after app installation. The framework probably performs API key validation to make sure it's legit.
Since my fragments containing com.google.android.gms.maps.MapView are not displayed on the first screen, there's a risk a user downloads the map for offline use in a hotel, goes into the wild, and... kaboom! - map is not displayed.
How to initialize Android Map framework so that maps are available later when there's no connection? Is there a way to skip online key validation?
After some experimenting I found out a simple solution.
So, first, in my first activity layout (it's a host activity for all my fragments) I added the following zero-sized invisible MapView:
<com.google.android.gms.maps.MapView
android:id="#+id/dummyMapViewToInitForOfflineUse"
android:layout_width="0dp"
android:layout_height="0dp"
android:visibility="invisible"
/>
Then, in the activity code, I added the following method:
private void initGoogleMapFrameworkToMakeItUsableOfflineLater() {
dummyMapViewToInitForOfflineUse.onCreate(new Bundle());
dummyMapViewToInitForOfflineUse.getMapAsync(ignored -> {
Timber.d("GoogleMap framework initialized and ready to use offline later");
});
}
You can call it in onCreate as well as at any other reasonable moment (I use AndroidAnnotations, so I called it from my init method annotated with #AfterViews). Obvoiusly, if you don't use AndroidAnnotations or other view binding framework, you need to perform findViewById(R.id.dummyMapViewToInitForOfflineUse).
If you are aiming at caching google map's tiles for offline use then you may be violating their terms,You are first required to purchase their enterprise Maps API Premier, check this link How to cache Google map tiles for offline usage?

Android M reflection method freeStorageAndNotify exception

I'm using reflection method freeStorageAndNotify:
Method freeStorageAndNotify = null;
freeStorageAndNotify = service.packageManager.getClass().getMethod(
"freeStorageAndNotify", long.class, IPackageDataObserver.class);
freeStorageAndNotify.invoke(PackageManager.class, maxCache + freeSpace, packageDataObserver);
This causes InvocationTargetException:
java.lang.SecurityException: Neither user 10199 nor current process has android.permission.CLEAR_APP_CACHE.
Some points:
- I already have android.permission.CLEAR_APP_CACHE
- This happens only in android "M" Version (Flashed the preview sdk from developer site)
I know this is a hack, and google doesn't bring some official API for that,
But there are so many cleaning apps which cleans all the device cache in one click, so if someone know how to bypass this issue with another workaround i'll be happy to see that.
Thanks very much for the help
There was a bug raised on Android 5 regarding how any app can wipe out all cache files with a regular permission, but cannot wipe out one package's cache files except with a signature-level permission. It's details where
PackageManager has a deleteApplicationCacheFiles() to delete the cache from one package.
This method is hidden from the SDK, and it requires
DELETE_CACHE_FILES, a signature-level permission.
PackageManager also has a freeStorageAndNotify() method, to delete
cache files from all packages. This method is hidden from the SDK, and
it requires the CLEAR_APP_CACHE permission, which is merely flagged
as "dangerous".
It was proposed to either that DELETE_CACHE_FILES should have its level relaxed,
CLEAR_APP_CACHE should have its level raised.
A framework engineer responded
Note that freeStorageAndNotify's purpose is not to wipe out all cache
files, but to free up X amount of space, for example by play store
before it tries to download and install an app. So there are reasons
to use it that work well with the system, but no reason for an app to
use the method that just blindly erases all cache files for a single
app (that is just there for the Settings app UI).
If indeed it is not an app error i.e. you haven't messed up the permissions and it works on Marshmallow / 6 / api 23 and not others that could only mean it became a signature level permission as well, like DELETE_CACHE_FILES.
A signature|system permission, meaning that it can only be held by
apps that are signed with the firmware's signing key or are installed
on the system partition (e.g., by a rooted device user). As described
in this answer.
This would make sense, considering their intended use / their vision (no reason for an app to use the method that just blindly erases all cache files for a single app). It may have even been restricted as a result of that bug. When Android 6's code will come out we will know better (current available is 5.1.1 - link to PackageManager's freeStorageAndNotify).
Refer to these pages: permissions by protection level and protection level definitions.
android.permission.CLEAR_APP_CACHE
This falls under the protection level "signature|privileged" which means that only same-signature or privileged apps (system signed basically) can have this permission.
Also you should check out the Behavior Changes in general.

Initializing an GoogleApiClient object

I want to use Cloud Save in my application but I can't find any example code. My first problem is the initialization and this is what I tried:
GoogleApiClient.Builder apiBuild = new GoogleApiClient.Builder(getApplicationContext());
GoogleApiClient api = apiBuild.build();
The error says that I should first add at least one API so i guess I should use
apiBuild.addApi(API);
But I don't know what API I should use for Cloud Save, does anyone?
It would be great if you could give me a complete example code.
According to this link...
The new Google Play Games Saved Games service introduced in July 2014 offers improved functionality for saving game state information and visually displaying player game progression. Game developers are highly encouraged to migrate from the Cloud Save (AppState) service to the new Saved Games (Snapshot) service as soon as possible. A new version of Cloud Save is coming soon.
At the bottom of the link, it takes you to a page where you can use this new services on android.
Here is the link.
So it appears that the api you should be adding is apiBuild.addApi(Drive.API);

Categories

Resources