対処する必要がある項目は 3 つあります。
A. SMS をBroadcastReceiver
B.MapView
を使用して注釈を付けるItemizedOverlay
C. からBroadcastReceiver
マップを表示するアクティビティに更新を伝える
項目 A: SMS を受信
BroadcastReceiver
クラスを実装します。
public class SMSBroadcastReceiver extends BroadcastReceiver
{
private static final String SMS_RECEIVED = "android.provider.Telephony.SMS_RECEIVED";
@Override
public void onReceive(Context context, Intent intent)
{
if (intent.getAction().equals (SMS_RECEIVED))
{
Bundle bundle = intent.getExtras();
if (bundle != null)
{
Object[] pdusData = (Object[])bundle.get("pdus");
for (int i = 0; i < pdus.length; i++)
{
SmsMessage message = SmsMessage.createFromPdu((byte[])pdus[i]);
/* ... extract lat/long from SMS here */
}
}
}
}
}
アプリ マニフェストでブロードキャスト レシーバーを指定します。
<manifest ... >
<application ... >
<receiver
android:name=".SMSBroadcastReceiver"
android:enabled="true"
android:exported="true">
<intent-filter>
<action android:name="android.provider.Telephony.SMS_RECEIVED"></action>
</intent-filter>
</receiver>
</application>
</manifest>
(クレジットはこのスレッドのポスターに送られます: Android - SMS ブロードキャスト受信機)
項目 B: 地図に注釈を付ける
から派生したクラスを作成します。これは、表示する必要があるマーカーをItemizedOverlay
に通知するために使用されます。MapView
class LocationOverlay extends ItemizedOverlay<OverlayItem>
{
public LocationOverlay(Drawable marker)
{
/* Initialize this class with a suitable `Drawable` to use as a marker image */
super( boundCenterBottom(marker));
}
@Override
protected OverlayItem createItem(int itemNumber)
{
/* This method is called to query each overlay item. Change this method if
you have more than one marker */
GeoPoint point = /* ... the long/lat from the sms */
return new OverlayItem(point, null, null);
}
@Override
public int size()
{
/* Return the number of markers here */
return 1; // You only have one point to display
}
}
次に、実際の地図を表示するアクティビティにオーバーレイを組み込みます。
public class CustomMapActivity extends MapActivity
{
MapView map;
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
/* We're assuming you've set up your map as a resource */
map = (MapView)findViewById(R.id.map);
/* We'll create the custom ItemizedOverlay and add it to the map */
LocationOverlay overlay = new LocationOverlay(getResources().getDrawable(R.drawable.icon));
map.getOverlays().add(overlay);
}
}
項目 C: 最新情報を伝達する
これは最も難しい部分です ( BroadcastReceiver からのアクティビティの更新も参照してください)。アプリMapActivity
が現在表示されている場合は、新しく受信したマーカーを通知する必要があります。MapActivity
がアクティブでない場合、ユーザーがマップを表示することを選択するまで、受信したポイントをどこかに保存する必要があります。
プライベート インテントを定義します(CustomMapActivity
)。
private final String UPDATE_MAP = "com.myco.myapp.UPDATE_MAP"
プライベートを作成しますBroadcastReceiver
(でCustomMapActivity
):
private BroadcastReceiver updateReceiver = new BroadcastReceiver()
{
@Override
public void onReceive(Context context, Intent intent)
{
// custom fields where the marker location is stored
int longitude = intent.getIntExtra("long");
int latitude = intent.getIntExtra("lat");
// ... add the point to the `LocationOverlay` ...
// (You will need to modify `LocationOverlay` if you wish to track more
// than one location)
// Refresh the map
map.invalidate();
}
}
BroadcastReceiver
アクティビティが開始されたらプライベートを登録します(これを に追加しますCustomMapActivity.onCreate
):
IntentFilter filter = new IntentFilter();
filter.addAction(UPDATE_MAP);
registerReceiver(updateReceiver /* from step 2 */, filter);
プライベート インテントをパブリックから呼び出しますBroadcastReceiver
(これを に追加しますSMSBroadcastReceiver.onReceive
):
Intent updateIntent = new Intent();
updateIntent.setAction(UPDATE_MAP);
updateIntent.putExtra("long", longitude);
updateIntent.putExtra("lat", latitude);
context.sendBroadcast(updateIntent);