• R/O
  • HTTP
  • SSH
  • HTTPS

提交

标签
No Tags

Frequently used words (click to add to your profile)

javac++androidlinuxc#windowsobjective-ccocoa誰得qtpythonphprubygameguibathyscaphec計画中(planning stage)翻訳omegatframeworktwitterdomtestvb.netdirectxゲームエンジンbtronarduinopreviewer

Android Samples


Commit MetaInfo

修订版e17d6f0f869e076892f0d5d13b545f0a36326ff7 (tree)
时间2019-05-04 20:40:08
作者Masahiko, SAWAI <say@user...>
CommiterMasahiko, SAWAI

Log Message

Added a new project.

* intent-service-foreground project

更改概述

差异

--- /dev/null
+++ b/intent-service-foreground/Makefile
@@ -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 $@
--- /dev/null
+++ b/intent-service-foreground/README.txt
@@ -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+
--- /dev/null
+++ b/intent-service-foreground/pom.xml
@@ -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>
--- /dev/null
+++ b/intent-service-foreground/src/main/AndroidManifest.xml
@@ -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>
--- /dev/null
+++ b/intent-service-foreground/src/main/java/com/example/hello/android/intent_service_foreground/CountDownIntentService.java
@@ -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+}
--- /dev/null
+++ b/intent-service-foreground/src/main/java/com/example/hello/android/intent_service_foreground/MainActivity.java
@@ -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+}
--- /dev/null
+++ b/intent-service-foreground/src/main/res/layout/main.xml
@@ -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+
--- /dev/null
+++ b/intent-service-foreground/src/main/res/values/strings.xml
@@ -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>
--- a/navigation-drawer-hello/pom.xml
+++ b/navigation-drawer-hello/pom.xml
@@ -25,8 +25,9 @@
2525 </dependency>
2626
2727 <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>
3031 <scope>compile</scope>
3132 </dependency>
3233
--- a/pom.xml
+++ b/pom.xml
@@ -83,6 +83,7 @@
8383 <module>imageview-hello</module>
8484 <module>imageview-zoom</module>
8585 <module>intent-service-hello</module>
86+ <module>intent-service-foreground</module>
8687
8788 <module>layer-system-overlay</module>
8889 <module>layout-framelayout-hello</module>