0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

カーナビSDK案件に参画して学んだ「リスナー」の基本

0
Last updated at Posted at 2026-01-12

1. はじめに

こんにちは!エンジニアとして、初めてカーナビ関連の案件に参画しました。

参画当初は「プローブデータ」「LBS」「オンロード/オフロード」といった専門用語の理解に苦しみ、さらには複数のSDKが入り混じっていたため、「今書いているコードはアプリ側なのか?SDK側なのか?」と、境界線がわからず混乱することもありました。

今回は、ProbeData SDKという機能の修正や試験、ドキュメント準備に携わる中で、改めて復習し、ようやく腑に落ちた 「リスナー(Listener)」 の基本構造についてまとめてみたいと思います。

2. リスナーの役割:なぜ必要なのか?

リスナーを言語化しようとすると意外と難しいですが、私は以下のように整理しました。

  • SDK側:データを収集する機能は持っているが、「データが取れた後に、それぞれのアプリが何(表示、ログ、保存など)をしたいか」 は知らない。
  • アプリ側:データが欲しいタイミングは知っているが、「どうやって低レイヤーのデータを集めるか」 の詳細は知らない。

この両者を繋ぐのが「リスナー」です。アプリ側で処理内容を記述した「予約票」をSDKに渡しておき、SDK側でイベントが発生した瞬間にその予約票を実行してもらう、というイメージです。

3. SDKで定義したリスナーをアプリで呼び出す流れ

実務でよく見かける、SDK側でインターフェースを定義し、アプリ側でその中身(実装)を記述する例を見てみましょう。

① SDK側:インターフェースの定義

SDK側で「データが取れた時」と「送信が終わった時」のルールを決めます。

// SDK側の定義
interface ProbeDataListener {
    // データ(位置情報や車両情報)が収集された時に呼ばれる
    fun onDataCaptured(data: String)
    
    // サーバーへのアップロード結果を通知する
    fun onUploadResult(isSuccess: Boolean)
}

② SDK側:リスナーを保持し、実行する

SDK側はアプリからリスナーを受け取る窓口を作り、内部でデータが溜まったらそれを実行します。

class ProbeDataSDK {
    private var listener: ProbeDataListener? = null

    // アプリ側からリスナーを登録(Add/Set)してもらうメソッド
    fun setListener(listener: ProbeDataListener) {
        this.listener = listener
    }

    // SDK内部で定期的に実行されるデータ処理(イメージ)
    private fun handleDataCollection() {
        val currentInfo = "Lat: 35.6, Lng: 139.7, Speed: 60km/h"
        
        // ★ここで「アプリ側で書かれた処理」が実行される!
        listener?.onDataCaptured(currentInfo)
    }
}

③ アプリ側:リスナーを登録して処理を動かす
アプリ起動時の初期化処理などで、SDKにリスナーを渡します。

// アプリ側の実装
val probeDataSdk = ProbeDataSDK()

// 初期化の流れでリスナーを登録
probeDataSdk.setListener(object : ProbeDataListener {
    override fun onDataCaptured(data: String) {
        // SDKからデータが届いた!ログに出して確認しよう
        Log.d("ProbeData", "収集データを受信: $data")
    }

    override fun onUploadResult(isSuccess: Boolean) {
        if (isSuccess) {
            Log.d("ProbeData", "アップロード成功!")
        } else {
            Log.e("ProbeData", "アップロード失敗...")
        }
    }
})

4. 現場での動作確認:Logcatの活用

実装した機能が正しく動いているかは、主にAndroid StudioのLogcatで確認しました。

  • アプリを起動して初期化が走った後、車が走っていなくても設定された頻度でデータが収集されているか?

  • 収集された座標や車両情報の「鮮度」は新しいか?

  • 一定時間経ってアップロードが走った際、onUploadResult が成功を返しているか?

実際のログを追いながら、SDK内部の動きとアプリ側の受け取りが一致した瞬間は、とてもスッキリしました!

5. 終わりに

最初は「SDK側とアプリ側、どっちを触っているんだっけ?」と迷うこともありましたが、リスナーの構造(定義・登録・実行)を整理することで、データの流れがクリアに見えるようになりました。

カーナビ案件のような大規模なプロジェクトでは、こうした基本的なデザインパターンが至る所で使われています。一つずつ仕組みを解明していくことが、成長への近道だと感じました。

この記事が、SDK開発やリスナーの理解に悩む方の参考になれば幸いです!

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?