Android 12 and material you detection - java

I'm trying to update my theme with the new Material You, it's working when I select a color in Android parameter (Screenshot red part) but when I disable it (blue part) I've got the default value color set in the SDK xml.
Example with: #android:color/system_accent1_0
I want to know how to check when user select it or not (red or blue part in screenshot), this way i will use another theme when disable. I guess I need to use the new method: applyToActivitiesIfAvailable :
#Override
public void onCreate() {
super.onCreate();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
DynamicColors.applyToActivitiesIfAvailable(this, R.style.AppDynamicTheme, (activity, themeResId) -> {
// ...implement your own logic here. Return `true` if dynamic colors should be applied.
return true; // <- How to know if it's enable or disable in Android parameter ?
});}
My 2nd question is about the icon of the application, when i put blank color in background of ic_launcher.xml it works but not with another color, do you know why ?
Thanks

Related

How to get notified about Android system theme change?

Android introduced Dark Theme in API level 29 and higher (https://developer.android.com/guide/topics/ui/look-and-feel/darktheme). To support Dark Theme in your own app your app's theme needs to inherit from DayNight theme.
But what if you did your own theming, is there any intent from Android to get noticed about the system theme change?
If you add android:configChanges="uiMode" to your activities in the manifest, when the user changes the theme, the onConfigurationChanged method is called. If you override that you can do all the related work in there. In order to check what the current theme is you can do the following:
val currentNightMode = configuration.uiMode and Configuration.UI_MODE_NIGHT_MASK
when (currentNightMode) {
Configuration.UI_MODE_NIGHT_NO -> {} // Night mode is not active, we're using the light theme
Configuration.UI_MODE_NIGHT_YES -> {} // Night mode is active, we're using dark theme
}
EDIT: Since the original question isn't specific to Kotlin, here is the Java version of the above for reference:
int currentNightMode = configuration.uiMode & Configuration.UI_MODE_NIGHT_MASK;
switch (currentNightMode) {
case Configuration.UI_MODE_NIGHT_NO:
// Night mode is not active, we're using the light theme
break;
case Configuration.UI_MODE_NIGHT_YES:
// Night mode is active, we're using dark theme
break;
}
(source)

Edit "app" attribute of xml element

So I got following problem:
I'm currently developing a sensor app and I'd like to check if the sensors are available or not. If they aren't, I want to change the color of a button (which starts an activity where the value of the sensor is being displayed) to grey.
Sadly, I can't just change the background color of the button because I'm using the Circle Button Library by Markushi.
This button looks like this:
<at.markushi.ui.CircleButton
android:layout_width="100dp"
android:layout_height="100dp"
android:src="#drawable/gyroscope"
app:cb_color="#color/colorMain"
app:cb_pressedRingWidth="8dip"
android:id="#+id/gyroscope"
android:layout_alignLeft="#+id/temperature"
android:layout_alignStart="#+id/temperature"
android:layout_below="#+id/title"/>
As you can see this attribute defines the color.
app:cb_color="#color/colorMain"
My Question is: How can I change this color programmaticly in this method?
public void testSensors() {
if (testManager.getDefaultSensor(Sensor.TYPE_TEMPERATURE) == null) {
}
}
EDIT:
setColor doesn't really work. There is this border left. (see image)
Also: I'm using #616161 as the new color.
EDIT2:
Found out, that the border is caused by the transparent circle thing which gets bigger, when the button is pressed. So basically removing this circle thing will be fine. I try to find an answer on my own :)
CircleButton button;
button = (Button)findViewById(R.id.buttonId);
public void testSensors() {
if (testManager.getDefaultSensor(Sensor.TYPE_TEMPERATURE) == null) {
button.setColor(Color.parse("#000000"));
}
}
If you are using normal button then
button.setBackgroundColor(ContextCompat.getColor(context,R.color.colorAccent));
You can use
1) Color.parse("#000000")
2) ContextCompat.getColor(context,R.color.yourColor)
You can use the setColor() method of the circleButton, as you can see from the source code here .
So basically what you need to do is get a reference to your circle Button, using the findViewById method of your activity. then
public void testSensors() {
if (testManager.getDefaultSensor(Sensor.TYPE_TEMPERATURE) == null) {
myCircleButton.setColor(Color.parse("#000000"));
}
}
Also if you are seeing the pressed ring, then that means the state of the button is somehow in the pressed state, so try setting it o false using the setPressed(false) method.
To answer this problem (if anyone has the same):
You can set the animation to 100. This somehow disables the circle.
For some reason the color of the button has now a fixed color (dark grey) but scince this is fine to me and I don't want to cry under my table, I just let it be and move on with my project.
mCircleButton.setAnimationProgress(100);
Thank you all so much for your help! :)

How to make the StatusBar transparent on Android4.2

It is knowed that the StatusBar is black default of Andriod 4.2.
However,I want to make the StatusBar transparent on Launcher and change to be black when it come into an activity. And then,when it come back to the Launcher,the StatusBar recover to transparent.
There is a way to implement,but it do not work perfectly(the Activity open firstly and the StatusBar turn transparent slowly,No strict synchronization).
set "status_bar_background" to be #00000000;
delete the code "mStatusBarWindow.setBackground(null);" which in method "makeStatusBarView()" of PhoneStatusBar.java;
Edit mPixelFormat = PixelFormat.OPAQUE to mPixelFormat = PixelFormat.TRANSLUCENT;
change the code in WindowStateAnimator.java
updateSurfaceWindowCrop(), after the code line
"applyDecorRect(mService.mSystemDecorRect);"
Added:
if(w.mAttrs.type == LayoutParams.TYPE_WALLPAPER) {
w.mSystemDecorRect.top = 0;
}
I think cannot change StatusBar. If you want change, you has to change SystemUI
. You can references via link: http://forum.xda-developers.com/showthread.php?t=2366476
Hide the status bar and use you own header instead of it, best Solution.

3 dot setting menu for android apps with custom title

in an android app,
if you create a new project,
then automatically the 3 dot settings menu is created on phones where it is needed
and it is handled the same way as it would have in older versions by:
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.activity_main, menu);
return true;
}
if you create a custom title, you have to add the 3 dot menu yourself
how do I know when it is needed? meaning phones that don't have the settings button
also how do i create a context menu that is customized and attached to the 3 dot button
Edit:
after a disscusion with Shobhit Puri, I understood that I was not considering the actionbar, since I am using a minimum API 8, I don't have it,
so there is the option that CommonsWare just supplied to check if the settings menu exists (I still need to check if it exists in API 8)
Shobhit Puri's suggestion was:
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(...) ;
ActionBar ab = getActionBar();
ab.setTitle("My Title");
ab.setSubtitle("sub-title") ;
but that of cores requires API 11 or the support library V7
either way I am excepting Shobhit Puri's answer, because of all his help, and I will post my final solution when I know it works
also thanks to CommonsWare for a nice answer
Edit2:
I decided to go with CommonsWare solution for now, I wrote it like this:
if (android.os.Build.VERSION.SDK_INT >= 14) {
ViewConfiguration vc = ViewConfiguration.get(this);
if (!vc.hasPermanentMenuKey()) {
setting_dots.setVisibility(View.VISIBLE);
setting_dots.setOnClickListener(this);
registerForContextMenu(setting_dots);
}
}
ideally I think you should use the actionbar, because it provides you with most of the work, but it has a lot of compatability issues with API 8 which for now I would rather avoid
As #dumazy pointed out that the Action bar's Menu Overflow icon is only shown on those devices which do not have a hardware menu-button.
How do I know when it is needed? meaning phones that don't have the settings button
This is handled by Android itself. You don't need to worry.
how do i create a context menu that is customized and attached to the 3 dot button
You can just have a an xml file inside Menu folder in res. Then you can specify the xml file inside the MenuInflater. Eg:
lets name it list_menu.xml
?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android" >
<item android:id="#+id/menu_item_1"
android:title="#string/menu_string_1"
android:showAsAction="ifRoom|withText"/>
<item android:id="#+id/menu_item_1"
android:title="#string/menu_string_2"
android:showAsAction="ifRoom|withText"/>
</menu>
In the onCreateOptionsMenu you can set it as:
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater mi = getMenuInflater();
mi.inflate(R.menu.list_menu, menu);
return true;
}
This menu would be attached to the overflow-icon and have the items that you want to show when it is clicked. There are some hacks like this which can show the overflow-icon on all devices but using them is highly discouraged. Let android handle this itself.
You seem to use Title bar. Instead, try to use Action Bar for the same.
Hope this answers your question.
how do I know when it is needed? meaning phones that don't have the settings button
Call hasPermanentMenuKey() on a ViewConfiguration.
also how do i create a context menu that is customized and attached to the 3 dot button
By programming. Since you are not using an action bar, it is impossible to give you specific advice that would be relevant.
Google says Actionbar overflow only appears on phones that have no menu hardware keys. Phones with menu keys display the action overflow when the user presses the key.
If you still want to implement this you may follow this solution.
Click here for your reference.
Just copy this method in your activity and call the method from onCreate method
private void getOverflowMenu() {
try {
ViewConfiguration config = ViewConfiguration.get(this);
Field menuKeyField = ViewConfiguration.class.getDeclaredField("sHasPermanentMenuKey");
if(menuKeyField != null) {
menuKeyField.setAccessible(true);
menuKeyField.setBoolean(config, false);
}
} catch (Exception e) {
e.printStackTrace();
}
}

How to disable "Window animation scale" programmatically on Android 4.0+ devices?

I'm using a Service that displays a view using WindowManager, and animation occurs every time I change the view's size using
windowManagerLayoutParams.height = newHeight;
((WindowManager) getSystemService(WINDOW_SERVICE)).updateViewLayout(mMainLayout, windowManagerLayoutParams);
If I disable manually the scale animations, no animation occurs.
Scale animation disabled manually like so:
http://www.cultofandroid.com/11143/android-4-0-tip-how-to-find-and-disable-animations-for-a-snappier-experience/
Is there a way to disable the window scale animations for my application programmatically?
I just had this same problem while working on a system overlay in the SystemUI package and decided to dig through the source to see if I could find a solution. WindowManager.LayoutParams has some hidden goodies that can solve this problem. The trick is to use the privateFlags member of WindowManager.LayoutParams like so:
windowManagerLayoutParams.privateFlags |= 0x00000040;
If you look at line 1019 of WindowManager.java you'll see that 0x00000040 is the value for PRIVATE_FLAG_NO_MOVE_ANIMATION. For me this did stop window animations from occurring on my view when I change the size via updateViewLayout()
I had the advantage of working on a system package so I am able to access privateFlags directly in my code but you are going to need to use reflection if you want to access this field.
As #clark stated this can be changed using reflection:
private void disableAnimations() {
try {
int currentFlags = (Integer) mLayoutParams.getClass().getField("privateFlags").get(mLayoutParams);
mLayoutParams.getClass().getField("privateFlags").set(mLayoutParams, currentFlags|0x00000040);
} catch (Exception e) {
//do nothing. Probably using other version of android
}
}
Did you try Activity#overridePendingTransition(0, 0)?
Check out the documentation:
Call immediately after one of the flavors of startActivity(Intent) or finish() to specify an explicit transition animation to perform next.

Categories

Resources