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

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

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

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

Android

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

Xamarin

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

Q&A

解決済

1回答

739閲覧

staticクラスでSensorManagerを使用する方法

yusuke2721

総合スコア15

C#

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

Android

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

Xamarin

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

0グッド

0クリップ

投稿2019/02/05 04:22

Xamarin.Androidで、端末データ(GPS, 加速度等)のアップロードを定期的に行うアプリを開発しています。

Activityで実装していたアップロード処理を、Serviceを用いて別スレッドにて行うよう実装変更したいのですが、
public class MainActivity : Activity, ISensorEventListener と記述してSensorManagerを使用していた部分を、
どのように書き換えればよいのか分からず、行き詰まっております。

staticやinterfaceを十分に理解できておらずお手上げ状態なのですが、
何かヒントがございましたらご教示いただけませんでしょうか。
よろしくお願いいたします。

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

Service内、別スレッドにてBackgroundThread.Main()を起動

C#

1[Service(Name = "com.CompanyName.App.BackgroundService", Exported = true, Process = ":Process")] 2public class BackgroundService : Service 3{ 4 Task task; 5 6 public override IBinder OnBind(Intent intent) 7 { 8 return null; 9 } 10 11 [return: GeneratedEnum] 12 public override StartCommandResult OnStartCommand(Intent intent, [GeneratedEnum] StartCommandFlags flags, int startId) 13 { 14 task = new Task(() => BackgroundThread.Main()); 15 task.Start(); 16 return StartCommandResult.NotSticky; 17 } 18 19 public override void OnDestroy() 20 { 21 base.OnDestroy(); 22 task.Dispose(); 23 task = null; 24 StopSelf(); 25 } 26}

別スレッドで行うセンサー処理やアップロード処理(Timerでループ)

C#

1//public static class BackgroundThread : ISensorEventListener 2//↑「静的クラスではインターフェイスを実装できません」とのこと 3public static class BackgroundThread 4{ 5 private static Context _Context; 6 private static IGeolocator _GeoLocator; 7 private static Position _LastPos; 8 private static System.Timers.Timer _SecTimer; 9 private static SensorManager _SensorManager; 10 private static string _MacAddress; 11 private static double[] _Accel = new double[] { 0, 0, 0 }; 12 13 public static async void Main() 14 { 15 _Context = MainApplication.GetContext(); 16 _MacAddress = AppUtil.GetDeviceMacAddress(); 17 18 _GeoLocator = CrossGeolocator.Current; 19 _GeoLocator.DesiredAccuracy = 10; 20 _GeoLocator.AllowsBackgroundUpdates = true; 21 _GeoLocator.PositionChanged += Geolocator_PositionChanged; 22 await _GeoLocator.StartListeningAsync(1000, 0, true); 23 24 // 加速度センサー 25 //_SensorManager = (SensorManager)GetSystemService(Context.SensorService); 26 //_SensorManager.RegisterListener(this, _SensorManager.GetDefaultSensor(SensorType.Accelerometer), SensorDelay.Normal); 27 28 _SecTimer = new System.Timers.Timer(); 29 _SecTimer.Elapsed += (sender, args) => SecTimer_Tick(); 30 _SecTimer.Interval = 10 * 1000; 31 _SecTimer.Start(); 32 } 33 34 //public void OnSensorChanged(SensorEvent e) 35 //{ 36 // switch (e.Sensor.Type) 37 // { 38 // case SensorType.Accelerometer: 39 // _Accel[0] = acc.X; 40 // _Accel[1] = acc.Y; 41 // _Accel[2] = acc.Z; 42 // break; 43 // default: 44 // break; 45 // } 46 //} 47 // 48 //public void OnAccuracyChanged(Sensor sensor, [GeneratedEnum] SensorStatus accuracy) 49 //{ 50 // 51 //} 52 53 private static void Geolocator_PositionChanged(object sender, PositionEventArgs e) 54 { 55 if (e.Position.Accuracy <= 100) 56 { 57 _LastPos = new Position 58 { 59 Timestamp = e.Position.Timestamp.ToLocalTime(), 60 Latitude = e.Position.Latitude, 61 Longitude = AppUtil.ToRoundDown(e.Position.Longitude, 62 }; 63 } 64 } 65 66 private static async void SecTimer_Tick() 67 { 68 try 69 { 70 // 情報をサーバーへPOST 71 using (var httpClient = new HttpClient()) 72 { 73 httpClient.Timeout = TimeSpan.FromMilliseconds(10000); 74 httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); 75 76 var jArray = new JArray(); 77 var jObj = new JObject(); 78 jObj.Add("DeviceMacAddress", _MacAddress); 79 jObj.Add("AccelerometerX", _Accel[0]); 80 jObj.Add("AccelerometerY", _Accel[1]); 81 jObj.Add("AccelerometerZ", _Accel[2]); 82 jObj.Add("GpsDatetime", _LastPos.Timestamp); 83 jObj.Add("GpsLat", _LastPos.Latitude); 84 jObj.Add("GpsLon", _LastPos.Longitude); 85 jArray.Add(jObj); 86 87 var content = new StringContent(jArray.ToString(), System.Text.Encoding.UTF8, "application/json"); 88 await httpClient.PostAsync(_Context.GetString(Resource.String.DomainUrl) + _Context.GetString(Resource.String.ApiValues), content); 89 } 90 } 91 catch (Exception ex) 92 { 93 Console.WriteLine(ex.Message); 94 } 95 } 96}

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

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

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

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

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

guest

回答1

0

ベストアンサー

staticクラスはインターフェースを実装できないので、staticクラスを使わずにシングルトンにするには以下のようにします。

C#

1public class BackgroundThread : ISensorEventListener 2{ 3 public static BackgroundThread Instance { get; } = new BackgroundThread(); 4 5 private Context _Context; 6 private IGeolocator _GeoLocator; 7 private Position _LastPos; 8 private System.Timers.Timer _SecTimer; 9 private SensorManager _SensorManager; 10 private string _MacAddress; 11 private double[] _Accel = new double[] { 0, 0, 0 }; 12 13 private BackgroundThread() 14 { 15 } 16 17 public async void Main() 18 { 19 _Context = MainApplication.GetContext(); 20 _MacAddress = AppUtil.GetDeviceMacAddress(); 21 22 _GeoLocator = CrossGeolocator.Current; 23 _GeoLocator.DesiredAccuracy = 10; 24 _GeoLocator.AllowsBackgroundUpdates = true; 25 _GeoLocator.PositionChanged += Geolocator_PositionChanged; 26 await _GeoLocator.StartListeningAsync(1000, 0, true); 27 28 // 加速度センサー 29 _SensorManager = (SensorManager)GetSystemService(Context.SensorService); 30 _SensorManager.RegisterListener(this, _SensorManager.GetDefaultSensor(SensorType.Accelerometer), SensorDelay.Normal); 31 32 _SecTimer = new System.Timers.Timer(); 33 _SecTimer.Elapsed += (sender, args) => SecTimer_Tick(); 34 _SecTimer.Interval = 10 * 1000; 35 _SecTimer.Start(); 36 } 37 38 public void OnSensorChanged(SensorEvent e) 39 { 40 ... 41 } 42 43 public void OnAccuracyChanged(Sensor sensor, [GeneratedEnum] SensorStatus accuracy) 44 { 45 46 } 47 48 private void Geolocator_PositionChanged(object sender, PositionEventArgs e) 49 { 50 ... 51 } 52 53 private async void SecTimer_Tick() 54 { 55 ... 56 } 57}

呼び出すときは、こうします。

C#

1task = new Task(() => BackgroundThread.Instance.Main());

投稿2019/02/05 05:18

編集2019/02/05 05:27
f-miyu

総合スコア1625

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

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

yusuke2721

2019/02/05 06:46

実行することができました! Singletonパターンを知らなかったので、勉強になりました。 ありがとうございます!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問