GeotriggerHandlerReceiver is deprecated in PlotProjects. What is the alternative to use? - java

I see in the documentation of Plot Project that GeotriggerHandlerReceiver should be used, but according to Android Studio for the version com.plotprojects:plot-android:2.4.0-beta this Receiver is already deprecated.
Image from Android Studio
3.5 Geotrigger handler
When you want to handle your geotriggers, or use them as trigger events for your own code, you can use the geotrigger handler. Plot automatically detects whether a service is registered in AndroidManifest.xml that extends from the class GeotriggerHandlerReceiver. Implementations of GeotriggerHandlerReceiver must implement the method public List handleGeotriggers(List geotriggers). When the service is defined, Plot will send the geotriggers to this method before considering them as handled. This allows you to add custom code that is triggered by entering (or exiting) a geofence or beacon region.
//Example implementation for handleGeotriggers:
public class MyGeotriggerHandlerReceiver extends GeotriggerHandlerReceiver {
#Override
public List<Geotrigger> handleGeotriggers(List<Geotrigger> geotriggers) {
List<Geotrigger> passedGeotriggers = new ArrayList<Geotrigger>();
for (Geotrigger geotrigger : geotriggers) {
String data = geotrigger.getData();
if (data.equals("pass")) {
passedGeotriggers.add(geotrigger);
}
}
return passedGeotriggers;
}
}

Indeed we're deprecating the GeotriggerHandlerReceiver and will remove it in the next version. In order to maintain your code up to date follow this guide. The guide explains why and how to do this.
We're in the process of updating our documentation to make it more organised and complete.
Cheers!

Related

Change the name of duplicated events in #region "Event implementation for <interface>" for Xamarin Android Binding library

I'm attempting to create a Xamarin Binding Library for the Android UseButton library. I created my binding project, included the .aar and set Build Action = LibraryProjectZip. As was expected, a bunch of errors popped up and I've managed to get rid of most using the Metadata.xml file, except for a bunch that follow the same pattern:
Error CS0102 The type 'CrossBridgeCommunicator' already contains a definition for 'WebViewDismiss'
I checked the CrossBridgeCommunicator class, and found it has 2 copies of about 12 events. Here's a snippet of one of these duplicates
#region "Event implementation for Com.Usebutton.Sdk.Internal.Bridge.BridgeMessageParser.IListener"
...
public event EventHandler WebViewDismiss {
add {
global::Java.Interop.EventHelper.AddEventHandler<global::Com.Usebutton.Sdk.Internal.Bridge.BridgeMessageParser.IListener, global::Com.Usebutton.Sdk.Internal.Bridge.BridgeMessageParser.IListenerImplementor>(
ref weak_implementor___SetMainBridge,
__CreateIListenerImplementor,
__v => MainBridge = __v,
__h => __h.OnWebViewDismissHandler += value);
}
...
}
...
public event EventHandler WebViewDismiss {
add {
global::Java.Interop.EventHelper.AddEventHandler<global::Com.Usebutton.Sdk.Internal.Bridge.BridgeMessageParser.IListener, global::Com.Usebutton.Sdk.Internal.Bridge.BridgeMessageParser.IListenerImplementor>(
ref weak_implementor___SetWidgetBridge,
__CreateIListenerImplementor,
__v => WidgetBridge = __v,
__h => __h.OnWebViewDismissHandler += value);
}
...
}
The only difference between them is that they access different attributes in their bodies (the "weak_implementor__"). I checked the original class in a Java decompiler and it doesn't implement any of these events; in fact, it doesn't even implement the interface. What it does have are 2 fields of this interface type. I'm guessing Xamarin creates these methods for some reason, but I don't know why or how. They don't even appear on the api.xml (nor do the fields).
I tried to change the name of the events using the Metadata.xml file, but, since these events don't even exist in the Java class, I don't know how to find them. I even tried to remove the fields using "remove-node", but am getting the warning no nodes matched. Does anyone know how can I change these events' names? Again, they come from the same interface, but are created directly on the class that has 2 fields of the interface type.
Thanks in advance.

Is it possible to create necessary / required interfaces?

i have a little kont in my brain about structuring our code. We have a REST Backend based on SpringBoot. To handle requests regarding to security checks we use HandlerInterceptors. In some specific cases we need a specific interceptor and not our default one. The default one is registered in a 3rd party lib that no one can forget it. But i want all coders to think about this specific interceptor.
Actually, i just said it to them to achieve this.
Here's my question: Is there an option to create required (or necessary) interfaces which must be implemented? This would be a way to provide our security code by lib and to have the security that every coder implemented our specific interface (also if he just does nothing with it).
pseudo code:
public interface thinkForIt(){
Object SecBean specificSecBean;
public void methodToThinkOn();
}
public SecImpl implements thinkForIt(){
#Override
public void methodToThinkOn(){
return null; // i thought about it but i do not need to do anyting!
}
If the interface thinkForIt would have any annotations like #required, users could get warning or error if they did not implement it...
Looking for a solution and thanks for your comments in advance!
Your overall design is questionable; you are reinventing security code, which is always a red flag. Use Spring Security instead.
However, there's a simple way to ensure that "some bean of type Foo" has been registered with the context:
#Component
#RequiredArgsConstructor
public class ContextConfigurationVerifier {
final Foo required;
}

Cannot override Java function in Kotlin

I am currently developing a BLE-enabled Android app targeting API 27 using Kotlin.
I am attempting to override a function within android.bluetooth.BluetoothGatt. There are a number of callbacks available to be overridden to enable the handling of certain BLE events.
For example, I override onConnectionStateChange() in the following way:
private val bluetoothGattCallback = object : BluetoothGattCallback() {
override fun onConnectionStateChange(gatt: BluetoothGatt, status: Int, newState: Int) {
/* do stuff */
}
This works just fine.
My issue stems from trying to override onConnectionUpdated(). This callback is defined in the same way as onConnectionStateChange() in the BLE API source, so how come I can't override it? This is how I am attempting to override it (still within the BluetoothGattCallback() object):
fun onConnectionUpdated(gatt: BluetoothGatt, interval: Int, latency: Int, timeout: Int, status: Int) {
/* do stuff */
}
EDIT: I forgot to mention that, when I add the override keyword it provides the error message: OnConnectionUpdated overrides nothing..
Forgive my naivety, I don't often work with Kotlin/Java, thanks.
You should not use this method, it is only for internal use and not part of the public API. Therefore it is hidden via #hide. For more information about #hide and how to access it regardless see What does #hide mean in the Android source code?
Note that using reflection to access it as described in the link above is discouraged
The method you want to use is on the dark-greylist with the following restrictions:
dark-greylist:
For apps whose target SDK is below API level 28: each use of a dark
greylist interface is permitted.
apps whose target SDK is API level 28 or higher: same behavior as blacklist
blacklist: restricted regardless of target SDK. The platform will behave as if the interface is absent. For example, it will throw NoSuchMethodError/NoSuchFieldException whenever the app is trying to use it, and will not include it when the app wants to know the list of fields/methods of a particular class.

How to access the Impl classes of Twitter4J?

Using MongoDB, I need to persist objects from Twitter4J. Twitter4J uses interfaces, which are implemented in JSON versions. Example:
The API returns Status (an interface), and Status is implemented as StatusJSONImpl.
I can't save Status to MongoDB, I need to implement StatusJSONImpl.
My issue is, this class StatusJSONImpl is not public (see here) so I can't use it in my code. I tried to download the source of Twitter4J to manually add "public" to StatusJSONImpl: I can do:
Status status = twitter.updateStatus(latestStatus);
String statusStringified = TwitterObjectFactory.getRawJSON(status);
StatusJSONImpl statusImplemented = (StatusJSONImpl) TwitterObjectFactory.createUserList(statusStringified);
SingletonLaunchDB.getMongo().save(statusImplemented);
But I still get a java.lang.IllegalAccessError on the class StatusJSONImpl at run time.
I see from other SA answers that users routinely point other users to this Impl classes... how do they do to use it in their code?
Your help is much appreciated.
Status is serializable. To recover StatusJSONImpl from statusStringified you can write.
JSONObject json = new JSONObject(statusStringified);
Status status = new StatusJSONImpl(json);
The code sample is from StatusSerializationTest.java
I hope this helps.
Use the static factory method on TwitterObjectFactory:
Status status = TwitterObjectFactory.createStatus(statusAsString);
StatusJSONImpl is an implementation detail which library users are not meant deal with. The only thing a user of the library should care about is the contract (the Status interface in this case) which is necessarily public and the library authors promise to fulfill. On the other hand, the concrete classes like StatusJSONImpl are not public on purpose in order to prevent consumers from using them and getting tightly coupled to a specific implementation which may change over time. And from the authors' point of view, by coding to an interface they are then free to return any concrete type they wish as long as it fulfills the contract.
If you check the class that is returned from the factory method, it is StatusJSONImpl. But to reiterate, as a user of the library you should need to know or care about that.
Status status = TwitterObjectFactory.createStatus(statusAsString);
status.getClass(); // class twitter4j.StatusJSONImpl
To understand more about why this is done, you can read about static factory methods.

Using "Adapter" pattern

How I understand, the Goal of the Adapter pattern is to call some class methods using some interface (which opened to clients). To make adapter pattern we need to implement some interface (which uses by client), and also we need to extend some class, which methods client need to call when calling interface methods.
class Adapter extends NeedClass implements PublicInterface{}
But what if we haven't interface, but have only 2 classes? For example we have some class(not interface!) which methods uses clients. Now we need to call methods of other class by making adapter class, but we cant to do this, because we cant make multiple Inheritance on the adapter class.
class Adapter extends NeedClass, PublicInterface
above code doesnt work.
What we can do in this case?
You can has an instance of NeedClass in Adapter and call it, when you need. So you extend only from PublicInterface.
public class Adapter extends PublicInterface {
private NeedClass needClass;
#Override
public void doSomething() {
needClass.doSomethingElse("someParameter");
}
}
You can use a composition instead of inheritance. Add a field to Adapter class of type NeedClass:
public class Adapter extends PublicInterface {
private NeedClass needClass;
}
Then inside Adapter methods delegate execution to needClass field.
From what i have understood the Adapter Pattern.
it is helpful when dealing with the third part codes such as API which is/ are subject to changes any time and my likely to break your code if implemented direct.
For example : Using Paypal in your site for payment online.let's assume the Paypal uses the method payMoney() for payment. and after sometime they decide to change the method to something else let's say sendMoney(). This is likely to break your code if implemented directly, with the use of Adapter Design pattern this can be solves as follow
the third part code => Paypal
class Paypal {
public function __construct(){
// their codes
}
public function payMoney($amount){
// the logic of validating
// the $amount variables and do the payment
}
}
so implement it directly in the code as below will break the code
$pay = new Paypal();
$pay->payMoney(200);
using adapter will save numbers of hours and a complex work of updating the code from payMoney() to sendMoney() in every where that the API scripts has been implemented. Adapter enable update in one place and that's it.
Let see it.
class paypalAdapter {
private $paypal;
// Paypal object into construct and check if it's pa
// Paypal object via type hint
public function __construct(PayPal $paypal) {
$this->paypal = $paypal;
}
// call the Paypal method in your own
//custom method that is to be
// implemented directly into your code
public function pay($amount) {
$this->paypal->payMoney($amount);
}
}
so it is like that and there you can go and use the PaypalAdater directly into the code as follow;
$pay = new PaypalAdapter(new Paypal);
$pay->pay(200);
So in future when the Vendor(Paypal) decide to use sendMoney instead of payMoney what to be done is to open the PaypalAdapter class and do the following in the pay($amount) method:
// SEE THIS METHOD ABOVE TO OBSERVE CHANGES
// FROM $this->paypal->payMoney($amount);
// TO $this->paypal->senMoney($amount);
public function pay($amount) {
$this->paypal->sendMoney($amount);
}
After this minor change in one place, everything works well as before.

Categories