How to get styles from Android Resources class? - android

I'm swappping between applications in Android, I pass a series of parameters to customize the other application (colors, logos, etc.), but I can't find the styles I pass, I can only find the drawables, colors, layouts.
Is there a way to find the styles?
I'm using this
Intent intent = new Intent();
intent.setClassName("com.app.to.call", "com.app.to.call.LoginActivity");
intent.putExtra("package", getPackageName());
intent.putExtra("style", R.style.AppTheme);
startActivity(intent);
From the othe app I'm using
if(customization.getKeys().getString(Global.LINK_PACKAGE) == null) {
customization = null;
}else{
Resources resources = getPackageManager().getResourcesForApplication(customization.getKeys().getString(Global.LINK_PACKAGE));
container.setBackgroundColor(resources.getColor(customization.getKeys().getInt(Global.LINK_BACKGROUND_COLOR)));
setTheme();//How can I get the style?
}
where customization.getKeys() are the keys I pass.

Remember that R class between two application can have the same name variable but a different value. I don't recommend pass R values between apps

Related

How to change theme from another app resource in android?

I know there is a way to set themes by defining in styles.xml and use it like that
setTheme(android.R.style.MyTheme);
However, I want to get themes from another app which I developed as well. I know the resources names and actually I am able to get theme id with this code block;
Resources res = getPackageManager().getResourcesForApplication("com.example.theme");
int resThemeId = res.getIdentifier("my_theme","style","com.example.theme");
When I debug, I see that resThemeId is not zero.
Then, I need the final command to set this theme. Before super.onCreate() function, I try to implement this method but it seems it is not working
setTheme(resThemeId);
But instead of this, if I write below statement, I works fine
setTheme(android.R.style.Theme_Holo_Light);
So, what should I do to use a theme from different package resource?
So, what should I do to use a theme from different package resource?
You shouldn't do this for many reasons. I wrote a simple project that shows that it is indeed possible as long as the package contains the resources your activity uses.
See: https://github.com/jaredrummler/SO-41872033
Basically, you would need to return the package's resources from the activity:
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;
}
}
This is just to show that it is possible. Again, I recommend that you avoid this.
As already mentioned in a comment you can access resources from other applications, but using another applications theme will not work.
Since having proof is always a good thing let's have a look at the source code (I used API 24 sources)
Calling setTheme() on an Activity will invoke initializeTheme() in the ContextThemeWrapper parent class, which will end up calling onApplyThemeResource(..) which in turn will try to load the actual theme data from resources by calling theme.applyStyle(resId, true)
Following the chain through the wrapper Resources.Theme we can see in ResourcesImpl.ThemeImpl the following, where AssetManager is called to load the style into the theme:
void applyStyle(int resId, boolean force) {
synchronized (mKey) {
AssetManager.applyThemeStyle(mTheme, resId, force);
mThemeResId = resId;
mKey.append(resId, force);
}
}
This is where you try and fail to load the foreign theme from your other app.
Since most of the methods you would need to use are static calls or package local methods it does not seem that there is any way to achieve what you want, (e.g. applying or creating a new Theme)
Even if you get a hold of the other application's AssetManager by using getAssets() on a context there is no accessible method to create or apply themes.
So the only way to use another app's resources would be to add the resources to yours.
Have you seen this demo: Multiple Theme Material Design
You can check this demo for runtime theme change.
Hope it will helps you.

how to get application's original logo icon?

Application's icon can be gotten by following code:
Drawable drawable = ResolveInfo.loadIcon(packageManager);
But it is the drawable that maybe modified by ROM (like: right-angle changed to round angle corner), so my question is how can I get original logo icon by program?
P.S. some launcher can do this, like MIUI launcher.
You can get application icon using PackageManager
PackageManager manager = context.getPackageManager();
Drawable appIcon = manager.getApplicationIcon(packagename);
public static Drawable getApplicationIcon(Context context, String packname){
PackageManager pm = context.getPackageManager();
try {
PackageInfo pInfo = pm.getPackageInfo(packname, 0);
int resId = pInfo.applicationInfo.icon;
AssetManager assetManager = AssetManager.class.newInstance();
AssetManager.class.getMethod("addAssetPath", new Class[]{String.class}).invoke(assetManager, pInfo.applicationInfo.sourceDir);
Resources oRes = context.getResources();
Resources resources = new Resources(assetManager, oRes.getDisplayMetrics(), oRes.getConfiguration());
Drawable result = resources.getDrawable(resId);
assetManager.close();
return result;
} catch (Exception e) {
e.printStackTrace();
}
return pm.getDefaultActivityIcon();
}
Sorry for the late reply. But I hope this will help someone new to android.
This method will get the icon associated with the Activity.
public static Drawable getOriginalActivityIcon(Context context,ResolveInfo resolveInfo){
PackageManager packageManager=context.getPackageManager();
try {
ActivityInfo info=resolveInfo.activityInfo;
Drawable drawable = packageManager.getDrawable(info.packageName,info.getIconResource(), packageManager.getApplicationInfo(info.packageName, 0));
if(drawable==null){
drawable=resolveInfo.loadIcon(packageManager);
}
return drawable;
}catch (Exception e){
e.printStackTrace();
}
return packageManager.getDefaultActivityIcon();
}
Use this code
getPackageManager().getApplicationIcon(packagename);
Drawable icon = getPackageManager().getApplicationIcon(packageInfo.packageName);
The conclusion is that if a round icon exists and no adaptive icon exists, you can't get a square icon. Unless this system is customized with a different Android framework than AOSP, such as the MIUI.
At first I was just like you, looking around for a way to load the square icon. I've tried every answer including the ones here.
Finally I found that if both square and round icons are set, then the Android system framework returns the ResId of the round icon when you request the ResId of the icon. At last I went searching for the code of the Android system framework and verified this guess:
When a developer specifies an adaptive application icon, and a non-adaptive round application icon, create an alias from the round icon to the regular icon for v26 APIs and up. We do this because certain devices prefer android:roundIcon over android:icon regardless of the API levels of the drawables set for either. This auto-aliasing behaviour allows an app to prefer the android:roundIcon on API 25 devices, and prefer the adaptive icon on API 26 devices.
If the application contains adaptive icons and the API level >= 26, you can use it to draw out square icon. For example.

making customized theme for android phone

I'm a new mobile developer and i know how to put theme on an application i was able to make 2 mobile application as of now but i wanted to try to make a customized theme for phones. I'm wondering if anyone out there has idea on the following.
1.how to make a customized theme for phone.
2.what is the format of the theme.
3.is it possible to make it in eclipse.
4.what are the things needed to consider to make a theme for phone.
5.how to implement customized theme on phone.
6.available tutorial on making a customized phone theme.
If you want to change theme of a specific theme application like GO Launcher or aHome you can find a link on their site, see this question for more information Themes in Android?
but you can also write your launcher application, if you want to do this, you can see this links: Build An Application Launcher For Android
But if you want to change theme of your application, so you can read these documents and tutorials:
developer.android.com/guide/topics/ui/themes.html
Android Styles and Themes - Tutorial
Another way that i think you must know for building several themes is building an apk for every theme of your application, this solution make your app size smaller. like this function:
public static Resources getResource() {
resourcePackageName = "com.mine.MyApp";
PackageManager packageManager = mContext.getPackageManager();
Resources resources = null, resources2 = null;
try {
resources = mContext.getResources();
resources2 = packageManager
.getResourcesForApplication("com.mine.MyAppTheme");
resourcePackageName = "com.mine.MyAppTheme";
} catch (Exception e) {
Log.d("ss", e.toString());
}
if (resources2 != null)
mResource = resources2;
else
mResource = resources;
return mResource;
}
In this code, your app name is com.mine.MyApp and you have a app with all of resources in the com.mine.MyApp that is your theme, name of theme apk app is com.mine.MyAppTheme. you can use several apk as several theme. just put your resources on theme apk file. you can see this question:
Writing themed applications in Android

Dynamically find the theme name in Android application

I have a tablet application which I am rebranding so there are multiple themes, based on the type of user.
I'd like to find the name of the theme that is currently being applied, and based on that theme then I can do some back-end functionality changes.
I have to dynamically set some image resources, which is fine as long as I pass in the correct theme resource (the R.style.redtheme), but I'd like to set this dynamically.
TypedArray a = getTheme().obtainStyledAttributes(R.style.redtheme, new int[] {aTabResource.mDrawableAttrId});
To do the styling I'm creating custom attributes and then overriding them in the styles.
If there is no simple way to get the theme, I will just save a preference.
The package manager has access to quite a bit of metadata.
It can be accessed like this:
int theme = 0; //0==not set
try
{
String packageName = getClass().getPackage().getName();
PackageInfo packageInfo = getPackageManager().getPackageInfo(packageName, PackageManager.GET_META_DATA);
theme = packageInfo.applicationInfo.theme;
}
catch (Exception e)
{
e.printStackTrace();
}
After this runs, theme will have the style resource.

Android: access "system"-drawables

I'm currently working on an app to display the battery status and I'd like to use Android-drawables instead of own images to reduce the app size.
I've found this page which lists available images and the availability for each SDK-version:http://www.fixedd.com/projects/android_drawables_display
My question: How can I access the "system"-drawables? If you click on the link and choose the tab "Status", there are some battery-drawables like "stat_sys_battery_0", but I can't access it, Eclipse doesn't offer intellisense for it and won't compile the app if I use one of those drawables.
As those drawables are part of all SDK-versions, I'd think I should be able to use them, or are those "special" drawables protected in a way so they can only be used by system-functions (and not apps)?
Any idea is appreciated.
Select0r
Hope this is what you were looking for:
private BroadcastReceiver mBatInfoReceiver = new BroadcastReceiver(){
#Override
public void onReceive(Context arg0, Intent intent) {
int level = intent.getIntExtra("level", 0);
int batteryIconId = intent.getIntExtra("icon-small", 0);
Button toolBarBattery = (Button) findViewById(R.id.toolBarButton);
LevelListDrawable batteryLevel = (LevelListDrawable) getResources().getDrawable(batteryIconId);
batteryLevel.setLevel(level);
toolBarBattery.setBackgroundDrawable(batteryLevel);
}
};
I've found another link with information that not all drawables are public. It doesn't say why some drawables would be private, but I guess I'll have to live with the fact and copy the needed images to my app.http://androiddrawableexplorer.appspot.com/
NOTE: Some of the images in the Android jar are not public and therefore cannot be directly used (you can copy them to you own application, but can't reference them via the "android" package namespace).
There actually seems to be a way to access the system icons, but it's not really working as stated in the documentation, but I'll add it in case somebody is interested:
intent.getIntExtra(BatteryManager.EXTRA_ICON_SMALL, -1)
Will get you the resource-ID of the icon that matches the current battery-status:http://developer.android.com/reference/android/os/BatteryManager.html#EXTRA_ICON_SMALL
Extra for ACTION_BATTERY_CHANGED:
integer containing the resource ID of
a small status bar icon indicating the
current battery state.
However, it always returns the same icon, no matter what the actual battery level is. Finding the icon by just trying random numbers may work, but I don't know if the IDs are consistent throughout the SKD-levels as well as different machines, so I'd rather not rely in that.

Categories

Resources