从广播短信接收器更新谷歌地图标记

时间:2012-04-18 19:01:56

标签: android android-layout android-intent google-maps-api-3 mapactivity

我是android和java的新手。我正在尝试使应用程序执行以下任务。

  • 接收传入的短信(具有纬度和经度信息)
  • 使用标记在地图上显示它们 所以每次短信来到地图都会得到一个新的标记。

目前我有一张地图,我可以展示一个点,我已经实现了一个广播接收器,以获得短信和经度形式的短信。

但我不确定如何在接收新短信时从广播接收器更新地图。

任何帮助或提示都会有用。

谢谢

2 个答案:

答案 0 :(得分:5)

您需要解决3个问题:

一个。通过BroadcastReceiver

接收短信

B中。使用MapView

注释ItemizedOverlay

℃。将更新从BroadcastReceiver传达给显示地图的活动

项目A:接收短信

  1. 实施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 */
                    }
                }
            }
        }
    }
    
  2. 在应用清单中指定您的广播接收器:

    <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>
    
  3. (积分转到此主题中的海报:Android - SMS Broadcast receiver

    项目B:注释地图

    1. 创建一个派生自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
         } 
      }
      
    2. 现在,将叠加层合并到一个显示实际地图的活动中:

      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);
              }
      }
      
    3. 项目C:传达更新

      这是最棘手的部分(另见Updating an Activity from a BroadcastReceiver)。如果应用的MapActivity当前可见,则需要通知新接收的标记。如果MapActivity未激活,则任何收到的点都需要存储在某处,直到用户选择查看地图为止。

      1. 定义私人意图(在CustomMapActivity中):

        private final String UPDATE_MAP = "com.myco.myapp.UPDATE_MAP"
        
      2. 创建私人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();
            }
        }
        
      3. 在活动开始时注册您的私人BroadcastReceiver(将其添加到CustomMapActivity.onCreate):

        IntentFilter filter = new IntentFilter();
        filter.addAction(UPDATE_MAP);
        registerReceiver(updateReceiver /* from step 2 */, filter);
        
      4. 从公众BroadcastReceiver调用您的私人意图(将其添加到SMSBroadcastReceiver.onReceive):

        Intent updateIntent = new Intent();
        updateIntent.setAction(UPDATE_MAP);
        updateIntent.putExtra("long", longitude);
        updateIntent.putExtra("lat", latitude);
        context.sendBroadcast(updateIntent);
        

答案 1 :(得分:4)

听起来您正在寻找有关如何在Activity和BroadcastReceiver之间进行通信的详细信息?一种方法(有许多不同的方法)是让你的地图活动注册一个临时的BroadcastReceiver,它被设置为只收听你应用中的私人广播,然后让你的短信广播接收器生成一个新的广播,其纬度/经度来自短信。在地图活动中,您的接收器每次收到新的私人广播时都会向地图添加一个新点。