Android Samples
Revision | e17d6f0f869e076892f0d5d13b545f0a36326ff7 (tree) |
---|---|
Time | 2019-05-04 20:40:08 |
Author | Masahiko, SAWAI <say@user...> |
Commiter | Masahiko, SAWAI |
Added a new project.
* intent-service-foreground project
@@ -0,0 +1,46 @@ | ||
1 | + | |
2 | +all : package | |
3 | + | |
4 | +#################### build | |
5 | + | |
6 | +compile : | |
7 | + mvn $@ | |
8 | + | |
9 | +gen : | |
10 | + mvn android:generate-sources | |
11 | + | |
12 | +package : | |
13 | + mvn $@ | |
14 | + | |
15 | +release : | |
16 | + mvn clean -Prelease package | |
17 | + | |
18 | +install : | |
19 | + mvn $@ | |
20 | + | |
21 | +deploy : | |
22 | + mvn package android:deploy | |
23 | + | |
24 | +undeploy : | |
25 | + mvn android:undeploy | |
26 | + | |
27 | +rebuild : | |
28 | + mvn clean package | |
29 | + | |
30 | +redeploy : | |
31 | + mvn clean package android:deploy | |
32 | + | |
33 | +#################### emulator | |
34 | + | |
35 | +start : | |
36 | + mvn android:emulator-start | |
37 | + | |
38 | +stop : | |
39 | + mvn android:emulator-stop | |
40 | + | |
41 | +#################### | |
42 | +dist : | |
43 | + mvn assembly:assembly | |
44 | + | |
45 | +clean : | |
46 | + mvn $@ |
@@ -0,0 +1,37 @@ | ||
1 | +! intent-service-foreground | |
2 | + | |
3 | +IntentService を使って非同期処理を実現するサンプル. | |
4 | + | |
5 | +バックグラウンドサービスはOreo(API Level 26)以降は基本的に許可されず強制終了されてしまう。 | |
6 | +そのため非同期タスクを投げる場合には通知を表示してフォアグラウンドサービスとする必要がある。 | |
7 | + | |
8 | +IntentService を使ってフォアグラウンドサービスを実現するサンプル。 | |
9 | + | |
10 | +* Service#startForeground() - API Level 5 | |
11 | + | |
12 | + | |
13 | +以下参考サイト | |
14 | +* http://techbooster.jpn.org/andriod/application/1570/ | |
15 | + | |
16 | +以下まとめ。 | |
17 | +* タスクは startService() で呼び出すたびにキューイングされる | |
18 | +* IntentService で同時に作業できるタスクは1つ | |
19 | +* キューにタスクが一つもなくなったらサービスは自動で終了する | |
20 | +* バックグラウンドで動作し続けるというよりはバッチ処理的なものに使う | |
21 | + | |
22 | + | |
23 | +!! ビルドターゲット | |
24 | + | |
25 | +http://maven-android-plugin-m2site.googlecode.com/svn/plugin-info.html | |
26 | + | |
27 | +* mvn compile - アプリケーションのコンパイル | |
28 | +* mvn package - apk の作成 | |
29 | +* mvn clean - ビルドファイルの削除 | |
30 | +* mvn install - maven の local リポジトリにインストール | |
31 | + | |
32 | +* mvn android:deploy - エミュレータやデバイスにインストール | |
33 | +* mvn android:generate-sources | |
34 | + | |
35 | +* mvn install - アプリケーションのインストール | |
36 | +* mvn uninstall - アプリケーションのアンインストール | |
37 | + |
@@ -0,0 +1,121 @@ | ||
1 | +<project | |
2 | + xmlns="http://maven.apache.org/POM/4.0.0" | |
3 | + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | |
4 | + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd" | |
5 | +> | |
6 | + <modelVersion>4.0.0</modelVersion> | |
7 | + <groupId>com.example.hello</groupId> | |
8 | + <artifactId>intent-service-foreground</artifactId> | |
9 | + <packaging>apk</packaging> | |
10 | + <version>1.0.0</version> | |
11 | + <name>IntentService Foregound</name> | |
12 | + <url>http://www.example.com/</url> | |
13 | + | |
14 | + <parent> | |
15 | + <groupId>com.example.hello</groupId> | |
16 | + <artifactId>android-samples</artifactId> | |
17 | + <version>1.0.0</version> | |
18 | + </parent> | |
19 | + | |
20 | + <dependencies> | |
21 | + | |
22 | + <dependency> | |
23 | + <groupId>android</groupId> | |
24 | + <artifactId>android</artifactId> | |
25 | + </dependency> | |
26 | + | |
27 | + <dependency> | |
28 | + <groupId>junit</groupId> | |
29 | + <artifactId>junit</artifactId> | |
30 | + <scope>test</scope> | |
31 | + </dependency> | |
32 | + </dependencies> | |
33 | + | |
34 | + <build> | |
35 | + | |
36 | + <plugins> | |
37 | + <plugin> | |
38 | + <groupId>com.simpligility.maven.plugins</groupId> | |
39 | + <artifactId>android-maven-plugin</artifactId> | |
40 | + <extensions>true</extensions> | |
41 | + </plugin> | |
42 | + | |
43 | + <!-- mvn compile --> | |
44 | + <plugin> | |
45 | + <groupId>org.apache.maven.plugins</groupId> | |
46 | + <artifactId>maven-compiler-plugin</artifactId> | |
47 | + <configuration> | |
48 | + <source>1.5</source> | |
49 | + <target>1.5</target> | |
50 | + <encoding>UTF-8</encoding> | |
51 | + </configuration> | |
52 | + </plugin> | |
53 | + | |
54 | + <!-- mvn assembly:assembly --> | |
55 | + <plugin> | |
56 | + <groupId>org.apache.maven.plugins</groupId> | |
57 | + <artifactId>maven-assembly-plugin</artifactId> | |
58 | + <configuration> | |
59 | + <descriptorRefs> | |
60 | + <!-- | |
61 | + <descriptorRef>jar-with-dependencies</descriptorRef> | |
62 | + <descriptorRef>bin</descriptorRef> | |
63 | + <descriptorRef>src</descriptorRef> | |
64 | + --> | |
65 | + <descriptorRef>project</descriptorRef> | |
66 | + </descriptorRefs> | |
67 | + </configuration> | |
68 | + </plugin> | |
69 | + | |
70 | + <!-- mvn resources:resources --> | |
71 | + <plugin> | |
72 | + <groupId>org.apache.maven.plugins</groupId> | |
73 | + <artifactId>maven-resources-plugin</artifactId> | |
74 | + <configuration> | |
75 | + <encoding>UTF-8</encoding> | |
76 | + </configuration> | |
77 | + </plugin> | |
78 | + | |
79 | + <!-- mvn site --> | |
80 | + <plugin> | |
81 | + <groupId>org.apache.maven.plugins</groupId> | |
82 | + <artifactId>maven-site-plugin</artifactId> | |
83 | + <configuration> | |
84 | + <locales>en</locales> | |
85 | + <inputEncoding>UTF-8</inputEncoding> | |
86 | + <outputEncoding>UTF-8</outputEncoding> | |
87 | + | |
88 | + <reportPlugins> | |
89 | + <plugin> | |
90 | + <groupId>org.apache.maven.plugins</groupId> | |
91 | + <artifactId>maven-project-info-reports-plugin</artifactId> | |
92 | + </plugin> | |
93 | + | |
94 | + <!-- mvn javadoc:javadoc --> | |
95 | + <plugin> | |
96 | + <groupId>org.apache.maven.plugins</groupId> | |
97 | + <artifactId>maven-javadoc-plugin</artifactId> | |
98 | + <configuration> | |
99 | + <charset>utf-8</charset> | |
100 | + </configuration> | |
101 | + </plugin> | |
102 | + </reportPlugins> | |
103 | + </configuration> | |
104 | + </plugin> | |
105 | + | |
106 | + </plugins> | |
107 | + | |
108 | + <!-- mvn resources:resources --> | |
109 | + <resources> | |
110 | + <resource> | |
111 | + <directory>src/main/res</directory> | |
112 | + <filtering>false</filtering> | |
113 | + <includes> | |
114 | + <include>**/*.properties</include> | |
115 | + </includes> | |
116 | + </resource> | |
117 | + </resources> | |
118 | + </build> | |
119 | + | |
120 | + | |
121 | +</project> |
@@ -0,0 +1,30 @@ | ||
1 | +<?xml version="1.0" encoding="utf-8"?> | |
2 | +<manifest | |
3 | + xmlns:android="http://schemas.android.com/apk/res/android" | |
4 | + package="com.example.hello.android.intent_service_foreground" | |
5 | + android:versionCode="1" | |
6 | + android:versionName="1.0" | |
7 | +> | |
8 | + <uses-sdk android:minSdkVersion="5" android:targetSdkVersion="26" /> | |
9 | + | |
10 | + <application android:label="@string/app_name"> | |
11 | + | |
12 | + <!-- Activity Manifest --> | |
13 | + <activity | |
14 | + android:name="MainActivity" | |
15 | + android:label="@string/app_name" | |
16 | + > | |
17 | + <intent-filter> | |
18 | + <action android:name="android.intent.action.MAIN" /> | |
19 | + <category android:name="android.intent.category.LAUNCHER" /> | |
20 | + </intent-filter> | |
21 | + </activity> | |
22 | + | |
23 | + <!-- Service Manifest --> | |
24 | + <service | |
25 | + android:name="CountDownIntentService" | |
26 | + android:label="Count Down IntentService" | |
27 | + /> | |
28 | + | |
29 | + </application> | |
30 | +</manifest> |
@@ -0,0 +1,218 @@ | ||
1 | +/* | |
2 | + * The MIT License | |
3 | + * | |
4 | + * Copyright 2014 Masahiko, SAWAI <masahiko.sawai@gmail.com>. | |
5 | + * | |
6 | + * Permission is hereby granted, free of charge, to any person obtaining a copy | |
7 | + * of this software and associated documentation files (the "Software"), to deal | |
8 | + * in the Software without restriction, including without limitation the rights | |
9 | + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | |
10 | + * copies of the Software, and to permit persons to whom the Software is | |
11 | + * furnished to do so, subject to the following conditions: | |
12 | + * | |
13 | + * The above copyright notice and this permission notice shall be included in | |
14 | + * all copies or substantial portions of the Software. | |
15 | + * | |
16 | + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
17 | + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
18 | + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | |
19 | + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |
20 | + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | |
21 | + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | |
22 | + * THE SOFTWARE. | |
23 | + */ | |
24 | +package com.example.hello.android.intent_service_foreground; | |
25 | + | |
26 | +import android.app.IntentService; | |
27 | +import android.app.Notification; | |
28 | +import android.app.NotificationChannel; | |
29 | +import android.app.NotificationManager; | |
30 | +import android.app.PendingIntent; | |
31 | +import android.content.Context; | |
32 | +import android.content.Intent; | |
33 | +import android.graphics.Bitmap; | |
34 | +import android.graphics.BitmapFactory; | |
35 | +import android.os.Build; | |
36 | +import android.util.Log; | |
37 | + | |
38 | +/** | |
39 | + * | |
40 | + * @author sawai | |
41 | + */ | |
42 | +public class CountDownIntentService extends IntentService | |
43 | +{ | |
44 | + | |
45 | + private static final String NOTIFICATION_TITLE = "Count Down Service"; | |
46 | + private static final String NOTIFICATION_MESSAGE = "Count down on going"; | |
47 | + private static final String NOTIFICATION_CHANNEL_COUNTDOWN_ID = "countdown"; | |
48 | + private static final int NOTIFICATION_ID_COUNT_DOWN_DOING = 1; | |
49 | + private static final int FOREGROUND_ID = 1; // 0以外 | |
50 | + | |
51 | + public static final String EXTRA_COUNT = "count"; | |
52 | + private static final long COUNT_INTERVAL_MSEC = 10000; // 1sec | |
53 | + private static final int DEFAULT_COUNT = 5; | |
54 | + private static final String LOG_TAG = "XXX"; | |
55 | + | |
56 | + public CountDownIntentService(String name) | |
57 | + { | |
58 | + super(name); | |
59 | + } | |
60 | + | |
61 | + public CountDownIntentService() | |
62 | + { | |
63 | + super(CountDownIntentService.class.getName()); | |
64 | + } | |
65 | + | |
66 | + @Override | |
67 | + public void onCreate() | |
68 | + { | |
69 | + Log.i(LOG_TAG, "CountDownService#onCreate() : Hello"); | |
70 | + super.onCreate(); | |
71 | + Log.i(LOG_TAG, "CountDownService#onCreate() : Bye"); | |
72 | + } | |
73 | + | |
74 | + @Override | |
75 | + public void onDestroy() | |
76 | + { | |
77 | + Log.i(LOG_TAG, "CountDownService#onDestroy() : Hello"); | |
78 | + super.onDestroy(); | |
79 | + Log.i(LOG_TAG, "CountDownService#onDestroy() : Bye"); | |
80 | + } | |
81 | + | |
82 | + @Override | |
83 | + public void onStart(Intent intent, int startId) | |
84 | + { | |
85 | + Log.i(LOG_TAG, "CountDownService#onStart() : Hello"); | |
86 | + super.onStart(intent, startId); | |
87 | + Log.i(LOG_TAG, "CountDownService#onStart() : bye"); | |
88 | + } | |
89 | + | |
90 | + @Override | |
91 | + protected void onHandleIntent(Intent intent) | |
92 | + { | |
93 | + Log.i(LOG_TAG, "CountDownService#onHandleIntent() : Hello"); | |
94 | + | |
95 | + Notification notification = buildNotification(); | |
96 | + startForeground(FOREGROUND_ID, notification); // API Level 5 | |
97 | + | |
98 | + int count = intent.getIntExtra(EXTRA_COUNT, DEFAULT_COUNT); | |
99 | + try | |
100 | + { | |
101 | + doCountDown(count); | |
102 | + } | |
103 | + finally | |
104 | + { | |
105 | + stopForeground(true); | |
106 | + } | |
107 | + | |
108 | + Log.i(LOG_TAG, "CountDownService#onHandleIntent() : Bye "); | |
109 | + } | |
110 | + | |
111 | + private Notification buildNotification() | |
112 | + { | |
113 | + Notification notification = null; | |
114 | + | |
115 | + // 通知をタップしたときに送信されるインテントを作成 | |
116 | + Intent mainActivityIntent = new Intent(getApplicationContext(), MainActivity.class); | |
117 | + PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, mainActivityIntent, 0); | |
118 | + | |
119 | + NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); | |
120 | + Log.v(LOG_TAG, "builder() : Build.VERSION.SDK_INT -> " + Build.VERSION.SDK_INT); | |
121 | + if (Build.VERSION.SDK_INT >= 26) | |
122 | + { | |
123 | + Log.v(LOG_TAG, "builder() : if Build.VERSION.SDK_INT >= 26"); | |
124 | + // 通知チャンネル作成 | |
125 | + NotificationChannel channel = new NotificationChannel(NOTIFICATION_CHANNEL_COUNTDOWN_ID, NOTIFICATION_TITLE, NotificationManager.IMPORTANCE_DEFAULT); | |
126 | + notificationManager.createNotificationChannel(channel); | |
127 | + | |
128 | + // 通知時の音・バイブ・ライトの設定 | |
129 | + // NotificationChannel#enableVibration(boolean) | |
130 | + // NotificationChannel#enableLights(boolean) | |
131 | + // NotificationChannel#setSound(Uri, AudioAttributes) | |
132 | + channel.enableVibration(true); | |
133 | + channel.enableLights(true); | |
134 | + | |
135 | + // Notification.Builder (API 11 で追加)を作成 | |
136 | + // API 26 では Notification.Builder(Context context, String channelId) を使う | |
137 | + Notification.Builder builder = new Notification.Builder( | |
138 | + getApplicationContext(), NOTIFICATION_CHANNEL_COUNTDOWN_ID); | |
139 | + | |
140 | + // 通知をタップしたときに送信されるインテントを設定 | |
141 | + builder.setContentIntent(pendingIntent); | |
142 | + // 通知したときにステータスバーに表示されるアイコン | |
143 | + builder.setSmallIcon(android.R.drawable.stat_sys_download); | |
144 | + // Notificationを開いたときに表示されるタイトル | |
145 | + builder.setContentTitle(NOTIFICATION_TITLE); | |
146 | + // Notificationを開いたときに表示されるサブタイトル | |
147 | + builder.setContentText(NOTIFICATION_MESSAGE); | |
148 | + | |
149 | + // 通知作成 | |
150 | + notification = builder.build(); | |
151 | + | |
152 | + // 通知を削除不可能に設定(タップして移動したら消えます) | |
153 | + notification.flags = notification.flags | Notification.FLAG_ONGOING_EVENT; | |
154 | + | |
155 | + } | |
156 | + else | |
157 | + { | |
158 | + Log.v(LOG_TAG, "buildNotification() : if Build.VERSION.SDK_INT <= 25"); | |
159 | + | |
160 | + // Notification.Builder (API 11 で追加)を作成 | |
161 | + Notification.Builder builder = new Notification.Builder(getApplicationContext()); | |
162 | + | |
163 | + // 通知をタップしたときに送信されるインテントを設定 | |
164 | + builder.setContentIntent(pendingIntent); | |
165 | + // 通知したときにステータスバーに表示されるテキストを設定 | |
166 | + builder.setTicker(NOTIFICATION_TITLE); | |
167 | + // 通知したときにステータスバーに表示されるアイコン | |
168 | + builder.setSmallIcon(android.R.drawable.stat_sys_download); | |
169 | + // 通知の大きいアイコン | |
170 | + Bitmap bigIcon = BitmapFactory.decodeResource(getResources(), android.R.mipmap.sym_def_app_icon); | |
171 | + builder.setLargeIcon(bigIcon); | |
172 | + | |
173 | + // Notificationを開いたときに表示されるタイトル | |
174 | + builder.setContentTitle(NOTIFICATION_TITLE); | |
175 | + // Notificationを開いたときに表示されるサブタイトル | |
176 | + builder.setContentText(NOTIFICATION_MESSAGE); | |
177 | + // 通知するタイミング | |
178 | + builder.setWhen(System.currentTimeMillis()); | |
179 | + | |
180 | + // 通知時の音・バイブ・ライトの設定 | |
181 | + // API 26 では非推奨になっているため、以下のメソッドを使う | |
182 | + // NotificationChannel#enableVibration(boolean) | |
183 | + // NotificationChannel#enableLights(boolean) | |
184 | + // NotificationChannel#setSound(Uri, AudioAttributes) | |
185 | + builder.setDefaults(Notification.DEFAULT_SOUND | |
186 | + | Notification.DEFAULT_VIBRATE | |
187 | + | Notification.DEFAULT_LIGHTS); | |
188 | + | |
189 | + // 通知作成 | |
190 | + notification = builder.build(); | |
191 | + | |
192 | + // 通知を削除不可能に設定(タップして移動したら消えます) | |
193 | + //notification.flags = notification.flags | Notification.FLAG_ONGOING_EVENT; | |
194 | + } | |
195 | + | |
196 | + // Notificationを作成して通知 | |
197 | + notificationManager.notify(NOTIFICATION_ID_COUNT_DOWN_DOING, notification); | |
198 | + | |
199 | + return notification; | |
200 | + } | |
201 | + | |
202 | + private void doCountDown(int count) | |
203 | + { | |
204 | + for (int i = count; i >= 0; i--) | |
205 | + { | |
206 | + Log.i(LOG_TAG, "CountDownService#doCountDown() count => " + i); | |
207 | + try | |
208 | + { | |
209 | + Thread.sleep(COUNT_INTERVAL_MSEC); | |
210 | + } | |
211 | + catch (InterruptedException ex) | |
212 | + { | |
213 | + Log.e(LOG_TAG, "sleep failed.", ex); | |
214 | + } | |
215 | + } | |
216 | + | |
217 | + } | |
218 | +} |
@@ -0,0 +1,94 @@ | ||
1 | +/* | |
2 | + * The MIT License | |
3 | + * | |
4 | + * Copyright 2014 Masahiko, SAWAI <masahiko.sawai@gmail.com>. | |
5 | + * | |
6 | + * Permission is hereby granted, free of charge, to any person obtaining a copy | |
7 | + * of this software and associated documentation files (the "Software"), to deal | |
8 | + * in the Software without restriction, including without limitation the rights | |
9 | + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | |
10 | + * copies of the Software, and to permit persons to whom the Software is | |
11 | + * furnished to do so, subject to the following conditions: | |
12 | + * | |
13 | + * The above copyright notice and this permission notice shall be included in | |
14 | + * all copies or substantial portions of the Software. | |
15 | + * | |
16 | + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
17 | + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
18 | + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | |
19 | + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |
20 | + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | |
21 | + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | |
22 | + * THE SOFTWARE. | |
23 | + */ | |
24 | +package com.example.hello.android.intent_service_foreground; | |
25 | + | |
26 | +import android.app.Activity; | |
27 | +import android.content.Intent; | |
28 | +import android.os.Build; | |
29 | +import android.os.Bundle; | |
30 | +import android.util.Log; | |
31 | +import android.view.View; | |
32 | +import android.view.View.OnClickListener; | |
33 | +import android.widget.Button; | |
34 | +import android.widget.Toast; | |
35 | + | |
36 | +public class MainActivity extends Activity implements OnClickListener | |
37 | +{ | |
38 | + | |
39 | + private static final String LOG_TAG = "XXX"; | |
40 | + | |
41 | + @Override | |
42 | + protected void onCreate(Bundle savedInstanceState) | |
43 | + { | |
44 | + Log.d(LOG_TAG, "MainActivity#onCreate() : Hello"); | |
45 | + super.onCreate(savedInstanceState); | |
46 | + setContentView(R.layout.main); | |
47 | + | |
48 | + Button startCountDownButton = (Button) findViewById(R.id.start_count_down_button); | |
49 | + startCountDownButton.setOnClickListener(this); | |
50 | + | |
51 | + Button startCountDown3Button = (Button) findViewById(R.id.start_count_down_3_button); | |
52 | + startCountDown3Button.setOnClickListener(this); | |
53 | + Log.d(LOG_TAG, "MainActivity#onCreate() : Bye"); | |
54 | + } | |
55 | + | |
56 | + public void onClick(View view) | |
57 | + { | |
58 | + switch (view.getId()) | |
59 | + { | |
60 | + case R.id.start_count_down_button: | |
61 | + Toast.makeText(getApplicationContext(), "Start Count Down!", Toast.LENGTH_SHORT).show(); | |
62 | + startCountDownService(); | |
63 | + break; | |
64 | + case R.id.start_count_down_3_button: | |
65 | + Toast.makeText(getApplicationContext(), "Start Count Down 3!", Toast.LENGTH_SHORT).show(); | |
66 | + startCountDownService(3); | |
67 | + break; | |
68 | + } | |
69 | + } | |
70 | + | |
71 | + private void startCountDownService(Integer count) | |
72 | + { | |
73 | + Intent intent = new Intent(MainActivity.this, CountDownIntentService.class); | |
74 | + if (count != null) | |
75 | + { | |
76 | + intent.putExtra(CountDownIntentService.EXTRA_COUNT, 3); | |
77 | + } | |
78 | + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) | |
79 | + { | |
80 | + startForegroundService(intent); | |
81 | + | |
82 | + } | |
83 | + else | |
84 | + { | |
85 | + startService(intent); | |
86 | + } | |
87 | + | |
88 | + } | |
89 | + | |
90 | + private void startCountDownService() | |
91 | + { | |
92 | + startCountDownService(null); | |
93 | + } | |
94 | +} |
@@ -0,0 +1,22 @@ | ||
1 | +<?xml version="1.0" encoding="utf-8"?> | |
2 | +<LinearLayout | |
3 | + xmlns:android="http://schemas.android.com/apk/res/android" | |
4 | + android:orientation="vertical" | |
5 | + android:layout_width="fill_parent" | |
6 | + android:layout_height="fill_parent" | |
7 | + android:padding="10dip" | |
8 | +> | |
9 | + <Button | |
10 | + android:id="@+id/start_count_down_button" | |
11 | + android:layout_width="fill_parent" | |
12 | + android:layout_height="wrap_content" | |
13 | + android:text="@string/start_count_down" | |
14 | + /> | |
15 | + <Button | |
16 | + android:id="@+id/start_count_down_3_button" | |
17 | + android:layout_width="fill_parent" | |
18 | + android:layout_height="wrap_content" | |
19 | + android:text="@string/start_count_down_3" | |
20 | + /> | |
21 | +</LinearLayout> | |
22 | + |
@@ -0,0 +1,6 @@ | ||
1 | +<?xml version="1.0" encoding="utf-8"?> | |
2 | +<resources> | |
3 | + <string name="app_name">Intent Service Hello</string> | |
4 | + <string name="start_count_down">Start Count Down</string> | |
5 | + <string name="start_count_down_3">Start Count Down 3</string> | |
6 | +</resources> |
@@ -25,8 +25,9 @@ | ||
25 | 25 | </dependency> |
26 | 26 | |
27 | 27 | <dependency> |
28 | - <groupId>android.support</groupId> | |
29 | - <artifactId>compatibility-v4</artifactId> | |
28 | + <groupId>com.android.support</groupId> | |
29 | + <artifactId>support-v4</artifactId> | |
30 | + <type>aar</type> | |
30 | 31 | <scope>compile</scope> |
31 | 32 | </dependency> |
32 | 33 |
@@ -83,6 +83,7 @@ | ||
83 | 83 | <module>imageview-hello</module> |
84 | 84 | <module>imageview-zoom</module> |
85 | 85 | <module>intent-service-hello</module> |
86 | + <module>intent-service-foreground</module> | |
86 | 87 | |
87 | 88 | <module>layer-system-overlay</module> |
88 | 89 | <module>layout-framelayout-hello</module> |