Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android :: How to change theme from other apk programmatically

Tags:

android

themes

I have a apps named: preference, and i want to make themes for this apps. My AndroidManifest.xml of preference is:

<application
    android:allowBackup="true"
    android:icon="@drawable/ic_launcher"
    android:label="@string/app_name"
    android:theme="@style/AppTheme" >
    <activity
        android:name="com.example.preference.MainActivity"
        android:label="@string/app_name" >
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />
            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>        
</application>

And in the MainActivity.java: I received theme change button click by:

themeChange = (Button) findViewById(R.id.themeChange);
themeChange.setOnClickListener(this);

I have a theme application which has PinkTheme (styles.xml) and the package name is com.example.theme.

<resources xmlns:android="http://schemas.android.com/apk/res/android">
    <style name="AppBaseTheme" parent="android:Theme.Light">
        <!--
            Theme customizations available in newer API levels can go in
            res/values-vXX/styles.xml, while customizations related to
            backward-compatibility can go here.
        -->
    </style>
    <style name="PinkTheme" parent="AppBaseTheme" >
        <item name="android:textColor">#FF69B4</item>
        <item name="android:typeface">monospace</item>
        <item name="android:textSize">40sp</item>
        <item name="android:windowBackground">#008000</item>
    </style>
</resources>

And the onClick() of my preference is:

public void onClick(View v) {
    // TODO Auto-generated method stub
    switch(v.getId()){

    case R.id.themeChange:          
      Resources res = null;
      try {
          res = getPackageManager().getResourcesForApplication("com.example.theme");
      } catch (NameNotFoundException e) {
          // TODO Auto-generated catch block
          e.printStackTrace();
      }
      if(null != res) {
        int sId = res.getIdentifier("com.example.theme:style/PinkTheme", null, null);
        Theme themeObject = res.newTheme();  // theme object
        themeObject.applyStyle(sId, true);  // Place new attribute values into the theme
        getTheme().setTo(themeObject);
      }
        break;

    default:
        break;

    }
}

I have received theme Object of the theme package and try to setTheme of the preference application. But its not working. Please help me that: how to set theme from others application to my current application programmatically.

like image 588
Rontdu Avatar asked Aug 10 '14 06:08

Rontdu


2 Answers

If you want to change settings in one application from another, then probably the easiest way to do it is to put a theme ID into an intent and send that intent to your MainActivity (or to an IntentService) where the receiving app can process the data. For example when the intent arrives, you can process it like you do a click event in your "onClick" logic.

For example, an app can create an intent like this:

    Intent intent = new Intent("android.intent.action.MAIN");
    intent.setComponent(new ComponentName("your.package", "your.package.component"));
    intent.putExtra("theme_id", "theme_1");
    startActivity(intent);

Then in your activity, use getIntent().getStringExtra("theme_id") to get the data passed to your app.

like image 121
Jim Avatar answered Oct 22 '22 19:10

Jim


You would need to use the application's resources to load the theme. I have answered this in another thread here: https://stackoverflow.com/a/41948943/1048340

Here is an example where the package "com.example.theme" is installed and we use the app's resources and theme style in another app:

public class MainActivity extends AppCompatActivity {

  Resources resources;

  @Override protected void onCreate(Bundle savedInstanceState) {

    int themeResId = getResources().getIdentifier("AppTheme", "style", "com.example.theme");
    if (themeResId != 0) {
      setTheme(themeResId);
    }

    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
  }

  @Override public Resources getResources() {
    if (resources == null) {
      try {
        resources = getPackageManager().getResourcesForApplication("com.example.theme");
      } catch (PackageManager.NameNotFoundException e) {
        resources = super.getResources();
      }
    }
    return resources;
  }

}

See here for a working project on GitHub.


This can lead to problems because all layouts, drawables, strings, etc. will be loaded from the other application's resources. Therefore, you should avoid using a theme from another package and instead copy the resources and theme to your own project.

like image 29
Jared Rummler Avatar answered Oct 22 '22 20:10

Jared Rummler