プログラム規模が大きくなるほど、特に、プログラム開発のスタートが重要である。後になるほど修正が難しくなる。 急ぐ話ではないので、月日をかけてじっくりと進めよう。
地図アプリの大きな役割として、位置情報の取得がある。別アプリとするか、一体化するかは大した問題ではなく、 後からでも、変更できる。
位置情報取得はフォアグラウンドサービスとして実装して、broadcast により地図表示アプリ(Activity)に送る。
現在の地図アプリMapXで broadcast している位置情報を新しいアプリ map3 で受け取ってみよう。
MapXでは次のメソッドで取得した位置情報を文字列化している。これを broadcast するとともに、 その日のログファイルに定期的に追記している。
public static String toString(Location loc) { long utcMillis = loc.getTime(); Instant instant = Instant.ofEpochSecond((utcMillis+500)/1000); LocalDateTime ldt = LocalDateTime.ofInstant(instant, ZoneId.systemDefault()); String format = "%02d:%02d:%02d,%.7f,%.7f,%.1f,%.2f,%.1f\n"; return String.format(Locale.JAPAN, format, ldt.getHour(), ldt.getMinute(), ldt.getSecond(), loc.getLongitude(), loc.getLatitude(), loc.getAltitude(), loc.getSpeed(), loc.getAccuracy()); }
broadcastされたデータを受け取るのは簡単である。 位置情報取得サービスが自アプリに属しても、他アプリに属しても全く同じプログラムで受け取ることができる。 Manifestに記述するものは何もない。
public class MainActivity extends AppCompatActivity { TextView tvLocation; GPSReceiver mGPSReceiver; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); tvLocation = findViewById(R.id.txtTime); mGPSReceiver = new GPSReceiver(); IntentFilter filter = new IntentFilter(); filter.addAction("com.example.mapx.broadcast"); registerReceiver(mGPSReceiver, filter); } class GPSReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { Bundle extras = intent.getExtras(); String location = extras.getString("com.example.mapx.location"); tvLocation.setText(location); } } }