我是android和java的新手。我正在尝试制作一个应用程序来执行以下任务。
- 接收传入的短信(其中将包含纬度和经度信息)
- 用标记在地图上显示它们所以每次收到短信时,地图都应该有一个新的标记。
目前我有一张可以显示一个点的地图,并且我已经实现了一个广播接收器来从 SMS 中获取纬度和经度。
但我不确定如何在接收到新短信时从广播接收器更新地图。
任何帮助或提示都会很有用。
谢谢
我是android和java的新手。我正在尝试制作一个应用程序来执行以下任务。
目前我有一张可以显示一个点的地图,并且我已经实现了一个广播接收器来从 SMS 中获取纬度和经度。
但我不确定如何在接收到新短信时从广播接收器更新地图。
任何帮助或提示都会很有用。
谢谢
您需要解决 3 个问题:
A. 通过 a 接收短信BroadcastReceiver
B.MapView
使用 an注释 aItemizedOverlay
BroadcastReceiver
C.向显示地图的活动传达更新
实现你的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 广播接收器)
创建一个派生自 的类ItemizedOverlay
,用于通知 aMapView
需要显示的任何标记:
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);
}
}
这是最棘手的部分(另请参阅从 BroadcastReceiver 更新活动)。如果应用程序MapActivity
当前可见,则需要通知它新收到的标记。如果MapActivity
未激活,则需要将任何接收到的点存储在某处,直到用户选择查看地图。
定义私有意图(in CustomMapActivity
):
private final String UPDATE_MAP = "com.myco.myapp.UPDATE_MAP"
创建私有BroadcastReceiver
(in 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);
听起来您正在寻找有关如何在 Activity 和 BroadcastReceiver 之间进行通信的详细信息?一种方法(有许多不同的方法)是让您的地图活动注册一个临时广播接收器,该广播接收器设置为仅收听来自您的应用程序的私人广播,然后让您的 SMS 广播接收器生成一个新的广播,其纬度/经度来自短信。在您的地图活动中,您的接收器每次收到新的私人广播时都会向地图添加一个新点。