22

Might be I missed something but is there any flag for knowing if the clock is round or square?

I could imagine that this is important if you want to design the background of the notifications.

rekire
  • 45,039
  • 29
  • 149
  • 249
  • I wrote a short guide about receiving window insets: http://gruszczy.blogspot.com/2015/03/handling-round-screens-using.html – gruszczy Mar 25 '15 at 03:02

7 Answers7

21

Update for API 23:

To determine if the screen is round you can use

context.getResources().getConfiguration().isScreenRound()

Android reference

Or you can use the round and notround resource qualifiers and let the system apply the proper resources but beware that this will not work on devices running API 22 or lower

Source

Thanks to people who pointed out this change.

Old asnwer

From google I/O talk (https://www.youtube.com/watch?v=naf_WbtFAlY#t=284):

From SDK 20 android.view.View class has

public void setOnApplyWindowInsetsListener(OnApplyWindowInsetsListener listener)

and OnApplyWindowInsetsListener has a callback method onApplyWindowsInset

public WindowInsets onApplyWindowInsets(View view, WindowInsets windowInsets){

    if (windowInsets.isRound()){
        //Do stuff
    }

}
IonSpin
  • 1,209
  • 1
  • 13
  • 16
  • 1
    Any idea on how to get this callback to actually fire? I've added an OnApplyWindowInsetsListener to my root view, but onApplyWindowInsets() is never called. Another SO post suggested that I need to call requestApplyInsets() on that view manually, but that doesn't help either. – String Aug 20 '14 at 04:39
  • I've only seen the method called if the device is round. It seems like right now the only way to get it to work properly is to set the 'square defaults' before setting the listener, and then only set the round values in the listener. – Jherico Oct 08 '14 at 22:00
  • Here I created a small class that simplify using it - https://github.com/tajchert/ShapeWear – Michał Tajchert Feb 16 '15 at 14:18
  • Please switch to resource qualifier "-round" and/or getResources().getConfiguration().isScreenRound() – Mark Renouf Mar 29 '16 at 21:39
3

You will probably want to use the WatchViewStub, which is included in the wearable-support library. In the stub, you specify a roundLayout and rectLayout, and the correct one will automatically be inflated based on the user's screen shape. See the WatchViewStub sample app that is included in the SDK for an example of how to do this.

EDIT: The source code for the wearable samples is now online. For this case, take a look at the WatchViewStub sample, which "demonstrates how to specify different layouts for round and rectangular screens": https://developer.android.com/samples/WatchViewStub/project.html

Quick reference:

In the layout:

    <android.blah.WatchViewStub
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:rectLayout="@layout/rect"
        app:roundLayout="@layout/round" />

where rect and round are different layouts for rectangular and round displays.

In the Activity:

setContentView(R.layout.main);
final WatchViewStub stub = (WatchViewStub) findViewById(R.id.stub);
stub.setOnLayoutInflatedListener(new WatchViewStub.OnLayoutInflatedListener() {
    @Override
    public void onLayoutInflated(WatchViewStub stub) {
        mTextView = (TextView) stub.findViewById(R.id.text);
        Log.d(TAG, "TextView: " + mTextView.getText() + " view=" + mTextView);
    }
});

The onLayoutInflated is optional, but it lets you see what is in the layout that got inflated, so you could do addtional customizations based on which layout the WatchViewStub chose to inflate (rectangular or round).

Tony Wickham
  • 4,296
  • 3
  • 25
  • 33
  • The WatchViewStub is part of the closed source Android Wear library from google. The APIs from this library are not supported by all Android watches and specially not in cheaper Chinese OEM models. Make sure that your target watch supports Android Wear before using WatchViewStub. Also WatchViewStub is deprecated starting with API 23 and there are [better ways available](https://android-developers.googleblog.com/2016/04/build-beautifully-for-android-wear.html). – Farrukh Najmi May 04 '17 at 11:19
3

Starting with API 23 you can use the -round and -notround resource qualifiers. So there is no need in some weeks to use the WatchViewStub.

Just as a small example take this layouts:

layout-round/example.xml:

<?xml version="1.0" encoding="utf-8"?>
<TextView
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:gravity="center"
    android:text="@string/round_string"/>

layout-notround/example.xml:

<?xml version="1.0" encoding="utf-8"?>
<TextView
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:gravity="center"
    android:text="@string/square_string"/>

Of cause you could also use just one string:

layout/example.xml:

<?xml version="1.0" encoding="utf-8"?>
<TextView
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:gravity="center"
    android:text="@string/string"/>

values-round/strings.xml:

<resources>
    <string name="string">I am round</string>
</resources>

values-notround/strings.xml:

<resources>
    <string name="string">I am square</string>
</resources>

source

rekire
  • 45,039
  • 29
  • 149
  • 249
1

Following IonSpin's answer, the following lines work just fine:

    if (getResources().getConfiguration().isScreenRound()) {
        //code for round wearables
    } else {
        //code for notround wearables
    }
JorgeAmVF
  • 1,392
  • 3
  • 14
  • 28
0

The windowinsets approach failed in my devices, so I did a small trick, ugly but functional.
If you need to check inside your activity then add in your layout a hidden textview with the value "1" in the round layout and "0" in the rect layout.

<TextView
    android:id="@+id/isRound"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:visibility="gone"
    android:text="1" />

Then in the activity:

TextView isRoundText = (TextView) view.findViewById(R.id.isRound);
boolean isRound = "1".equals(isRoundText.getText());
rekire
  • 45,039
  • 29
  • 149
  • 249
Ignacio Tomas Crespo
  • 3,068
  • 1
  • 14
  • 12
0

I'd like to add my own two cents here because I think I found a solution, although a bit dummy, rather simple and straightforward.

Why ? First, the two solutions exposed by @IonSpin are perfectly working, but the first require SDK 23 minimum, and the other is asynchronous...

Using the -round and -notround qualifiers, simply add a dummy empty view in your Activity XML Layout that is inside the layout-round folder as followed :

<View
    android:layout_width="0dp"
    android:layout_height="0dp"
    android:id="@+id/isRound"/>

Then in your Activity onCreate(), simple do:

Log.d(TAG, "is not round ? " + (findViewById(R.id.isRound) == null));

And it should print on a square smartwatch:

MainActivity: is not round ? true

As a new developer on Android Wear, I find this solution a bit unbelievable but it does work with my Sony SmartWatch 3 and on a Virtual Round Android Wear device.

The only shortcoming / trade-off here is that you have to place a dummy view in all your layouts...

Can you guys confirm it works for you as well ?

Mackovich
  • 2,633
  • 3
  • 25
  • 60
-1

If I understood correctly it'll be using standard Android resources, meaning you can just put your layout in layout-circle and you're done.

Stefan Hoth
  • 2,546
  • 3
  • 19
  • 32
  • I guess that I would put my image in `drawable-circle`. I get now the error message: *`invalid resource directory name: [...]\build\res\all\debug/drawable-circle`*. So I guess you are wrong. – rekire Mar 20 '14 at 07:15
  • @rekire It's a developer preview and the platform will change until the release. So I'm not surprised the tools don't support this yet. – Stefan Hoth Mar 20 '14 at 07:51
  • That make sense. I will only accept this answer if it works for me, but in the meantime +1 ;-) – rekire Mar 20 '14 at 07:53
  • 1
    [OnApplyWindowInsets](https://developer.android.com/reference/android/view/View.html#onApplyWindowInsets(android.view.WindowInsets)) is the class which reports whether the device is round or square! – Paresh Mayani Aug 03 '14 at 08:28
  • Starting with API 23 those suffixes are -round and -notround. – rekire Feb 04 '16 at 19:04