android:label="@string/select_device"
android:theme="@android:style/Theme.Dialog"
android:configChanges="orientation|keyboardHidden" />
+
+
+ <!-- Service Samples -->
+
+ <service android:name=".TelemetryService" />
+
+ <activity android:name=".TelemetryServiceActivities$Controller"
+ android:label="@string/activity_telemetry_service_controller"
+ android:launchMode="singleTop">
+<!--
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.SAMPLE_CODE" />
+ </intent-filter>
+-->
+ </activity>
+
+ <activity android:name="TelemetryServiceActivities$Binding"
+ android:label="@string/activity_telemetry_service_binding">
+<!--
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.SAMPLE_CODE" />
+ </intent-filter>
+-->
+ </activity>
+
</application>
</manifest>
SRC=\
$(SRC_DIR)/AltosDroid.java \
+ $(SRC_DIR)/TelemetryService.java \
+ $(SRC_DIR)/TelemetryServiceActivities.java \
$(SRC_DIR)/BluetoothChatService.java \
$(SRC_DIR)/DeviceListActivity.java
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2007 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.
+-->
+
+<!-- Demonstrates starting and stopping a local service.
+ See corresponding Java code com.android.sdk.app.LocalSerice.java. -->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:padding="4dip"
+ android:gravity="center_horizontal"
+ android:layout_width="match_parent" android:layout_height="match_parent">
+
+ <TextView
+ android:layout_width="match_parent" android:layout_height="wrap_content"
+ android:layout_weight="0"
+ android:paddingBottom="4dip"
+ android:text="@string/telemetry_service_binding"/>
+
+ <Button android:id="@+id/bind"
+ android:layout_width="wrap_content" android:layout_height="wrap_content"
+ android:text="@string/bind_service">
+ <requestFocus />
+ </Button>
+
+ <Button android:id="@+id/unbind"
+ android:layout_width="wrap_content" android:layout_height="wrap_content"
+ android:text="@string/unbind_service">
+ </Button>
+
+</LinearLayout>
+
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2007 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.
+-->
+
+<!-- Demonstrates starting and stopping a local service.
+ See corresponding Java code com.android.sdk.app.LocalSerice.java. -->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:padding="4dip"
+ android:gravity="center_horizontal"
+ android:layout_width="match_parent" android:layout_height="match_parent">
+
+ <TextView
+ android:layout_width="match_parent" android:layout_height="wrap_content"
+ android:layout_weight="0"
+ android:paddingBottom="4dip"
+ android:text="@string/telemetry_service_controller"/>
+
+ <Button android:id="@+id/start"
+ android:layout_width="wrap_content" android:layout_height="wrap_content"
+ android:text="@string/start_service">
+ <requestFocus />
+ </Button>
+
+ <Button android:id="@+id/stop"
+ android:layout_width="wrap_content" android:layout_height="wrap_content"
+ android:text="@string/stop_service">
+ </Button>
+
+</LinearLayout>
+
limitations under the License.
-->
<menu xmlns:android="http://schemas.android.com/apk/res/android">
+ <item android:id="@+id/telemetry_service_control"
+ android:icon="@android:drawable/ic_menu_manage"
+ android:title="@string/telemetry_service_control" />
+ <item android:id="@+id/telemetry_service_bind"
+ android:icon="@android:drawable/ic_menu_rotate"
+ android:title="@string/telemetry_service_bind" />
<item android:id="@+id/secure_connect_scan"
android:icon="@android:drawable/ic_menu_search"
android:title="@string/secure_connect" />
<string name="secure_connect">Connect a device - Secure</string>
<string name="insecure_connect">Connect a device - Insecure</string>
<string name="discoverable">Make discoverable</string>
+
+ <!-- Service -->
+ <string name="telemetry_service_label">AltOS Telemetry Service</string>
+ <string name="telemetry_service_started">Telemetry Service Started</string>
+ <string name="telemetry_service_stopped">Telemetry Service Stopped</string>
+
+
+
+ <string name="telemetry_service_control">Start/Stop Service</string>
+ <string name="telemetry_service_bind">Bind/Unbind Service</string>
+
+ <string name="activity_telemetry_service_controller">App/Service/Local Service Controller</string>
+ <string name="telemetry_service_controller">This demonstrates how you can implement persistent services that
+ may be started and stopped as desired.</string>
+ <string name="start_service">Start Service</string>
+ <string name="stop_service">Stop Service</string>
+
+ <string name="activity_telemetry_service_binding">App/Service/Local Service Binding</string>
+ <string name="telemetry_service_binding">This demonstrates how you can connect with a persistent
+ service. Notice how it automatically starts for you, and play around with the
+ interaction between this and Local Service Controller.</string>
+ <string name="bind_service">Bind Service</string>
+ <string name="unbind_service">Unbind Service</string>
+ <string name="telemetry_service_connected">Connected to local service</string>
+ <string name="telemetry_service_disconnected">Disconnected from local service</string>
+
</resources>
public boolean onOptionsItemSelected(MenuItem item) {
Intent serverIntent = null;
switch (item.getItemId()) {
+ case R.id.telemetry_service_control:
+ serverIntent = new Intent(this, TelemetryServiceActivities.Controller.class);
+ startActivity(serverIntent);
+ return true;
+ case R.id.telemetry_service_bind:
+ serverIntent = new Intent(this, TelemetryServiceActivities.Binding.class);
+ startActivity(serverIntent);
+ return true;
case R.id.secure_connect_scan:
// Launch the DeviceListActivity to see devices and do scan
serverIntent = new Intent(this, DeviceListActivity.class);
--- /dev/null
+/*
+ * Copyright (C) 2007 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 org.altusmetrum.AltosDroid;
+
+import android.app.Notification;
+import android.app.NotificationManager;
+import android.app.PendingIntent;
+import android.app.Service;
+import android.content.Intent;
+import android.os.Binder;
+import android.os.IBinder;
+import android.util.Log;
+import android.widget.Toast;
+
+// Need the following import to get access to the app resources, since this
+// class is in a sub-package.
+import org.altusmetrum.AltosDroid.R;
+
+
+
+public class TelemetryService extends Service {
+ private NotificationManager mNM;
+
+ // Unique Identification Number for the Notification.
+ // We use it on Notification start, and to cancel it.
+ private int NOTIFICATION = R.string.telemetry_service_started;
+
+ /**
+ * Class for clients to access. Because we know this service always
+ * runs in the same process as its clients, we don't need to deal with
+ * IPC.
+ */
+ public class TelemetryBinder extends Binder {
+ TelemetryService getService() {
+ return TelemetryService.this;
+ }
+ }
+
+ @Override
+ public void onCreate() {
+ mNM = (NotificationManager)getSystemService(NOTIFICATION_SERVICE);
+
+ // Display a notification about us starting. We put an icon in the status bar.
+ showNotification();
+ }
+
+ @Override
+ public int onStartCommand(Intent intent, int flags, int startId) {
+ Log.i("TelemetryService", "Received start id " + startId + ": " + intent);
+ // We want this service to continue running until it is explicitly
+ // stopped, so return sticky.
+ return START_STICKY;
+ }
+
+ @Override
+ public void onDestroy() {
+ // Cancel the persistent notification.
+ mNM.cancel(NOTIFICATION);
+
+ // Tell the user we stopped.
+ Toast.makeText(this, R.string.telemetry_service_stopped, Toast.LENGTH_SHORT).show();
+ }
+
+ @Override
+ public IBinder onBind(Intent intent) {
+ return mBinder;
+ }
+
+ // This is the object that receives interactions from clients. See
+ // RemoteService for a more complete example.
+ private final IBinder mBinder = new TelemetryBinder();
+
+ /**
+ * Show a notification while this service is running.
+ */
+ private void showNotification() {
+ // In this sample, we'll use the same text for the ticker and the expanded notification
+ CharSequence text = getText(R.string.telemetry_service_started);
+
+ // Set the icon, scrolling text and timestamp
+ Notification notification = new Notification(R.drawable.am_status, text,
+ System.currentTimeMillis());
+
+ // The PendingIntent to launch our activity if the user selects this notification
+ PendingIntent contentIntent = PendingIntent.getActivity(this, 0,
+ new Intent(this, TelemetryServiceActivities.Controller.class), 0);
+
+ // Set the info for the views that show in the notification panel.
+ notification.setLatestEventInfo(this, getText(R.string.telemetry_service_label),
+ text, contentIntent);
+
+ // Send the notification.
+ mNM.notify(NOTIFICATION, notification);
+ }
+}
--- /dev/null
+/*
+ * Copyright (C) 2007 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 org.altusmetrum.AltosDroid;
+
+import org.altusmetrum.AltosDroid.R;
+
+import android.app.Activity;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.ServiceConnection;
+import android.os.Bundle;
+import android.os.IBinder;
+import android.view.View;
+import android.view.View.OnClickListener;
+import android.widget.Button;
+import android.widget.Toast;
+
+public class TelemetryServiceActivities {
+ /**
+ * <p>Example of explicitly starting and stopping the local service.
+ * This demonstrates the implementation of a service that runs in the same
+ * process as the rest of the application, which is explicitly started and stopped
+ * as desired.</p>
+ *
+ * <p>Note that this is implemented as an inner class only keep the sample
+ * all together; typically this code would appear in some separate class.
+ */
+ public static class Controller extends Activity {
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ setContentView(R.layout.telemetry_service_controller);
+
+ // Watch for button clicks.
+ Button button = (Button)findViewById(R.id.start);
+ button.setOnClickListener(mStartListener);
+ button = (Button)findViewById(R.id.stop);
+ button.setOnClickListener(mStopListener);
+ }
+
+ private OnClickListener mStartListener = new OnClickListener() {
+ public void onClick(View v) {
+ // Make sure the service is started. It will continue running
+ // until someone calls stopService(). The Intent we use to find
+ // the service explicitly specifies our service component, because
+ // we want it running in our own process and don't want other
+ // applications to replace it.
+ startService(new Intent(Controller.this,
+ TelemetryService.class));
+ }
+ };
+
+ private OnClickListener mStopListener = new OnClickListener() {
+ public void onClick(View v) {
+ // Cancel a previous call to startService(). Note that the
+ // service will not actually stop at this point if there are
+ // still bound clients.
+ stopService(new Intent(Controller.this,
+ TelemetryService.class));
+ }
+ };
+ }
+
+ // ----------------------------------------------------------------------
+
+ /**
+ * Example of binding and unbinding to the local service.
+ * This demonstrates the implementation of a service which the client will
+ * bind to, receiving an object through which it can communicate with the service.</p>
+ *
+ * <p>Note that this is implemented as an inner class only keep the sample
+ * all together; typically this code would appear in some separate class.
+ */
+ public static class Binding extends Activity {
+ private boolean mIsBound;
+
+
+ private TelemetryService mBoundService;
+
+ private ServiceConnection mConnection = new ServiceConnection() {
+ public void onServiceConnected(ComponentName className, IBinder service) {
+ // This is called when the connection with the service has been
+ // established, giving us the service object we can use to
+ // interact with the service. Because we have bound to a explicit
+ // service that we know is running in our own process, we can
+ // cast its IBinder to a concrete class and directly access it.
+ mBoundService = ((TelemetryService.TelemetryBinder)service).getService();
+
+ // Tell the user about this for our demo.
+ Toast.makeText(Binding.this, R.string.telemetry_service_connected,
+ Toast.LENGTH_SHORT).show();
+ }
+
+ public void onServiceDisconnected(ComponentName className) {
+ // This is called when the connection with the service has been
+ // unexpectedly disconnected -- that is, its process crashed.
+ // Because it is running in our same process, we should never
+ // see this happen.
+ mBoundService = null;
+ Toast.makeText(Binding.this, R.string.telemetry_service_disconnected,
+ Toast.LENGTH_SHORT).show();
+ }
+ };
+
+ void doBindService() {
+ // Establish a connection with the service. We use an explicit
+ // class name because we want a specific service implementation that
+ // we know will be running in our own process (and thus won't be
+ // supporting component replacement by other applications).
+ bindService(new Intent(Binding.this,
+ TelemetryService.class), mConnection, Context.BIND_AUTO_CREATE);
+ mIsBound = true;
+ }
+
+ void doUnbindService() {
+ if (mIsBound) {
+ // Detach our existing connection.
+ unbindService(mConnection);
+ mIsBound = false;
+ }
+ }
+
+ @Override
+ protected void onDestroy() {
+ super.onDestroy();
+ doUnbindService();
+ }
+
+
+ private OnClickListener mBindListener = new OnClickListener() {
+ public void onClick(View v) {
+ doBindService();
+ }
+ };
+
+ private OnClickListener mUnbindListener = new OnClickListener() {
+ public void onClick(View v) {
+ doUnbindService();
+ }
+ };
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ setContentView(R.layout.telemetry_service_binding);
+
+ // Watch for button clicks.
+ Button button = (Button)findViewById(R.id.bind);
+ button.setOnClickListener(mBindListener);
+ button = (Button)findViewById(R.id.unbind);
+ button.setOnClickListener(mUnbindListener);
+ }
+ }
+}