diff options
| -rw-r--r-- | altosdroid/AndroidManifest.xml | 27 | ||||
| -rw-r--r-- | altosdroid/Makefile.am | 2 | ||||
| -rw-r--r-- | altosdroid/res/drawable-hdpi/am_status.png | bin | 0 -> 804 bytes | |||
| -rw-r--r-- | altosdroid/res/drawable-mdpi/am_status.png | bin | 0 -> 595 bytes | |||
| -rw-r--r-- | altosdroid/res/layout/telemetry_service_binding.xml | 42 | ||||
| -rw-r--r-- | altosdroid/res/layout/telemetry_service_controller.xml | 42 | ||||
| -rw-r--r-- | altosdroid/res/menu/option_menu.xml | 6 | ||||
| -rw-r--r-- | altosdroid/res/values/strings.xml | 26 | ||||
| -rw-r--r-- | altosdroid/src/org/altusmetrum/AltosDroid/AltosDroid.java | 8 | ||||
| -rw-r--r-- | altosdroid/src/org/altusmetrum/AltosDroid/TelemetryService.java | 109 | ||||
| -rw-r--r-- | altosdroid/src/org/altusmetrum/AltosDroid/TelemetryServiceActivities.java | 171 | 
11 files changed, 433 insertions, 0 deletions
diff --git a/altosdroid/AndroidManifest.xml b/altosdroid/AndroidManifest.xml index b72f0384..1d55737d 100644 --- a/altosdroid/AndroidManifest.xml +++ b/altosdroid/AndroidManifest.xml @@ -34,5 +34,32 @@                    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> diff --git a/altosdroid/Makefile.am b/altosdroid/Makefile.am index 557a5722..0732087b 100644 --- a/altosdroid/Makefile.am +++ b/altosdroid/Makefile.am @@ -18,6 +18,8 @@ SRC_DIR=src/org/altusmetrum/AltosDroid  SRC=\  	$(SRC_DIR)/AltosDroid.java \ +	$(SRC_DIR)/TelemetryService.java \ +	$(SRC_DIR)/TelemetryServiceActivities.java \  	$(SRC_DIR)/BluetoothChatService.java \  	$(SRC_DIR)/DeviceListActivity.java diff --git a/altosdroid/res/drawable-hdpi/am_status.png b/altosdroid/res/drawable-hdpi/am_status.png Binary files differnew file mode 100644 index 00000000..03f9dd7d --- /dev/null +++ b/altosdroid/res/drawable-hdpi/am_status.png diff --git a/altosdroid/res/drawable-mdpi/am_status.png b/altosdroid/res/drawable-mdpi/am_status.png Binary files differnew file mode 100644 index 00000000..07f7f073 --- /dev/null +++ b/altosdroid/res/drawable-mdpi/am_status.png diff --git a/altosdroid/res/layout/telemetry_service_binding.xml b/altosdroid/res/layout/telemetry_service_binding.xml new file mode 100644 index 00000000..950d0d3a --- /dev/null +++ b/altosdroid/res/layout/telemetry_service_binding.xml @@ -0,0 +1,42 @@ +<?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> + diff --git a/altosdroid/res/layout/telemetry_service_controller.xml b/altosdroid/res/layout/telemetry_service_controller.xml new file mode 100644 index 00000000..189d2f6c --- /dev/null +++ b/altosdroid/res/layout/telemetry_service_controller.xml @@ -0,0 +1,42 @@ +<?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> + diff --git a/altosdroid/res/menu/option_menu.xml b/altosdroid/res/menu/option_menu.xml index 18de725c..27625e9c 100644 --- a/altosdroid/res/menu/option_menu.xml +++ b/altosdroid/res/menu/option_menu.xml @@ -14,6 +14,12 @@       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" /> diff --git a/altosdroid/res/values/strings.xml b/altosdroid/res/values/strings.xml index 60823b12..0b2f9227 100644 --- a/altosdroid/res/values/strings.xml +++ b/altosdroid/res/values/strings.xml @@ -38,4 +38,30 @@      <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> diff --git a/altosdroid/src/org/altusmetrum/AltosDroid/AltosDroid.java b/altosdroid/src/org/altusmetrum/AltosDroid/AltosDroid.java index 87f89cf9..b4a3227c 100644 --- a/altosdroid/src/org/altusmetrum/AltosDroid/AltosDroid.java +++ b/altosdroid/src/org/altusmetrum/AltosDroid/AltosDroid.java @@ -339,6 +339,14 @@ public class AltosDroid extends Activity {      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); diff --git a/altosdroid/src/org/altusmetrum/AltosDroid/TelemetryService.java b/altosdroid/src/org/altusmetrum/AltosDroid/TelemetryService.java new file mode 100644 index 00000000..40dff354 --- /dev/null +++ b/altosdroid/src/org/altusmetrum/AltosDroid/TelemetryService.java @@ -0,0 +1,109 @@ +/* + * 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); +    } +} diff --git a/altosdroid/src/org/altusmetrum/AltosDroid/TelemetryServiceActivities.java b/altosdroid/src/org/altusmetrum/AltosDroid/TelemetryServiceActivities.java new file mode 100644 index 00000000..5191cfa9 --- /dev/null +++ b/altosdroid/src/org/altusmetrum/AltosDroid/TelemetryServiceActivities.java @@ -0,0 +1,171 @@ +/* + * 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); +        } +    } +}  | 
