0% found this document useful (0 votes)
2 views

lecture12 (2)

The document provides an overview of Android Service programming, detailing how to create and manage services that run in the background, including their lifecycle and communication with activities. It explains the basic steps to implement a service, including the necessary code and manifest modifications, and introduces the concept of IntentService for handling background tasks. Additionally, it covers how to communicate between services and activities using broadcasts and intents, along with a homework assignment to enhance the application with a ProgressBar for displaying progress.

Uploaded by

Aniqa Safiudeen
Copyright
© © All Rights Reserved
Available Formats
Download as KEY, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
2 views

lecture12 (2)

The document provides an overview of Android Service programming, detailing how to create and manage services that run in the background, including their lifecycle and communication with activities. It explains the basic steps to implement a service, including the necessary code and manifest modifications, and introduces the concept of IntentService for handling background tasks. Additionally, it covers how to communicate between services and activities using broadcasts and intents, along with a homework assignment to enhance the application with a ProgressBar for displaying progress.

Uploaded by

Aniqa Safiudeen
Copyright
© © All Rights Reserved
Available Formats
Download as KEY, PDF, TXT or read online on Scribd
You are on page 1/ 18

CIS 694/EEC 693Android

Sensor Programming

Lecture 12
Wenbing Zhao
Department of Electrical Engineering and Computer
Science
Cleveland State University
[email protected]

8/16/21
Services
How to create a service that runs in the
background
How to perform long-running tasks in a
separate thread
How to perform repeated tasks in a service
How an activity and a service
communicate

8/16/21
What is a Service
A facility for the application to tell the system
about something it wants to be doing in the
background
Even when the user is not directly interacting with the
application
This corresponds to calls to Context.startService(), which
ask the system to schedule work for the service, to be run
until the service or someone else explicitly stop it
A facility for an application to expose some of its
functionality to other applications
This corresponds to calls to Context.bindService(), which
allows a long-standing connection to be made to the
service in order to interact with it

8/16/21
What is a Service
A Service is not a separate process. The Service
object itself does not imply it is running in its own
process; unless otherwise specified, it runs in the
same process as the application it is part of
A Service is not a thread. It is not a means itself to
do work off of the main thread

8/16/21
Service Lifecycle
If someone calls Context.startService() then the system will
retrieve the service and then call its
onStartCommand(Intent, int, int) method with the arguments
supplied by the client
The service will at this point continue running until
Context.stopService() or stopSelf() is called
There are two major modes of operation depending on the
value they return from onStartCommand():
START_STICKY is used for services that are explicitly started and stopped
as needed
START_NOT_STICKY or START_REDELIVER_INTENT are used for services
that should only remain running while processing any commands sent to
them

8/16/21
Service Permission
Global access to a service can be enforced when it is
declared in its manifest's <service> tag
By doing so, other applications will need to declare a
corresponding <uses-permission> element in their own
manifest to be able to start, stop, or bind to the service

8/16/21
Basic Service
Basic steps of creating/using a service:
Create a separate service java class
Add service in the manifest
Start/stop the service from the main activity
Create a new project and name it Services
Modify manifest:
<?xml version="1.0" encoding="utf-8"?><manifest xmlns:android=
http://schemas.android.com/apk/res/android package="com.wenbing.services">
<application android:allowBackup="true" android:icon="@mipmap/ic_launcher"
android:label="@string/app_name" android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true" android:theme="@style/AppTheme"> <activity
android:name=".MainActivity"> <intent-filter> <action
android:name="android.intent.action.MAIN" /> <category
android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity>
<service android:name=".MyService" /> </application></manifest>

8/16/21
import android.app.Service;import

Basic Service
android.content.Intent;import
android.os.IBinder;import
android.widget.Toast;import
java.net.MalformedURLException;import
java.net.URL;import android.os.AsyncTask;
Add a new Java class: import android.util.Log;import
java.util.Timer;import java.util.TimerTask;
MyService
public class MyService extends Service { int counter = 0; static final int
UPDATE_INTERVAL = 1000; private Timer timer = new Timer(); @Override public IBinder
onBind(Intent arg0) { return null; } @Override public int onStartCommand(Intent intent,
int flags, int startId) { Toast.makeText(this, "Service Started", Toast.LENGTH_LONG).show();
doSomethingRepeatedly(); try { new DoBackgroundTask().execute( new
URL("http://www.amazon.com/somefiles.pdf"), new
URL("http://www.wrox.com/somefiles.pdf"), new
URL("http://www.google.com/somefiles.pdf"), new
URL("http://www.learn2develop.net/somefiles.pdf")); } catch (MalformedURLException e) {
e.printStackTrace(); } return START_STICKY; }

Perform task asynchronously: don’t wait for


completion

8/16/21
@Override public void onDestroy() { super.onDestroy(); if (timer != null){
timer.cancel(); } Toast.makeText(this, "Service Destroyed", Toast.LENGTH_LONG).show();
} private void doSomethingRepeatedly() { timer.scheduleAtFixedRate(new TimerTask() {
public void run() { Log.d("MyService", String.valueOf(++counter)); } }, 0,
UPDATE_INTERVAL); } private class DoBackgroundTask extends AsyncTask<URL, Integer, Long>
{ protected Long doInBackground(URL... urls) { int count = urls.length; long
totalBytesDownloaded = 0; for (int i = 0; i < count; i++) { totalBytesDownloaded +=
DownloadFile(urls[i]); publishProgress((int) (((i + 1) / (float) count) * 100)); }
return totalBytesDownloaded; }

Calculate percentage downloaded and report its


progress

8/16/21
onProgressUpdate is invoked when you call publishProgress()

protected void onProgressUpdate(Integer... progress) { Log.d("Downloading files",


String.valueOf(progress[0]) + "% downloaded"); Toast.makeText(getBaseContext(),
String.valueOf(progress[0]) + "% downloaded-"+counter,
Toast.LENGTH_LONG).show(); } protected void onPostExecute(Long result) {
Toast.makeText(getBaseContext(), "Downloaded " + result + " bytes",
Toast.LENGTH_LONG).show(); //stopSelf(); } } private int DownloadFile(URL url) {
try { //---simulate taking some time to The download a file---
onPostExecute() Thread.sleep(5000);
is invoked in the UI thread }
catch (InterruptedException e) { e.printStackTrace();
and is called when the} doInBackground()
//---return an arbitrary
method
number representing // the size of the file has
downloaded---
finished executionreturn 100; }}

Call stopSelf() if you want to destroy the service as soon as the long-running
task is done

8/16/21
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
Basic Service xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
Modify layout: add tools:context="com.....services.MainActivity"> <Button
two buttons to android:text="Start Service"
android:layout_height="50dp"
android:layout_width="90dp"

start/stop service android:id="@+id/btnStartService"


app:layout_constraintLeft_toLeftOf="@+id/activity_main"
app:layout_constraintTop_toTopOf="@+id/activity_main"
android:layout_marginTop="16dp"
app:layout_constraintRight_toRightOf="@+id/activity_main"
app:layout_constraintBottom_toTopOf="@+id/btnStopService"
android:layout_marginBottom="8dp"
android:onClick="startService" /> <Button
android:text="Stop Service" android:layout_width="88dp"
android:layout_height="48dp"
android:id="@+id/btnStopService"
app:layout_constraintLeft_toLeftOf="@+id/activity_main"
android:layout_marginStart="16dp"
app:layout_constraintTop_toTopOf="@+id/activity_main"
app:layout_constraintRight_toRightOf="@+id/activity_main"
android:layout_marginEnd="16dp"
app:layout_constraintBottom_toBottomOf="@+id/activity_main"
android:onClick="stopService" />
</android.support.constraint.ConstraintLayout>

8/16/21
Basic Service
Modify MainActivity.java: start/stop service
import android.support.v7.app.AppCompatActivity;import android.os.Bundle;import
android.content.Intent;import android.view.View;public class MainActivity extends
AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); }public void
startService(View view) { startService(new Intent(getBaseContext(), MyService.class)); }
public void stopService(View view) { stopService(new Intent(getBaseContext(),
MyService.class)); }}

8/16/21
Communication between Service and Activity

Create another app <?xml version="1.0" encoding="utf-8"?><manifest


xmlns:android="http://schemas.android.com/apk/res/android"
and name it package="com.....myservices2"> <application
android:allowBackup="true" android:icon="@mipmap/ic_launcher"
MyService2 android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
Add a Java class android:supportsRtl="true" android:theme="@style/AppTheme">
MyIntentService <activity android:name=".MainActivity"> <intent-filter>
<action android:name="android.intent.action.MAIN" />
Add the service in <category android:name="android.intent.category.LAUNCHER" />
</intent-filter> </activity> <service
manifest android:name=".MyIntentService" /> </application>
</manifest>

8/16/21
Communication between Service and Activity
import android.app.IntentService;import android.content.Intent;
import android.util.Log;import java.net.MalformedURLException;
import java.net.URL;public class MyIntentService extends
Populate IntentService { public MyIntentService() {
super("MyIntentServiceName"); } @Override protected void
MyIntentService.java onHandleIntent(Intent intent) { try { int result =
DownloadFile(new URL("http://www.amazon.com/somefile.pdf"));
Log.d("IntentService", "Downloaded " + result + " bytes");
Intent broadcastIntent = new Intent();
broadcastIntent.setAction("FILE_DOWNLOADED_ACTION");
getBaseContext().sendBroadcast(broadcastIntent); } catch
(MalformedURLException e) { e.printStackTrace(); } }
private int DownloadFile(URL url) { try {
Thread.sleep(5000); } catch (InterruptedException e)
{ e.printStackTrace(); } return 100; }}

//---send a broadcast to inform the


activity// that the file has been
downloaded---

8/16/21
Communication between Service and Activity
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;import
android.content.BroadcastReceiver;import
Modify android.content.Context;import android.content.Intent;
import android.content.IntentFilter;import
MainActivity.java android.view.View;import android.widget.Toast;public
class MainActivity extends AppCompatActivity {
IntentFilter intentFilter; @Override protected void
onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main); }
@Override public void onResume() {
super.onResume(); intentFilter = new
IntentFilter();
intentFilter.addAction("FILE_DOWNLOADED_ACTION"
); //---register the receiver---
registerReceiver(intentReceiver, intentFilter); }
@Override public void onPause() {
super.onPause(); //---unregister the receiver---
unregisterReceiver(intentReceiver); }
intent to filter for file downloaded
intent

8/16/21
Communication between Service and Activity

Modify MainActivity.java
public void startService(View view) { startService(new
Intent(getBaseContext(), MyIntentService.class)); } public void
stopService(View view) { stopService(new
Intent(getBaseContext(), MyIntentService.class)); } private
BroadcastReceiver intentReceiver = new BroadcastReceiver() {
@Override public void onReceive(Context context, Intent intent) {
Toast.makeText(getBaseContext(), "File downloaded!",
Toast.LENGTH_LONG).show(); } };}

Modify the layout to add two buttons as before

8/16/21
Communication between Service and Activity

You can put data into the intent as a way to communicate


specific data between the main activity and the service

// Creates a new Intent to start a service. Passes a URI in the Intent's "data" field.
mServiceIntent = new Intent();mServiceIntent.putExtra("download_url", dataUrl));

// Creates a new Intent containing a Uri object BROADCAST_ACTION is a custom Intent


action Intent localIntent = new Intent(Constants.BROADCAST_ACTION) // Puts
the status into the Intent .putExtra(Constants.EXTENDED_DATA_STATUS, status);
// Broadcasts the Intent to receivers in this app.
LocalBroadcastManager.getInstance(this).sendBroadcast(localIntent);

8/16/21
Homework#10
Modify the Services app:
Use a ProgressBar view instead/in addition to the Toast to
display the progress made by the service

8/16/21

You might also like