从 GCM 推送通知打开地图 Activity
Open Map Activity from GCM Push Notification
我正在尝试打开一个名为 'MapActivity' 的特定 activity,我想在其中加载我在地图上的当前位置并获取附近的地点。我让它工作了,还让 GCM 工作以将推送通知发送到我的设备 (Android 4.3)。剩下的唯一问题是打开我想要的activity,每次我点击消息都会出错。
这是我要加载的activity:
public class MapActivity extends FragmentActivity implements LocationListener {
private ProgressDialog pDialog, wDialog;
//private static String dataUrl = "https://maps.googleapis.com/maps/api/place/nearbysearch/json?location=-7.288804,%20112.814649&radius=5000&types=hospital&key=AIzaSyDuc4ab9iT7VPSZMCdKI416yQOeLprV5ME";
private String API_KEY = "###MYAPIKEY###";
private String PLACES_TYPE = "hospital";
private String RADIUS = "5000";
private static final int MAX_PLACES = 20;
private static final String TAG_RESULTS = "results";
private static final String TAG_GEOMETRY = "geometry";
private static final String TAG_LOCATION = "location";
private static final String TAG_LAT = "lat";
private static final String TAG_LNG = "lng";
private static final String TAG_ID = "id";
private static final String TAG_NAME = "name";
private static final String TAG_VICINITY = "vicinity";
private GoogleMap mMap;
protected LocationManager locationManager;
protected android.location.LocationListener locationListener;
protected Context context;
JSONArray tagResults = null;
ArrayList<HashMap<String,String>> hospitalList;
protected double currLat, currLng;
Location currLocation;
LatLng currLatLng;
private boolean alreadySet = false;
public void onProviderDisabled(String provider){
Log.d("Latitude", "disable");
}
public void onProviderEnabled(String provider){
Log.d("Latitude","enable");
}
public void onStatusChanged(String provider, int status, Bundle extras){
Log.d("Latitude", "status");
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_map);
hospitalList = new ArrayList<HashMap<String,String>>();
locationManager = (LocationManager)getSystemService(Context.LOCATION_SERVICE);
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, (android.location.LocationListener) this);
new GetPlaces().execute();
}
@Override
public void onLocationChanged(Location location) {
if(alreadySet == false) {
alreadySet = true;
currLat = location.getLatitude();
currLng = location.getLongitude();
currLocation = new Location("Current Location");
currLocation.setLatitude(location.getLatitude());
currLocation.setLongitude(location.getLongitude());
currLatLng = new LatLng(currLocation.getLatitude(),currLocation.getLongitude());
}
}
private class GetPlaces extends AsyncTask<Void,Void,Void> {
@Override
protected void onPreExecute(){
super.onPreExecute();
pDialog = new ProgressDialog(MapActivity.this);
pDialog.setMessage("Please wait...");
pDialog.setCancelable(false);
pDialog.show();
}
@Override
protected Void doInBackground(Void... arg0) {
while ( currLocation == null ) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
String api_address = "https://maps.googleapis.com/maps/api/place/nearbysearch/json?";
String api_lat = Double.toString(currLocation.getLatitude());
String api_lng = Double.toString(currLocation.getLongitude());
String param_location = "location=" + api_lat + "," + api_lng;
String param_radius = "&radius=5000";
String param_types = "&types=hospital";
String param_key = "&key=AIzaSyDuc4ab9iT7VPSZMCdKI416yQOeLprV5ME";
String apiURL = api_address + param_location + param_radius + param_types + param_key;
ServiceHandler serviceHandler = new ServiceHandler();
String jsonResponse = serviceHandler.makeServiceCall(apiURL,ServiceHandler.GET);
Log.d("Response: ", "> " + jsonResponse);
if(jsonResponse!=null) {
try {
JSONObject jsonObj = new JSONObject(jsonResponse);
tagResults = jsonObj.getJSONArray(TAG_RESULTS);
for(int i=0; i<tagResults.length(); i++) {
JSONObject resultObj = tagResults.getJSONObject(i);
String id = resultObj.getString(TAG_ID);
String name = resultObj.getString(TAG_NAME);
String vicinity = resultObj.getString(TAG_VICINITY);
JSONObject geometryObj = resultObj.getJSONObject(TAG_GEOMETRY);
JSONObject locationObj = geometryObj.getJSONObject(TAG_LOCATION);
String lat = locationObj.getString(TAG_LAT);
String lng = locationObj.getString(TAG_LNG);
HashMap<String, String> hospital = new HashMap<String, String>();
hospital.put(TAG_ID, id);
hospital.put(TAG_NAME, name);
hospital.put(TAG_VICINITY, vicinity);
hospital.put(TAG_LAT, lat);
hospital.put(TAG_LNG, lng);
hospitalList.add(hospital);
}
} catch (JSONException e) {
e.printStackTrace();
}
} else {
Log.e("ServiceHandler", "Couldn't get any data from the url");
}
return null;
}
protected void onPostExecute(Void result) {
super.onPostExecute(result);
if(pDialog.isShowing()) {
pDialog.dismiss();
}
if (mMap == null) {
mMap = ((SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map))
.getMap();
if (mMap != null) {
for(int i=0; i<MAX_PLACES; i++)
{
mMap.addMarker(new MarkerOptions()
.position(currLatLng)
.title("You are here now.")
.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_AZURE))
);
mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(currLatLng, 14));
mMap.addMarker(new MarkerOptions()
.position(new LatLng(Float.parseFloat(hospitalList.get(i).get(TAG_LAT)), Float.parseFloat(hospitalList.get(i).get(TAG_LNG))))
.title(hospitalList.get(i).get(TAG_NAME))
.snippet(hospitalList.get(i).get(TAG_VICINITY))
);
}
}
}
}
}
}
这是我用来在 MyGCMListernerService.java
上发送通知的函数
public class MyGcmListenerService extends GcmListenerService {
private static final String TAG = "MyGcmListenerService";
/**
* Called when message is received.
*
* @param from SenderID of the sender.
* @param data Data bundle containing message data as key/value pairs.
* For Set of keys use data.keySet().
*/
// [START receive_message]
@Override
public void onMessageReceived(String from, Bundle data) {
String message = data.getString("message");
Log.d(TAG, "DATA: " + data);
Log.d(TAG, "From: " + from);
Log.d(TAG, "Message: " + message);
/**
* Production applications would usually process the message here.
* Eg: - Syncing with server.
* - Store message in local database.
* - Update UI.
*/
/**
* In some cases it may be useful to show a notification indicating to the user
* that a message was received.
*/
sendNotification(message);
}
// [END receive_message]
/**
* Create and show a simple notification containing the received GCM message.
*
* @param message GCM message received.
*/
private void sendNotification(String message) {
Intent intent = new Intent(this, MapActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0 /* Request code */, intent, 0);
Log.i(TAG, "GCM Message: " + message);
Uri defaultSoundUri= RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this)
.setSmallIcon(R.drawable.ic_stat_ic_notification)
.setContentTitle("GCM Message")
.setStyle(new NotificationCompat.BigTextStyle().bigText(message))
.setContentText(message)
.setSound(defaultSoundUri)
.setContentIntent(pendingIntent);
NotificationManager notificationManager =
(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(0 /* ID of notification */, notificationBuilder.build());
}
}
我尝试像这样设置 Intent,但它没有用,显示它正在打开 activity,但随后它说应用程序已关闭。
Intent notificationIntent = new Intent(context, MapActivity.class);
PendingIntent intent = PendingIntent.getActivity(context, 0, notificationIntent, 0)
是否有人愿意帮助指出我的代码中的错误以及我应该如何修复它?非常感谢。
************************ 编辑 ******************** *****
我试着打开一个空的 activity 并且成功了。我想知道我的地图 Activity 是否有问题?如果它用于独立应用程序,它仍然可以完美运行。
我试图再次创建一个新的空白 activity,并将我所有的地图Activity 代码粘贴到其中,现在我收到这样的错误:
java.lang.RuntimeException: Unable to start activity ComponentInfo{gcm.play.android.samples.com.gcmquickstart/gcm.play.android.samples.com.gcmquickstart.MainActivity2Activity}: java.lang.ClassCastException: gcm.play.android.samples.com.gcmquickstart.MainActivity2Activity cannot be cast to android.location.LocationListener
它指向这一行
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, (android.location.LocationListener) this);
MapActivity 由 Fragment Activity 扩展,在其中您正在打开 Map 即也在片段内部打开,因此您无法在意图的帮助下直接调用 map 。
你可以这样做:
((MyFragmentActivity) getActivity()).replaceFragments();
然后在片段 activity 中替换该片段。
我正在尝试打开一个名为 'MapActivity' 的特定 activity,我想在其中加载我在地图上的当前位置并获取附近的地点。我让它工作了,还让 GCM 工作以将推送通知发送到我的设备 (Android 4.3)。剩下的唯一问题是打开我想要的activity,每次我点击消息都会出错。
这是我要加载的activity:
public class MapActivity extends FragmentActivity implements LocationListener {
private ProgressDialog pDialog, wDialog;
//private static String dataUrl = "https://maps.googleapis.com/maps/api/place/nearbysearch/json?location=-7.288804,%20112.814649&radius=5000&types=hospital&key=AIzaSyDuc4ab9iT7VPSZMCdKI416yQOeLprV5ME";
private String API_KEY = "###MYAPIKEY###";
private String PLACES_TYPE = "hospital";
private String RADIUS = "5000";
private static final int MAX_PLACES = 20;
private static final String TAG_RESULTS = "results";
private static final String TAG_GEOMETRY = "geometry";
private static final String TAG_LOCATION = "location";
private static final String TAG_LAT = "lat";
private static final String TAG_LNG = "lng";
private static final String TAG_ID = "id";
private static final String TAG_NAME = "name";
private static final String TAG_VICINITY = "vicinity";
private GoogleMap mMap;
protected LocationManager locationManager;
protected android.location.LocationListener locationListener;
protected Context context;
JSONArray tagResults = null;
ArrayList<HashMap<String,String>> hospitalList;
protected double currLat, currLng;
Location currLocation;
LatLng currLatLng;
private boolean alreadySet = false;
public void onProviderDisabled(String provider){
Log.d("Latitude", "disable");
}
public void onProviderEnabled(String provider){
Log.d("Latitude","enable");
}
public void onStatusChanged(String provider, int status, Bundle extras){
Log.d("Latitude", "status");
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_map);
hospitalList = new ArrayList<HashMap<String,String>>();
locationManager = (LocationManager)getSystemService(Context.LOCATION_SERVICE);
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, (android.location.LocationListener) this);
new GetPlaces().execute();
}
@Override
public void onLocationChanged(Location location) {
if(alreadySet == false) {
alreadySet = true;
currLat = location.getLatitude();
currLng = location.getLongitude();
currLocation = new Location("Current Location");
currLocation.setLatitude(location.getLatitude());
currLocation.setLongitude(location.getLongitude());
currLatLng = new LatLng(currLocation.getLatitude(),currLocation.getLongitude());
}
}
private class GetPlaces extends AsyncTask<Void,Void,Void> {
@Override
protected void onPreExecute(){
super.onPreExecute();
pDialog = new ProgressDialog(MapActivity.this);
pDialog.setMessage("Please wait...");
pDialog.setCancelable(false);
pDialog.show();
}
@Override
protected Void doInBackground(Void... arg0) {
while ( currLocation == null ) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
String api_address = "https://maps.googleapis.com/maps/api/place/nearbysearch/json?";
String api_lat = Double.toString(currLocation.getLatitude());
String api_lng = Double.toString(currLocation.getLongitude());
String param_location = "location=" + api_lat + "," + api_lng;
String param_radius = "&radius=5000";
String param_types = "&types=hospital";
String param_key = "&key=AIzaSyDuc4ab9iT7VPSZMCdKI416yQOeLprV5ME";
String apiURL = api_address + param_location + param_radius + param_types + param_key;
ServiceHandler serviceHandler = new ServiceHandler();
String jsonResponse = serviceHandler.makeServiceCall(apiURL,ServiceHandler.GET);
Log.d("Response: ", "> " + jsonResponse);
if(jsonResponse!=null) {
try {
JSONObject jsonObj = new JSONObject(jsonResponse);
tagResults = jsonObj.getJSONArray(TAG_RESULTS);
for(int i=0; i<tagResults.length(); i++) {
JSONObject resultObj = tagResults.getJSONObject(i);
String id = resultObj.getString(TAG_ID);
String name = resultObj.getString(TAG_NAME);
String vicinity = resultObj.getString(TAG_VICINITY);
JSONObject geometryObj = resultObj.getJSONObject(TAG_GEOMETRY);
JSONObject locationObj = geometryObj.getJSONObject(TAG_LOCATION);
String lat = locationObj.getString(TAG_LAT);
String lng = locationObj.getString(TAG_LNG);
HashMap<String, String> hospital = new HashMap<String, String>();
hospital.put(TAG_ID, id);
hospital.put(TAG_NAME, name);
hospital.put(TAG_VICINITY, vicinity);
hospital.put(TAG_LAT, lat);
hospital.put(TAG_LNG, lng);
hospitalList.add(hospital);
}
} catch (JSONException e) {
e.printStackTrace();
}
} else {
Log.e("ServiceHandler", "Couldn't get any data from the url");
}
return null;
}
protected void onPostExecute(Void result) {
super.onPostExecute(result);
if(pDialog.isShowing()) {
pDialog.dismiss();
}
if (mMap == null) {
mMap = ((SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map))
.getMap();
if (mMap != null) {
for(int i=0; i<MAX_PLACES; i++)
{
mMap.addMarker(new MarkerOptions()
.position(currLatLng)
.title("You are here now.")
.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_AZURE))
);
mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(currLatLng, 14));
mMap.addMarker(new MarkerOptions()
.position(new LatLng(Float.parseFloat(hospitalList.get(i).get(TAG_LAT)), Float.parseFloat(hospitalList.get(i).get(TAG_LNG))))
.title(hospitalList.get(i).get(TAG_NAME))
.snippet(hospitalList.get(i).get(TAG_VICINITY))
);
}
}
}
}
}
}
这是我用来在 MyGCMListernerService.java
上发送通知的函数public class MyGcmListenerService extends GcmListenerService {
private static final String TAG = "MyGcmListenerService";
/**
* Called when message is received.
*
* @param from SenderID of the sender.
* @param data Data bundle containing message data as key/value pairs.
* For Set of keys use data.keySet().
*/
// [START receive_message]
@Override
public void onMessageReceived(String from, Bundle data) {
String message = data.getString("message");
Log.d(TAG, "DATA: " + data);
Log.d(TAG, "From: " + from);
Log.d(TAG, "Message: " + message);
/**
* Production applications would usually process the message here.
* Eg: - Syncing with server.
* - Store message in local database.
* - Update UI.
*/
/**
* In some cases it may be useful to show a notification indicating to the user
* that a message was received.
*/
sendNotification(message);
}
// [END receive_message]
/**
* Create and show a simple notification containing the received GCM message.
*
* @param message GCM message received.
*/
private void sendNotification(String message) {
Intent intent = new Intent(this, MapActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0 /* Request code */, intent, 0);
Log.i(TAG, "GCM Message: " + message);
Uri defaultSoundUri= RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this)
.setSmallIcon(R.drawable.ic_stat_ic_notification)
.setContentTitle("GCM Message")
.setStyle(new NotificationCompat.BigTextStyle().bigText(message))
.setContentText(message)
.setSound(defaultSoundUri)
.setContentIntent(pendingIntent);
NotificationManager notificationManager =
(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(0 /* ID of notification */, notificationBuilder.build());
}
}
我尝试像这样设置 Intent,但它没有用,显示它正在打开 activity,但随后它说应用程序已关闭。
Intent notificationIntent = new Intent(context, MapActivity.class);
PendingIntent intent = PendingIntent.getActivity(context, 0, notificationIntent, 0)
是否有人愿意帮助指出我的代码中的错误以及我应该如何修复它?非常感谢。
************************ 编辑 ******************** *****
我试着打开一个空的 activity 并且成功了。我想知道我的地图 Activity 是否有问题?如果它用于独立应用程序,它仍然可以完美运行。
我试图再次创建一个新的空白 activity,并将我所有的地图Activity 代码粘贴到其中,现在我收到这样的错误:
java.lang.RuntimeException: Unable to start activity ComponentInfo{gcm.play.android.samples.com.gcmquickstart/gcm.play.android.samples.com.gcmquickstart.MainActivity2Activity}: java.lang.ClassCastException: gcm.play.android.samples.com.gcmquickstart.MainActivity2Activity cannot be cast to android.location.LocationListener
它指向这一行
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, (android.location.LocationListener) this);
MapActivity 由 Fragment Activity 扩展,在其中您正在打开 Map 即也在片段内部打开,因此您无法在意图的帮助下直接调用 map 。 你可以这样做: ((MyFragmentActivity) getActivity()).replaceFragments(); 然后在片段 activity 中替换该片段。