Briefly introduce the reason for this demand, this time due to the company's business needs, which has a "Set system language" function, is in the process of using the app, dynamic to switch the entire Android machine language, specific reference to the mobile Phone Settings page has language switching function. At first to want to be very simple things, it is not a simple resource internationalization, strings.xml resources file a whole not to OK? Really move hands is really not the case, internationalization is no problem, but how to change all the pages of the text resources, this is a problem. Below is a brief introduction to some of the online solutions.
First, API spoofing
The Android.jar that are fired into the phone contain the various classes and methods needed for Android, and the Android.jar for developers is just a part of it. API spoofing refers to the application of the simulation of non-public classes and methods so that the application compiled and generated apk, however, in the actual operation of the application is still fired into the mobile phone real android.jar.
Second, using Java reflection mechanism
Both Iactivitymanager and activitymanagernative are non-public classes that use Java reflection to invoke the methods in them.
But the drawback is obvious, both of these methods are to change the system's language type, the function and you go to set the page to set the language type effect. After discovering that new locale have been set up for the current system, not only have their own applications changed, but all of the applications in the system have changed, which is exactly what we need.
The core code is as follows:
/** * todo< Update System language > * * @author Xiho * @versionCode 1 < +1>/@SuppressWarnings ("unchecked") before each modification is submitted publ IC class Languageutils {public static void Updatelanguage (Locale Locale) {try {Object objiactmag, OBJACTM
agnative;
Class Clziactmag = Class.forName ("Android.app.IActivityManager");
Class clzactmagnative = class. forname ("android.app.ActivityManagerNative");
Amn = Activitymanagernative.getdefault ();
Method Mtdactmagnative$getdefault = clzactmagnative. Getdeclaredmethod ("Getdefault");
Objiactmag = Mtdactmagnative$getdefault.invoke (clzactmagnative);
Objiactmag = Amn.getconfiguration ();
Method mtdiactmag$getconfiguration = Clziactmag. Getdeclaredmethod ("GetConfiguration");
Configuration config = (Configuration) mtdiactmag$getconfiguration. Invoke (Objiactmag);
Set the locale to the new value Config.locale = locale; Persistent CONFIG.USersetlocale = true;
Class Clzconfig = class. forname ("Android.content.res.Configuration");
Java.lang.reflect.Field Usersetlocale = clzconfig. GetField ("Usersetlocale");
Usersetlocale.set (config, true);
You need to declare permissions here: Android.permission.CHANGE_CONFIGURATION//Will recall onCreate ();
Class[] Clzparams = {Configuration.class};
Objiactmag.updateconfiguration (config);
Method mtdiactmag$updateconfiguration = Clziactmag. Getdeclaredmethod ("Updateconfiguration", clzParams);
Mtdiactmag$updateconfiguration.invoke (objiactmag, config);
Backupmanager.datachanged ("com.android.providers.settings");
catch (Exception e) {e.printstacktrace ();
}
}
}
So we use the reflection mechanism of Java, invoke those hidden methods can be implemented.
Note that you call this method:
Objiactmag.updateconfiguration (config);
Mtdiactmag$updateconfiguration.invoke (objiactmag, config);
Need to add permissions:
Android.permission.CHANGE_CONFIGURATION
And the OnCreate method will be called back here, and I'll be in a hole in this place. (If you do some logic when calling this method, notice).
Final statement:
Since you are changing the configuration of your system, your signature should also be the system signature and Shareduserid. Otherwise it will be similar to the following error!
Error
Java.lang.SecurityException:Permission denial:updateconfiguration () from pid=31594, uid=10099 requires Android.permission.CHANGE_CONFIGURATION
All of you, watch out.