diff --git a/build.gradle b/build.gradle index e4873fbe3..1ec0c41b0 100644 --- a/build.gradle +++ b/build.gradle @@ -2,11 +2,13 @@ // vim: ts=4 sts=4 sw=4 expandtab buildscript { + ext.kotlin_version = '1.1.3-2' repositories { jcenter() } dependencies { classpath 'com.android.tools.build:gradle:2.3.3' + classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" // NOTE: Do not place your application dependencies here; they belong // in the individual module build.gradle files diff --git a/mobile/build.gradle b/mobile/build.gradle index 413448435..d9279e47e 100644 --- a/mobile/build.gradle +++ b/mobile/build.gradle @@ -1,5 +1,6 @@ apply plugin: 'com.android.application' - +apply plugin: 'kotlin-android' +apply plugin: 'kotlin-android-extensions' android { compileSdkVersion 26 buildToolsVersion "26.0.0" @@ -27,4 +28,8 @@ dependencies { compile fileTree(include: ['*.jar'], dir: 'libs') compile 'com.android.support:support-v4:26.0.0-beta2' compile 'com.android.support:appcompat-v7:26.0.0-beta2' + compile "org.jetbrains.kotlin:kotlin-stdlib-jre7:$kotlin_version" +} +repositories { + mavenCentral() } diff --git a/mobile/src/main/java/com/example/android/apis/app/AlarmController.java b/mobile/src/main/java/com/example/android/apis/app/AlarmController.java deleted file mode 100644 index 2ba573564..000000000 --- a/mobile/src/main/java/com/example/android/apis/app/AlarmController.java +++ /dev/null @@ -1,168 +0,0 @@ -/* - * 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 com.example.android.apis.app; - -// Need the following import to get access to the app resources, since this -// class is in a sub-package. -import com.example.android.apis.R; - -import android.app.Activity; -import android.app.AlarmManager; -import android.app.PendingIntent; -import android.content.Intent; -import android.os.SystemClock; -import android.os.Bundle; -import android.view.View; -import android.view.View.OnClickListener; -import android.widget.Button; -import android.widget.Toast; - -import java.util.Calendar; - -/** - * Example of scheduling one-shot and repeating alarms. See - * {@link OneShotAlarm} for the code run when the one-shot alarm goes off, and - * {@link RepeatingAlarm} for the code run when the repeating alarm goes off. - *

Demo

-App/Service/Alarm Controller - -

Source files

- - - - - - - - - - - - - - - - - -
src/com.example.android.apis/app/AlarmController.javaThe activity that lets you schedule alarms
src/com.example.android.apis/app/OneShotAlarm.javaThis is an intent receiver that executes when the - one-shot alarm goes off
src/com.example.android.apis/app/RepeatingAlarm.javaThis is an intent receiver that executes when the - repeating alarm goes off
/res/any/layout/alarm_controller.xmlDefines contents of the screen
- - */ -public class AlarmController extends Activity { - Toast mToast; - - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - - setContentView(R.layout.alarm_controller); - - // Watch for button clicks. - Button button = (Button)findViewById(R.id.one_shot); - button.setOnClickListener(mOneShotListener); - button = (Button)findViewById(R.id.start_repeating); - button.setOnClickListener(mStartRepeatingListener); - button = (Button)findViewById(R.id.stop_repeating); - button.setOnClickListener(mStopRepeatingListener); - } - - private OnClickListener mOneShotListener = new OnClickListener() { - public void onClick(View v) { - // When the alarm goes off, we want to broadcast an Intent to our - // BroadcastReceiver. Here we make an Intent with an explicit class - // name to have our own receiver (which has been published in - // AndroidManifest.xml) instantiated and called, and then create an - // IntentSender to have the intent executed as a broadcast. - Intent intent = new Intent(AlarmController.this, OneShotAlarm.class); - PendingIntent sender = PendingIntent.getBroadcast(AlarmController.this, - 0, intent, 0); - - // We want the alarm to go off 30 seconds from now. - Calendar calendar = Calendar.getInstance(); - calendar.setTimeInMillis(System.currentTimeMillis()); - calendar.add(Calendar.SECOND, 30); - - // Schedule the alarm! - AlarmManager am = (AlarmManager)getSystemService(ALARM_SERVICE); - am.set(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), sender); - - // Tell the user about what we did. - if (mToast != null) { - mToast.cancel(); - } - mToast = Toast.makeText(AlarmController.this, R.string.one_shot_scheduled, - Toast.LENGTH_LONG); - mToast.show(); - } - }; - - private OnClickListener mStartRepeatingListener = new OnClickListener() { - public void onClick(View v) { - // When the alarm goes off, we want to broadcast an Intent to our - // BroadcastReceiver. Here we make an Intent with an explicit class - // name to have our own receiver (which has been published in - // AndroidManifest.xml) instantiated and called, and then create an - // IntentSender to have the intent executed as a broadcast. - // Note that unlike above, this IntentSender is configured to - // allow itself to be sent multiple times. - Intent intent = new Intent(AlarmController.this, RepeatingAlarm.class); - PendingIntent sender = PendingIntent.getBroadcast(AlarmController.this, - 0, intent, 0); - - // We want the alarm to go off 30 seconds from now. - long firstTime = SystemClock.elapsedRealtime(); - firstTime += 15*1000; - - // Schedule the alarm! - AlarmManager am = (AlarmManager)getSystemService(ALARM_SERVICE); - am.setRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP, - firstTime, 15*1000, sender); - - // Tell the user about what we did. - if (mToast != null) { - mToast.cancel(); - } - mToast = Toast.makeText(AlarmController.this, R.string.repeating_scheduled, - Toast.LENGTH_LONG); - mToast.show(); - } - }; - - private OnClickListener mStopRepeatingListener = new OnClickListener() { - public void onClick(View v) { - // Create the same intent, and thus a matching IntentSender, for - // the one that was scheduled. - Intent intent = new Intent(AlarmController.this, RepeatingAlarm.class); - PendingIntent sender = PendingIntent.getBroadcast(AlarmController.this, - 0, intent, 0); - - // And cancel the alarm. - AlarmManager am = (AlarmManager)getSystemService(ALARM_SERVICE); - am.cancel(sender); - - // Tell the user about what we did. - if (mToast != null) { - mToast.cancel(); - } - mToast = Toast.makeText(AlarmController.this, R.string.repeating_unscheduled, - Toast.LENGTH_LONG); - mToast.show(); - } - }; -} - diff --git a/mobile/src/main/java/com/example/android/apis/app/AlarmController.kt b/mobile/src/main/java/com/example/android/apis/app/AlarmController.kt new file mode 100644 index 000000000..ad81fecfc --- /dev/null +++ b/mobile/src/main/java/com/example/android/apis/app/AlarmController.kt @@ -0,0 +1,152 @@ +/* + * 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 com.example.android.apis.app + +// Need the following import to get access to the app resources, since this +// class is in a sub-package. +import com.example.android.apis.R + +import android.app.Activity +import android.app.AlarmManager +import android.app.PendingIntent +import android.content.Intent +import android.os.SystemClock +import android.os.Bundle +import android.view.View +import android.view.View.OnClickListener +import android.widget.Button +import android.widget.Toast + +import java.util.Calendar + +/** + * Example of scheduling one-shot and repeating alarms. See + * [OneShotAlarm] for the code run when the one-shot alarm goes off, and + * [RepeatingAlarm] for the code run when the repeating alarm goes off. + *

Demo

+ * App/Service/Alarm Controller + + *

Source files

+ * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * +
src/com.example.android.apis/app/AlarmController.javaThe activity that lets you schedule alarms
src/com.example.android.apis/app/OneShotAlarm.javaThis is an intent receiver that executes when the + * one-shot alarm goes off
src/com.example.android.apis/app/RepeatingAlarm.javaThis is an intent receiver that executes when the + * repeating alarm goes off
/res/any/layout/alarm_controller.xmlDefines contents of the screen
* + */ + +class AlarmController : Activity (){ + var mToast: Toast? = null + override fun onCreate(savedInstanceState:Bundle?) : Unit { + super.onCreate(savedInstanceState) + setContentView(R.layout.alarm_controller) + + // Watch for button clicks. + var button = findViewById(R.id.one_shot) + button.setOnClickListener(mOneShotListener) + button = findViewById(R.id.start_repeating) + button.setOnClickListener(mStartRepeatingListener) + button = findViewById(R.id.stop_repeating) + button.setOnClickListener(mStopRepeatingListener) + } + val mOneShotListener = OnClickListener{ + // When the alarm goes off, we want to broadcast an Intent to our + // BroadcastReceiver. Here we make an Intent with an explicit class + // name to have our own receiver (which has been published in + // AndroidManifest.xml) instantiated and called, and then create an + // IntentSender to have the intent executed as a broadcast. + val intent:Intent = Intent(this@AlarmController, OneShotAlarm::class.java) + val sender:PendingIntent = PendingIntent.getBroadcast(this@AlarmController, 0, intent, 0) + + // We want the alarm to go off 30 seconds from now. + var calendar:Calendar = Calendar.getInstance() + calendar.timeInMillis=System.currentTimeMillis() + calendar.add(Calendar.SECOND, 30) + + // Schedule the alarm! + val am:AlarmManager = getSystemService(ALARM_SERVICE) as (AlarmManager) + am.set(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), sender) + + // Tell the user about what we did. + if (mToast != null) { + mToast!!.cancel() + } + mToast = Toast.makeText(this@AlarmController, R.string.one_shot_scheduled,Toast.LENGTH_LONG) + mToast!!.show() + + }; + val mStartRepeatingListener = OnClickListener{ + // When the alarm goes off, we want to broadcast an Intent to our + // BroadcastReceiver. Here we make an Intent with an explicit class + // name to have our own receiver (which has been published in + // AndroidManifest.xml) instantiated and called, and then create an + // IntentSender to have the intent executed as a broadcast. + // Note that unlike above, this IntentSender is configured to + // allow itself to be sent multiple times. + val intent:Intent = Intent(this@AlarmController, RepeatingAlarm::class.java) + val sender:PendingIntent = PendingIntent.getBroadcast(this@AlarmController,0, intent, 0) + + // We want the alarm to go off 30 seconds from now. + var firstTime : Long = SystemClock.elapsedRealtime() + firstTime += 15*1000L + + // Schedule the alarm! + val am:AlarmManager = getSystemService(ALARM_SERVICE) as AlarmManager + am.setRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP,firstTime, 15*1000, sender) + + // Tell the user about what we did. + if (mToast != null) { + mToast!!.cancel() + } + mToast = Toast.makeText(this@AlarmController, R.string.repeating_scheduled, Toast.LENGTH_LONG) + mToast!!.show() + + }; + val mStopRepeatingListener = OnClickListener { + // Create the same intent, and thus a matching IntentSender, for + // the one that was scheduled. + val intent:Intent = Intent(this@AlarmController, RepeatingAlarm::class.java) + val sender:PendingIntent = PendingIntent.getBroadcast(this@AlarmController, 0, intent, 0) + + // And cancel the alarm. + val am :AlarmManager= getSystemService(ALARM_SERVICE) as (AlarmManager) + am.cancel(sender) + + // Tell the user about what we did. + if (mToast != null) { + mToast!!.cancel(); + } + mToast = Toast.makeText(this@AlarmController, R.string.repeating_unscheduled,Toast.LENGTH_LONG) + mToast!!.show() + + }; +} + diff --git a/mobile/src/main/java/com/example/android/apis/app/AlarmService.java b/mobile/src/main/java/com/example/android/apis/app/AlarmService.java deleted file mode 100644 index 151838ae2..000000000 --- a/mobile/src/main/java/com/example/android/apis/app/AlarmService.java +++ /dev/null @@ -1,89 +0,0 @@ -/* - * 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 com.example.android.apis.app; - -// Need the following import to get access to the app resources, since this -// class is in a sub-package. -import com.example.android.apis.R; - -import android.app.Activity; -import android.app.AlarmManager; -import android.app.PendingIntent; -import android.content.Intent; -import android.os.SystemClock; -import android.os.Bundle; -import android.view.View; -import android.view.View.OnClickListener; -import android.widget.Button; -import android.widget.Toast; - - -/** - * This demonstrates how you can schedule an alarm that causes a service to - * be started. This is useful when you want to schedule alarms that initiate - * long-running operations, such as retrieving recent e-mails. - */ -public class AlarmService extends Activity { - private PendingIntent mAlarmSender; - - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - - // Create an IntentSender that will launch our service, to be scheduled - // with the alarm manager. - mAlarmSender = PendingIntent.getService(AlarmService.this, - 0, new Intent(AlarmService.this, AlarmService_Service.class), 0); - - setContentView(R.layout.alarm_service); - - // Watch for button clicks. - Button button = (Button)findViewById(R.id.start_alarm); - button.setOnClickListener(mStartAlarmListener); - button = (Button)findViewById(R.id.stop_alarm); - button.setOnClickListener(mStopAlarmListener); - } - - private OnClickListener mStartAlarmListener = new OnClickListener() { - public void onClick(View v) { - // We want the alarm to go off 30 seconds from now. - long firstTime = SystemClock.elapsedRealtime(); - - // Schedule the alarm! - AlarmManager am = (AlarmManager)getSystemService(ALARM_SERVICE); - am.setRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP, - firstTime, 30*1000, mAlarmSender); - - // Tell the user about what we did. - Toast.makeText(AlarmService.this, R.string.repeating_scheduled, - Toast.LENGTH_LONG).show(); - } - }; - - private OnClickListener mStopAlarmListener = new OnClickListener() { - public void onClick(View v) { - // And cancel the alarm. - AlarmManager am = (AlarmManager)getSystemService(ALARM_SERVICE); - am.cancel(mAlarmSender); - - // Tell the user about what we did. - Toast.makeText(AlarmService.this, R.string.repeating_unscheduled, - Toast.LENGTH_LONG).show(); - - } - }; -} diff --git a/mobile/src/main/java/com/example/android/apis/app/AlarmService.kt b/mobile/src/main/java/com/example/android/apis/app/AlarmService.kt new file mode 100644 index 000000000..15b7e617f --- /dev/null +++ b/mobile/src/main/java/com/example/android/apis/app/AlarmService.kt @@ -0,0 +1,77 @@ +/* + * 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 com.example.android.apis.app; + +// Need the following import to get access to the app resources, since this +// class is in a sub-package. +import com.example.android.apis.R; + +import android.app.Activity; +import android.app.AlarmManager; +import android.app.PendingIntent; +import android.content.Intent; +import android.os.SystemClock; +import android.os.Bundle; +import android.view.View.OnClickListener; +import android.widget.Toast; +import kotlinx.android.synthetic.main.alarm_service.* + + +class AlarmService : Activity() { + lateinit var mAlarmSender : PendingIntent + + override fun onCreate( savedInstanceState : Bundle?) { + super.onCreate(savedInstanceState) + + // Create an IntentSender that will launch our service, to be scheduled + // with the alarm manager. + mAlarmSender = PendingIntent.getService(this@AlarmService, + 0, Intent(this@AlarmService, AlarmService_Service::class.java), 0) + + setContentView(R.layout.alarm_service) + + // Watch for button clicks. + start_alarm.setOnClickListener(mStartAlarmListener) + stop_alarm.setOnClickListener(mStopAlarmListener) + } + + private val mStartAlarmListener= OnClickListener { + // We want the alarm to go off 30 seconds from now. + var firstTime : Long = SystemClock.elapsedRealtime() + + // Schedule the alarm! + var am :AlarmManager = getSystemService(ALARM_SERVICE) as AlarmManager + am.setRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP, + firstTime, 30*1000, mAlarmSender) + + // Tell the user about what we did. + Toast.makeText(this@AlarmService, R.string.repeating_scheduled, + Toast.LENGTH_LONG).show() + } + + private val mStopAlarmListener = OnClickListener{ + // And cancel the alarm. + var am :AlarmManager = getSystemService(ALARM_SERVICE) as AlarmManager + am.cancel(mAlarmSender) + + // Tell the user about what we did. + Toast.makeText(this@AlarmService, R.string.repeating_unscheduled, + Toast.LENGTH_LONG).show() + + + } +} \ No newline at end of file diff --git a/mobile/src/main/java/com/example/android/apis/app/AlarmService_Service.java b/mobile/src/main/java/com/example/android/apis/app/AlarmService_Service.java deleted file mode 100644 index cede9dced..000000000 --- a/mobile/src/main/java/com/example/android/apis/app/AlarmService_Service.java +++ /dev/null @@ -1,133 +0,0 @@ -/* - * 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 com.example.android.apis.app; - -// Need the following import to get access to the app resources, since this -// class is in a sub-package. -import com.example.android.apis.R; - -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.os.Parcel; -import android.os.RemoteException; -import android.widget.Toast; - -/** - * This is an example of implementing an application service that will run in - * response to an alarm, allowing us to move long duration work out of an - * intent receiver. - * - * @see AlarmService - * @see AlarmService_Alarm - */ -public class AlarmService_Service extends Service { - NotificationManager mNM; - - @Override - public void onCreate() { - mNM = (NotificationManager)getSystemService(NOTIFICATION_SERVICE); - - // show the icon in the status bar - showNotification(); - - // Start up the thread running the service. Note that we create a - // separate thread because the service normally runs in the process's - // main thread, which we don't want to block. - Thread thr = new Thread(null, mTask, "AlarmService_Service"); - thr.start(); - } - - @Override - public void onDestroy() { - // Cancel the notification -- we use the same ID that we had used to start it - mNM.cancel(R.string.alarm_service_started); - - // Tell the user we stopped. - Toast.makeText(this, R.string.alarm_service_finished, Toast.LENGTH_SHORT).show(); - } - - /** - * The function that runs in our worker thread - */ - Runnable mTask = new Runnable() { - public void run() { - // Normally we would do some work here... for our sample, we will - // just sleep for 30 seconds. - long endTime = System.currentTimeMillis() + 15*1000; - while (System.currentTimeMillis() < endTime) { - synchronized (mBinder) { - try { - mBinder.wait(endTime - System.currentTimeMillis()); - } catch (Exception e) { - } - } - } - - // Done with our work... stop the service! - AlarmService_Service.this.stopSelf(); - } - }; - - @Override - public IBinder onBind(Intent intent) { - return mBinder; - } - - /** - * 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.alarm_service_started); - - // The PendingIntent to launch our activity if the user selects this notification - PendingIntent contentIntent = PendingIntent.getActivity(this, 0, - new Intent(this, AlarmService.class), 0); - - // Set the info for the views that show in the notification panel. - Notification notification = new Notification.Builder(this) - .setSmallIcon(R.drawable.stat_sample) // the status icon - .setTicker(text) // the status text - .setWhen(System.currentTimeMillis()) // the time stamp - .setContentTitle(getText(R.string.alarm_service_label)) // the label of the entry - .setContentText(text) // the contents of the entry - .setContentIntent(contentIntent) // The intent to send when the entry is clicked - .build(); - - // Send the notification. - // We use a layout id because it is a unique number. We use it later to cancel. - mNM.notify(R.string.alarm_service_started, notification); - } - - /** - * This is the object that receives interactions from clients. See RemoteService - * for a more complete example. - */ - private final IBinder mBinder = new Binder() { - @Override - protected boolean onTransact(int code, Parcel data, Parcel reply, - int flags) throws RemoteException { - return super.onTransact(code, data, reply, flags); - } - }; -} - diff --git a/mobile/src/main/java/com/example/android/apis/app/AlarmService_Service.kt b/mobile/src/main/java/com/example/android/apis/app/AlarmService_Service.kt new file mode 100644 index 000000000..49cc3edef --- /dev/null +++ b/mobile/src/main/java/com/example/android/apis/app/AlarmService_Service.kt @@ -0,0 +1,127 @@ +/* + * 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 com.example.android.apis.app + +// Need the following import to get access to the app resources, since this +// class is in a sub-package. +import com.example.android.apis.R + +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.os.Parcel +import android.os.RemoteException +import android.widget.Toast + +/** + * This is an example of implementing an application service that will run in + * response to an alarm, allowing us to move long duration work out of an + * intent receiver. + + * @see AlarmService + + * @see AlarmService_Alarm + */ +class AlarmService_Service : Service() { + lateinit var mNM: NotificationManager + + override fun onCreate() { + mNM = getSystemService(NOTIFICATION_SERVICE) as NotificationManager + + // show the icon in the status bar + showNotification() + + // Start up the thread running the service. Note that we create a + // separate thread because the service normally runs in the process's + // main thread, which we don't want to block. + var thr: Thread = Thread(null, mTask, "AlarmService_Service") + thr.start() + } + + override fun onDestroy() { + // Cancel the notification -- we use the same ID that we had used to start it + mNM.cancel(R.string.alarm_service_started) + + // Tell the user we stopped. + Toast.makeText(this, R.string.alarm_service_finished, Toast.LENGTH_SHORT).show() + } + + + // The function that runs in our worker thread + + val mTask: Runnable = Runnable { + // Normally we would do some work here... for our sample, we will + // just sleep for 30 seconds. + var endTime: Long = System.currentTimeMillis() + 15 * 1000 + while (System.currentTimeMillis() < endTime) { + synchronized(mBinder) { + try { + // mBinder.wait(endTime - System.currentTimeMillis()) + } catch (e: Exception) { + } + + } + } + + // Done with our work... stop the service! + this@AlarmService_Service.stopSelf() + } + + override public fun onBind(intent: Intent?): IBinder { + return mBinder + } + + // Show a notification while this service is running. + + private fun showNotification() { + // In this sample, we'll use the same text for the ticker and the expanded notification + val text: CharSequence = getText(R.string.alarm_service_started) + + // The PendingIntent to launch our activity if the user selects this notification + var contentIntent: PendingIntent = PendingIntent.getActivity(this, 0, + Intent(applicationContext, AlarmService::class.java), 0) + + // Set the info for the views that show in the notification panel. + var notification: Notification = Notification.Builder(this) + .setSmallIcon(R.drawable.stat_sample) // the status icon + .setTicker(text) // the status text + .setWhen(System.currentTimeMillis()) // the time stamp + .setContentTitle(getText(R.string.alarm_service_label)) // the label of the entry + .setContentText(text) // the contents of the entry + .setContentIntent(contentIntent) // The intent to send when the entry is clicked + .build() + + // Send the notification. + // We use a layout id because it is a unique number. We use it later to cancel. + mNM.notify(R.string.alarm_service_started, notification) + } + + /* * This is the object that receives interactions from clients. See RemoteService + * for a more complete example.*/ + + private val mBinder = object : Binder() { + @Throws(RemoteException::class) + override fun onTransact(code: Int, data: Parcel, reply: Parcel, + flags: Int): Boolean { + return super.onTransact(code, data, reply, flags) + } + } +} diff --git a/mobile/src/main/java/com/example/android/apis/app/FragmentAlertDialog.java b/mobile/src/main/java/com/example/android/apis/app/FragmentAlertDialog.java deleted file mode 100644 index 56ddc6b91..000000000 --- a/mobile/src/main/java/com/example/android/apis/app/FragmentAlertDialog.java +++ /dev/null @@ -1,109 +0,0 @@ -/* - * Copyright (C) 2010 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.apis.app; - -import com.example.android.apis.R; - -import android.app.Activity; -import android.app.AlertDialog; -import android.app.Dialog; -import android.app.DialogFragment; -import android.content.DialogInterface; -import android.os.Bundle; -import android.util.Log; -import android.view.View; -import android.view.View.OnClickListener; -import android.widget.Button; -import android.widget.TextView; - -/** - * Demonstrates how to show an AlertDialog that is managed by a Fragment. - */ -public class FragmentAlertDialog extends Activity { - - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - setContentView(R.layout.fragment_dialog); - - View tv = findViewById(R.id.text); - ((TextView)tv).setText("Example of displaying an alert dialog with a DialogFragment"); - - // Watch for button clicks. - Button button = (Button)findViewById(R.id.show); - button.setOnClickListener(new OnClickListener() { - public void onClick(View v) { - showDialog(); - } - }); - } - -//BEGIN_INCLUDE(activity) - void showDialog() { - DialogFragment newFragment = MyAlertDialogFragment.newInstance( - R.string.alert_dialog_two_buttons_title); - newFragment.show(getFragmentManager(), "dialog"); - } - - public void doPositiveClick() { - // Do stuff here. - Log.i("FragmentAlertDialog", "Positive click!"); - } - - public void doNegativeClick() { - // Do stuff here. - Log.i("FragmentAlertDialog", "Negative click!"); - } -//END_INCLUDE(activity) - -//BEGIN_INCLUDE(dialog) - public static class MyAlertDialogFragment extends DialogFragment { - - public static MyAlertDialogFragment newInstance(int title) { - MyAlertDialogFragment frag = new MyAlertDialogFragment(); - Bundle args = new Bundle(); - args.putInt("title", title); - frag.setArguments(args); - return frag; - } - - @Override - public Dialog onCreateDialog(Bundle savedInstanceState) { - int title = getArguments().getInt("title"); - - return new AlertDialog.Builder(getActivity()) - .setIcon(R.drawable.alert_dialog_icon) - .setTitle(title) - .setPositiveButton(R.string.alert_dialog_ok, - new DialogInterface.OnClickListener() { - public void onClick(DialogInterface dialog, int whichButton) { - ((FragmentAlertDialog)getActivity()).doPositiveClick(); - } - } - ) - .setNegativeButton(R.string.alert_dialog_cancel, - new DialogInterface.OnClickListener() { - public void onClick(DialogInterface dialog, int whichButton) { - ((FragmentAlertDialog)getActivity()).doNegativeClick(); - } - } - ) - .create(); - } - } -//END_INCLUDE(dialog) -} diff --git a/mobile/src/main/java/com/example/android/apis/app/FragmentAlertDialog.kt b/mobile/src/main/java/com/example/android/apis/app/FragmentAlertDialog.kt new file mode 100644 index 000000000..77394080f --- /dev/null +++ b/mobile/src/main/java/com/example/android/apis/app/FragmentAlertDialog.kt @@ -0,0 +1,94 @@ +/* + * Copyright (C) 2010 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.apis.app + +import com.example.android.apis.R +import android.app.Activity +import android.app.AlertDialog +import android.app.Dialog +import android.app.DialogFragment +import android.content.DialogInterface +import android.os.Bundle +import android.util.Log +import android.widget.Toast +import kotlinx.android.synthetic.main.fragment_dialog.* + +/** Demonstrates how to show an AlertDialog that is managed by a Fragment.*/ + +class FragmentAlertDialog : Activity() { + + override protected fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + setContentView(R.layout.fragment_dialog) + + //Display text on Screen + text.setText(R.string.fragment_alert_dialog_msg) + + // Watch for button clicks. + show.setOnClickListener { + showDialog() + } + } + + //BEGIN_INCLUDE(activity) + fun showDialog() { + val newFragment: DialogFragment = MyAlertDialogFragment.newInstance( + R.string.alert_dialog_two_buttons_title) + newFragment.show(fragmentManager, "dialog") + } + + fun doPositiveClick() { + // Do stuff here. + Log.i("FragmentAlertDialog", "Positive click!") + } + + fun doNegativeClick() { + // Do stuff here. + Log.i("FragmentAlertDialog", "Negative click!") + } +//END_INCLUDE(activity) + + //BEGIN_INCLUDE(dialog) + //-> static class , static method const + public class MyAlertDialogFragment : DialogFragment() { + companion object { + @JvmStatic + fun newInstance(title: Int): MyAlertDialogFragment { + val frag = MyAlertDialogFragment() + val args = Bundle() + args.putInt("title", title) + frag.arguments = args + return frag + } + } + + override + public fun onCreateDialog(savedInstanceState: Bundle?): Dialog { + val title: Int = arguments.getInt("title") + + return AlertDialog.Builder(activity) + .setIcon(R.drawable.alert_dialog_icon) + .setTitle(title) + .setPositiveButton(R.string.alert_dialog_ok + ) { dialog, whichButton -> (activity as FragmentAlertDialog).doPositiveClick() } + .setNegativeButton(R.string.alert_dialog_cancel + ) { dialog, whichButton -> (activity as FragmentAlertDialog).doNegativeClick() } + .create() + } + } +//END_INCLUDE(dialog) +} diff --git a/mobile/src/main/java/com/example/android/apis/app/IsolatedService.java b/mobile/src/main/java/com/example/android/apis/app/IsolatedService.java deleted file mode 100644 index bf3c52384..000000000 --- a/mobile/src/main/java/com/example/android/apis/app/IsolatedService.java +++ /dev/null @@ -1,206 +0,0 @@ -/* - * Copyright (C) 2012 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.apis.app; - -import android.app.Activity; -import android.app.Service; -import android.content.ComponentName; -import android.content.Context; -import android.content.Intent; -import android.content.ServiceConnection; -import android.os.Bundle; -import android.os.RemoteException; -import android.os.IBinder; -import android.os.RemoteCallbackList; -import android.util.Log; -import android.view.View; -import android.view.View.OnClickListener; -import android.widget.Button; -import android.widget.CheckBox; -import android.widget.TextView; - -// Need the following import to get access to the app resources, since this -// class is in a sub-package. -import com.example.android.apis.R; - -/** - * This is an example if implementing a Service that uses android:isolatedProcess. - */ -public class IsolatedService extends Service { - /** - * This is a list of callbacks that have been registered with the - * service. Note that this is package scoped (instead of private) so - * that it can be accessed more efficiently from inner classes. - */ - final RemoteCallbackList mCallbacks - = new RemoteCallbackList(); - - int mValue = 0; - - @Override - public void onCreate() { - Log.i("IsolatedService", "Creating IsolatedService: " + this); - } - - @Override - public void onDestroy() { - Log.i("IsolatedService", "Destroying IsolatedService: " + this); - // Unregister all callbacks. - mCallbacks.kill(); - } - - @Override - public IBinder onBind(Intent intent) { - return mBinder; - } - - /** - * The IRemoteInterface is defined through IDL - */ - private final IRemoteService.Stub mBinder = new IRemoteService.Stub() { - public void registerCallback(IRemoteServiceCallback cb) { - if (cb != null) mCallbacks.register(cb); - } - public void unregisterCallback(IRemoteServiceCallback cb) { - if (cb != null) mCallbacks.unregister(cb); - } - }; - - @Override - public void onTaskRemoved(Intent rootIntent) { - Log.i("IsolatedService", "Task removed in " + this + ": " + rootIntent); - stopSelf(); - } - - private void broadcastValue(int value) { - // Broadcast to all clients the new value. - final int N = mCallbacks.beginBroadcast(); - for (int i=0; i mClz; - final TextView mStatus; - boolean mServiceBound; - IRemoteService mService; - - ServiceInfo(Activity activity, Class clz, - int start, int stop, int bind, int status) { - mActivity = activity; - mClz = clz; - Button button = (Button)mActivity.findViewById(start); - button.setOnClickListener(mStartListener); - button = (Button)mActivity.findViewById(stop); - button.setOnClickListener(mStopListener); - CheckBox cb = (CheckBox)mActivity.findViewById(bind); - cb.setOnClickListener(mBindListener); - mStatus = (TextView)mActivity.findViewById(status); - } - - void destroy() { - if (mServiceBound) { - mActivity.unbindService(mConnection); - } - } - - private OnClickListener mStartListener = new OnClickListener() { - public void onClick(View v) { - mActivity.startService(new Intent(mActivity, mClz)); - } - }; - - private OnClickListener mStopListener = new OnClickListener() { - public void onClick(View v) { - mActivity.stopService(new Intent(mActivity, mClz)); - } - }; - - private OnClickListener mBindListener = new OnClickListener() { - public void onClick(View v) { - if (((CheckBox)v).isChecked()) { - if (!mServiceBound) { - if (mActivity.bindService(new Intent(mActivity, mClz), - mConnection, Context.BIND_AUTO_CREATE)) { - mServiceBound = true; - mStatus.setText("BOUND"); - } - } - } else { - if (mServiceBound) { - mActivity.unbindService(mConnection); - mServiceBound = false; - mStatus.setText(""); - } - } - } - }; - - private ServiceConnection mConnection = new ServiceConnection() { - public void onServiceConnected(ComponentName className, - IBinder service) { - mService = IRemoteService.Stub.asInterface(service); - if (mServiceBound) { - mStatus.setText("CONNECTED"); - } - } - - public void onServiceDisconnected(ComponentName className) { - // This is called when the connection with the service has been - // unexpectedly disconnected -- that is, its process crashed. - mService = null; - if (mServiceBound) { - mStatus.setText("DISCONNECTED"); - } - } - }; - } - - ServiceInfo mService1; - ServiceInfo mService2; - - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - - setContentView(R.layout.isolated_service_controller); - - mService1 = new ServiceInfo(this, IsolatedService.class, R.id.start1, R.id.stop1, - R.id.bind1, R.id.status1); - mService2 = new ServiceInfo(this, IsolatedService2.class, R.id.start2, R.id.stop2, - R.id.bind2, R.id.status2); - } - - @Override - protected void onDestroy() { - super.onDestroy(); - mService1.destroy(); - mService2.destroy(); - } - } -} diff --git a/mobile/src/main/java/com/example/android/apis/app/IsolatedService.kt b/mobile/src/main/java/com/example/android/apis/app/IsolatedService.kt new file mode 100644 index 000000000..874051470 --- /dev/null +++ b/mobile/src/main/java/com/example/android/apis/app/IsolatedService.kt @@ -0,0 +1,188 @@ +/* + * Copyright (C) 2012 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.apis.app + +import android.app.Activity +import android.app.Service +import android.content.ComponentName +import android.content.Context +import android.content.Intent +import android.content.ServiceConnection +import android.os.Bundle +import android.os.RemoteException +import android.os.IBinder +import android.os.RemoteCallbackList +import android.util.Log +import android.view.View +import android.view.View.OnClickListener +import android.widget.Button +import android.widget.CheckBox +import android.widget.TextView + +// Need the following import to get access to the app resources, since this +// class is in a sub-package. +import com.example.android.apis.R + +/** + * This is an example if implementing a Service that uses android:isolatedProcess. + */ +open class IsolatedService : Service() { + /** + * This is a list of callbacks that have been registered with the + * service. Note that this is package scoped (instead of private) so + * that it can be accessed more efficiently from inner classes. + */ + internal val mCallbacks = RemoteCallbackList() + + internal var mValue = 0 + + override fun onCreate() { + Log.i("IsolatedService", "Creating IsolatedService: " + this) + } + + override fun onDestroy() { + Log.i("IsolatedService", "Destroying IsolatedService: " + this) + // Unregister all callbacks. + mCallbacks.kill() + } + + override fun onBind(intent: Intent): IBinder? { + return mBinder + } + + /** + * The IRemoteInterface is defined through IDL + */ + private val mBinder = object : IRemoteService.Stub() { + override fun registerCallback(cb: IRemoteServiceCallback?) { + if (cb != null) mCallbacks.register(cb) + } + + override fun unregisterCallback(cb: IRemoteServiceCallback?) { + if (cb != null) mCallbacks.unregister(cb) + } + } + + override fun onTaskRemoved(rootIntent: Intent) { + Log.i("IsolatedService", "Task removed in " + this + ": " + rootIntent) + stopSelf() + } + + private fun broadcastValue(value: Int) { + // Broadcast to all clients the new value. + val N = mCallbacks.beginBroadcast() + for (i in 0..N - 1) { + try { + mCallbacks.getBroadcastItem(i).valueChanged(value) + } catch (e: RemoteException) { + // The RemoteCallbackList will take care of removing + // the dead object for us. + } + + } + mCallbacks.finishBroadcast() + } + + // ---------------------------------------------------------------------- + + class Controller : Activity() { + internal class ServiceInfo(val mActivity: Activity, val mClz: Class<*>, + start: Int, stop: Int, bind: Int, status: Int) { + lateinit var mStatus: TextView + var mServiceBound: Boolean = false + var mService: IRemoteService? = null + + + + fun destroy() { + if (mServiceBound) { + mActivity.unbindService(mConnection) + } + } + + private val mStartListener = OnClickListener { mActivity.startService(Intent(mActivity, mClz)) } + + private val mStopListener = OnClickListener { mActivity.stopService(Intent(mActivity, mClz)) } + + private val mBindListener = OnClickListener { v -> + if ((v as CheckBox).isChecked) { + if (!mServiceBound) { + if (mActivity.bindService(Intent(mActivity, mClz), + mConnection, Context.BIND_AUTO_CREATE)) { + mServiceBound = true + mStatus.text = "BOUND" + } + } + } else { + if (mServiceBound) { + mActivity.unbindService(mConnection) + mServiceBound = false + mStatus.text = "" + } + } + } + init { + var button = mActivity.findViewById(start) as Button + button.setOnClickListener(mStartListener) + button = mActivity.findViewById(stop) as Button + button.setOnClickListener(mStopListener) + val cb = mActivity.findViewById(bind) as CheckBox + cb.setOnClickListener(mBindListener) + mStatus = mActivity.findViewById(status) as TextView + } + + private val mConnection = object : ServiceConnection { + override fun onServiceConnected(className: ComponentName, + service: IBinder) { + mService = IRemoteService.Stub.asInterface(service) + if (mServiceBound) { + mStatus.text = "CONNECTED" + } + } + + override fun onServiceDisconnected(className: ComponentName) { + // This is called when the connection with the service has been + // unexpectedly disconnected -- that is, its process crashed. + mService = null + if (mServiceBound) { + mStatus.text = "DISCONNECTED" + } + } + } + } + + internal lateinit var mService1: ServiceInfo + internal lateinit var mService2: ServiceInfo + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + + setContentView(R.layout.isolated_service_controller) + + mService1 = ServiceInfo(this, IsolatedService::class.java, R.id.start1, R.id.stop1, + R.id.bind1, R.id.status1) + mService2 = ServiceInfo(this, IsolatedService2::class.java, R.id.start2, R.id.stop2, + R.id.bind2, R.id.status2) + } + + override fun onDestroy() { + super.onDestroy() + mService1.destroy() + mService2.destroy() + } + } +} diff --git a/mobile/src/main/java/com/example/android/apis/app/IsolatedService2.java b/mobile/src/main/java/com/example/android/apis/app/IsolatedService2.kt similarity index 87% rename from mobile/src/main/java/com/example/android/apis/app/IsolatedService2.java rename to mobile/src/main/java/com/example/android/apis/app/IsolatedService2.kt index d313a67a8..a87f7065b 100644 --- a/mobile/src/main/java/com/example/android/apis/app/IsolatedService2.java +++ b/mobile/src/main/java/com/example/android/apis/app/IsolatedService2.kt @@ -14,11 +14,9 @@ * limitations under the License. */ -package com.example.android.apis.app; +package com.example.android.apis.app /** * Stub to be able to have another instance of IsolatedService running. */ -public class IsolatedService2 extends IsolatedService { - -} +class IsolatedService2 : IsolatedService() diff --git a/mobile/src/main/java/com/example/android/apis/app/LocalService.java b/mobile/src/main/java/com/example/android/apis/app/LocalService.kt similarity index 57% rename from mobile/src/main/java/com/example/android/apis/app/LocalService.java rename to mobile/src/main/java/com/example/android/apis/app/LocalService.kt index a3742ca6a..b0e5a39b6 100644 --- a/mobile/src/main/java/com/example/android/apis/app/LocalService.java +++ b/mobile/src/main/java/com/example/android/apis/app/LocalService.kt @@ -14,108 +14,105 @@ * limitations under the License. */ -package com.example.android.apis.app; - -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.os.PowerManager; -import android.util.Log; -import android.widget.Toast; +package com.example.android.apis.app + +import android.app.Notification +import android.app.NotificationManager +import android.app.PendingIntent +import android.app.Service +import android.content.Context +import android.content.Intent +import android.os.Binder +import android.os.IBinder +import android.os.PowerManager +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 com.example.android.apis.R; +import com.example.android.apis.R /** * This is an example of implementing an application service that runs locally - * in the same process as the application. The {@link LocalServiceActivities.Controller} - * and {@link LocalServiceActivities.Binding} classes show how to interact with the + * in the same process as the application. The [LocalServiceActivities.Controller] + * and [LocalServiceActivities.Binding] classes show how to interact with the * service. + * - *

Notice the use of the {@link NotificationManager} when interesting things + * Notice the use of the [NotificationManager] when interesting things * happen in the service. This is generally how background services should * interact with the user, rather than doing something more disruptive such as * calling startActivity(). */ //BEGIN_INCLUDE(service) -public class LocalService extends Service { - private NotificationManager mNM; +class LocalService : Service() { + private var mNM: NotificationManager? = null // Unique Identification Number for the Notification. // We use it on Notification start, and to cancel it. - private int NOTIFICATION = R.string.local_service_started; + private val NOTIFICATION = R.string.local_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 LocalBinder extends Binder { - LocalService getService() { - return LocalService.this; - } + inner class LocalBinder : Binder() { + internal val service: LocalService + get() = this@LocalService } - - @Override - public void onCreate() { - mNM = (NotificationManager)getSystemService(NOTIFICATION_SERVICE); + + override fun onCreate() { + mNM = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager // Display a notification about us starting. We put an icon in the status bar. - showNotification(); + showNotification() } - @Override - public int onStartCommand(Intent intent, int flags, int startId) { - Log.i("LocalService", "Received start id " + startId + ": " + intent); - return START_NOT_STICKY; + override fun onStartCommand(intent: Intent, flags: Int, startId: Int): Int { + Log.i("LocalService", "Received start id $startId: $intent") + return Service.START_NOT_STICKY } - @Override - public void onDestroy() { + override fun onDestroy() { // Cancel the persistent notification. - mNM.cancel(NOTIFICATION); + mNM!!.cancel(NOTIFICATION) // Tell the user we stopped. - Toast.makeText(this, R.string.local_service_stopped, Toast.LENGTH_SHORT).show(); + Toast.makeText(this, R.string.local_service_stopped, Toast.LENGTH_SHORT).show() } - @Override - public IBinder onBind(Intent intent) { - return mBinder; + override fun onBind(intent: Intent): IBinder? { + return mBinder } // This is the object that receives interactions from clients. See // RemoteService for a more complete example. - private final IBinder mBinder = new LocalBinder(); + private val mBinder = LocalBinder() /** * Show a notification while this service is running. */ - private void showNotification() { + private fun showNotification() { // In this sample, we'll use the same text for the ticker and the expanded notification - CharSequence text = getText(R.string.local_service_started); + val text = getText(R.string.local_service_started) // The PendingIntent to launch our activity if the user selects this notification - PendingIntent contentIntent = PendingIntent.getActivity(this, 0, - new Intent(this, LocalServiceActivities.Controller.class), 0); + val contentIntent = PendingIntent.getActivity(this, 0, + Intent(this, LocalServiceActivities.Controller::class.java), 0) // Set the info for the views that show in the notification panel. - Notification notification = new Notification.Builder(this) + val notification = Notification.Builder(this) .setSmallIcon(R.drawable.stat_sample) // the status icon .setTicker(text) // the status text .setWhen(System.currentTimeMillis()) // the time stamp .setContentTitle(getText(R.string.local_service_label)) // the label of the entry .setContentText(text) // the contents of the entry .setContentIntent(contentIntent) // The intent to send when the entry is clicked - .build(); + .build() // Send the notification. - mNM.notify(NOTIFICATION, notification); + mNM!!.notify(NOTIFICATION, notification) } } //END_INCLUDE(service) diff --git a/mobile/src/main/java/com/example/android/apis/app/LocalServiceActivities.java b/mobile/src/main/java/com/example/android/apis/app/LocalServiceActivities.java deleted file mode 100644 index a6c3fd822..000000000 --- a/mobile/src/main/java/com/example/android/apis/app/LocalServiceActivities.java +++ /dev/null @@ -1,171 +0,0 @@ -/* - * 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 com.example.android.apis.app; - -import com.example.android.apis.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 LocalServiceActivities { - /** - *

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.

- * - *

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.local_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, - LocalService.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, - LocalService.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.

- * - *

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; - -// BEGIN_INCLUDE(bind) - private LocalService 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 = ((LocalService.LocalBinder)service).getService(); - - // Tell the user about this for our demo. - Toast.makeText(Binding.this, R.string.local_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.local_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, - LocalService.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(); - } -// END_INCLUDE(bind) - - 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.local_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); - } - } -} diff --git a/mobile/src/main/java/com/example/android/apis/app/LocalServiceActivities.kt b/mobile/src/main/java/com/example/android/apis/app/LocalServiceActivities.kt new file mode 100644 index 000000000..67ac9fa46 --- /dev/null +++ b/mobile/src/main/java/com/example/android/apis/app/LocalServiceActivities.kt @@ -0,0 +1,157 @@ +/* + * 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 com.example.android.apis.app + +import com.example.android.apis.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 +import kotlinx.android.synthetic.main.local_service_binding.* +import kotlinx.android.synthetic.main.local_service_controller.* + +class LocalServiceActivities { + /** + * + * 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. + + * + * Note that this is implemented as an inner class only keep the sample + * all together; typically this code would appear in some separate class. + */ + class Controller : Activity() { + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + + setContentView(R.layout.local_service_controller) + + // Watch for button clicks. + start.setOnClickListener(mStartListener) + stop.setOnClickListener(mStopListener) + } + + private val mStartListener = OnClickListener { + // 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(Intent(this@Controller, + LocalService::class.java)) + } + + private val mStopListener = OnClickListener { + // Cancel a previous call to startService(). Note that the + // service will not actually stop at this point if there are + // still bound clients. + stopService(Intent(this@Controller, + LocalService::class.java)) + } + } + + // ---------------------------------------------------------------------- + + /** + * 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. + + * + * Note that this is implemented as an inner class only keep the sample + * all together; typically this code would appear in some separate class. + */ + class Binding : Activity() { + private var mIsBound: Boolean = false + + // BEGIN_INCLUDE(bind) + private var mBoundService: LocalService? = null + + private val mConnection = object : ServiceConnection { + override fun onServiceConnected(className: ComponentName, service: IBinder) { + // 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 = (service as LocalService.LocalBinder).service + + // Tell the user about this for our demo. + Toast.makeText(this@Binding, R.string.local_service_connected, + Toast.LENGTH_SHORT).show() + } + + override fun onServiceDisconnected(className: ComponentName) { + // 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(this@Binding, R.string.local_service_disconnected, + Toast.LENGTH_SHORT).show() + } + } + + internal fun 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(Intent(this@Binding, + LocalService::class.java), mConnection, Context.BIND_AUTO_CREATE) + mIsBound = true + } + + internal fun doUnbindService() { + if (mIsBound) { + // Detach our existing connection. + unbindService(mConnection) + mIsBound = false + } + } + + override fun onDestroy() { + super.onDestroy() + doUnbindService() + } + // END_INCLUDE(bind) + + private val mBindListener = OnClickListener { doBindService() } + + private val mUnbindListener = OnClickListener { doUnbindService() } + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + + setContentView(R.layout.local_service_binding) + + // Watch for button clicks. + bind.setOnClickListener(mBindListener) + unbind.setOnClickListener(mUnbindListener) + } + } +} diff --git a/mobile/src/main/java/com/example/android/apis/app/NotificationBackgroundService.java b/mobile/src/main/java/com/example/android/apis/app/NotificationBackgroundService.kt similarity index 52% rename from mobile/src/main/java/com/example/android/apis/app/NotificationBackgroundService.java rename to mobile/src/main/java/com/example/android/apis/app/NotificationBackgroundService.kt index bd5f0601f..c0a6122a0 100644 --- a/mobile/src/main/java/com/example/android/apis/app/NotificationBackgroundService.java +++ b/mobile/src/main/java/com/example/android/apis/app/NotificationBackgroundService.kt @@ -14,85 +14,78 @@ * limitations under the License. */ -package com.example.android.apis.app; +package com.example.android.apis.app // Need the following import to get access to the app resources, since this // class is in a sub-package. -import com.example.android.apis.R; +import com.example.android.apis.R -import android.app.Activity; -import android.app.Notification; -import android.app.NotificationManager; -import android.app.PendingIntent; -import android.app.Service; -import android.content.Context; -import android.content.Intent; -import android.os.Bundle; -import android.os.IBinder; -import android.view.View; -import android.view.View.OnClickListener; -import android.widget.Button; +import android.app.Activity +import android.app.Notification +import android.app.NotificationManager +import android.app.PendingIntent +import android.app.Service +import android.content.Context +import android.content.Intent +import android.os.Bundle +import android.os.IBinder +import android.view.View +import android.view.View.OnClickListener +import android.widget.Button +import kotlinx.android.synthetic.main.notification_background_service.* /** * Example service that gets launched from a notification and runs in the background. */ -public class NotificationBackgroundService extends Service { - @Override - public int onStartCommand(Intent intent, int flags, int startId) { - ((NotificationManager)getSystemService(Context.NOTIFICATION_SERVICE)) - .cancel(R.layout.notification_background_service); - stopSelf(startId); - return START_NOT_STICKY; +class NotificationBackgroundService : Service() { + override fun onStartCommand(intent: Intent, flags: Int, startId: Int): Int { + (getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager) + .cancel(R.layout.notification_background_service) + stopSelf(startId) + return Service.START_NOT_STICKY } - @Override - public IBinder onBind(Intent intent) { - return null; + override fun onBind(intent: Intent): IBinder? { + return null } /** * Demo UI that allows the user to post the notification. */ - public static class Controller extends Activity { - private NotificationManager mNM; + class Controller : Activity() { + lateinit private var mNM: NotificationManager - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) - mNM = (NotificationManager) getSystemService(NOTIFICATION_SERVICE); + mNM = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager - setContentView(R.layout.notification_background_service); + setContentView(R.layout.notification_background_service) - Button button = (Button) findViewById(R.id.notify); - button.setOnClickListener(mNotify); + notify.setOnClickListener(mNotify) } - private void showNotification(CharSequence text) { + private fun showNotification(text: CharSequence) { // The PendingIntent to launch our activity if the user selects this notification - PendingIntent contentIntent = PendingIntent.getService(this, 0, - new Intent(this, NotificationBackgroundService.class), 0); + val contentIntent = PendingIntent.getService(this, 0, + Intent(this, NotificationBackgroundService::class.java), 0) // Set the info for the views that show in the notification panel. - Notification notification = new Notification.Builder(this) + val notification = Notification.Builder(this) .setSmallIcon(R.drawable.stat_sample) // the status icon .setTicker(text) // the status text .setWhen(System.currentTimeMillis()) // the time stamp .setContentTitle(getText(R.string.notification_background_label)) // the label of the entry .setContentText(text) // the contents of the entry .setContentIntent(contentIntent) // The intent to send when the entry is clicked - .build(); + .build() // Send the notification. // We use a layout id because it is a unique number. We use it later to cancel. - mNM.notify(R.layout.notification_background_service, notification); + mNM.notify(R.layout.notification_background_service, notification) } - private OnClickListener mNotify = new OnClickListener() { - public void onClick(View v) { - showNotification("Selecting this will cause a background service to run."); - } - }; + private val mNotify = OnClickListener { showNotification("Selecting this will cause a background service to run.") } } } diff --git a/mobile/src/main/java/com/example/android/apis/app/NotifyingController.java b/mobile/src/main/java/com/example/android/apis/app/NotifyingController.java deleted file mode 100644 index b8b4e3f7f..000000000 --- a/mobile/src/main/java/com/example/android/apis/app/NotifyingController.java +++ /dev/null @@ -1,61 +0,0 @@ -/* - * 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 com.example.android.apis.app; - -// Need the following import to get access to the app resources, since this -// class is in a sub-package. -import com.example.android.apis.R; - -import android.app.Activity; -import android.content.Intent; -import android.os.Bundle; -import android.view.View; -import android.view.View.OnClickListener; -import android.widget.Button; - -/** - * Controller to start and stop a service. The serivce will update a status bar - * notification every 5 seconds for a minute. - */ -public class NotifyingController extends Activity { - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - - setContentView(R.layout.notifying_controller); - - Button button = (Button) findViewById(R.id.notifyStart); - button.setOnClickListener(mStartListener); - button = (Button) findViewById(R.id.notifyStop); - button.setOnClickListener(mStopListener); - } - - private OnClickListener mStartListener = new OnClickListener() { - public void onClick(View v) { - startService(new Intent(NotifyingController.this, - NotifyingService.class)); - } - }; - - private OnClickListener mStopListener = new OnClickListener() { - public void onClick(View v) { - stopService(new Intent(NotifyingController.this, - NotifyingService.class)); - } - }; -} - diff --git a/mobile/src/main/java/com/example/android/apis/app/NotifyingController.kt b/mobile/src/main/java/com/example/android/apis/app/NotifyingController.kt new file mode 100644 index 000000000..866c6744e --- /dev/null +++ b/mobile/src/main/java/com/example/android/apis/app/NotifyingController.kt @@ -0,0 +1,53 @@ +/* + * 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 com.example.android.apis.app + +// Need the following import to get access to the app resources, since this +// class is in a sub-package. +import com.example.android.apis.R + +import android.app.Activity +import android.content.Intent +import android.os.Bundle +import android.view.View.OnClickListener +import kotlinx.android.synthetic.main.notifying_controller.* + +/** + * Controller to start and stop a service. The serivce will update a status bar + * notification every 5 seconds for a minute. + */ +class NotifyingController : Activity() { + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + + setContentView(R.layout.notifying_controller) + + notifyStart.setOnClickListener(mStartListener) + notifyStop.setOnClickListener(mStopListener) + } + + private val mStartListener = OnClickListener { + startService(Intent(this@NotifyingController, + NotifyingService::class.java)) + } + + private val mStopListener = OnClickListener { + stopService(Intent(this@NotifyingController, + NotifyingService::class.java)) + } +} + diff --git a/mobile/src/main/java/com/example/android/apis/app/NotifyingService.java b/mobile/src/main/java/com/example/android/apis/app/NotifyingService.java deleted file mode 100644 index acb00950c..000000000 --- a/mobile/src/main/java/com/example/android/apis/app/NotifyingService.java +++ /dev/null @@ -1,131 +0,0 @@ -/* - * 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 com.example.android.apis.app; - -// Need the following import to get access to the app resources, since this -// class is in a sub-package. -import com.example.android.apis.R; - -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.ConditionVariable; -import android.os.IBinder; -import android.os.Parcel; -import android.os.RemoteException; - -/** - * This is an example of service that will update its status bar balloon - * every 5 seconds for a minute. - * - */ -public class NotifyingService extends Service { - - // Use a layout id for a unique identifier - private static int MOOD_NOTIFICATIONS = R.layout.status_bar_notifications; - - // variable which controls the notification thread - private ConditionVariable mCondition; - - @Override - public void onCreate() { - mNM = (NotificationManager) getSystemService(NOTIFICATION_SERVICE); - - // Start up the thread running the service. Note that we create a - // separate thread because the service normally runs in the process's - // main thread, which we don't want to block. - Thread notifyingThread = new Thread(null, mTask, "NotifyingService"); - mCondition = new ConditionVariable(false); - notifyingThread.start(); - } - - @Override - public void onDestroy() { - // Cancel the persistent notification. - mNM.cancel(MOOD_NOTIFICATIONS); - // Stop the thread from generating further notifications - mCondition.open(); - } - - private Runnable mTask = new Runnable() { - public void run() { - for (int i = 0; i < 4; ++i) { - showNotification(R.drawable.stat_happy, - R.string.status_bar_notifications_happy_message); - if (mCondition.block(5 * 1000)) - break; - showNotification(R.drawable.stat_neutral, - R.string.status_bar_notifications_ok_message); - if (mCondition.block(5 * 1000)) - break; - showNotification(R.drawable.stat_sad, - R.string.status_bar_notifications_sad_message); - if (mCondition.block(5 * 1000)) - break; - } - // Done with our work... stop the service! - NotifyingService.this.stopSelf(); - } - }; - - @Override - public IBinder onBind(Intent intent) { - return mBinder; - } - - private void showNotification(int moodId, int textId) { - // In this sample, we'll use the same text for the ticker and the expanded notification - CharSequence text = getText(textId); - - // The PendingIntent to launch our activity if the user selects this notification - PendingIntent contentIntent = PendingIntent.getActivity(this, 0, - new Intent(this, NotifyingController.class), 0); - - // Set the icon and timestamp. - // Note that in this example, we do not set the tickerText. We update the icon enough that - // it is distracting to show the ticker text every time it changes. We strongly suggest - // that you do this as well. (Think of of the "New hardware found" or "Network connection - // changed" messages that always pop up) - // Set the info for the views that show in the notification panel. - Notification notification = new Notification.Builder(this) - .setSmallIcon(moodId) - .setWhen(System.currentTimeMillis()) - .setContentTitle(getText(R.string.status_bar_notifications_mood_title)) - .setContentText(text) // the contents of the entry - .setContentIntent(contentIntent) // The intent to send when the entry is clicked - .build(); - - // Send the notification. - // We use a layout id because it is a unique number. We use it later to cancel. - mNM.notify(MOOD_NOTIFICATIONS, notification); - } - - // This is the object that receives interactions from clients. See - // RemoteService for a more complete example. - private final IBinder mBinder = new Binder() { - @Override - protected boolean onTransact(int code, Parcel data, Parcel reply, - int flags) throws RemoteException { - return super.onTransact(code, data, reply, flags); - } - }; - - private NotificationManager mNM; -} diff --git a/mobile/src/main/java/com/example/android/apis/app/NotifyingService.kt b/mobile/src/main/java/com/example/android/apis/app/NotifyingService.kt new file mode 100644 index 000000000..cad3b133c --- /dev/null +++ b/mobile/src/main/java/com/example/android/apis/app/NotifyingService.kt @@ -0,0 +1,128 @@ +/* + * 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 com.example.android.apis.app + +// Need the following import to get access to the app resources, since this +// class is in a sub-package. +import com.example.android.apis.R + +import android.app.Notification +import android.app.NotificationManager +import android.app.PendingIntent +import android.app.Service +import android.content.Context +import android.content.Intent +import android.os.Binder +import android.os.ConditionVariable +import android.os.IBinder +import android.os.Parcel +import android.os.RemoteException + +/** + * This is an example of service that will update its status bar balloon + * every 5 seconds for a minute. + + */ +class NotifyingService : Service() { + + // variable which controls the notification thread + lateinit private var mCondition: ConditionVariable + + override fun onCreate() { + mNM = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager + // Start up the thread running the service. Note that we create a + // separate thread because the service normally runs in the process's + // main thread, which we don't want to block. + val notifyingThread = Thread(null, mTask, "NotifyingService") + mCondition = ConditionVariable(false) + notifyingThread.start() + } + + override fun onDestroy() { + // Cancel the persistent notification. + mNM.cancel(MOOD_NOTIFICATIONS) + // Stop the thread from generating further notifications + mCondition.open() + } + + private val mTask = Runnable { + for (i in 0..3) { + showNotification(R.drawable.stat_happy, + R.string.status_bar_notifications_happy_message) + if (mCondition.block((5 * 1000).toLong())) + break + showNotification(R.drawable.stat_neutral, + R.string.status_bar_notifications_ok_message) + if (mCondition.block((5 * 1000).toLong())) + break + showNotification(R.drawable.stat_sad, + R.string.status_bar_notifications_sad_message) + if (mCondition.block((5 * 1000).toLong())) + break + } + // Done with our work... stop the service! + this@NotifyingService.stopSelf() + } + + override fun onBind(intent: Intent): IBinder? { + return mBinder + } + + private fun showNotification(moodId: Int, textId: Int) { + // In this sample, we'll use the same text for the ticker and the expanded notification + val text = getText(textId) + + // The PendingIntent to launch our activity if the user selects this notification + val contentIntent = PendingIntent.getActivity(this, 0, + Intent(this, NotifyingController::class.java), 0) + + // Set the icon and timestamp. + // Note that in this example, we do not set the tickerText. We update the icon enough that + // it is distracting to show the ticker text every time it changes. We strongly suggest + // that you do this as well. (Think of of the "New hardware found" or "Network connection + // changed" messages that always pop up) + // Set the info for the views that show in the notification panel. + val notification = Notification.Builder(this) + .setSmallIcon(moodId) + .setWhen(System.currentTimeMillis()) + .setContentTitle(getText(R.string.status_bar_notifications_mood_title)) + .setContentText(text) // the contents of the entry + .setContentIntent(contentIntent) // The intent to send when the entry is clicked + .build() + + // Send the notification. + // We use a layout id because it is a unique number. We use it later to cancel. + mNM.notify(MOOD_NOTIFICATIONS, notification) + } + + // This is the object that receives interactions from clients. See + // RemoteService for a more complete example. + private val mBinder = object : Binder() { + @Throws(RemoteException::class) + override fun onTransact(code: Int, data: Parcel, reply: Parcel, + flags: Int): Boolean { + return super.onTransact(code, data, reply, flags) + } + } + + lateinit private var mNM: NotificationManager + + companion object { + // Use a layout id for a unique identifier + private val MOOD_NOTIFICATIONS = R.layout.status_bar_notifications + } +} diff --git a/mobile/src/main/java/com/example/android/apis/app/ServiceStartArguments.java b/mobile/src/main/java/com/example/android/apis/app/ServiceStartArguments.java deleted file mode 100644 index 584dff35c..000000000 --- a/mobile/src/main/java/com/example/android/apis/app/ServiceStartArguments.java +++ /dev/null @@ -1,273 +0,0 @@ -/* - * 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 com.example.android.apis.app; - -import android.app.Activity; -import android.app.Notification; -import android.app.NotificationManager; -import android.app.PendingIntent; -import android.app.Service; -import android.content.Intent; -import android.os.Bundle; -import android.os.Handler; -import android.os.HandlerThread; -import android.os.IBinder; -import android.os.Looper; -import android.os.Message; -import android.os.Process; -import android.util.Log; -import android.view.View; -import android.view.View.OnClickListener; -import android.widget.Button; -import android.widget.Toast; - -import com.example.android.apis.R; - -/** - * This is an example of implementing an application service that runs locally - * in the same process as the application. The {@link Controller} - * class shows how to interact with the service. - * - *

Notice the use of the {@link NotificationManager} when interesting things - * happen in the service. This is generally how background services should - * interact with the user, rather than doing something more disruptive such as - * calling startActivity(). - * - *

For applications targeting Android 1.5 or beyond, you may want consider - * using the {@link android.app.IntentService} class, which takes care of all the - * work of creating the extra thread and dispatching commands to it. - */ -public class ServiceStartArguments extends Service { - private NotificationManager mNM; - private Intent mInvokeIntent; - private volatile Looper mServiceLooper; - private volatile ServiceHandler mServiceHandler; - - private final class ServiceHandler extends Handler { - public ServiceHandler(Looper looper) { - super(looper); - } - - @Override - public void handleMessage(Message msg) { - Bundle arguments = (Bundle)msg.obj; - - String txt = arguments.getString("name"); - - Log.i("ServiceStartArguments", "Message: " + msg + ", " - + arguments.getString("name")); - - if ((msg.arg2&Service.START_FLAG_REDELIVERY) == 0) { - txt = "New cmd #" + msg.arg1 + ": " + txt; - } else { - txt = "Re-delivered #" + msg.arg1 + ": " + txt; - } - - showNotification(txt); - - // Normally we would do some work here... for our sample, we will - // just sleep for 5 seconds. - long endTime = System.currentTimeMillis() + 5*1000; - while (System.currentTimeMillis() < endTime) { - synchronized (this) { - try { - wait(endTime - System.currentTimeMillis()); - } catch (Exception e) { - } - } - } - - hideNotification(); - - Log.i("ServiceStartArguments", "Done with #" + msg.arg1); - stopSelf(msg.arg1); - } - - }; - - @Override - public void onCreate() { - mNM = (NotificationManager)getSystemService(NOTIFICATION_SERVICE); - - Toast.makeText(this, R.string.service_created, - Toast.LENGTH_SHORT).show(); - - // This is who should be launched if the user selects our persistent - // notification. - mInvokeIntent = new Intent(this, Controller.class); - - // Start up the thread running the service. Note that we create a - // separate thread because the service normally runs in the process's - // main thread, which we don't want to block. We also make it - // background priority so CPU-intensive work will not disrupt our UI. - HandlerThread thread = new HandlerThread("ServiceStartArguments", - Process.THREAD_PRIORITY_BACKGROUND); - thread.start(); - - mServiceLooper = thread.getLooper(); - mServiceHandler = new ServiceHandler(mServiceLooper); - } - - @Override - public int onStartCommand(Intent intent, int flags, int startId) { - Log.i("ServiceStartArguments", - "Starting #" + startId + ": " + intent.getExtras()); - Message msg = mServiceHandler.obtainMessage(); - msg.arg1 = startId; - msg.arg2 = flags; - msg.obj = intent.getExtras(); - mServiceHandler.sendMessage(msg); - Log.i("ServiceStartArguments", "Sending: " + msg); - - // For the start fail button, we will simulate the process dying - // for some reason in onStartCommand(). - if (intent.getBooleanExtra("fail", false)) { - // Don't do this if we are in a retry... the system will - // eventually give up if we keep crashing. - if ((flags&START_FLAG_RETRY) == 0) { - // Since the process hasn't finished handling the command, - // it will be restarted with the command again, regardless of - // whether we return START_REDELIVER_INTENT. - Process.killProcess(Process.myPid()); - } - } - - // Normally we would consistently return one kind of result... - // however, here we will select between these two, so you can see - // how they impact the behavior. Try killing the process while it - // is in the middle of executing the different commands. - return intent.getBooleanExtra("redeliver", false) - ? START_REDELIVER_INTENT : START_NOT_STICKY; - } - - @Override - public void onDestroy() { - mServiceLooper.quit(); - - hideNotification(); - - // Tell the user we stopped. - Toast.makeText(ServiceStartArguments.this, R.string.service_destroyed, - Toast.LENGTH_SHORT).show(); - } - - @Override - public IBinder onBind(Intent intent) { - return null; - } - - /** - * Show a notification while this service is running. - */ - private void showNotification(String text) { - // The PendingIntent to launch our activity if the user selects this notification - PendingIntent contentIntent = PendingIntent.getActivity(this, 0, - new Intent(this, Controller.class), 0); - - // Set the info for the views that show in the notification panel. - Notification.Builder noteBuilder = new Notification.Builder(this) - .setSmallIcon(R.drawable.stat_sample) // the status icon - .setTicker(text) // the status text - .setWhen(System.currentTimeMillis()) // the time stamp - .setContentTitle(getText(R.string.service_start_arguments_label)) // the label - .setContentText(text) // the contents of the entry - .setContentIntent(contentIntent); // The intent to send when the entry is clicked - - // We show this for as long as our service is processing a command. - noteBuilder.setOngoing(true); - - // Send the notification. - // We use a string id because it is a unique number. We use it later to cancel. - mNM.notify(R.string.service_created, noteBuilder.build()); - } - - private void hideNotification() { - mNM.cancel(R.string.service_created); - } - - // ---------------------------------------------------------------------- - - /** - * Example of explicitly starting the {@link ServiceStartArguments}. - * - *

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.service_start_arguments_controller); - - // Watch for button clicks. - Button button = (Button)findViewById(R.id.start1); - button.setOnClickListener(mStart1Listener); - button = (Button)findViewById(R.id.start2); - button.setOnClickListener(mStart2Listener); - button = (Button)findViewById(R.id.start3); - button.setOnClickListener(mStart3Listener); - button = (Button)findViewById(R.id.startfail); - button.setOnClickListener(mStartFailListener); - button = (Button)findViewById(R.id.kill); - button.setOnClickListener(mKillListener); - } - - private OnClickListener mStart1Listener = new OnClickListener() { - public void onClick(View v) { - startService(new Intent(Controller.this, - ServiceStartArguments.class) - .putExtra("name", "One")); - } - }; - - private OnClickListener mStart2Listener = new OnClickListener() { - public void onClick(View v) { - startService(new Intent(Controller.this, - ServiceStartArguments.class) - .putExtra("name", "Two")); - } - }; - - private OnClickListener mStart3Listener = new OnClickListener() { - public void onClick(View v) { - startService(new Intent(Controller.this, - ServiceStartArguments.class) - .putExtra("name", "Three") - .putExtra("redeliver", true)); - } - }; - - private OnClickListener mStartFailListener = new OnClickListener() { - public void onClick(View v) { - startService(new Intent(Controller.this, - ServiceStartArguments.class) - .putExtra("name", "Failure") - .putExtra("fail", true)); - } - }; - - private OnClickListener mKillListener = new OnClickListener() { - public void onClick(View v) { - // This is to simulate the service being killed while it is - // running in the background. - Process.killProcess(Process.myPid()); - } - }; - } -} - diff --git a/mobile/src/main/java/com/example/android/apis/app/ServiceStartArguments.kt b/mobile/src/main/java/com/example/android/apis/app/ServiceStartArguments.kt new file mode 100644 index 000000000..a00827f9f --- /dev/null +++ b/mobile/src/main/java/com/example/android/apis/app/ServiceStartArguments.kt @@ -0,0 +1,257 @@ +/* + * 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 com.example.android.apis.app + +import android.app.Activity +import android.app.Notification +import android.app.NotificationManager +import android.app.PendingIntent +import android.app.Service +import android.content.Intent +import android.os.Bundle +import android.os.Handler +import android.os.HandlerThread +import android.os.IBinder +import android.os.Looper +import android.os.Message +import android.os.Process +import android.util.Log +import android.view.View.OnClickListener +import android.widget.Toast + +import com.example.android.apis.R +import com.example.android.apis.R.id.* +import kotlinx.android.synthetic.main.service_start_arguments_controller.* + +/** + * This is an example of implementing an application service that runs locally + * in the same process as the application. The [Controller] + * class shows how to interact with the service. + + * + * Notice the use of the [NotificationManager] when interesting things + * happen in the service. This is generally how background services should + * interact with the user, rather than doing something more disruptive such as + * calling startActivity(). + + * + * For applications targeting Android 1.5 or beyond, you may want consider + * using the [android.app.IntentService] class, which takes care of all the + * work of creating the extra thread and dispatching commands to it. + */ + +class ServiceStartArguments : Service() { + lateinit private var mNM: NotificationManager + lateinit private var mInvokeIntent: Intent + @Volatile + lateinit private var mServiceLooper: Looper + @Volatile + lateinit private var mServiceHandler: ServiceHandler + + private inner class ServiceHandler( looper:Looper ): Handler(looper) { + init { } + + override fun handleMessage(msg: Message) { + val arguments = msg.obj as Bundle + + var txt: String = arguments.getString("name") + + Log.i("ServiceStartArguments", "Message: " + msg + ", " + + arguments.getString("name")) + + if (msg.arg2 and Service.START_FLAG_REDELIVERY == 0) { + txt = "New cmd #" + msg.arg1 + ": " + txt + } else { + txt = "Re-delivered #" + msg.arg1 + ": " + txt + } + + showNotification(txt) + + // Normally we would do some work here... for our sample, we will + // just sleep for 5 seconds. + val endTime = System.currentTimeMillis() + 5 * 1000 + while (System.currentTimeMillis() < endTime) { + synchronized(this) { + try { + //wait(endTime - System.currentTimeMillis()) + } catch (e: Exception) { + } + + } + } + + hideNotification() + + Log.i("ServiceStartArguments", "Done with #" + msg.arg1) + stopSelf(msg.arg1) + } + + } + + override public fun onCreate() { + mNM = getSystemService(NOTIFICATION_SERVICE) as NotificationManager + + Toast.makeText(this, R.string.service_created, + Toast.LENGTH_SHORT).show() + + // This is who should be launched if the user selects our persistent + // notification. + mInvokeIntent = Intent(this, Controller::class.java) + + // Start up the thread running the service. Note that we create a + // separate thread because the service normally runs in the process's + // main thread, which we don't want to block. We also make it + // background priority so CPU-intensive work will not disrupt our UI. + var thread: HandlerThread = HandlerThread("ServiceStartArguments", + Process.THREAD_PRIORITY_BACKGROUND) + thread.start() + + mServiceLooper = thread.getLooper() + mServiceHandler = ServiceHandler(mServiceLooper) + } + + override public fun onStartCommand( intent:Intent, flags:Int, startId :Int):Int + { + Log.i("ServiceStartArguments", + "Starting #" + startId + ": " + intent.getExtras()) + var msg = mServiceHandler . obtainMessage () + msg.arg1 = startId + msg.arg2 = flags + msg.obj = intent.getExtras() + mServiceHandler.sendMessage(msg) + Log.i("ServiceStartArguments", "Sending: " + msg); + + // For the start fail button, we will simulate the process dying + // for some reason in onStartCommand(). + if (intent.getBooleanExtra("fail", false)) { + // Don't do this if we are in a retry... the system will + // eventually give up if we keep crashing. + if ((flags and START_FLAG_RETRY) == 0) { + // Since the process hasn't finished handling the command, + // it will be restarted with the command again, regardless of + // whether we return START_REDELIVER_INTENT. + Process.killProcess(Process.myPid()) + } + } + + // Normally we would consistently return one kind of result... + // however, here we will select between these two, so you can see + // how they impact the behavior. Try killing the process while it + // is in the middle of executing the different commands. + var flag: Int= START_NOT_STICKY + if (intent.getBooleanExtra("redeliver", false)) + flag = START_REDELIVER_INTENT + + return flag + } + + override + public fun onDestroy() + { + mServiceLooper.quit() + + hideNotification() + + // Tell the user we stopped. + Toast.makeText(this@ServiceStartArguments, R.string.service_destroyed, + Toast.LENGTH_SHORT).show() + } + + override public fun onBind(intent:Intent):IBinder? + { + return null + } + + //Show a notification while this service is running. + + private fun showNotification(text:String) + { + // The PendingIntent to launch our activity if the user selects this notification + val contentIntent :PendingIntent= PendingIntent . getActivity (this, 0, + Intent (this, Controller::class.java), 0) + + // Set the info for the views that show in the notification panel. + var noteBuilder = Notification.Builder(this) + .setSmallIcon(R.drawable.stat_sample) // the status icon + .setTicker(text) // the status text + .setWhen(System.currentTimeMillis()) // the time stamp + .setContentTitle(getText(R.string.service_start_arguments_label)) // the label + .setContentText(text) // the contents of the entry + .setContentIntent(contentIntent) // The intent to send when the entry is clicked + + // We show this for as long as our service is processing a command. + noteBuilder.setOngoing(true) + + // Send the notification. + // We use a string id because it is a unique number. We use it later to cancel. + mNM.notify(R.string.service_created, noteBuilder.build()) + } + + private fun hideNotification() + { + mNM.cancel(R.string.service_created) + } + + +/** + * Example of explicitly starting the [ServiceStartArguments]. + * Note that this is implemented as an inner class only keep the sample + * all together; typically this code would appear in some separate class. */ + + class Controller : Activity() { + override protected fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + + setContentView(R.layout.service_start_arguments_controller) + + start1.setOnClickListener(mStart1Listener) + start2.setOnClickListener(mStart2Listener) + start3.setOnClickListener(mStart3Listener) + startfail.setOnClickListener(mStartFailListener) + kill.setOnClickListener(mKillListener) + } + + private val mStart1Listener = OnClickListener { + startService(Intent(this@Controller, + ServiceStartArguments::class.java).putExtra("name", "One")) + } + + private val mStart2Listener = OnClickListener { + startService(Intent(this@Controller, + ServiceStartArguments::class.java).putExtra("name", "Two")) + } + private val mStart3Listener = OnClickListener { + startService(Intent(this@Controller, + ServiceStartArguments::class.java).putExtra("name", "Three") + .putExtra("redeliver", true)) + } + + + private val mStartFailListener = OnClickListener { + startService(Intent(this@Controller, + ServiceStartArguments::class.java) + .putExtra("name", "Three") + .putExtra("name", "Failure") + .putExtra("fail", true)) + } + + private val mKillListener = OnClickListener { + Process.killProcess(Process.myPid()) + } + + } +} diff --git a/mobile/src/main/java/com/example/android/apis/text/Link.java b/mobile/src/main/java/com/example/android/apis/text/Link.java deleted file mode 100644 index cc3ed5b9a..000000000 --- a/mobile/src/main/java/com/example/android/apis/text/Link.java +++ /dev/null @@ -1,84 +0,0 @@ -/* - * 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 com.example.android.apis.text; - -import com.example.android.apis.R; - -import android.app.Activity; -import android.graphics.Typeface; -import android.os.Bundle; -import android.text.Html; -import android.text.SpannableString; -import android.text.Spanned; -import android.text.method.LinkMovementMethod; -import android.text.style.StyleSpan; -import android.text.style.URLSpan; -import android.widget.TextView; - -public class Link extends Activity { - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - - setContentView(R.layout.link); - - // text1 shows the android:autoLink property, which - // automatically linkifies things like URLs and phone numbers - // found in the text. No java code is needed to make this - // work. - - // text2 has links specified by putting tags in the string - // resource. By default these links will appear but not - // respond to user input. To make them active, you need to - // call setMovementMethod() on the TextView object. - - TextView t2 = (TextView) findViewById(R.id.text2); - t2.setMovementMethod(LinkMovementMethod.getInstance()); - - // text3 shows creating text with links from HTML in the Java - // code, rather than from a string resource. Note that for a - // fixed string, using a (localizable) resource as shown above - // is usually a better way to go; this example is intended to - // illustrate how you might display text that came from a - // dynamic source (eg, the network). - - TextView t3 = (TextView) findViewById(R.id.text3); - t3.setText( - Html.fromHtml( - "text3: Constructed from HTML programmatically. Text with a " + - "link " + - "created in the Java source code using HTML.")); - t3.setMovementMethod(LinkMovementMethod.getInstance()); - - // text4 illustrates constructing a styled string containing a - // link without using HTML at all. Again, for a fixed string - // you should probably be using a string resource, not a - // hardcoded value. - - SpannableString ss = new SpannableString( - "text4: Manually created spans. Click here to dial the phone."); - - ss.setSpan(new StyleSpan(Typeface.BOLD), 0, 30, - Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); - ss.setSpan(new URLSpan("tel:4155551212"), 31+6, 31+10, - Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); - - TextView t4 = (TextView) findViewById(R.id.text4); - t4.setText(ss); - t4.setMovementMethod(LinkMovementMethod.getInstance()); - } -} diff --git a/mobile/src/main/java/com/example/android/apis/text/Link.kt b/mobile/src/main/java/com/example/android/apis/text/Link.kt new file mode 100644 index 000000000..ad6b2e3ef --- /dev/null +++ b/mobile/src/main/java/com/example/android/apis/text/Link.kt @@ -0,0 +1,98 @@ +/* + * 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 com.example.android.apis.text + +import com.example.android.apis.R + +import android.app.Activity +import android.graphics.Typeface +import android.os.Bundle +import android.text.Html +import android.text.SpannableString +import android.text.Spanned +import android.text.method.LinkMovementMethod +import android.text.style.StyleSpan +import android.text.style.URLSpan +import android.view.View +import android.widget.TextView + +class Link : Activity() { + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + + setContentView(R.layout.link) + + // text1 shows the android:autoLink property, which + // automatically linkifies things like URLs and phone numbers + // found in the text. No java code is needed to make this + // work. + + // text2 has links specified by putting tags in the string + // resource. By default these links will appear but not + // respond to user input. To make them active, you need to + // call setMovementMethod() on the TextView object. + + val t2 by lazy { + findViewById(R.id.text2) as TextView + } + t2.movementMethod = LinkMovementMethod.getInstance() + + // text3 shows creating text with links from HTML in the Java + // code, rather than from a string resource. Note that for a + // fixed string, using a (localizable) resource as shown above + // is usually a better way to go; this example is intended to + // illustrate how you might display text that came from a + // dynamic source (eg, the network). + + val t3 by lazy { + findViewById(R.id.text3) as TextView + } + if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.N) { + t3.text = Html.fromHtml( + "text3: Constructed from HTML programmatically. Text with a " + + "link " + + "created in the Java source code using HTML.", Html.FROM_HTML_MODE_LEGACY) + } + else{ + t3.text = Html.fromHtml( + "text3: Constructed from HTML programmatically. Text with a " + + "link " + + "created in the Java source code using HTML.") + } + t3.movementMethod = LinkMovementMethod.getInstance() + + // text4 illustrates constructing a styled string containing a + // link without using HTML at all. Again, for a fixed string + // you should probably be using a string resource, not a + // hardcoded value. + + val ss = SpannableString( + "text4: Manually created spans. Click here to dial the phone.") + + ss.setSpan(StyleSpan(Typeface.BOLD), 0, 30, + Spanned.SPAN_EXCLUSIVE_EXCLUSIVE) + ss.setSpan(URLSpan("tel:4155551212"), 31 + 6, 31 + 10, + Spanned.SPAN_EXCLUSIVE_EXCLUSIVE) + + val t4 by lazy{ + findViewById(R.id.text4) as TextView + } + t4.text = ss + t4.movementMethod = LinkMovementMethod.getInstance() + } +} + diff --git a/mobile/src/main/java/com/example/android/apis/text/LogTextBox.java b/mobile/src/main/java/com/example/android/apis/text/LogTextBox.java deleted file mode 100644 index 09957c5bf..000000000 --- a/mobile/src/main/java/com/example/android/apis/text/LogTextBox.java +++ /dev/null @@ -1,64 +0,0 @@ -/* - * 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 com.example.android.apis.text; - -import android.widget.TextView; -import android.content.Context; -import android.text.method.ScrollingMovementMethod; -import android.text.method.MovementMethod; -import android.text.Editable; -import android.util.AttributeSet; - -/** - * This is a TextView that is Editable and by default scrollable, - * like EditText without a cursor. - * - *

- * XML attributes - *

- * See - * {@link android.R.styleable#TextView TextView Attributes}, - * {@link android.R.styleable#View View Attributes} - */ -public class LogTextBox extends TextView { - public LogTextBox(Context context) { - this(context, null); - } - - public LogTextBox(Context context, AttributeSet attrs) { - this(context, attrs, android.R.attr.textViewStyle); - } - - public LogTextBox(Context context, AttributeSet attrs, int defStyle) { - super(context, attrs, defStyle); - } - - @Override - protected MovementMethod getDefaultMovementMethod() { - return ScrollingMovementMethod.getInstance(); - } - - @Override - public Editable getText() { - return (Editable) super.getText(); - } - - @Override - public void setText(CharSequence text, BufferType type) { - super.setText(text, BufferType.EDITABLE); - } -} diff --git a/mobile/src/main/java/com/example/android/apis/text/LogTextBox.kt b/mobile/src/main/java/com/example/android/apis/text/LogTextBox.kt new file mode 100644 index 000000000..1b7a93cec --- /dev/null +++ b/mobile/src/main/java/com/example/android/apis/text/LogTextBox.kt @@ -0,0 +1,52 @@ +/* + * 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 com.example.android.apis.text + +import android.widget.TextView +import android.content.Context +import android.text.method.ScrollingMovementMethod +import android.text.method.MovementMethod +import android.text.Editable +import android.util.AttributeSet + +/** + * This is a TextView that is Editable and by default scrollable, + * like EditText without a cursor. + + * + * + * **XML attributes** + * + * + * See + * [TextView Attributes][android.R.styleable.TextView], + * [View Attributes][android.R.styleable.View] + */ +class LogTextBox @JvmOverloads constructor(context: Context, attrs: AttributeSet ?= null, defStyle: Int = android.R.attr.textViewStyle) : TextView(context, attrs, defStyle) { + + override fun getDefaultMovementMethod(): MovementMethod { + return ScrollingMovementMethod.getInstance() + } + + override fun getText(): Editable { + return super.getText() as Editable + } + + override fun setText(text: CharSequence, type: TextView.BufferType) { + super.setText(text, TextView.BufferType.EDITABLE) + } +} diff --git a/mobile/src/main/java/com/example/android/apis/text/LogTextBox1.java b/mobile/src/main/java/com/example/android/apis/text/LogTextBox1.kt similarity index 59% rename from mobile/src/main/java/com/example/android/apis/text/LogTextBox1.java rename to mobile/src/main/java/com/example/android/apis/text/LogTextBox1.kt index 18136296f..75e5010e8 100644 --- a/mobile/src/main/java/com/example/android/apis/text/LogTextBox1.java +++ b/mobile/src/main/java/com/example/android/apis/text/LogTextBox1.kt @@ -21,30 +21,25 @@ import android.app.Activity; import android.os.Bundle; import android.view.View; -import android.widget.Button; +import kotlinx.android.synthetic.main.log_text_box_1.* /** * Using a LogTextBox to display a scrollable text area * to which text is appended. * */ -public class LogTextBox1 extends Activity { - - private LogTextBox mText; - - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - - setContentView(R.layout.log_text_box_1); - - mText = (LogTextBox) findViewById(R.id.text); - - Button addButton = (Button) findViewById(R.id.add); - addButton.setOnClickListener(new View.OnClickListener() { - - public void onClick(View v) { - mText.append("This is a test\n"); - } }); +class LogTextBox1 : Activity() { + + + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + + setContentView(R.layout.log_text_box_1) + + val mText by lazy { + findViewById(R.id.text) as LogTextBox } + add.setOnClickListener { mText.append("This is a test\n") } } } + diff --git a/mobile/src/main/java/com/example/android/apis/text/Marquee.java b/mobile/src/main/java/com/example/android/apis/text/Marquee.kt similarity index 78% rename from mobile/src/main/java/com/example/android/apis/text/Marquee.java rename to mobile/src/main/java/com/example/android/apis/text/Marquee.kt index ba82ed6cf..5e040ce9f 100644 --- a/mobile/src/main/java/com/example/android/apis/text/Marquee.java +++ b/mobile/src/main/java/com/example/android/apis/text/Marquee.kt @@ -21,11 +21,9 @@ import android.app.Activity; import android.os.Bundle; -public class Marquee extends Activity { - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - - setContentView(R.layout.marquee); +class Marquee : Activity() { + override fun onCreate(savedInstanceState:Bundle ?) { + super.onCreate(savedInstanceState) + setContentView(R.layout.marquee) } } diff --git a/mobile/src/main/java/com/example/android/apis/text/_index.html b/mobile/src/main/java/com/example/android/apis/text/_index.html index c995a0cac..74c3cc474 100644 --- a/mobile/src/main/java/com/example/android/apis/text/_index.html +++ b/mobile/src/main/java/com/example/android/apis/text/_index.html @@ -1,8 +1,8 @@

Linkify
-
Demonstrates the Demonstrates the Linkify -class, which converts URLs in a block of text into hyperlinks.
+class, which converts URLs in a block of text into hyperlinks.
diff --git a/mobile/src/main/java/com/example/android/apis/view/SeekBar1.java b/mobile/src/main/java/com/example/android/apis/view/SeekBar1.kt similarity index 62% rename from mobile/src/main/java/com/example/android/apis/view/SeekBar1.java rename to mobile/src/main/java/com/example/android/apis/view/SeekBar1.kt index 65d01d4e2..f39b4f501 100644 --- a/mobile/src/main/java/com/example/android/apis/view/SeekBar1.java +++ b/mobile/src/main/java/com/example/android/apis/view/SeekBar1.kt @@ -18,6 +18,7 @@ import android.app.Activity; import android.os.Bundle; +import android.view.View import android.widget.CheckBox; import android.widget.CompoundButton; import android.widget.CompoundButton.OnCheckedChangeListener; @@ -30,7 +31,7 @@ /** * Demonstrates how to use a seek bar */ -public class SeekBar1 extends Activity implements SeekBar.OnSeekBarChangeListener { +/*public class SeekBar1 extends Activity implements SeekBar.OnSeekBarChangeListener { SeekBar mSeekBar; TextView mProgressText; @@ -70,4 +71,35 @@ public void onStartTrackingTouch(SeekBar seekBar) { public void onStopTrackingTouch(SeekBar seekBar) { mTrackingText.setText(getString(R.string.seekbar_tracking_off)); } -} +}*/ +class SeekBar1 : Activity(), SeekBar.OnSeekBarChangeListener{ + lateinit private var mSeekBar : SeekBar; + lateinit private var mProgressText : TextView; + lateinit private var mTrackingText : TextView; + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + setContentView(R.layout.seekbar_1) + + mSeekBar = findViewById(R.id.seek) as SeekBar + mSeekBar.setOnSeekBarChangeListener(this) + mProgressText = findViewById(R.id.progress) as TextView + mTrackingText = findViewById(R.id.tracking) as TextView + + (findViewById(R.id.enabled) as CheckBox).setOnCheckedChangeListener { buttonView, isChecked -> + findViewById(R.id.seekMin).setEnabled(isChecked); + findViewById(R.id.seekMax).setEnabled(isChecked); + mSeekBar.setEnabled(isChecked); + } + } + override fun onProgressChanged(seekBar: SeekBar?, progress: Int, fromTouch: Boolean) { + mProgressText.setText("$progress ${resources.getString(R.string.seekbar_from_touch)} = $fromTouch"); + } + + override fun onStartTrackingTouch(p0: SeekBar?) { + mTrackingText.setText(getString(R.string.seekbar_tracking_on)); + } + + override fun onStopTrackingTouch(p0: SeekBar?) { + mTrackingText.setText(getString(R.string.seekbar_tracking_off)); + } +} \ No newline at end of file diff --git a/mobile/src/main/res/layout/service_start_arguments_controller.xml b/mobile/src/main/res/layout/service_start_arguments_controller.xml index bcf4a65ff..154b67cf5 100644 --- a/mobile/src/main/res/layout/service_start_arguments_controller.xml +++ b/mobile/src/main/res/layout/service_start_arguments_controller.xml @@ -15,7 +15,7 @@ --> + See corresponding Java code com.android.sdk.ServiceStartArguments.ktjava. --> App/Fragment/Alert Dialog - + Example of displaying an alert dialog with a DialogFragment App/Fragment/Arguments Demonstrates a fragment that takes arguments as a Bundle at runtime (on the right) or from attributes in a layout (on the left).