Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
370 views
in Technique[技术] by (71.8m points)

android - updating google maps marker from a broadcast sms receiver

I am a newbie to android and java. I am trying to make an application to perform following task.

  • receive incoming sms (which will have latitude and longitude information)
  • show them on map with markers So every time an sms comes map should get a new marker.

currently I have a map where I can show a point and I have implemented a broadcast receiver to get lattitude and longitude form SMS.

But I am unsure how to update the map from broadcast receiver on receiving a new sms.

Any help or tips will be useful.

Thank you

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

There are 3 items you need to address:

A. Receive an SMS via a BroadcastReceiver

B. Annotating a MapView using an ItemizedOverlay

C. Communicate the updates from the BroadcastReceiver to the activity showing the map

Item A: Receive SMS

  1. Implement your BroadcastReceiver class:

    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. Specify your broadcast receiver in the app manifest:

    <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>
    

(Credits go to the posters in this thread: Android - SMS Broadcast receiver)

Item B: Annotate the Map

  1. Create a class derived from ItemizedOverlay, which is used to inform a MapView of any markers which need to be displayed:

    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. Now, incorporate the overlay into an activity that displays the actual map:

    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);
            }
    }
    

Item C: Communicate the updates

This is the trickiest part (see also Updating an Activity from a BroadcastReceiver). If the app's MapActivity is currently visible, it needs to be notified of the newly received markers. If the MapActivity isn't active, any received points need to be stored somewhere until the user chooses to view the map.

  1. Define the private intent (in CustomMapActivity):

    private final String UPDATE_MAP = "com.myco.myapp.UPDATE_MAP"
    
  2. Create the private 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();
        }
    }
    
  3. Register your private BroadcastReceiver when the activity is started (add this to CustomMapActivity.onCreate):

    IntentFilter filter = new IntentFilter();
    filter.addAction(UPDATE_MAP);
    registerReceiver(updateReceiver /* from step 2 */, filter);
    
  4. Invoke your private intent from the public BroadcastReceiver (add this to SMSBroadcastReceiver.onReceive):

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

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...