Commit 45cf2f39 by onuma

Task #42447 OS8 バックグランドサービス対応

parent 37ce0f52
...@@ -21,6 +21,8 @@ ...@@ -21,6 +21,8 @@
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/> <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
<uses-permission android:name="android.permission.BLUETOOTH" /> <uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" /> <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" />
<!-- GCM --> <!-- GCM -->
<uses-permission android:name="android.permission.GET_ACCOUNTS" /> <uses-permission android:name="android.permission.GET_ACCOUNTS" />
...@@ -58,6 +60,11 @@ ...@@ -58,6 +60,11 @@
</intent-filter> </intent-filter>
</service> </service>
<service
android:name="jp.agentec.abook.abv.launcher.android.BackgroundDownloadService"
android:enabled="true"
android:exported="false" />
<receiver android:name="jp.agentec.abook.abv.launcher.android.OnAppDownloadReceiver"> <receiver android:name="jp.agentec.abook.abv.launcher.android.OnAppDownloadReceiver">
<intent-filter> <intent-filter>
<action android:name="android.intent.action.DOWNLOAD_NOTIFICATION_CLICKED" /> <action android:name="android.intent.action.DOWNLOAD_NOTIFICATION_CLICKED" />
......
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android"> <paths xmlns:android="http://schemas.android.com/apk/res/android">
<cache-path name="cache_files" path="."/> <cache-path name="cache_files" path="."/>
<external-path name="external_files" path="."/>
</paths> </paths>
package jp.agentec.abook.abv.launcher.android;
import android.app.DownloadManager;
import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.net.Uri;
import android.os.Build;
import android.os.Environment;
import android.os.IBinder;
import android.support.v4.content.FileProvider;
import java.io.File;
import jp.agentec.abook.abv.bl.acms.type.AcmsApis;
import jp.agentec.abook.abv.bl.common.ABVEnvironment;
import jp.agentec.abook.abv.bl.common.log.Logger;
import jp.agentec.abook.abv.bl.data.ABVDataCache;
import jp.agentec.adf.util.DateTimeFormat;
import jp.agentec.adf.util.DateTimeUtil;
public class BackgroundDownloadService extends Service {
private final static String LOG_TAG = BackgroundDownloadService.class.getSimpleName();
private DownloadManager mDownloadManager;
private long mDownloadedFileID;
private String notificationChannelId;
private String notificationChannelIdLow;
private NotificationManager mNotificationManager;
@Override
public void onCreate() {
super.onCreate();
mDownloadManager = (DownloadManager) getSystemService(Context.DOWNLOAD_SERVICE);
notificationChannelId = getApplicationContext().getPackageName();
notificationChannelIdLow += ".Low";
if (mNotificationManager == null) {
mNotificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
NotificationChannel notificationChannel = new NotificationChannel(notificationChannelId, getString(R.string.app_name), NotificationManager.IMPORTANCE_DEFAULT);
NotificationChannel notificationChannelLow = new NotificationChannel(notificationChannelIdLow, getString(R.string.app_name), NotificationManager.IMPORTANCE_LOW);
if (mNotificationManager != null) {
mNotificationManager.createNotificationChannel(notificationChannel);
mNotificationManager.createNotificationChannel(notificationChannelLow);
}
}
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
if (intent == null) {
return START_STICKY;
}
BroadcastReceiver onDownloadComplete = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
unregisterReceiver(this);
// Prevents the occasional unintentional call.
if (mDownloadedFileID == -1) {
return;
}
try {
File file = new File(context.getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS), ABVEnvironment.APK_FILE_NAME);
if (file.exists()) {
Uri apkUri = FileProvider.getUriForFile(context, context.getPackageName() + ".provider", file);
Intent updateIntent = new Intent(Intent.ACTION_VIEW);
updateIntent.setDataAndType(apkUri, "application/vnd.android.package-archive");
updateIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
updateIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
// Android10(Q)
if (Build.VERSION.SDK_INT >= 29) {
sendNotify(updateIntent, getString(R.string.app_update), false);
Logger.d(LOG_TAG, "sendNotify(updateIntent...).");
} else {
stopForeground(true);
startActivity(updateIntent);
Logger.d(LOG_TAG, "startActivity(fileIntent).");
}
} else {
sendNotify(intent, getString(R.string.DOWNLOAD_ERROR), false);
Logger.w(LOG_TAG, "sendNotify(intent...).");
}
} catch (Exception ex) {
sendNotify(intent, getString(R.string.DOWNLOAD_ERROR), false);
Logger.e(LOG_TAG, "startActivity(fileIntent).", ex);
} finally {
// Sets up the prevention of an unintentional call.
mDownloadedFileID = -1;
}
}
};
try {
ABVEnvironment abvEnvironment = ABVEnvironment.getInstance();
ABVDataCache dataCache = ABVDataCache.getInstance();
String currentDate = DateTimeUtil.toString(DateTimeUtil.getCurrentTimestamp(), DateTimeFormat.yyyyMMddHHmmss000_none);
String downloadUrl = AcmsApis.getDownloadApplicationFileUrl(abvEnvironment.acmsAddress, dataCache.getUrlPath(), dataCache.getMemberInfo().sid, currentDate);
Logger.d(LOG_TAG, "downloadUrl=%s", downloadUrl);
DownloadManager.Request request = new DownloadManager.Request(Uri.parse(downloadUrl));
request.setDescription("ABook Plus New Version File");
//LANケーブル接続のタイプ(ETHERNET TYPE)がないため、セットしない
//request.setAllowedNetworkTypes(DownloadManager.Request.NETWORK_MOBILE | DownloadManager.Request.NETWORK_WIFI);
File file = new File(getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS), ABVEnvironment.APK_FILE_NAME);
Logger.d(LOG_TAG, "download local file=%s", file.getAbsolutePath());
File[] childs = file.getParentFile().listFiles();
if (childs != null && childs.length > 0 && childs[0].exists()) {
childs[0].delete();
}
request.setDestinationUri(Uri.fromFile(file));
// Registers function to listen to the completion of the download.
registerReceiver(onDownloadComplete, new IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE));
// Download 開始
Logger.d(LOG_TAG, "mDownloadManager.enqueue(request).");
mDownloadedFileID = mDownloadManager.enqueue(request);
//5秒以内にstartForegroundを呼ばないとクラッシュ
int uniqueId = (int) System.currentTimeMillis();
Notification notification = getNotification(uniqueId, intent, getString(R.string.download_start), true);
startForeground(uniqueId, notification);
} catch (Exception ex) {
Logger.e(LOG_TAG, "mDownloadManager.enqueue(request).", ex);
}
return super.onStartCommand(intent, flags, startId);
}
private void sendNotify(Intent intent, String message, boolean isImportanceLow) {
stopForeground(true);
int uniqueId = (int) System.currentTimeMillis();
Notification notification = getNotification(uniqueId, intent, message, isImportanceLow);
if (mNotificationManager != null) {
mNotificationManager.notify(uniqueId, notification);
Logger.d(LOG_TAG, "sendNotify()");
}
}
private Notification getNotification(int uniqueId, Intent intent, String message, boolean isImportanceLow) {
PendingIntent pendingIntent = PendingIntent.getActivity(this, uniqueId, intent, PendingIntent.FLAG_UPDATE_CURRENT);
return new Notification.Builder(this)
.setDefaults(Notification.DEFAULT_ALL)
.setSmallIcon(R.drawable.icon)
.setWhen(System.currentTimeMillis())
.setAutoCancel(true)
.setContentTitle(getString(R.string.app_name))
.setContentText(message)
.setContentIntent(pendingIntent)
.setChannelId(isImportanceLow ? notificationChannelIdLow : notificationChannelId)
.build();
}
@Override
public IBinder onBind(Intent intent) {
return null;
}
}
...@@ -6,7 +6,9 @@ import android.content.Context; ...@@ -6,7 +6,9 @@ import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.database.Cursor; import android.database.Cursor;
import android.net.Uri; import android.net.Uri;
import android.os.Build;
import android.os.Environment; import android.os.Environment;
import android.support.v4.content.FileProvider;
import android.util.Log; import android.util.Log;
import android.widget.Toast; import android.widget.Toast;
...@@ -27,6 +29,10 @@ public class OnAppDownloadReceiver extends BroadcastReceiver { ...@@ -27,6 +29,10 @@ public class OnAppDownloadReceiver extends BroadcastReceiver {
@Override @Override
public void onReceive(Context context, Intent intent) { public void onReceive(Context context, Intent intent) {
if (DownloadManager.ACTION_DOWNLOAD_COMPLETE.equals(intent.getAction())) { if (DownloadManager.ACTION_DOWNLOAD_COMPLETE.equals(intent.getAction())) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
return;
}
long id = intent.getLongExtra(DownloadManager.EXTRA_DOWNLOAD_ID, -1); long id = intent.getLongExtra(DownloadManager.EXTRA_DOWNLOAD_ID, -1);
Logger.d("Download Complete ID : " + id); Logger.d("Download Complete ID : " + id);
...@@ -58,11 +64,25 @@ public class OnAppDownloadReceiver extends BroadcastReceiver { ...@@ -58,11 +64,25 @@ public class OnAppDownloadReceiver extends BroadcastReceiver {
if (downloadedTo != null && downloadedTo.toLowerCase().endsWith(".apk")) { if (downloadedTo != null && downloadedTo.toLowerCase().endsWith(".apk")) {
File file = new File(context.getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS), ABVEnvironment.APK_FILE_NAME); File file = new File(context.getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS), ABVEnvironment.APK_FILE_NAME);
if (file.exists()) { if (file.exists()) {
try {
// Android7でアップデート
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
Uri apkUri = FileProvider.getUriForFile(context, context.getPackageName() + ".provider", file);
Intent updateIntent = new Intent(Intent.ACTION_VIEW);
updateIntent.setDataAndType(apkUri, "application/vnd.android.package-archive");
updateIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
updateIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
context.startActivity(updateIntent);
} else {
Intent i = new Intent(Intent.ACTION_VIEW); Intent i = new Intent(Intent.ACTION_VIEW);
// Activity以外からActivityを呼び出すためのフラグを設定 // Activity以外からActivityを呼び出すためのフラグを設定
i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
i.setDataAndType(Uri.fromFile(file), "application/vnd.android.package-archive"); i.setDataAndType(Uri.fromFile(file), "application/vnd.android.package-archive");
context.startActivity(i); context.startActivity(i);
}
} catch (Exception ex) {
Logger.e("OnAppDownloadReceiver.startActivity(fileIntent).", ex);
}
} else { } else {
Toast.makeText(context, "No Exist APK File: ", Toast.LENGTH_LONG).show(); Toast.makeText(context, "No Exist APK File: ", Toast.LENGTH_LONG).show();
} }
......
...@@ -12,6 +12,7 @@ import android.content.Intent; ...@@ -12,6 +12,7 @@ import android.content.Intent;
import android.content.IntentFilter; import android.content.IntentFilter;
import android.content.SharedPreferences; import android.content.SharedPreferences;
import android.net.Uri; import android.net.Uri;
import android.os.Build;
import android.os.Bundle; import android.os.Bundle;
import android.os.Environment; import android.os.Environment;
import android.view.View; import android.view.View;
...@@ -48,6 +49,7 @@ import jp.agentec.abook.abv.bl.logic.UserAuthenticateLogic; ...@@ -48,6 +49,7 @@ import jp.agentec.abook.abv.bl.logic.UserAuthenticateLogic;
import jp.agentec.abook.abv.cl.environment.NetworkAdapter; import jp.agentec.abook.abv.cl.environment.NetworkAdapter;
import jp.agentec.abook.abv.cl.push.FcmManager; import jp.agentec.abook.abv.cl.push.FcmManager;
import jp.agentec.abook.abv.cl.util.PreferenceUtil; import jp.agentec.abook.abv.cl.util.PreferenceUtil;
import jp.agentec.abook.abv.launcher.android.BackgroundDownloadService;
import jp.agentec.abook.abv.launcher.android.OnAppDownloadReceiver; import jp.agentec.abook.abv.launcher.android.OnAppDownloadReceiver;
import jp.agentec.abook.abv.launcher.android.R; import jp.agentec.abook.abv.launcher.android.R;
import jp.agentec.abook.abv.ui.common.appinfo.AppDefType; import jp.agentec.abook.abv.ui.common.appinfo.AppDefType;
...@@ -255,7 +257,11 @@ public abstract class ABVNoAuthenticatedActivity extends ABVActivity { ...@@ -255,7 +257,11 @@ public abstract class ABVNoAuthenticatedActivity extends ABVActivity {
public void onClick(DialogInterface dialog, int which) { public void onClick(DialogInterface dialog, int which) {
// バージョンアップフラグをON // バージョンアップフラグをON
PreferenceUtil.put(getApplicationContext(), AppDefType.DefPrefKey.APP_VERSIONUP_PROCESSING, true); PreferenceUtil.put(getApplicationContext(), AppDefType.DefPrefKey.APP_VERSIONUP_PROCESSING, true);
// Android8以上でバックグラウンドをフォアグラウンドで処理
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
Intent serviceIntent = new Intent(mContext, BackgroundDownloadService.class);
startForegroundService(serviceIntent);
} else {
// Download 開始 // Download 開始
DownloadManager downloadManager = (DownloadManager) getSystemService(DOWNLOAD_SERVICE); DownloadManager downloadManager = (DownloadManager) getSystemService(DOWNLOAD_SERVICE);
String currentDate = DateTimeUtil.toString(DateTimeUtil.getCurrentTimestamp(), DateTimeFormat.yyyyMMddHHmmss000_none); String currentDate = DateTimeUtil.toString(DateTimeUtil.getCurrentTimestamp(), DateTimeFormat.yyyyMMddHHmmss000_none);
...@@ -264,7 +270,7 @@ public abstract class ABVNoAuthenticatedActivity extends ABVActivity { ...@@ -264,7 +270,7 @@ public abstract class ABVNoAuthenticatedActivity extends ABVActivity {
Request request = new Request(Uri.parse(downloadUrl)); Request request = new Request(Uri.parse(downloadUrl));
request.setDescription("ABook Plus New Version File"); request.setDescription("ABook Plus New Version File");
//LANケーブル接続のタイプ(ETHERNET TYPE)がないため、セットしない //LANケーブル接続のタイプ(ETHERNET TYPE)がないため、セットしない
// request.setAllowedNetworkTypes(DownloadManager.Request.NETWORK_MOBILE | DownloadManager.Request.NETWORK_WIFI); // request.setAllowedNetworkTypes(DownloadManager.Request.NETWORK_MOBILE | DownloadManager.Request.NETWORK_WIFI);
File file = new File(getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS), ABVEnvironment.APK_FILE_NAME); File file = new File(getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS), ABVEnvironment.APK_FILE_NAME);
Logger.d(TAG, "download local file=%s", file.getAbsolutePath()); Logger.d(TAG, "download local file=%s", file.getAbsolutePath());
File[] childs = file.getParentFile().listFiles(); File[] childs = file.getParentFile().listFiles();
...@@ -275,6 +281,7 @@ public abstract class ABVNoAuthenticatedActivity extends ABVActivity { ...@@ -275,6 +281,7 @@ public abstract class ABVNoAuthenticatedActivity extends ABVActivity {
downloadManager.enqueue(request); downloadManager.enqueue(request);
registerReceiver(new OnAppDownloadReceiver(), new IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE)); registerReceiver(new OnAppDownloadReceiver(), new IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE));
}
// アプリを閉じる // アプリを閉じる
saveLeaveAppTime(); saveLeaveAppTime();
......
package jp.agentec.abook.abv.ui.home.activity; package jp.agentec.abook.abv.ui.home.activity;
import android.app.Activity;
import android.app.AlertDialog; import android.app.AlertDialog;
import android.app.Application;
import android.app.DownloadManager; import android.app.DownloadManager;
import android.app.DownloadManager.Request; import android.app.DownloadManager.Request;
import android.content.Context; import android.content.Context;
...@@ -11,6 +13,7 @@ import android.content.SharedPreferences; ...@@ -11,6 +13,7 @@ import android.content.SharedPreferences;
import android.content.res.Configuration; import android.content.res.Configuration;
import android.content.res.Resources; import android.content.res.Resources;
import android.net.Uri; import android.net.Uri;
import android.os.Build;
import android.os.Bundle; import android.os.Bundle;
import android.os.Environment; import android.os.Environment;
import android.os.Handler; import android.os.Handler;
...@@ -42,8 +45,11 @@ import jp.agentec.abook.abv.bl.logic.AbstractLogic; ...@@ -42,8 +45,11 @@ import jp.agentec.abook.abv.bl.logic.AbstractLogic;
import jp.agentec.abook.abv.bl.logic.ContractLogic; import jp.agentec.abook.abv.bl.logic.ContractLogic;
import jp.agentec.abook.abv.bl.logic.UserAuthenticateLogic; import jp.agentec.abook.abv.bl.logic.UserAuthenticateLogic;
import jp.agentec.abook.abv.cl.helper.ABVUncaughtExceptionHandler; import jp.agentec.abook.abv.cl.helper.ABVUncaughtExceptionHandler;
import jp.agentec.abook.abv.cl.helper.PreferenceHelper;
import jp.agentec.abook.abv.cl.util.PreferenceUtil; import jp.agentec.abook.abv.cl.util.PreferenceUtil;
import jp.agentec.abook.abv.cl.util.RawResourceUtil; import jp.agentec.abook.abv.cl.util.RawResourceUtil;
import jp.agentec.abook.abv.launcher.android.ABVApplication;
import jp.agentec.abook.abv.launcher.android.BackgroundDownloadService;
import jp.agentec.abook.abv.launcher.android.OnAppDownloadReceiver; import jp.agentec.abook.abv.launcher.android.OnAppDownloadReceiver;
import jp.agentec.abook.abv.launcher.android.R; import jp.agentec.abook.abv.launcher.android.R;
import jp.agentec.abook.abv.ui.common.appinfo.AppDefType; import jp.agentec.abook.abv.ui.common.appinfo.AppDefType;
...@@ -362,6 +368,12 @@ public class ABookSettingFragment extends PreferenceFragment { ...@@ -362,6 +368,12 @@ public class ABookSettingFragment extends PreferenceFragment {
dialog.setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() { dialog.setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() {
@Override @Override
public void onClick(DialogInterface dialog, int which) { public void onClick(DialogInterface dialog, int which) {
// Android8以上でバックグラウンドをフォアグラウンドで処理
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
Context context = getActivity().getApplicationContext();
Intent serviceIntent = new Intent(context, BackgroundDownloadService.class);
context.startForegroundService(serviceIntent);
} else {
// Download 開始 // Download 開始
DownloadManager downloadManager = (DownloadManager) getActivity().getSystemService(Context.DOWNLOAD_SERVICE); DownloadManager downloadManager = (DownloadManager) getActivity().getSystemService(Context.DOWNLOAD_SERVICE);
String currentDate = DateTimeUtil.toString(DateTimeUtil.getCurrentTimestamp(), DateTimeFormat.yyyyMMddHHmmss000_none); String currentDate = DateTimeUtil.toString(DateTimeUtil.getCurrentTimestamp(), DateTimeFormat.yyyyMMddHHmmss000_none);
...@@ -370,7 +382,7 @@ public class ABookSettingFragment extends PreferenceFragment { ...@@ -370,7 +382,7 @@ public class ABookSettingFragment extends PreferenceFragment {
Request request = new Request(Uri.parse(downloadUrl)); Request request = new Request(Uri.parse(downloadUrl));
request.setDescription("ABook Plus New Version File"); request.setDescription("ABook Plus New Version File");
//LANケーブル接続のタイプ(ETHERNET TYPE)がないため、セットしない //LANケーブル接続のタイプ(ETHERNET TYPE)がないため、セットしない
// request.setAllowedNetworkTypes(DownloadManager.Request.NETWORK_MOBILE | DownloadManager.Request.NETWORK_WIFI); // request.setAllowedNetworkTypes(DownloadManager.Request.NETWORK_MOBILE | DownloadManager.Request.NETWORK_WIFI);
File file = new File(getActivity().getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS), ABVEnvironment.APK_FILE_NAME); File file = new File(getActivity().getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS), ABVEnvironment.APK_FILE_NAME);
Logger.d(TAG, "download local file=%s", file.getAbsolutePath()); Logger.d(TAG, "download local file=%s", file.getAbsolutePath());
...@@ -384,7 +396,7 @@ public class ABookSettingFragment extends PreferenceFragment { ...@@ -384,7 +396,7 @@ public class ABookSettingFragment extends PreferenceFragment {
} }
getActivity().registerReceiver(new OnAppDownloadReceiver(), new IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE)); getActivity().registerReceiver(new OnAppDownloadReceiver(), new IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE));
}
// アプリを閉じる // アプリを閉じる
saveLeaveAppTime(); saveLeaveAppTime();
getActivity().moveTaskToBack(true); getActivity().moveTaskToBack(true);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment