Android Google Maps Utility - onClusterClick causes NullPointerException error - android

Writing an app in Nativescript. The following setup works fine without errors:
// initialize cluster manager
dis.cluster_manager = new dis.clustering.ClusterManager(app.android.context, dis.gMap);
// Instantiate the cluster manager algorithm as is done in the ClusterManager, so we can access cluster items themselves, rather than cluster markers
dis.cluster_manager_algorithm = new dis.clustering.algo.NonHierarchicalDistanceBasedAlgorithm();
dis.cluster_manager.setAlgorithm(dis.cluster_manager_algorithm);
var CustomClusterRenderer = dis.clustering.view.DefaultClusterRenderer.extend({
//constructor
init: function () {},
onBeforeClusterItemRendered: function (item, markerOptions) {
console.log("onBeforeClusterItemRendered");
},
onBeforeClusterRendered: function (cluster, markerOptions) {
console.log("onBeforeClusterRendered!!!!!!!!!!");
}
});
dis.cluster_renderer = new CustomClusterRenderer(app.android.context, dis.gMap, dis.cluster_manager);
dis.cluster_renderer.setMinClusterSize(1);
dis.cluster_manager.setRenderer(dis.cluster_renderer);
dis.gMap.setOnCameraIdleListener(dis.cluster_manager);
// must be called after every unit add/remove
dis.cluster_manager.cluster();
Now, I want to listen to "on cluster clicks" and "on cluster item clicks". Adding the following:
dis.gMap.setOnMarkerClickListener(dis.cluster_manager);
dis.cluster_manager.setOnClusterClickListener(new dis.clustering.ClusterManager.OnClusterClickListener({
onClusterClick: function(cluster) {
console.log("onClusterClick");
}
}));
dis.cluster_manager.setOnClusterItemClickListener(new dis.clustering.ClusterManager.OnClusterItemClickListener({
onClusterItemClick: function(item) {
console.log("onClusterItemClick");
}
}));
It compiles and runs fine, that is, when I click on the cluster marker OR cluster item marker, I get the appropriate console.log, but immediately after the app crashes and I get this error:
java.lang.NullPointerException: Attempt to invoke virtual method
'boolean java.langBoolean.booleanValue()' on a null object reference
Any ideas?

Well great, 2 days wasted, was wondering why the hell does function in source has type boolean:
public interface OnClusterClickListener<T extends ClusterItem> {
public boolean onClusterClick(Cluster<T> cluster);
}
As it turns out, because it's expecting a boolean. No brainer...
dis.cluster_manager.setOnClusterClickListener(new dis.clustering.ClusterManager.OnClusterClickListener({
onClusterClick: function(cluster) {
console.log("onClusterClick");
return true;
}
}));

Related

On Android, how to check the phone screen is casting?

I need to check if the Android phone my app runs on is using casting which is enabled outside of my app.
It seems CastSession or SessionManager can provide the session related to my app which is not helpful for me.
For example, I can start casting with an app called xx which will cast or mirror the entire screen of my phone. Now, I need to notify when I open my app that the phone's screen is casting/mirroring so I can prevent showing specific content on my app.
I checked it with the code below:
val isCastingEnabledLiveData = MutableLiveData<Boolean>()
fun isCastingEnabled(context: Context): Boolean {
val mediaRouter = MediaRouter.getInstance(context)
if (mediaRouter.routes.size <= 1) {
isCastingEnabledLiveData.value = false
return
}
val selector = MediaRouteSelector.Builder()
.addControlCategory(MediaControlIntent.CATEGORY_LIVE_VIDEO)
.addControlCategory(MediaControlIntent.CATEGORY_REMOTE_PLAYBACK)
.build()
mediaRouter.addCallback(selector, object : MediaRouter.Callback() {
override fun onRouteChanged(router: MediaRouter?, route: MediaRouter.RouteInfo?) {
super.onRouteChanged(router, route)
isCastingEnabledLiveData.value = if (route != mediaRouter.defaultRoute) {
route?.connectionState != MediaRouter.RouteInfo.CONNECTION_STATE_DISCONNECTED
} else false
}
})
}
you can check whether the phone screen is casting or not by using the MediaRouter class.
Here is an example of how you could check if the phone screen is casting:
MediaRouter mediaRouter = (MediaRouter)
getSystemService(Context.MEDIA_ROUTER_SERVICE);
MediaRouter.RouteInfo route = mediaRouter.getSelectedRoute();
if(route.isDefault()){
// Screen is not casting
} else {
// Screen is casting
}
This code uses the getSelectedRoute() method of the MediaRouter class to get the currently selected route. If the returned RouteInfo object is the default route, then the screen is not casting, otherwise it is.
Please note that this code uses the getSystemService(Context.MEDIA_ROUTER_SERVICE) method to get an instance of the MediaRouter class, so it should be called from an Activity or Service context.
Additionally, you could also use MediaRouter.Callback and MediaRouter.addCallback to set a callback to monitor the state of the casting, so you could get the updates on the casting state change as well.

Reroute bannerinstruction while offroutelistener detected

I am overriding allowreroutefrom() function from routelistener to pick up my custom route when offroutelistener is detected. I am returning false and starting the new navigation with custom computed route. But I want to show the Rerouting bannerinstruction when reroute happens. How to give our own instruction in banner?
The InstructionView has showRerouteState() and hideRerouteState() methods that you can use:
#Override
public boolean allowRerouteFrom(Point offRoutePoint) {
// Fetch new route
InstructionView instructionView = findViewById(R.id.instructionView);
instructionView.showRerouteState();
return false;
}

info window not showing

This is really killing me, I had them working then rewrote a bunch of code, and now it doesn't and I've got no version control! Any help is appreciated.
I create the markers in a Utility class.
private static MarkerOptions buildAmarker(LatLng location, String bankType, String locationDetails,
float markerColour) {
MarkerOptions binMarker = new MarkerOptions().position(location).title(bankType)
.snippet(locationDetails)
.icon(BitmapDescriptorFactory.defaultMarker(markerColour));
//.snippet(siteName + " | " + locationDetails);
return binMarker;enter code here
Then after my Loader completes, onLoadFinish, it hands me back various list of marker Options objects, I process them into Markers here:
private List<Marker> addBankListToMap(List<MarkerOptions> oneBankList) {
Log.i("ADDING a selected", "banks list to map");
// we need to save NEW lists of map attached markers OR can't change marker visibility
List<Marker> newBankList = new ArrayList<>();
for (int i = 0; i < oneBankList.size(); i++) {
MarkerOptions binMarker = oneBankList.get(i);
Marker newMarker = m_map.addMarker(binMarker);
newMarker.setVisible(true);
newBankList.add(newMarker);
//Log.e("!!!addingBank", newMarker.getTitle() + newMarker.getSnippet());
}
return newBankList;
Then end onLoadFinish with this
// setup click event for home marker to launch change home screen
m_map.setOnMarkerClickListener(EarthquakeActivity.this);
But none of the info windows appear if clicked. What am I missing? It was working till I rewrote my code, and I made a LOT of algorthmic improvements, I use arrays instead of half a dozen hashmaps, so the memory overhead should be less.
I can only think I've either deleted something crucial in a tidy up while being tired.
OR
I've blocked the info windows somehow. Some sleuthing to find the block, by disabling the changes, has failed. So it seems I've deleted something, forgotten something vital.
What do I need to do to get infoWindows working again? This is absolutely vital to my app. Arrggg!
#Override
public boolean onMarkerClick(Marker marker) {
if (marker.equals(homeMarkerFinal)) {
// TODO make this launch the change home address screen
Log.wtf("markerClicked", "!!!!");
Intent settingsIntent = new Intent(EarthquakeActivity.this, SettingsActivity.class);
startActivity(settingsIntent);
}
return true;
}
This is just for a single marker, the home marker. All the other markers are unnamed, I've got around 4000 markers stored in Lists as MarkerOptions. These lists are passed to addBankListToMap as oneBankList and converted into Markers, and attached to the map.
To show inforwindow you need call:
marker.showInfoWindow();
Pls put in in your onMarkerClick function.
Brilliant phongvan!, of course at some point I deleted this
else {
marker.showInfoWindow();
}
onMarkerClick.
Thankgod! My app had become useless! :) A thousand thanks phongvan.

Unable to find the error in logcat

I am unable to find the error in my android application. I have read guides on how to read logcat errors but the problem with my error is that it is not from my classes. Could someone give me some idea on how I could debug this?
I have a two spinners in my layout. One of which has an string array fixed for its list of items inside. The other spinner's items are generated dynamically with some code. The program actually runs fine on the emulator. But when I run on my device, a toggle button which doesnt uses the spinner crashes the application. If there is any more detail or information that I need to share to debug, do let me know.
Sorry I did post the logcat but the image disappeared. The complete logcat is below now.
And here is the toggle button which crashed the application when pressed.
public void onToggleClicked(View view) {
Context context = getApplicationContext();
if (checkConnectivity()) {
// Is the toggle on?
boolean on = tglbtn.isChecked();
if (on) {
startRepeatingTask();
} else {
stopRepeatingTask();
}
}
else {
Toast.makeText(context, "Please check your internet connection.", Toast.LENGTH_LONG).show();
}
}
These are the two methods....
Runnable mStatusChecker = new Runnable() {
#Override
public void run() {
//updateStatus(); //this function can change value of mInterval.
new updateBuses().execute();
mHandler.postDelayed(mStatusChecker, mInterval);
}
};
void startRepeatingTask() {
mStatusChecker.run();
}
void stopRepeatingTask() {
mHandler.removeCallbacks(mStatusChecker);
}
The updateBuses class is an Asynctask which has nothing to do with my spinners. This is the method which populates my spinner.
private void plotBuses(ArrayList<MyMarker> markers) {
Log.d("Checking Array", mMyMarkersArray.toString());
if(markers.size() > 0)
{
for (MyMarker myMarker : markers)
{
// Create bus marker with custom icon and other options
Log.d("plotting", myMarker.getmLabel());
MarkerOptions markerOption = new MarkerOptions().position(new LatLng(myMarker.getmLatitude(), myMarker.getmLongitude()));
markerOption.title(myMarker.getmLabel());
markerOption.icon(BitmapDescriptorFactory.fromResource(R.drawable.ic_bus));
Marker currentMarker = map.addMarker(markerOption);
mMarkersHashMap.put(currentMarker, myMarker);
}
Log.d("check hashmap:", mMarkersHashMap.toString());
ArrayAdapter<String> dataAdapter = new ArrayAdapter<String>
(this, android.R.layout.simple_spinner_item,spinnerList);
dataAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
spinner1.setAdapter(dataAdapter);
}
}
The spinnerList is not null because my spinner populates with the items inside my spinner.
According to documentation the purpose of the method makeAndAddView() that throws NullPointerException:
Obtain a view, either by pulling an existing view from the recycler or by getting a new one from the adapter.
This method tries to get the View by accessing adapter that is bound to this Spinner.
P.S.
What API version do you use during building? What are the AVD and actual phone Android versions you are testing on?

android usage of "controller.query(activity);" in scoreloop

i am attempting to implement a built in controller that is part of the scoreloop library. the documentation states:
Basic Usage:
To invoke the TOS dialog if it was not accepted previously, the following code may be used:
final TermsOfServiceController controller = new TermsOfServiceController(new TermsOfServiceControllerObserver() {
#Override
public void termsOfServiceControllerDidFinish(final TermsOfServiceController controller, final Boolean accepted) {
if(accepted != null) {
// we have conclusive result.
if(accepted) {
// user did accept
}
else {
// user did reject
}
}
}
});
controller.query(activity);
but when i paste this into my code i get the following syntax errors:
am i using this incorrectly? how and where would this be used any ideas?
EDIT: after moving the statement to the method where i want to show the dialog i now get the following error:
You seem to be calling controller.query(activity) in a class body where a declaration is expected. Move the statement controller.query(activity) to a method where you would like to show the dialog.

Categories

Resources