Clear parse installation cache on Android - android

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);

Related

BeanShell Android Issue. Unable to start activity remotely

Good day. The main amazing thing about the BeanShell is the idea that i can control what i want to be done dynamically from the server and i thought it would be amazing.
Although i never succeded in achieving that and seems no one else tried to start activity from the beanshell either.
Here how it goes. I simply want to pass the code from the server side to the Android,Android is going to evaluate that code within interpreter and run that.
The issue is that i am getting the exception from BeanShell no matter what i try.
The code from server side is the next.
$response['method'] = "import my.some.name.*;"
. "startActivity(new Intent(this,MyProfile.class))";
The code for Android is the next.
try {
String responseBody = response.body().string();
JSONObject jsonObject = new JSONObject(responseBody);
String method = jsonObject.optString("method");
Interpreter interpreter = new Interpreter();
try {
Object res = interpreter.eval(method);
} catch (EvalError evalError) {
evalError.printStackTrace();
}
} catch (IOException e) {
e.printStackTrace();
} catch (JSONException e) {
e.printStackTrace();
}
}
But i am getting the next exception from the BeanShell
Sourced file: inline evaluation of: ``import my.some.name.*;startActivity(new Intent(this,MyProfile.class));'' : Class: MyProfile not found in namespace : at Line: 1 : in file: inline evaluation of: ``import my.some.name.*;startActivity(new Intent(this,MyProfile.class));'' : MyProfile
Any ideas what is going on?
Just in case if anyone needs the same solution i am posting for everyone to know.
Here how it goes.
Firstly you need to know that whatever you are trying to do on the server side remember that the BeanShell actually does not know anything about the String code you are passing itself,as it is going to interpret it just like a code out of box so with the help of CommonWare hint about full name path i managed to get it working.
So first step to do is to initialize the Interpreter.
Basic initialization goes like this :
String responseBody = response.body().string();
JSONObject jsonObject = new JSONObject(responseBody);
String method = jsonObject.optString("method");
Interpreter interpreter = new Interpreter();
try {
interpreter.set("context",getApplicationContext());
Object res = interpreter.eval(method);
} catch (EvalError evalError) {
evalError.printStackTrace();
}
Take a very attentive notice about the context as it was my main issue going back and forth as at the moment when i succeded to actually force BeanShell recognize my classes,the BeanShell started to throw Method not found exception about the startActivity() so by thinking logically we can assume that we would set the context as activity as the parent one for our remote methods and start evaluating everything from the context. So here how the remote code is looking.
$response['method'] = "import ink.va.activities;"
. "import android.content.Intent;"
. "import android.content.*;"
. "context.startActivity(new android.content.Intent(context, my.package.name.MyProfile.class));";
The most important things to notice here.
• We are importing everything possible for BeanSherll to recognize our classes,even if they are Android-Build,no matter,still we need to import them.
• If you are going to use any class,then as CommonWare noticed out,you MUST specify the full path to that Class E.G my.package.name.MyProfile.class.
• As i was getting Command Not Found i started to think about the context.startActivity() as i have defined the context beforehand in BeanShell as my parent from which i am going to use methods and Woala,everything worked like a charm!
Possible Problems
I don't know a lot about BeanShell, but there's a couple of issues here
You can import a class (in a compiled language) at runtime
You're trying to do the equivalent of Reflection (but aren't doing any)
Security. No user would consent to you having control to open a screen on their app remotely
Presumably BeanShell is supposed to do the reflection under the covers, but in an case you won't be able to do the import.
Possible solutions
The class/activity using the library should import everything (I'm not sure if a compiler will even retain this)
You can use reflection directly, with things like "method from name". The downside is it's very limited what code you can send from the server unless you handle a myriad of cases.
You could only send names/commands; to specific endpoints in your java app (this is what I recommend) and plan the actions you want ahead of time
$response['method'] = "my.some.name.MyProfile";
JSONObject jsonObject = new JSONObject(response.body().string());
String nameParam = jsonObject.optString("method");
Class<? extends Activity> clazz = Class.forName(nameParam); //wrap with try
startActivity( new Intent(this, clazz) )

How to get version info from a shared library into the Android manifest?

We have a shared library that contains version info and is referenced by all our projects in our Visual Studio Solution.
For the most part, we can reference the version string from every project and the dll reflect the info accordingly.
My issue here is, with our Android application (xamarin based). It has a manifest file which contains the versionName and versionCode.
How can we make those values in our android manifest file read from our shared project?
My understanding is that, it is not possible. Because
The manifest file presents essential information about your app to the Android system, information the system must have before it can run any of the app's code.
From Google's documentation
So this is a file that is required before the App builds.
C# Code in Shared Project (SAP/PCL) is ready to be used only after successful Compilation. So logically setting the Version Code and Version Name in Android Manifest File from Shared logic is not possible.
Another standard approach would be to set it from String Resource (XML) file in Android. You may have to copy and paste the value from Shared Project to strings.xml file and refer it in manifest, like
#string/versionCode
Note: I do not know anything about xamarin.
In java you can get the versioninfo from the manifest like this
public static String getAppVersionName(final Context context) {
try {
final String versionName = context.getPackageManager()
.getPackageInfo(context.getPackageName(), 0).versionName;
return versionName;
} catch (final NameNotFoundException e) {
}
return null;
}
I assume that xamarin has some mechanism to call PackageManager to get Packageinfo, too
You could do this by using a Dependency Service. Here's a great article on them: https://developer.xamarin.com/guides/xamarin-forms/dependency-service/
The idea would be your Dependency Service would expose the Android specific information to the shared code library.
For instance you might have an interface in your common code declared such as:
public interface IPlatformVersionInfo
{
string GetOSVersion ();
}
Now, in your Android library you would implement it:
public class PlatformVersionInfo : IPlatformVersionInfo
{
public string GetOSVersion () {
return Android.OS.Build.VERSION.SdkInt.ToString ();
}
}
Finally, in your common code you would use your dependency service of choice to invoke an instance of it:
var osVersion = DependencyService.Get<IPlatformVersionInfo>().GetOSVersion ();
Of course this is somewhat pseudo-code and depending what dependency service you choose the code may look a bit different.

make getSystemService() recognize our new system service

I'm using the book "Embedded Android".
I'm making a new System Service using AOSP(4.0.3_r1).
I want my system service to be registered in frameworks/base/core/java/android/content/app/ContextImpl.java so that I can use it through getSystemService() method.
The problem is, I can't find the app folder under content:androidroot/frameworks/base/core/java/android/content/app/ContextImpl.java
But, I found it in:androidroot/frameworks/base/core/java/android/app/ContextImpl.java
Are these 2 files the same? or is it just missing(the content/app folder)?
Any idea on what to do?
Karim wrote his book mostly orienting on Android 2.3.4 version. Something can be changed from this time. This is an example what has been changed.
Are these 2 files the same? or is it just missing(the content/app folder)?
These are the same files.
Any idea on what to do?
As I said the implementation has been changed. I looked into the code and here what you can change to make your code working (I can only suppose because I did not actually build my code). In the static block of ContextImpl class you need to add the following code:
registerService(ACCOUNT_SERVICE, new ServiceFetcher() {
public Object createService(ContextImpl ctx) {
IBinder b = ServiceManager.getService(OPERSYS_SERVICE);
IOpersysService service = IOpersysService.Stub.asInterface(b);
return new OpersysManager(service);
}});
You need to use SystemServer which holds all system services' names.
You should check this link out:
http://processors.wiki.ti.com/index.php/Android-Adding_SystemService

Clearing the data of another application

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.

How do I use Android PowerProfile private API?

I downloaded the source code from the below link and added to my project.
http://grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android/2.2_r1.1/com/android/internal/os/PowerProfile.java
I am getting and it can not find R file shown below.
int id = com.android.internal.R.xml.power_profile;
Also can not import
import com.android.internal.util.XmlUtils;
I basically want to measure the power consumption of Android devices.
Personally using patached android.jar just causes headaches, using reflection is a 'simple' way of accessing PowerProfile.java. But as #FoamyGuy and countless others have noted this is hidden api so wrap it in a big try catch as it could break on later version of Android.
Class<?> powerProfileClazz = Class.forName("com.android.internal.os.PowerProfile");
//get constructor that takes a context object
Class[] argTypes = { Context.class };
Constructor constructor = powerProfileClazz
.getDeclaredConstructor(argTypes);
Object[] arguments = { context };
//Instantiate
Object powerProInstance = constructor.newInstance(arguments);
//define method
Method batteryCap = powerProfileClazz.getMethod("getBatteryCapacity", null);
//call method
Log.d(TAG, batteryCap.invoke(powerProInstance, null).toString());
Yes you can access the internal API that is com.android.internal.os.PowerProfile
just take a look at this link, and follow the step by step process.
You could use
int id = Resources.getSystem().getIdentifier("power_profile", "xml", "android");
But be aware of what FoamyGuy commented.
Easiest way to do this is to download the framework.jar of android and include that as external library in your project. After including the framework.jar in your android project you can find that resource file.

Categories

Resources