質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

Android

Androidは、Google社が開発したスマートフォンやタブレットなど携帯端末向けのプラットフォームです。 カーネル・ミドルウェア・ユーザーインターフェイス・ウェブブラウザ・電話帳などのアプリケーションやソフトウェアをひとつにまとめて構成。 カーネル・ライブラリ・ランタイムはほとんどがC言語/C++、アプリケーションなどはJavaSEのサブセットとAndroid環境で書かれています。

Xamarin

Xamarin(ザマリン)は、iPhoneなどのiOSやAndroidで動作し、C# 言語を用いてアプリを開発できるクロスプラットフォーム開発環境です。Xamarin Studioと C# 言語を用いて、 iOS と Android の両方の開発を行うことができます。

Q&A

解決済

1回答

1477閲覧

AndroidのStopService()でServiceの別スレッド処理を終了できない

yusuke2721

総合スコア15

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

Android

Androidは、Google社が開発したスマートフォンやタブレットなど携帯端末向けのプラットフォームです。 カーネル・ミドルウェア・ユーザーインターフェイス・ウェブブラウザ・電話帳などのアプリケーションやソフトウェアをひとつにまとめて構成。 カーネル・ライブラリ・ランタイムはほとんどがC言語/C++、アプリケーションなどはJavaSEのサブセットとAndroid環境で書かれています。

Xamarin

Xamarin(ザマリン)は、iPhoneなどのiOSやAndroidで動作し、C# 言語を用いてアプリを開発できるクロスプラットフォーム開発環境です。Xamarin Studioと C# 言語を用いて、 iOS と Android の両方の開発を行うことができます。

0グッド

1クリップ

投稿2019/01/31 06:10

編集2019/01/31 09:12

Xamarin.Androidで、定期的にGPS情報アップロードを行うアプリを開発しています。

通常はMainActivityのTimer処理でアップロードを行っていますが、
ホームボタン押下等でアプリ終了され、OnStop()に入った場合はServiceを立ち上げて上記処理を行い、
アプリ起動でOnCreate()に入った場合に、Serviceを完全にキルしたいと考えています。

C#

1var context = this.ApplicationContext; 2context.StopService(new Intent(context, typeof(BackgroundService)));

上記のコードをOnCreate()やTimer処理内で実行すると、
開発者向けオプション内の「実行中のアプリ」リストからはクリアされているのですが、
「実行中のアプリ→キャッシュしたプロセスを表示」リストには残存しており、おそらくそれが原因で、Serviceがリスタートしているようです。
いわゆるゾンビ状態となり、Serviceを終了できず困っています。

「キャッシュしたプロセスを表示」リストから、バックグラウンドプロセスを終了させる方法はございますでしょうか。
よろしくお願いいたします。

~開発環境等~
Visual Studio 2017
Xamarin.Android
Android 7.1 (APIレベル25 - Nougat)

MainActivity.cs

C#

1public class MainActivity : Activity 2{ 3 protected override void OnCreate(Bundle bundle) 4 { 5 base.OnCreate(bundle); 6 SetContentView(Resource.Layout.Main); 7 8 //サービスがあれば終了させる 9 var context = this.ApplicationContext; 10 context.StopService(new Intent(context, typeof(BackgroundService))); 11 } 12 13 protected async override void OnStop() 14 { 15 //サービスを起動 16 var context = this.ApplicationContext; 17 var serviceIntent = new Intent(context, typeof(BackgroundService)); 18 serviceIntent.AddFlags(ActivityFlags.NewTask); 19 context.StartService(serviceIntent); 20 21 base.OnStop(); 22 System.Diagnostics.Process.GetCurrentProcess().CloseMainWindow(); 23 } 24}

BackgroundService.cs

C#

1[Service(Name = "com.CompanyName.App.BackgroundService", Exported = true, Process = ":Process")] 2public class BackgroundService : Service 3{ 4 /// <summary> 5 /// 6 /// </summary> 7 Thread thread; 8 9 /// <summary> 10 /// 11 /// </summary> 12 /// <param name="intent"></param> 13 /// <returns></returns> 14 public override IBinder OnBind(Intent intent) 15 { 16 return null; 17 } 18 19 /// <summary> 20 /// 21 /// </summary> 22 /// <param name="intent"></param> 23 /// <param name="flags"></param> 24 /// <param name="startId"></param> 25 /// <returns></returns> 26 [return: GeneratedEnum] 27 public override StartCommandResult OnStartCommand(Intent intent, [GeneratedEnum] StartCommandFlags flags, int startId) 28 { 29 try 30 { 31 thread = new Thread(() => 32 { 33 //var bundle = new Bundle(); 34 //global::Xamarin.Forms.Forms.Init(this, bundle); 35 36 // 別スレッドでWhile処理を用いてアップロードを実行 37 BackgroundThread.Main(); 38 }); 39 thread.Start(); 40 41 return StartCommandResult.NotSticky; 42 } 43 catch(Exception ex) 44 { 45 return StartCommandResult.NotSticky; 46 } 47 } 48 49 /// <summary> 50 /// 51 /// </summary> 52 public override void OnDestroy() 53 { 54 try 55 { 56 base.OnDestroy(); 57 58 thread.Interrupt(); 59 thread = null; 60 61 StopSelf(); 62 } 63 catch (Exception ex) 64 { 65 66 } 67 } 68}

BackgroundThread.cs

C#

1public static class BackgroundThread 2{ 3 /// <summary> 4 /// GPS 5 /// </summary> 6 private static IGeolocator _GeoLocator; 7 8 /// <summary> 9 /// GPS取得データ 10 /// </summary> 11 private static Position _LastPos; 12 13 public static async void Main() 14 { 15 var mac = AppUtil.GetDeviceMacAddress(); 16 17 _GeoLocator = CrossGeolocator.Current; 18 _GeoLocator.DesiredAccuracy = 10; 19 _GeoLocator.AllowsBackgroundUpdates = true; 20 _GeoLocator.PositionChanged -= Geolocator_PositionChanged; 21 _GeoLocator.PositionChanged += Geolocator_PositionChanged; 22 await _GeoLocator.StartListeningAsync(1000, 0, true); 23 24 while (true) 25 { 26 try 27 { 28 // 位置情報をサーバーへPOST 29 using (var httpClient = new HttpClient()) 30 { 31 httpClient.Timeout = TimeSpan.FromMilliseconds(10000); 32 httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); 33 34 // JSON形式に 35 var jArray = new JArray(); 36 37 var jObj = new JObject(); 38 jObj.Add("DeviceMacAddress", mac); 39 jObj.Add("GpsAccelerometerX", 0); 40 jObj.Add("GpsAccelerometerY", 0); 41 jObj.Add("GpsAccelerometerZ", 0); 42 jObj.Add("GpsDatetime", _LastPos.Timestamp); 43 jObj.Add("GpsLat", _LastPos.Latitude); 44 jObj.Add("GpsLon", _LastPos.Longitude); 45 jObj.Add("GpsSpeed", _LastPos.Speed); 46 jObj.Add("GpsDirection", _LastPos.Heading); 47 jObj.Add("GpsAccuracy", _LastPos.Accuracy); 48 jArray.Add(jObj); 49 50 var content = new StringContent(jArray.ToString(), System.Text.Encoding.UTF8, "application/json"); 51 //httpClient.PostAsync(GetString(Resource.String.DomainUrl) + GetString(Resource.String.ApiValues), content); 52 await httpClient.PostAsync(@"http://www.xxx.com/api/values/", content); 53 } 54 } 55 catch (Exception ex) 56 { 57 string message = ex.Message; 58 Console.WriteLine(ex.Message); 59 } 60 61 Thread.Sleep(10000); 62 } 63 } 64 65 /// <summary> 66 /// 位置情報更新 67 /// </summary> 68 /// <param name="sender"></param> 69 /// <param name="e"></param> 70 private static void Geolocator_PositionChanged(object sender, PositionEventArgs e) 71 { 72 if (e.Position.Accuracy <= 100) 73 { 74 _LastPos = new Position 75 { 76 Timestamp = e.Position.Timestamp.ToLocalTime(), 77 Latitude = e.Position.Latitude, 78 Longitude = AppUtil.ToRoundDown(e.Position.Longitude, 79 Speed = e.Position.Speed, 80 Heading = e.Position.Heading, 81 Accuracy = e.Position.Accuracy 82 }; 83 } 84 } 85 86}

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

amay077

2019/01/31 08:05

直接の解決方法ではないですが、「位置情報の取得とアップロード」はもっぱら Service に任せて、MainActivity では Service が開始されていなければ開始する、のではダメなのでしょうか?「アプリ起動中は MainActivity で行い、アプリ終了時のみ Service に行わせる」理由が分からないです。
yusuke2721

2019/01/31 11:55 編集

おっしゃる通りでございます…。 最初にこの方法を知っていれば良かったのですが、設計変更が難しい箇所が多く、このような状況となりました。
guest

回答1

0

自己解決

Serviceクラスに付けたProcess名で検索して、Killすることでとりあえずうまく動きそうです。
[Service(Name = "com.CompanyName.App.BackgroundService", Exported = true, Process = ":Process")]

<uses-permission android:name="android.permission.KILL_BACKGROUND_PROCESSES" /> 下記コードを動かすために、上のパーミッションも必要です。

MainActivity.OnCreate()で下記コードを呼び出す

C#

1private void KillBgProc() 2{ 3 try 4 { 5 var amgr = (ActivityManager)this.GetSystemService(Context.ActivityService); 6 var list = amgr.RunningAppProcesses; 7 if (list != null) 8 { 9 for (int i = 0; i < list.Count; i++) 10 { 11 ActivityManager.RunningAppProcessInfo apinfo = list[i]; 12 13 var pkgList = apinfo.PkgList; 14 if (apinfo.ProcessName.Contains("TestProject.TestProject:Process")) 15 { 16 for (int j = 0; j < pkgList.Count; j++) 17 { 18 amgr.KillBackgroundProcesses(pkgList[j]); 19 } 20 } 21 } 22 } 23 } 24 catch (Exception ex) 25 { 26 } 27}

投稿2019/01/31 07:51

yusuke2721

総合スコア15

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問