upload android base code part7
|
@ -0,0 +1,35 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
~ Copyright 2016 Google Inc.
|
||||
~
|
||||
~ Licensed under the Apache License, Version 2.0 (the "License");
|
||||
~ you may not use this file except in compliance with the License.
|
||||
~ You may obtain a copy of the License at
|
||||
~
|
||||
~ http://www.apache.org/licenses/LICENSE-2.0
|
||||
~
|
||||
~ Unless required by applicable law or agreed to in writing, software
|
||||
~ distributed under the License is distributed on an "AS IS" BASIS,
|
||||
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
~ See the License for the specific language governing permissions and
|
||||
~ limitations under the License.
|
||||
-->
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="com.example.android.wearable.wear.wearverifyremoteapp"
|
||||
android:versionCode="1"
|
||||
android:versionName="1.0">
|
||||
|
||||
<application android:allowBackup="true"
|
||||
android:label="@string/app_name"
|
||||
android:icon="@mipmap/ic_launcher"
|
||||
android:theme="@style/AppThemeCustom">
|
||||
|
||||
<activity android:name=".MainMobileActivity">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN"/>
|
||||
<category android:name="android.intent.category.LAUNCHER"/>
|
||||
</intent-filter>
|
||||
</activity>
|
||||
|
||||
</application>
|
||||
</manifest>
|
After Width: | Height: | Size: 196 B |
|
@ -0,0 +1,42 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
~ Copyright 2016 Google Inc.
|
||||
~
|
||||
~ Licensed under the Apache License, Version 2.0 (the "License");
|
||||
~ you may not use this file except in compliance with the License.
|
||||
~ You may obtain a copy of the License at
|
||||
~
|
||||
~ http://www.apache.org/licenses/LICENSE-2.0
|
||||
~
|
||||
~ Unless required by applicable law or agreed to in writing, software
|
||||
~ distributed under the License is distributed on an "AS IS" BASIS,
|
||||
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
~ See the License for the specific language governing permissions and
|
||||
~ limitations under the License.
|
||||
-->
|
||||
<LinearLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:paddingBottom="@dimen/activity_vertical_margin"
|
||||
android:paddingLeft="@dimen/activity_horizontal_margin"
|
||||
android:paddingRight="@dimen/activity_horizontal_margin"
|
||||
android:paddingTop="@dimen/activity_vertical_margin"
|
||||
android:orientation="vertical"
|
||||
tools:context="com.example.android.wearable.wear.wearverifyremoteapp.MainMobileActivity">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/information_text_view"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="0dp"
|
||||
android:layout_weight="5"/>
|
||||
|
||||
<Button
|
||||
android:id="@+id/remote_open_button"
|
||||
android:layout_width="match_parent"
|
||||
android:text="Install App on Wear device(s)"
|
||||
android:layout_height="0dp"
|
||||
android:layout_weight="1"
|
||||
android:visibility="invisible"/>
|
||||
</LinearLayout>
|
After Width: | Height: | Size: 3.3 KiB |
After Width: | Height: | Size: 2.2 KiB |
After Width: | Height: | Size: 4.7 KiB |
After Width: | Height: | Size: 7.5 KiB |
After Width: | Height: | Size: 10 KiB |
|
@ -0,0 +1,24 @@
|
|||
<!--
|
||||
Copyright 2013 The Android Open Source Project
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
|
||||
<resources>
|
||||
|
||||
<!-- Semantic definitions -->
|
||||
|
||||
<dimen name="horizontal_page_margin">@dimen/margin_huge</dimen>
|
||||
<dimen name="vertical_page_margin">@dimen/margin_medium</dimen>
|
||||
|
||||
</resources>
|
|
@ -0,0 +1,25 @@
|
|||
<!--
|
||||
Copyright 2013 The Android Open Source Project
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
|
||||
<resources>
|
||||
|
||||
<style name="Widget.SampleMessage">
|
||||
<item name="android:textAppearance">?android:textAppearanceLarge</item>
|
||||
<item name="android:lineSpacingMultiplier">1.2</item>
|
||||
<item name="android:shadowDy">-6.5</item>
|
||||
</style>
|
||||
|
||||
</resources>
|
|
@ -0,0 +1,22 @@
|
|||
<!--
|
||||
Copyright 2013 The Android Open Source Project
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
|
||||
<resources>
|
||||
|
||||
<!-- Activity themes -->
|
||||
<style name="Theme.Base" parent="android:Theme.Holo.Light" />
|
||||
|
||||
</resources>
|
|
@ -0,0 +1,21 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
Copyright 2013 The Android Open Source Project
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
|
||||
<resources>
|
||||
|
||||
|
||||
</resources>
|
|
@ -0,0 +1,24 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
Copyright 2013 The Android Open Source Project
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
|
||||
<resources>
|
||||
|
||||
<!-- Activity themes -->
|
||||
<style name="Theme.Base" parent="android:Theme.Material.Light">
|
||||
</style>
|
||||
|
||||
</resources>
|
|
@ -0,0 +1,31 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
Copyright 2013 The Android Open Source Project
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
|
||||
<resources>
|
||||
<string name="app_name">WearVerifyRemoteApp</string>
|
||||
<string name="intro_message">
|
||||
<![CDATA[
|
||||
|
||||
|
||||
Sample demonstrates best practices for checking if the remote version of your app is installed on a
|
||||
connected device. This enables standalone Android Wear apps to check if the phone app is installed
|
||||
and the other way around.
|
||||
|
||||
|
||||
]]>
|
||||
</string>
|
||||
</resources>
|
|
@ -0,0 +1,21 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
~ Copyright 2016 Google Inc.
|
||||
~
|
||||
~ Licensed under the Apache License, Version 2.0 (the "License");
|
||||
~ you may not use this file except in compliance with the License.
|
||||
~ You may obtain a copy of the License at
|
||||
~
|
||||
~ http://www.apache.org/licenses/LICENSE-2.0
|
||||
~
|
||||
~ Unless required by applicable law or agreed to in writing, software
|
||||
~ distributed under the License is distributed on an "AS IS" BASIS,
|
||||
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
~ See the License for the specific language governing permissions and
|
||||
~ limitations under the License.
|
||||
-->
|
||||
<resources>
|
||||
<color name="colorPrimary">#3F51B5</color>
|
||||
<color name="colorPrimaryDark">#303F9F</color>
|
||||
<color name="colorAccent">#FF4081</color>
|
||||
</resources>
|
|
@ -0,0 +1,21 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
~ Copyright 2016 Google Inc.
|
||||
~
|
||||
~ Licensed under the Apache License, Version 2.0 (the "License");
|
||||
~ you may not use this file except in compliance with the License.
|
||||
~ You may obtain a copy of the License at
|
||||
~
|
||||
~ http://www.apache.org/licenses/LICENSE-2.0
|
||||
~
|
||||
~ Unless required by applicable law or agreed to in writing, software
|
||||
~ distributed under the License is distributed on an "AS IS" BASIS,
|
||||
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
~ See the License for the specific language governing permissions and
|
||||
~ limitations under the License.
|
||||
-->
|
||||
<resources>
|
||||
<!-- Default screen margins, per the Android Design guidelines. -->
|
||||
<dimen name="activity_horizontal_margin">16dp</dimen>
|
||||
<dimen name="activity_vertical_margin">16dp</dimen>
|
||||
</resources>
|
|
@ -0,0 +1,27 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
~ Copyright 2016 Google Inc.
|
||||
~
|
||||
~ Licensed under the Apache License, Version 2.0 (the "License");
|
||||
~ you may not use this file except in compliance with the License.
|
||||
~ You may obtain a copy of the License at
|
||||
~
|
||||
~ http://www.apache.org/licenses/LICENSE-2.0
|
||||
~
|
||||
~ Unless required by applicable law or agreed to in writing, software
|
||||
~ distributed under the License is distributed on an "AS IS" BASIS,
|
||||
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
~ See the License for the specific language governing permissions and
|
||||
~ limitations under the License.
|
||||
-->
|
||||
<resources>
|
||||
|
||||
<!-- Base application theme. -->
|
||||
<style name="AppThemeCustom" parent="Theme.AppCompat.Light.DarkActionBar">
|
||||
<!-- Customize your theme here. -->
|
||||
<item name="colorPrimary">@color/colorPrimary</item>
|
||||
<item name="colorPrimaryDark">@color/colorPrimaryDark</item>
|
||||
<item name="colorAccent">@color/colorAccent</item>
|
||||
</style>
|
||||
|
||||
</resources>
|
|
@ -0,0 +1,32 @@
|
|||
<!--
|
||||
Copyright 2013 The Android Open Source Project
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
|
||||
<resources>
|
||||
|
||||
<!-- Define standard dimensions to comply with Holo-style grids and rhythm. -->
|
||||
|
||||
<dimen name="margin_tiny">4dp</dimen>
|
||||
<dimen name="margin_small">8dp</dimen>
|
||||
<dimen name="margin_medium">16dp</dimen>
|
||||
<dimen name="margin_large">32dp</dimen>
|
||||
<dimen name="margin_huge">64dp</dimen>
|
||||
|
||||
<!-- Semantic definitions -->
|
||||
|
||||
<dimen name="horizontal_page_margin">@dimen/margin_medium</dimen>
|
||||
<dimen name="vertical_page_margin">@dimen/margin_medium</dimen>
|
||||
|
||||
</resources>
|
|
@ -0,0 +1,42 @@
|
|||
<!--
|
||||
Copyright 2013 The Android Open Source Project
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
|
||||
<resources>
|
||||
|
||||
<!-- Activity themes -->
|
||||
|
||||
<style name="Theme.Base" parent="android:Theme.Light" />
|
||||
|
||||
<style name="Theme.Sample" parent="Theme.Base" />
|
||||
|
||||
<style name="AppTheme" parent="Theme.Sample" />
|
||||
<!-- Widget styling -->
|
||||
|
||||
<style name="Widget" />
|
||||
|
||||
<style name="Widget.SampleMessage">
|
||||
<item name="android:textAppearance">?android:textAppearanceMedium</item>
|
||||
<item name="android:lineSpacingMultiplier">1.1</item>
|
||||
</style>
|
||||
|
||||
<style name="Widget.SampleMessageTile">
|
||||
<item name="android:background">@drawable/tile</item>
|
||||
<item name="android:shadowColor">#7F000000</item>
|
||||
<item name="android:shadowDy">-3.5</item>
|
||||
<item name="android:shadowRadius">2</item>
|
||||
</style>
|
||||
|
||||
</resources>
|
|
@ -0,0 +1,22 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
~ Copyright 2016 Google Inc.
|
||||
~
|
||||
~ Licensed under the Apache License, Version 2.0 (the "License");
|
||||
~ you may not use this file except in compliance with the License.
|
||||
~ You may obtain a copy of the License at
|
||||
~
|
||||
~ http://www.apache.org/licenses/LICENSE-2.0
|
||||
~
|
||||
~ Unless required by applicable law or agreed to in writing, software
|
||||
~ distributed under the License is distributed on an "AS IS" BASIS,
|
||||
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
~ See the License for the specific language governing permissions and
|
||||
~ limitations under the License.
|
||||
-->
|
||||
<resources>
|
||||
<string-array name="android_wear_capabilities">
|
||||
<!-- IMPORTANT NOTE: Should be different than capability in Wear res/values/wear.xml. -->
|
||||
<item>verify_remote_example_phone_app</item>
|
||||
</string-array>
|
||||
</resources>
|
|
@ -0,0 +1,341 @@
|
|||
/*
|
||||
* Copyright (C) 2016 Google Inc. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.example.android.wearable.wear.wearverifyremoteapp;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.os.ResultReceiver;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.v7.app.AppCompatActivity;
|
||||
import android.util.Log;
|
||||
import android.view.View;
|
||||
import android.widget.Button;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import com.google.android.gms.common.ConnectionResult;
|
||||
import com.google.android.gms.common.api.GoogleApiClient;
|
||||
import com.google.android.gms.common.api.PendingResult;
|
||||
import com.google.android.gms.common.api.ResultCallback;
|
||||
import com.google.android.gms.wearable.CapabilityApi;
|
||||
import com.google.android.gms.wearable.CapabilityInfo;
|
||||
import com.google.android.gms.wearable.Node;
|
||||
import com.google.android.gms.wearable.NodeApi;
|
||||
import com.google.android.gms.wearable.Wearable;
|
||||
import com.google.android.wearable.intent.RemoteIntent;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* Checks if the sample's Wear app is installed on remote Wear device(s). If it is not, allows the
|
||||
* user to open the app listing on the Wear devices' Play Store.
|
||||
*/
|
||||
public class MainMobileActivity extends AppCompatActivity implements
|
||||
GoogleApiClient.ConnectionCallbacks,
|
||||
GoogleApiClient.OnConnectionFailedListener,
|
||||
CapabilityApi.CapabilityListener {
|
||||
|
||||
private static final String TAG = "MainMobileActivity";
|
||||
|
||||
private static final String WELCOME_MESSAGE = "Welcome to our Mobile app!\n\n";
|
||||
|
||||
private static final String CHECKING_MESSAGE =
|
||||
WELCOME_MESSAGE + "Checking for Wear Devices for app...\n";
|
||||
|
||||
private static final String NO_DEVICES =
|
||||
WELCOME_MESSAGE
|
||||
+ "You have no Wear devices linked to your phone at this time.\n";
|
||||
|
||||
private static final String MISSING_ALL_MESSAGE =
|
||||
WELCOME_MESSAGE
|
||||
+ "You are missing the Wear app on all your Wear Devices, please click on the "
|
||||
+ "button below to install it on those device(s).\n";
|
||||
|
||||
private static final String INSTALLED_SOME_DEVICES_MESSAGE =
|
||||
WELCOME_MESSAGE
|
||||
+ "Wear app installed on some your device(s) (%s)!\n\nYou can now use the "
|
||||
+ "MessageApi, DataApi, etc.\n\n"
|
||||
+ "To install the Wear app on the other devices, please click on the button "
|
||||
+ "below.\n";
|
||||
|
||||
private static final String INSTALLED_ALL_DEVICES_MESSAGE =
|
||||
WELCOME_MESSAGE
|
||||
+ "Wear app installed on all your devices (%s)!\n\nYou can now use the "
|
||||
+ "MessageApi, DataApi, etc.";
|
||||
|
||||
// Name of capability listed in Wear app's wear.xml.
|
||||
// IMPORTANT NOTE: This should be named differently than your Phone app's capability.
|
||||
private static final String CAPABILITY_WEAR_APP = "verify_remote_example_wear_app";
|
||||
|
||||
// Links to Wear app (Play Store).
|
||||
// TODO: Replace with your links/packages.
|
||||
private static final String PLAY_STORE_APP_URI =
|
||||
"market://details?id=com.example.android.wearable.wear.wearverifyremoteapp";
|
||||
|
||||
// Result from sending RemoteIntent to wear device(s) to open app in play/app store.
|
||||
private final ResultReceiver mResultReceiver = new ResultReceiver(new Handler()) {
|
||||
@Override
|
||||
protected void onReceiveResult(int resultCode, Bundle resultData) {
|
||||
Log.d(TAG, "onReceiveResult: " + resultCode);
|
||||
|
||||
if (resultCode == RemoteIntent.RESULT_OK) {
|
||||
Toast toast = Toast.makeText(
|
||||
getApplicationContext(),
|
||||
"Play Store Request to Wear device successful.",
|
||||
Toast.LENGTH_SHORT);
|
||||
toast.show();
|
||||
|
||||
} else if (resultCode == RemoteIntent.RESULT_FAILED) {
|
||||
Toast toast = Toast.makeText(
|
||||
getApplicationContext(),
|
||||
"Play Store Request Failed. Wear device(s) may not support Play Store, "
|
||||
+ " that is, the Wear device may be version 1.0.",
|
||||
Toast.LENGTH_LONG);
|
||||
toast.show();
|
||||
|
||||
} else {
|
||||
throw new IllegalStateException("Unexpected result " + resultCode);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
private TextView mInformationTextView;
|
||||
private Button mRemoteOpenButton;
|
||||
|
||||
private Set<Node> mWearNodesWithApp;
|
||||
private List<Node> mAllConnectedNodes;
|
||||
|
||||
private GoogleApiClient mGoogleApiClient;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
Log.d(TAG, "onCreate()");
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_main);
|
||||
|
||||
mInformationTextView = (TextView) findViewById(R.id.information_text_view);
|
||||
mRemoteOpenButton = (Button) findViewById(R.id.remote_open_button);
|
||||
|
||||
mInformationTextView.setText(CHECKING_MESSAGE);
|
||||
|
||||
mRemoteOpenButton.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
openPlayStoreOnWearDevicesWithoutApp();
|
||||
}
|
||||
});
|
||||
|
||||
mGoogleApiClient = new GoogleApiClient.Builder(this)
|
||||
.addApi(Wearable.API)
|
||||
.addConnectionCallbacks(this)
|
||||
.addOnConnectionFailedListener(this)
|
||||
.build();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected void onPause() {
|
||||
Log.d(TAG, "onPause()");
|
||||
super.onPause();
|
||||
|
||||
if ((mGoogleApiClient != null) && mGoogleApiClient.isConnected()) {
|
||||
|
||||
Wearable.CapabilityApi.removeCapabilityListener(
|
||||
mGoogleApiClient,
|
||||
this,
|
||||
CAPABILITY_WEAR_APP);
|
||||
|
||||
mGoogleApiClient.disconnect();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onResume() {
|
||||
Log.d(TAG, "onResume()");
|
||||
super.onResume();
|
||||
if (mGoogleApiClient != null) {
|
||||
mGoogleApiClient.connect();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onConnected(@Nullable Bundle bundle) {
|
||||
Log.d(TAG, "onConnected()");
|
||||
|
||||
// Set up listeners for capability changes (install/uninstall of remote app).
|
||||
Wearable.CapabilityApi.addCapabilityListener(
|
||||
mGoogleApiClient,
|
||||
this,
|
||||
CAPABILITY_WEAR_APP);
|
||||
|
||||
// Initial request for devices with our capability, aka, our Wear app installed.
|
||||
findWearDevicesWithApp();
|
||||
|
||||
// Initial request for all Wear devices connected (with or without our capability).
|
||||
// Additional Note: Because there isn't a listener for ALL Nodes added/removed from network
|
||||
// that isn't deprecated, we simply update the full list when the Google API Client is
|
||||
// connected and when capability changes come through in the onCapabilityChanged() method.
|
||||
findAllWearDevices();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onConnectionSuspended(int i) {
|
||||
Log.d(TAG, "onConnectionSuspended(): connection to location client suspended: " + i);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onConnectionFailed(@NonNull ConnectionResult connectionResult) {
|
||||
Log.e(TAG, "onConnectionFailed(): " + connectionResult);
|
||||
}
|
||||
|
||||
/*
|
||||
* Updates UI when capabilities change (install/uninstall wear app).
|
||||
*/
|
||||
public void onCapabilityChanged(CapabilityInfo capabilityInfo) {
|
||||
Log.d(TAG, "onCapabilityChanged(): " + capabilityInfo);
|
||||
|
||||
mWearNodesWithApp = capabilityInfo.getNodes();
|
||||
|
||||
// Because we have an updated list of devices with/without our app, we need to also update
|
||||
// our list of active Wear devices.
|
||||
findAllWearDevices();
|
||||
|
||||
verifyNodeAndUpdateUI();
|
||||
}
|
||||
|
||||
private void findWearDevicesWithApp() {
|
||||
Log.d(TAG, "findWearDevicesWithApp()");
|
||||
|
||||
// You can filter this by FILTER_REACHABLE if you only want to open Nodes (Wear Devices)
|
||||
// directly connect to your phone.
|
||||
PendingResult<CapabilityApi.GetCapabilityResult> pendingResult =
|
||||
Wearable.CapabilityApi.getCapability(
|
||||
mGoogleApiClient,
|
||||
CAPABILITY_WEAR_APP,
|
||||
CapabilityApi.FILTER_ALL);
|
||||
|
||||
pendingResult.setResultCallback(new ResultCallback<CapabilityApi.GetCapabilityResult>() {
|
||||
@Override
|
||||
public void onResult(@NonNull CapabilityApi.GetCapabilityResult getCapabilityResult) {
|
||||
Log.d(TAG, "onResult(): " + getCapabilityResult);
|
||||
|
||||
if (getCapabilityResult.getStatus().isSuccess()) {
|
||||
CapabilityInfo capabilityInfo = getCapabilityResult.getCapability();
|
||||
mWearNodesWithApp = capabilityInfo.getNodes();
|
||||
verifyNodeAndUpdateUI();
|
||||
|
||||
} else {
|
||||
Log.d(TAG, "Failed CapabilityApi: " + getCapabilityResult.getStatus());
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void findAllWearDevices() {
|
||||
Log.d(TAG, "findAllWearDevices()");
|
||||
|
||||
PendingResult<NodeApi.GetConnectedNodesResult> pendingResult =
|
||||
Wearable.NodeApi.getConnectedNodes(mGoogleApiClient);
|
||||
|
||||
pendingResult.setResultCallback(new ResultCallback<NodeApi.GetConnectedNodesResult>() {
|
||||
@Override
|
||||
public void onResult(@NonNull NodeApi.GetConnectedNodesResult getConnectedNodesResult) {
|
||||
|
||||
if (getConnectedNodesResult.getStatus().isSuccess()) {
|
||||
mAllConnectedNodes = getConnectedNodesResult.getNodes();
|
||||
verifyNodeAndUpdateUI();
|
||||
|
||||
} else {
|
||||
Log.d(TAG, "Failed CapabilityApi: " + getConnectedNodesResult.getStatus());
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void verifyNodeAndUpdateUI() {
|
||||
Log.d(TAG, "verifyNodeAndUpdateUI()");
|
||||
|
||||
if ((mWearNodesWithApp == null) || (mAllConnectedNodes == null)) {
|
||||
Log.d(TAG, "Waiting on Results for both connected nodes and nodes with app");
|
||||
|
||||
} else if (mAllConnectedNodes.isEmpty()) {
|
||||
Log.d(TAG, NO_DEVICES);
|
||||
mInformationTextView.setText(NO_DEVICES);
|
||||
mRemoteOpenButton.setVisibility(View.INVISIBLE);
|
||||
|
||||
} else if (mWearNodesWithApp.isEmpty()) {
|
||||
Log.d(TAG, MISSING_ALL_MESSAGE);
|
||||
mInformationTextView.setText(MISSING_ALL_MESSAGE);
|
||||
mRemoteOpenButton.setVisibility(View.VISIBLE);
|
||||
|
||||
} else if (mWearNodesWithApp.size() < mAllConnectedNodes.size()) {
|
||||
// TODO: Add your code to communicate with the wear app(s) via
|
||||
// Wear APIs (MessageApi, DataApi, etc.)
|
||||
|
||||
String installMessage =
|
||||
String.format(INSTALLED_SOME_DEVICES_MESSAGE, mWearNodesWithApp);
|
||||
Log.d(TAG, installMessage);
|
||||
mInformationTextView.setText(installMessage);
|
||||
mRemoteOpenButton.setVisibility(View.VISIBLE);
|
||||
|
||||
} else {
|
||||
// TODO: Add your code to communicate with the wear app(s) via
|
||||
// Wear APIs (MessageApi, DataApi, etc.)
|
||||
|
||||
String installMessage =
|
||||
String.format(INSTALLED_ALL_DEVICES_MESSAGE, mWearNodesWithApp);
|
||||
Log.d(TAG, installMessage);
|
||||
mInformationTextView.setText(installMessage);
|
||||
mRemoteOpenButton.setVisibility(View.INVISIBLE);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private void openPlayStoreOnWearDevicesWithoutApp() {
|
||||
Log.d(TAG, "openPlayStoreOnWearDevicesWithoutApp()");
|
||||
|
||||
// Create a List of Nodes (Wear devices) without your app.
|
||||
ArrayList<Node> nodesWithoutApp = new ArrayList<>();
|
||||
|
||||
for (Node node : mAllConnectedNodes) {
|
||||
if (!mWearNodesWithApp.contains(node)) {
|
||||
nodesWithoutApp.add(node);
|
||||
}
|
||||
}
|
||||
|
||||
if (!nodesWithoutApp.isEmpty()) {
|
||||
Log.d(TAG, "Number of nodes without app: " + nodesWithoutApp.size());
|
||||
|
||||
Intent intent =
|
||||
new Intent(Intent.ACTION_VIEW)
|
||||
.addCategory(Intent.CATEGORY_BROWSABLE)
|
||||
.setData(Uri.parse(PLAY_STORE_APP_URI));
|
||||
|
||||
for (Node node : nodesWithoutApp) {
|
||||
RemoteIntent.startRemoteActivity(
|
||||
getApplicationContext(),
|
||||
intent,
|
||||
mResultReceiver,
|
||||
node.getId());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,51 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
~ Copyright 2016 Google Inc.
|
||||
~
|
||||
~ Licensed under the Apache License, Version 2.0 (the "License");
|
||||
~ you may not use this file except in compliance with the License.
|
||||
~ You may obtain a copy of the License at
|
||||
~
|
||||
~ http://www.apache.org/licenses/LICENSE-2.0
|
||||
~
|
||||
~ Unless required by applicable law or agreed to in writing, software
|
||||
~ distributed under the License is distributed on an "AS IS" BASIS,
|
||||
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
~ See the License for the specific language governing permissions and
|
||||
~ limitations under the License.
|
||||
-->
|
||||
<manifest package="com.example.android.wearable.wear.wearverifyremoteapp"
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:versionCode="1"
|
||||
android:versionName="1.0">
|
||||
|
||||
<uses-feature android:name="android.hardware.type.watch"/>
|
||||
<!-- Required for Always-on. -->
|
||||
<uses-permission android:name="android.permission.WAKE_LOCK"/>
|
||||
|
||||
<application
|
||||
android:allowBackup="true"
|
||||
android:icon="@mipmap/ic_launcher"
|
||||
android:label="@string/app_name"
|
||||
android:supportsRtl="true"
|
||||
android:theme="@android:style/Theme.DeviceDefault">
|
||||
|
||||
<meta-data
|
||||
android:name="com.google.android.wearable.standalone"
|
||||
android:value="true" />
|
||||
|
||||
<!--If you want your app to run on pre-22, then set required to false -->
|
||||
<uses-library android:name="com.google.android.wearable" android:required="false" />
|
||||
|
||||
<activity
|
||||
android:name=".MainWearActivity"
|
||||
android:label="@string/app_name"
|
||||
android:theme="@android:style/Theme.DeviceDefault.Light">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN"/>
|
||||
<category android:name="android.intent.category.LAUNCHER"/>
|
||||
</intent-filter>
|
||||
</activity>
|
||||
|
||||
</application>
|
||||
</manifest>
|
|
@ -0,0 +1,42 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
~ Copyright 2016 Google Inc.
|
||||
~
|
||||
~ Licensed under the Apache License, Version 2.0 (the "License");
|
||||
~ you may not use this file except in compliance with the License.
|
||||
~ You may obtain a copy of the License at
|
||||
~
|
||||
~ http://www.apache.org/licenses/LICENSE-2.0
|
||||
~
|
||||
~ Unless required by applicable law or agreed to in writing, software
|
||||
~ distributed under the License is distributed on an "AS IS" BASIS,
|
||||
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
~ See the License for the specific language governing permissions and
|
||||
~ limitations under the License.
|
||||
-->
|
||||
<LinearLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical"
|
||||
android:paddingTop="@dimen/activity_main_top_padding"
|
||||
android:paddingRight="@dimen/activity_main_right_padding"
|
||||
android:paddingLeft="@dimen/activity_main_left_padding"
|
||||
android:paddingBottom="@dimen/activity_main_bottom_padding"
|
||||
tools:context="com.example.android.wearable.wear.wearverifyremoteapp.MainWearActivity">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/information_text_view"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="0dp"
|
||||
android:layout_weight="3"/>
|
||||
|
||||
<Button
|
||||
android:id="@+id/remote_open_button"
|
||||
android:layout_width="match_parent"
|
||||
android:text="Install Mobile App"
|
||||
android:layout_height="0dp"
|
||||
android:layout_weight="1"
|
||||
android:visibility="invisible"/>
|
||||
</LinearLayout>
|
After Width: | Height: | Size: 3.3 KiB |
After Width: | Height: | Size: 2.2 KiB |
After Width: | Height: | Size: 4.7 KiB |
After Width: | Height: | Size: 7.5 KiB |
|
@ -0,0 +1,22 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
~ Copyright 2016 Google Inc.
|
||||
~
|
||||
~ Licensed under the Apache License, Version 2.0 (the "License");
|
||||
~ you may not use this file except in compliance with the License.
|
||||
~ You may obtain a copy of the License at
|
||||
~
|
||||
~ http://www.apache.org/licenses/LICENSE-2.0
|
||||
~
|
||||
~ Unless required by applicable law or agreed to in writing, software
|
||||
~ distributed under the License is distributed on an "AS IS" BASIS,
|
||||
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
~ See the License for the specific language governing permissions and
|
||||
~ limitations under the License.
|
||||
-->
|
||||
<resources>
|
||||
<dimen name="activity_main_top_padding">36dp</dimen>
|
||||
<dimen name="activity_main_bottom_padding">22dp</dimen>
|
||||
<dimen name="activity_main_right_padding">36dp</dimen>
|
||||
<dimen name="activity_main_left_padding">36dp</dimen>
|
||||
</resources>
|
|
@ -0,0 +1,22 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
~ Copyright 2016 Google Inc.
|
||||
~
|
||||
~ Licensed under the Apache License, Version 2.0 (the "License");
|
||||
~ you may not use this file except in compliance with the License.
|
||||
~ You may obtain a copy of the License at
|
||||
~
|
||||
~ http://www.apache.org/licenses/LICENSE-2.0
|
||||
~
|
||||
~ Unless required by applicable law or agreed to in writing, software
|
||||
~ distributed under the License is distributed on an "AS IS" BASIS,
|
||||
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
~ See the License for the specific language governing permissions and
|
||||
~ limitations under the License.
|
||||
-->
|
||||
<resources>
|
||||
<dimen name="activity_main_top_padding">5dp</dimen>
|
||||
<dimen name="activity_main_bottom_padding">5dp</dimen>
|
||||
<dimen name="activity_main_right_padding">5dp</dimen>
|
||||
<dimen name="activity_main_left_padding">5dp</dimen>
|
||||
</resources>
|
|
@ -0,0 +1,19 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
~ Copyright 2016 Google Inc.
|
||||
~
|
||||
~ Licensed under the Apache License, Version 2.0 (the "License");
|
||||
~ you may not use this file except in compliance with the License.
|
||||
~ You may obtain a copy of the License at
|
||||
~
|
||||
~ http://www.apache.org/licenses/LICENSE-2.0
|
||||
~
|
||||
~ Unless required by applicable law or agreed to in writing, software
|
||||
~ distributed under the License is distributed on an "AS IS" BASIS,
|
||||
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
~ See the License for the specific language governing permissions and
|
||||
~ limitations under the License.
|
||||
-->
|
||||
<resources>
|
||||
<string name="app_name">Wear Verify Remote App</string>
|
||||
</resources>
|
|
@ -0,0 +1,22 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
~ Copyright 2016 Google Inc.
|
||||
~
|
||||
~ Licensed under the Apache License, Version 2.0 (the "License");
|
||||
~ you may not use this file except in compliance with the License.
|
||||
~ You may obtain a copy of the License at
|
||||
~
|
||||
~ http://www.apache.org/licenses/LICENSE-2.0
|
||||
~
|
||||
~ Unless required by applicable law or agreed to in writing, software
|
||||
~ distributed under the License is distributed on an "AS IS" BASIS,
|
||||
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
~ See the License for the specific language governing permissions and
|
||||
~ limitations under the License.
|
||||
-->
|
||||
<resources>
|
||||
<string-array name="android_wear_capabilities">
|
||||
<!-- IMPORTANT NOTE: Should be different than capability in App res/values/wear.xml. -->
|
||||
<item>verify_remote_example_wear_app</item>
|
||||
</string-array>
|
||||
</resources>
|
|
@ -0,0 +1,302 @@
|
|||
/*
|
||||
* Copyright (C) 2016 Google Inc. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.example.android.wearable.wear.wearverifyremoteapp;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.os.ResultReceiver;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.wearable.activity.WearableActivity;
|
||||
import android.support.wearable.view.ConfirmationOverlay;
|
||||
import android.util.Log;
|
||||
import android.view.View;
|
||||
import android.widget.Button;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.google.android.gms.common.ConnectionResult;
|
||||
import com.google.android.gms.common.api.GoogleApiClient;
|
||||
import com.google.android.gms.common.api.PendingResult;
|
||||
import com.google.android.gms.common.api.ResultCallback;
|
||||
import com.google.android.gms.wearable.CapabilityApi;
|
||||
import com.google.android.gms.wearable.CapabilityInfo;
|
||||
import com.google.android.gms.wearable.Node;
|
||||
import com.google.android.gms.wearable.Wearable;
|
||||
import com.google.android.wearable.intent.RemoteIntent;
|
||||
import com.google.android.wearable.playstore.PlayStoreAvailability;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* Checks if the phone app is installed on remote device. If it is not, allows user to open app
|
||||
* listing on the phone's Play or App Store.
|
||||
*/
|
||||
public class MainWearActivity extends WearableActivity implements
|
||||
GoogleApiClient.ConnectionCallbacks,
|
||||
GoogleApiClient.OnConnectionFailedListener,
|
||||
CapabilityApi.CapabilityListener {
|
||||
|
||||
private static final String TAG = "MainWearActivity";
|
||||
|
||||
private static final String WELCOME_MESSAGE = "Welcome to our Wear app!\n\n";
|
||||
|
||||
private static final String CHECKING_MESSAGE =
|
||||
WELCOME_MESSAGE + "Checking for Mobile app...\n";
|
||||
|
||||
private static final String MISSING_MESSAGE =
|
||||
WELCOME_MESSAGE
|
||||
+ "You are missing the required phone app, please click on the button below to "
|
||||
+ "install it on your phone.\n";
|
||||
|
||||
private static final String INSTALLED_MESSAGE =
|
||||
WELCOME_MESSAGE
|
||||
+ "Mobile app installed on your %s!\n\nYou can now use MessageApi, "
|
||||
+ "DataApi, etc.";
|
||||
|
||||
// Name of capability listed in Phone app's wear.xml.
|
||||
// IMPORTANT NOTE: This should be named differently than your Wear app's capability.
|
||||
private static final String CAPABILITY_PHONE_APP = "verify_remote_example_phone_app";
|
||||
|
||||
// Links to install mobile app for both Android (Play Store) and iOS.
|
||||
// TODO: Replace with your links/packages.
|
||||
private static final String PLAY_STORE_APP_URI =
|
||||
"market://details?id=com.example.android.wearable.wear.wearverifyremoteapp";
|
||||
|
||||
// TODO: Replace with your links/packages.
|
||||
private static final String APP_STORE_APP_URI =
|
||||
"https://itunes.apple.com/us/app/android-wear/id986496028?mt=8";
|
||||
|
||||
// Result from sending RemoteIntent to phone to open app in play/app store.
|
||||
private final ResultReceiver mResultReceiver = new ResultReceiver(new Handler()) {
|
||||
@Override
|
||||
protected void onReceiveResult(int resultCode, Bundle resultData) {
|
||||
|
||||
if (resultCode == RemoteIntent.RESULT_OK) {
|
||||
new ConfirmationOverlay().showOn(MainWearActivity.this);
|
||||
|
||||
} else if (resultCode == RemoteIntent.RESULT_FAILED) {
|
||||
new ConfirmationOverlay()
|
||||
.setType(ConfirmationOverlay.FAILURE_ANIMATION)
|
||||
.showOn(MainWearActivity.this);
|
||||
|
||||
} else {
|
||||
throw new IllegalStateException("Unexpected result " + resultCode);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
private TextView mInformationTextView;
|
||||
private Button mRemoteOpenButton;
|
||||
|
||||
private Node mAndroidPhoneNodeWithApp;
|
||||
|
||||
private GoogleApiClient mGoogleApiClient;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
Log.d(TAG, "onCreate()");
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
setContentView(R.layout.activity_main);
|
||||
setAmbientEnabled();
|
||||
|
||||
mInformationTextView = (TextView) findViewById(R.id.information_text_view);
|
||||
mRemoteOpenButton = (Button) findViewById(R.id.remote_open_button);
|
||||
|
||||
mInformationTextView.setText(CHECKING_MESSAGE);
|
||||
|
||||
mRemoteOpenButton.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
openAppInStoreOnPhone();
|
||||
}
|
||||
});
|
||||
|
||||
mGoogleApiClient = new GoogleApiClient.Builder(this)
|
||||
.addApi(Wearable.API)
|
||||
.addConnectionCallbacks(this)
|
||||
.addOnConnectionFailedListener(this)
|
||||
.build();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected void onPause() {
|
||||
Log.d(TAG, "onPause()");
|
||||
super.onPause();
|
||||
|
||||
if ((mGoogleApiClient != null) && mGoogleApiClient.isConnected()) {
|
||||
Wearable.CapabilityApi.removeCapabilityListener(
|
||||
mGoogleApiClient,
|
||||
this,
|
||||
CAPABILITY_PHONE_APP);
|
||||
|
||||
mGoogleApiClient.disconnect();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onResume() {
|
||||
Log.d(TAG, "onResume()");
|
||||
super.onResume();
|
||||
if (mGoogleApiClient != null) {
|
||||
mGoogleApiClient.connect();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onConnected(@Nullable Bundle bundle) {
|
||||
Log.d(TAG, "onConnected()");
|
||||
|
||||
// Set up listeners for capability changes (install/uninstall of remote app).
|
||||
Wearable.CapabilityApi.addCapabilityListener(
|
||||
mGoogleApiClient,
|
||||
this,
|
||||
CAPABILITY_PHONE_APP);
|
||||
|
||||
checkIfPhoneHasApp();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onConnectionSuspended(int i) {
|
||||
Log.d(TAG, "onConnectionSuspended(): connection to location client suspended: " + i);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onConnectionFailed(@NonNull ConnectionResult connectionResult) {
|
||||
Log.e(TAG, "onConnectionFailed(): " + connectionResult);
|
||||
}
|
||||
|
||||
/*
|
||||
* Updates UI when capabilities change (install/uninstall phone app).
|
||||
*/
|
||||
public void onCapabilityChanged(CapabilityInfo capabilityInfo) {
|
||||
Log.d(TAG, "onCapabilityChanged(): " + capabilityInfo);
|
||||
|
||||
mAndroidPhoneNodeWithApp = pickBestNodeId(capabilityInfo.getNodes());
|
||||
verifyNodeAndUpdateUI();
|
||||
}
|
||||
|
||||
private void checkIfPhoneHasApp() {
|
||||
Log.d(TAG, "checkIfPhoneHasApp()");
|
||||
|
||||
PendingResult<CapabilityApi.GetCapabilityResult> pendingResult =
|
||||
Wearable.CapabilityApi.getCapability(
|
||||
mGoogleApiClient,
|
||||
CAPABILITY_PHONE_APP,
|
||||
CapabilityApi.FILTER_ALL);
|
||||
|
||||
pendingResult.setResultCallback(new ResultCallback<CapabilityApi.GetCapabilityResult>() {
|
||||
|
||||
@Override
|
||||
public void onResult(@NonNull CapabilityApi.GetCapabilityResult getCapabilityResult) {
|
||||
Log.d(TAG, "onResult(): " + getCapabilityResult);
|
||||
|
||||
if (getCapabilityResult.getStatus().isSuccess()) {
|
||||
CapabilityInfo capabilityInfo = getCapabilityResult.getCapability();
|
||||
mAndroidPhoneNodeWithApp = pickBestNodeId(capabilityInfo.getNodes());
|
||||
verifyNodeAndUpdateUI();
|
||||
|
||||
} else {
|
||||
Log.d(TAG, "Failed CapabilityApi: " + getCapabilityResult.getStatus());
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void verifyNodeAndUpdateUI() {
|
||||
|
||||
if (mAndroidPhoneNodeWithApp != null) {
|
||||
|
||||
// TODO: Add your code to communicate with the phone app via
|
||||
// Wear APIs (MessageApi, DataApi, etc.)
|
||||
|
||||
String installMessage =
|
||||
String.format(INSTALLED_MESSAGE, mAndroidPhoneNodeWithApp.getDisplayName());
|
||||
Log.d(TAG, installMessage);
|
||||
mInformationTextView.setText(installMessage);
|
||||
mRemoteOpenButton.setVisibility(View.INVISIBLE);
|
||||
|
||||
} else {
|
||||
Log.d(TAG, MISSING_MESSAGE);
|
||||
mInformationTextView.setText(MISSING_MESSAGE);
|
||||
mRemoteOpenButton.setVisibility(View.VISIBLE);
|
||||
}
|
||||
}
|
||||
|
||||
private void openAppInStoreOnPhone() {
|
||||
Log.d(TAG, "openAppInStoreOnPhone()");
|
||||
|
||||
int playStoreAvailabilityOnPhone =
|
||||
PlayStoreAvailability.getPlayStoreAvailabilityOnPhone(getApplicationContext());
|
||||
|
||||
switch (playStoreAvailabilityOnPhone) {
|
||||
|
||||
// Android phone with the Play Store.
|
||||
case PlayStoreAvailability.PLAY_STORE_ON_PHONE_AVAILABLE:
|
||||
Log.d(TAG, "\tPLAY_STORE_ON_PHONE_AVAILABLE");
|
||||
|
||||
// Create Remote Intent to open Play Store listing of app on remote device.
|
||||
Intent intentAndroid =
|
||||
new Intent(Intent.ACTION_VIEW)
|
||||
.addCategory(Intent.CATEGORY_BROWSABLE)
|
||||
.setData(Uri.parse(PLAY_STORE_APP_URI));
|
||||
|
||||
RemoteIntent.startRemoteActivity(
|
||||
getApplicationContext(),
|
||||
intentAndroid,
|
||||
mResultReceiver);
|
||||
break;
|
||||
|
||||
// Assume iPhone (iOS device) or Android without Play Store (not supported right now).
|
||||
case PlayStoreAvailability.PLAY_STORE_ON_PHONE_UNAVAILABLE:
|
||||
Log.d(TAG, "\tPLAY_STORE_ON_PHONE_UNAVAILABLE");
|
||||
|
||||
// Create Remote Intent to open App Store listing of app on iPhone.
|
||||
Intent intentIOS =
|
||||
new Intent(Intent.ACTION_VIEW)
|
||||
.addCategory(Intent.CATEGORY_BROWSABLE)
|
||||
.setData(Uri.parse(APP_STORE_APP_URI));
|
||||
|
||||
RemoteIntent.startRemoteActivity(
|
||||
getApplicationContext(),
|
||||
intentIOS,
|
||||
mResultReceiver);
|
||||
break;
|
||||
|
||||
case PlayStoreAvailability.PLAY_STORE_ON_PHONE_ERROR_UNKNOWN:
|
||||
Log.d(TAG, "\tPLAY_STORE_ON_PHONE_ERROR_UNKNOWN");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* There should only ever be one phone in a node set (much less w/ the correct capability), so
|
||||
* I am just grabbing the first one (which should be the only one).
|
||||
*/
|
||||
private Node pickBestNodeId(Set<Node> nodes) {
|
||||
Log.d(TAG, "pickBestNodeId(): " + nodes);
|
||||
|
||||
Node bestNodeId = null;
|
||||
// Find a nearby node/phone or pick one arbitrarily. Realistically, there is only one phone.
|
||||
for (Node node : nodes) {
|
||||
bestNodeId = node;
|
||||
}
|
||||
return bestNodeId;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
|
||||
page.tags="WearVerifyRemoteApp"
|
||||
sample.group=Wearable
|
||||
@jd:body
|
||||
|
||||
<p>
|
||||
|
||||
Sample demonstrates best practices for checking if the remote version of your app is installed on a
|
||||
connected device. This enables standalone Android Wear apps to check if the phone app is installed
|
||||
and the other way around.
|
||||
|
||||
</p>
|