upload android base code part7

This commit is contained in:
August 2018-08-08 18:09:17 +08:00
parent 4e516ec6ed
commit 841ae54672
25229 changed files with 1709508 additions and 0 deletions

View file

@ -0,0 +1,42 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2014 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.
-->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.android.wearable.findphone">
<uses-sdk android:minSdkVersion="18"
android:targetSdkVersion="23" />
<uses-permission android:name="android.permission.VIBRATE" />
<application
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@android:style/Theme.Holo.Light"
android:allowBackup="true">
<meta-data
android:name="com.google.android.gms.version"
android:value="@integer/google_play_services_version" />
<service
android:name="com.example.android.wearable.findphone.SoundAlarmListenerService" >
<intent-filter>
<action android:name="com.google.android.gms.wearable.BIND_LISTENER" />
</intent-filter>
</service>
</application>
</manifest>

Binary file not shown.

After

Width:  |  Height:  |  Size: 1,000 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 196 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 696 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

View file

@ -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>

View file

@ -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>

View file

@ -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>

View file

@ -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>

View file

@ -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>

View file

@ -0,0 +1,32 @@
<?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">FindMyPhone</string>
<string name="intro_message">
<![CDATA[
This sample application notifies you when you may have left your phone behind
(specifically, when your companion and wearable disconnect). If you have misplaced your phone, but
it is still connected to your wearable, you can also start an activity on the wearable to sound an
alarm on your phone.
]]>
</string>
</resources>

View file

@ -0,0 +1,18 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2014 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>

View file

@ -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>

View file

@ -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>

View file

@ -0,0 +1,7 @@
<resources>
<string-array name="android_wear_capabilities">
<!-- declaring that phone provides find_me capability -->
<item>find_me</item>
</string-array>
</resources>

View file

@ -0,0 +1,100 @@
/*
* Copyright (C) 2014 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.
*/
package com.example.android.wearable.findphone;
import android.media.AudioManager;
import android.media.MediaPlayer;
import android.media.RingtoneManager;
import android.net.Uri;
import android.util.Log;
import com.google.android.gms.wearable.DataEvent;
import com.google.android.gms.wearable.DataEventBuffer;
import com.google.android.gms.wearable.DataMap;
import com.google.android.gms.wearable.WearableListenerService;
import java.io.IOException;
/**
* Listens for disconnection from home device.
*/
public class SoundAlarmListenerService extends WearableListenerService {
private static final String TAG = "ExampleFindPhoneApp";
private static final String FIELD_ALARM_ON = "alarm_on";
private AudioManager mAudioManager;
private static int mOrigVolume;
private int mMaxVolume;
private Uri mAlarmSound;
private MediaPlayer mMediaPlayer;
@Override
public void onCreate() {
super.onCreate();
mAudioManager = (AudioManager) getSystemService(AUDIO_SERVICE);
mOrigVolume = mAudioManager.getStreamVolume(AudioManager.STREAM_ALARM);
mMaxVolume = mAudioManager.getStreamMaxVolume(AudioManager.STREAM_ALARM);
mAlarmSound = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_ALARM);
mMediaPlayer = new MediaPlayer();
}
@Override
public void onDestroy() {
// Reset the alarm volume to the user's original setting.
mAudioManager.setStreamVolume(AudioManager.STREAM_ALARM, mOrigVolume, 0);
mMediaPlayer.release();
super.onDestroy();
}
@Override
public void onDataChanged(DataEventBuffer dataEvents) {
if (Log.isLoggable(TAG, Log.DEBUG)) {
Log.d(TAG, "onDataChanged: " + dataEvents + " for " + getPackageName());
}
for (DataEvent event : dataEvents) {
if (event.getType() == DataEvent.TYPE_DELETED) {
Log.i(TAG, event + " deleted");
} else if (event.getType() == DataEvent.TYPE_CHANGED) {
Boolean alarmOn =
DataMap.fromByteArray(event.getDataItem().getData()).get(FIELD_ALARM_ON);
if (alarmOn) {
mOrigVolume = mAudioManager.getStreamVolume(AudioManager.STREAM_ALARM);
mMediaPlayer.reset();
// Sound alarm at max volume.
mAudioManager.setStreamVolume(AudioManager.STREAM_ALARM, mMaxVolume, 0);
mMediaPlayer.setAudioStreamType(AudioManager.STREAM_ALARM);
try {
mMediaPlayer.setDataSource(getApplicationContext(), mAlarmSound);
mMediaPlayer.prepare();
} catch (IOException e) {
Log.e(TAG, "Failed to prepare media player to play alarm.", e);
}
mMediaPlayer.start();
} else {
// Reset the alarm volume to the user's original setting.
mAudioManager.setStreamVolume(AudioManager.STREAM_ALARM, mOrigVolume, 0);
if (mMediaPlayer.isPlaying()) {
mMediaPlayer.stop();
}
}
}
}
}
}

View file

@ -0,0 +1,54 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2014 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.
-->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.android.wearable.findphone" >
<uses-sdk android:minSdkVersion="20"
android:targetSdkVersion="22" />
<uses-permission android:name="android.permission.VIBRATE" />
<uses-feature android:name="android.hardware.type.watch" />
<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@android:style/Theme.DeviceDefault" >
<meta-data
android:name="com.google.android.gms.version"
android:value="@integer/google_play_services_version" />
<service android:name=".DisconnectListenerService" >
<intent-filter>
<action android:name="com.google.android.gms.wearable.BIND_LISTENER" />
</intent-filter>
</service>
<service android:name="com.example.android.wearable.findphone.FindPhoneService"/>
<activity
android:name=".FindPhoneActivity"
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>
</manifest>

Binary file not shown.

After

Width:  |  Height:  |  Size: 653 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1,000 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 696 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

View file

@ -0,0 +1,25 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2014 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">Find My Phone</string>
<string name="left_phone_title">Forgetting something?</string>
<string name="left_phone_content">You may have left your phone behind.</string>
<string name="turn_alarm_on">Tap to sound an alarm on phone.</string>
<string name="turn_alarm_off">Tap to stop the alarm.</string>
</resources>

View file

@ -0,0 +1,145 @@
/*
* Copyright (C) 2014 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.
*/
package com.example.android.wearable.findphone;
import android.app.Notification;
import android.app.NotificationManager;
import android.os.Bundle;
import android.util.Log;
import com.google.android.gms.common.api.GoogleApiClient;
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.gms.wearable.WearableListenerService;
import java.util.List;
import java.util.Set;
/**
* Listens for changes in connectivity between this wear device and the phone. More precisely, we
* need to distinguish the case that the wear device and the phone are connected directly from all
* other possible cases. To this end, the phone app has registered itself to provide the "find_me"
* capability and we need to look for connected nodes that provide this capability AND are nearby,
* to exclude a connection through the cloud. The proper way would have been to use the
* {@code onCapabilitiesChanged()} callback but currently that callback cannot discover the case
* where a connection switches from wifi to direct; this shortcoming will be addressed in future
* updates but for now we will use the {@code onConnectedNodes()} callback.
*/
public class DisconnectListenerService extends WearableListenerService
implements GoogleApiClient.ConnectionCallbacks {
private static final String TAG = "ExampleFindPhoneApp";
private static final int FORGOT_PHONE_NOTIFICATION_ID = 1;
/* the capability that the phone app would provide */
private static final String FIND_ME_CAPABILITY_NAME = "find_me";
private GoogleApiClient mGoogleApiClient;
@Override
public void onCreate() {
super.onCreate();
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addApi(Wearable.API)
.addConnectionCallbacks(this)
.build();
}
@Override
public void onConnectedNodes(List<Node> connectedNodes) {
// After we are notified by this callback, we need to query for the nodes that provide the
// "find_me" capability and are directly connected.
if (mGoogleApiClient.isConnected()) {
setOrUpdateNotification();
} else if (!mGoogleApiClient.isConnecting()) {
mGoogleApiClient.connect();
}
}
private void setOrUpdateNotification() {
Wearable.CapabilityApi.getCapability(
mGoogleApiClient, FIND_ME_CAPABILITY_NAME,
CapabilityApi.FILTER_REACHABLE).setResultCallback(
new ResultCallback<CapabilityApi.GetCapabilityResult>() {
@Override
public void onResult(CapabilityApi.GetCapabilityResult result) {
if (result.getStatus().isSuccess()) {
updateFindMeCapability(result.getCapability());
} else {
Log.e(TAG,
"setOrUpdateNotification() Failed to get capabilities, "
+ "status: "
+ result.getStatus().getStatusMessage());
}
}
});
}
private void updateFindMeCapability(CapabilityInfo capabilityInfo) {
Set<Node> connectedNodes = capabilityInfo.getNodes();
if (connectedNodes.isEmpty()) {
setupLostConnectivityNotification();
} else {
for (Node node : connectedNodes) {
// we are only considering those nodes that are directly connected
if (node.isNearby()) {
((NotificationManager) getSystemService(NOTIFICATION_SERVICE))
.cancel(FORGOT_PHONE_NOTIFICATION_ID);
}
}
}
}
/**
* Creates a notification to inform user that the connectivity to phone has been lost (possibly
* left the phone behind).
*/
private void setupLostConnectivityNotification() {
Notification.Builder notificationBuilder = new Notification.Builder(this)
.setContentTitle(getString(R.string.left_phone_title))
.setContentText(getString(R.string.left_phone_content))
.setVibrate(new long[]{0, 200}) // Vibrate for 200 milliseconds.
.setSmallIcon(R.drawable.ic_launcher)
.setLocalOnly(true)
.setPriority(Notification.PRIORITY_MAX);
Notification card = notificationBuilder.build();
((NotificationManager) getSystemService(NOTIFICATION_SERVICE))
.notify(FORGOT_PHONE_NOTIFICATION_ID, card);
}
@Override
public void onConnected(Bundle bundle) {
setOrUpdateNotification();
}
@Override
public void onConnectionSuspended(int cause) {
}
@Override
public void onDestroy() {
if (mGoogleApiClient.isConnected() || mGoogleApiClient.isConnecting()) {
mGoogleApiClient.disconnect();
}
super.onDestroy();
}
}

View file

@ -0,0 +1,86 @@
/*
* Copyright (C) 2014 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.
*/
package com.example.android.wearable.findphone;
import android.app.Activity;
import android.app.Notification;
import android.app.Notification.Action;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.text.Spannable;
import android.text.SpannableString;
import android.text.style.RelativeSizeSpan;
public class FindPhoneActivity extends Activity {
private static final int FIND_PHONE_NOTIFICATION_ID = 2;
private static Notification.Builder notification;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Create a notification with an action to toggle an alarm on the phone.
Intent toggleAlarmOperation = new Intent(this, FindPhoneService.class);
toggleAlarmOperation.setAction(FindPhoneService.ACTION_TOGGLE_ALARM);
PendingIntent toggleAlarmIntent = PendingIntent.getService(this, 0, toggleAlarmOperation,
PendingIntent.FLAG_CANCEL_CURRENT);
Action alarmAction = new Action(R.drawable.alarm_action_icon, "", toggleAlarmIntent);
// This intent turns off the alarm if the user dismisses the card from the wearable.
Intent cancelAlarmOperation = new Intent(this, FindPhoneService.class);
cancelAlarmOperation.setAction(FindPhoneService.ACTION_CANCEL_ALARM);
PendingIntent cancelAlarmIntent = PendingIntent.getService(this, 0, cancelAlarmOperation,
PendingIntent.FLAG_CANCEL_CURRENT);
// Use a spannable string for the notification title to resize it.
SpannableString title = new SpannableString(getString(R.string.app_name));
title.setSpan(new RelativeSizeSpan(0.85f), 0, title.length(), Spannable.SPAN_POINT_MARK);
notification = new Notification.Builder(this)
.setContentTitle(title)
.setContentText(getString(R.string.turn_alarm_on))
.setSmallIcon(R.drawable.ic_launcher)
.setVibrate(new long[] {0, 50}) // Vibrate to bring card to top of stream.
.setDeleteIntent(cancelAlarmIntent)
.extend(new Notification.WearableExtender()
.addAction(alarmAction)
.setContentAction(0)
.setHintHideIcon(true))
.setLocalOnly(true)
.setPriority(Notification.PRIORITY_MAX);
((NotificationManager) getSystemService(NOTIFICATION_SERVICE))
.notify(FIND_PHONE_NOTIFICATION_ID, notification.build());
finish();
}
/**
* Updates the text on the wearable notification. This is used so the notification reflects the
* current state of the alarm on the phone. For instance, if the alarm is turned on, the
* notification text indicates that the user can tap it to turn it off, and vice-versa.
*
* @param context
* @param notificationText The new text to display on the wearable notification.
*/
public static void updateNotification(Context context, String notificationText) {
notification.setContentText(notificationText);
((NotificationManager) context.getSystemService(NOTIFICATION_SERVICE))
.notify(FIND_PHONE_NOTIFICATION_ID, notification.build());
}
}

View file

@ -0,0 +1,125 @@
/*
* Copyright (C) 2014 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.
*/
package com.example.android.wearable.findphone;
import android.app.IntentService;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.wearable.DataItemBuffer;
import com.google.android.gms.wearable.DataMap;
import com.google.android.gms.wearable.PutDataMapRequest;
import com.google.android.gms.wearable.Wearable;
import java.util.concurrent.TimeUnit;
/**
* Creates a sound on the paired phone to find it.
*/
public class FindPhoneService extends IntentService implements GoogleApiClient.ConnectionCallbacks,
GoogleApiClient.OnConnectionFailedListener {
private static final String TAG = "ExampleFindPhoneApp";
private static final String FIELD_ALARM_ON = "alarm_on";
private static final String PATH_SOUND_ALARM = "/sound_alarm";
public static final String ACTION_TOGGLE_ALARM = "action_toggle_alarm";
public static final String ACTION_CANCEL_ALARM = "action_alarm_off";
// Timeout for making a connection to GoogleApiClient (in milliseconds).
private static final long CONNECTION_TIME_OUT_MS = 100;
private GoogleApiClient mGoogleApiClient;
public FindPhoneService() {
super(FindPhoneService.class.getSimpleName());
}
@Override
public void onCreate() {
super.onCreate();
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addApi(Wearable.API)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.build();
}
@Override
protected void onHandleIntent(Intent intent) {
mGoogleApiClient.blockingConnect(CONNECTION_TIME_OUT_MS, TimeUnit.MILLISECONDS);
if (Log.isLoggable(TAG, Log.VERBOSE)) {
Log.v(TAG, "FindPhoneService.onHandleIntent");
}
if (mGoogleApiClient.isConnected()) {
// Set the alarm off by default.
boolean alarmOn = false;
if (intent.getAction().equals(ACTION_TOGGLE_ALARM)) {
// Get current state of the alarm.
DataItemBuffer result = Wearable.DataApi.getDataItems(mGoogleApiClient).await();
try {
if (result.getStatus().isSuccess()) {
if (result.getCount() == 1) {
alarmOn = DataMap.fromByteArray(result.get(0).getData())
.getBoolean(FIELD_ALARM_ON, false);
} else {
Log.e(TAG, "Unexpected number of DataItems found.\n"
+ "\tExpected: 1\n"
+ "\tActual: " + result.getCount());
}
} else if (Log.isLoggable(TAG, Log.DEBUG)) {
Log.d(TAG, "onHandleIntent: failed to get current alarm state");
}
} finally {
result.release();
}
// Toggle alarm.
alarmOn = !alarmOn;
// Change notification text based on new value of alarmOn.
String notificationText = alarmOn ? getString(R.string.turn_alarm_off)
: getString(R.string.turn_alarm_on);
FindPhoneActivity.updateNotification(this, notificationText);
}
// Use alarmOn boolean to update the DataItem - phone will respond accordingly
// when it receives the change.
PutDataMapRequest putDataMapRequest = PutDataMapRequest.create(PATH_SOUND_ALARM);
putDataMapRequest.getDataMap().putBoolean(FIELD_ALARM_ON, alarmOn);
putDataMapRequest.setUrgent();
Wearable.DataApi.putDataItem(mGoogleApiClient, putDataMapRequest.asPutDataRequest())
.await();
} else {
Log.e(TAG, "Failed to toggle alarm on phone - Client disconnected from Google Play "
+ "Services");
}
mGoogleApiClient.disconnect();
}
@Override
public void onConnected(Bundle connectionHint) {
}
@Override
public void onConnectionSuspended(int cause) {
}
@Override
public void onConnectionFailed(ConnectionResult result) {
}
}

View file

@ -0,0 +1,13 @@
page.tags="FindMyPhone"
sample.group=Wearable
@jd:body
<p>
This sample application notifies you when you may have left your phone behind
(specifically, when your companion and wearable disconnect). If you have misplaced your phone, but
it is still connected to your wearable, you can also start an activity on the wearable to sound an
alarm on your phone.
</p>