I am following this official tutorial. I am facing a problem for setting disk cache root path. I am using Here Map inside a Fragment. Here is the code i am using.
mapFragment = (AndroidXMapFragment)getChildFragmentManager().findFragmentById(R.id.mapFragment);
String diskCacheRoot = getContext().getExternalFilesDir(null) + File.separator + ".here-maps";
boolean success = com.here.android.mpa.common.MapSettings.setIsolatedDiskCacheRootPath(
diskCacheRoot,
getString(R.string.hereMapServiceIntentName));
if (!success){
Toast.makeText(getContext().getApplicationContext(), "Unable to set isolated disk cache path.", Toast.LENGTH_LONG).show();
}else{
// initialize map
}
For the first time i am getting success true. When i come back this Fragment again success is always false.
From official documentation for setIsolatedDiskCacheRootPath method
Returns:
false if path matches default disk cache path or path is a file or
invalid or is not writable or intentAction matches default service
connection name, otherwise true.
Not sure for which case i am getting false.
If i clear my app from recent and relaunch again then First time i got success true.
Can anyone can explain the scenario why this is happening.
Changing the Files Directory method working now. Using getFilesDir instead of getExternalFilesDir is working for me.
String diskCacheRoot = getContext().getFilesDir().getPath() + File.separator + ".here-maps";
Andrew's suggestion is also working for me.
It occurs for me since 3.13.x too, and worked before 3.13.x.
Please read documentation: https://developer.here.com/documentation/android-premium/api_reference_java/com/here/android/mpa/common/MapSettings.html
It is said:
The method must be called before the init() methods on MapEngine.
You cannot run this method after mapEngine is initialised.
To fix this use the following logic:
if (!MapEngine.isInitialized()) {
MapSettings.setIsolatedDiskCacheRootPath(diskCacheRoot, ISOLATED_MAP_SERVICE_INTENT);
...
}
What about sdk premium 3.14.2 ?
Method setIsolatedDiskCacheRootPath() is deprecated ...
https://www.developer.here.com/documentation/android-premium/api_reference_java/com/here/android/mpa/common/MapSettings.html#setIsolatedDiskCacheRootPath-java.lang.String-java.lang.String-
#Deprecated
#HybridPlus
public static boolean setIsolatedDiskCacheRootPath(String var0, String var1) {
return com.nokia.maps.MapSettings.b(var0, var1);
}
Related
I'm trying to add a BackdoorMethod to a Xamarin.Forms application to bypass the login (IDP - opened in chrome browser) step. I have the feeling that the method is not getting triggered, but not sure, and I don't know how could I make sure about it.
I've read the documentation here: https://learn.microsoft.com/en-us/appcenter/test-cloud/uitest/working-with-backdoors
Check this thread: https://forums.xamarin.com/discussion/85821/xamarin-uitest-backdoor-on-droid-with-splash-screen-how-do-i-access-my-mainactivity
Checked this example: https://github.com/brminnick/UITestSampleApp/tree/master/Src
In the MainActivity.cs file I've defined the BackdoorMethod:
[Preserve, Export(nameof(BypassLoginScreen))]
public string BypassLoginScreen()
{
// some additional code here. the code is working, when I called it
// directly from OnCreate it was executed without any error
return "called";
}
From the test case i'm trying to invoke it like:
public constructorMethod(Platform platform)
{
this.platform = platform;
app = AppInitializer.StartApp(platform);
var result = app.Invoke("BypassLoginScreen"); // result == "<VOID>"
}
I'm not getting any error message, the method simply not called, or not returns anything. (or i don't know what's happening there with it, because breakpoint also not working as the app started from the device)
This should be already working. I have similar code and it works for me.
you can add inside your function
Android.Util.Log.WriteLine(Android.Util.LogPriority.Info, "BypassLoginScreen", $"Some text as info");
And observe the result in Device Logs, Filter by BypassLoginScreen to see if there is any log created with the tag BypassLoginScreen
does anyone know how to clear the data from the parse installation on the newer library version 1.10? In 1.8 you could do it via reflection by calling clear from memory, like described in this answer: ParseObject mergeREST raise ConcurrentModificationException
I am deleting the parse installation from web, and I also need to clear the ram cache on the android phone and I can't find a way to do it. Any ideas?
Solved by making a package in my project named com.parse, in it I've placed a file named ParseEasyAccess.java , it contains the following method:
public static void clearParse() {
ParseInstallation.getCurrentInstallationController().clearFromDisk();
ParseInstallation.getCurrentInstallationController().clearFromMemory();
}
You can call this from anywhere in the app and it will clear all the parse installation data from RAM & disk.
The accepted answer will not work for sdk version 1.13.1.
The only way to access those methods is like this:
ParseInstallation installation = ParseInstallation.getCurrentInstallation();
Class clazz = installation.getClass();
Method[] methods = clazz.getDeclaredMethods();
Method method1 = clazz.getDeclaredMethod("getCurrentInstallationController");
method1.setAccessible(true);
Object result = method1.invoke(installation);
Method method2 = result.getClass().getDeclaredMethod("clearFromDisk");
method2.setAccessible(true);
String result2=(String) method2.invoke(result);
Method method3 = result.getClass().getDeclaredMethod("clearFromMemory");
method3.setAccessible(true);
String result3=(String) method3.invoke(result);
I am trying to implement the fairly new Android TagManager from Google. I can't seem to be able to load the default values.
I have created my default json file:
assets/tagmanager/GTM-xxx.json
Which looks like this:
{ 'eulaTextVersion': '1' }
I have also added this code to actually pull the default file if nothing is found on the server:
TagManager mTagManager = TagManager.getInstance(this);
// The container is returned to containerFuture when available.
ContainerOpener.openContainer(
mTagManager, // TagManager instance.
CONTAINER_ID, // Tag Manager Container ID.
OpenType.PREFER_NON_DEFAULT, // Prefer not to get the default container, but stale is OK.
null, // Time to wait for saved container to load (ms). Default is 2000ms.
new ContainerOpener.Notifier() { // Called when container loads.
#Override
public void containerAvailable(Container container) {
// Handle assignment in callback to avoid blocking main thread.
mContainer = container;
}
}
);
int eulaTextVersion = (int) mContainer.getDouble("eulaTextVersion");
However, when I debug, my int eulaTextVersion is always zero, I can never get it to 1 like it should be from my default json. Could someone please help me out and show me where I am going wrong?
Thank you for the help.
Probably Google Tag Manager already downloaded first version for you. First version is probably empty. Just make next version with "Values" that contain "eulaTextVersion" and "Publish" it.
If you do not know how to set those values on your Google Tag Manger account look at: http://youtu.be/Xe8W5w68BRg?t=8m26s
You shouldn't be using quotation for numerical values. Try the following instead
{ 'eulaTextVersion': 1 }
I'm writing an application that should be able clear the private data of any other application. If you're wondering about the use case, its along the lines of an MDM/MAM client. I'd like to selectively wipe application data (vs. a full device wipe).
I came across the following API call in the Android source code.
ActivityManager.clearApplicationUserData(String packageName,IPackageDataObserverobserver)
The odd part is, that this is not really available to you as part of the SDK . (So eclipse will give you hell for trying to use it). However, it is present (see here),you can invoke it via reflection. I'm still however, unable to get hold of the IPackageDataObserver interface.
Is there a better way of doing this? I know it CAN be done since I've seen products like MaaS360 do a selective wipe of applications' data.
Any suggestions?
UPDATE
Based on what #lechlukasz has outlined below... the following code can execute...but you do finally land up with a SecurityException, since the package manager revokes the CLEAR_APP_USER_DATA permission when the app is installed.
Class<?> iPackageDataObserverClass= Class.forName("android.content.pm.IPackageDataObserver");
Class<ActivityManager> activityManagerClass=ActivityManager.class;
ActivityManager activityManager=(ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
Method clearDataMethod=activityManagerClass.getMethods()[0];
Object iPackageDataObserverObject = Proxy.newProxyInstance(
MyApp.class.getClassLoader(), new Class[]{iPackageDataObserverClass},
new InvocationHandler() {
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
Log.i("Proxy", method.getName() + ": " + Arrays.toString(args));
return null;
}
});
clearDataMethod.invoke(activityManager, "com.example.test",iPackageDataObserverObject);
So this works, insofar as the method can be called. No luck on actually being able to clear the data itself. :-(
The method you point isn't static method, so in order to call it you would need the ActivityManager instance, which would be the trickiest part, even if you have root privileges. I can't help you with that.
But as for instantiating IPackageDataObserver, I've managed to do this without special privileges, using standard refrection API:
Class ipdoClass = Class.forName("android.content.pm.IPackageDataObserver");
Object observer = Proxy.newProxyInstance(
MyApp.class.getClassLoader(), new Class[]{ipdoClass},
new InvocationHandler() {
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
Log.i("Proxy", method.getName() + ": " + Arrays.toString(args));
return null;
}
});
Your code should work, but you need to add appropriate permission in your manifest (CLEAR_APP_USER_DATA) and sign Your application with the platform key.
Using Flex 4.5 for Android development, this is the script that should create the database:
private var db:File = File.userDirectory.resolvePath("events.db");
private var conn:SQLConnection;
public function MyDB() {
conn = new SQLConnection();
conn.addEventListener(SQLEvent.OPEN, openHandler);
conn.addEventListener(SQLErrorEvent.ERROR, errorHandler);
conn.open(db, );
}
and I have added this permission:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
but I get this error:
SQLError: 'Error #3125: Unable to open the database file.', details:'Connection closed.', operation:'open', detailID:'1001'
at flash.data::SQLConnection/internalOpen()
at flash.data::SQLConnection/open()
at com.galleons.util::MyDB()[/Users/luca/Documents/Adobe Flash Builder 4.5/Galleons/src/com/galleons/util/MyDB.as:24]
I know it's an old question, but anyway I was facing the same error and found the cause. If any of the parent directories of File which you pass to SQLConnection.open() does not exist, Flash Player throws an Error with detailID=1001. Simply call dbFile.parent.createDirectory() and the error should be gone.
Similar answer was given on Adobe Forums: SQLError #3125
Have you checked the 'usual suspects'?
file exists
not locked by some other app / stale version of your app
path is correct
At least part of the problem is due to mixing the SQLConnection class's open() method – which is synchronous – with events that are only supposed to be used when opening an asynchronous connection. You would open an asynchronous connection by using the openAsync() method instead of the open() method.
The docs are contradictory in this matter because it is, in fact, possible to listen for SQLEvent.OPEN when opening a synchronous connection. However, notice that the SQLErrorEvent.ERROR listener is not being triggered in your code and you are instead getting a runtime error. The docs make no mention of SQLErrorEvent.ERROR working with a synchronous connection; that does appear to be the case.
It's possible this is an AIR bug, but I suspect mixing synchronous methods with asynchronous event listeners is just a gray area. It's also likely that the problem could be solved if you instead wrap the open() call in a try/catch block, which is the recommended way to catch synchronous errors:
try
{
conn.open(db);
trace("Hey, is that a database?", (db.exists));
}
catch (err:SQLError)
{
trace("Error, database not created:", err.message);
trace("Error details:", err.details);
}