Hello Everyone,
I have implemented PhoneListener to trace Incoming/Outgoing calls.
I found the demo app from BB support link & In BB Sample App. (PhoneAPIDemo)
Now I seen some strange behavior, When I write below statement in "callConnected" method I am getting valid phoneCall object but when I write below statement in "callDisconnected" method I am getting phoneCall object NULL.
I checked the callID is same for both method.
PhoneCall phoneCall = Phone.getCall( callId );
I am putting the above statement in "callDisconnected" method, because I require Elapsed-time.
phoneCall.getElapsedTime()
Please let me know why I am getting phoneCall NULL & what is the correct way to sort-out the issue.
I guess there is no "Call" to get when call has been disconnected.
Create a phoneCall object as a member variable, initialized it in isConnected() and call getElapsedTime() in callDisconnected().
public class HelpMario implements PhoneListener {
private static PhoneCall phoneCall;
....
....
....
public void callConnected(int arg0) {
phoneCall = Phone.getCall(arg0);
}
public void callDisconnected(int arg0) {
//Get Elapsed Time:
phoneCall.getElapsedTime());
}
}
Hope this helps.
Related
I have a native Android Activity that receives a callback interface as part of the Intent used to start it:
public interface ICallback : Serializable
{
void invoke(Result result);
}
I want to implement the callback in Xamarin as a lambda:
class CallbackWrapper : Java.Lang.Object, ICallback
{
private Action<Result> onInvoke;
public CallbackWrapper(Action<Result> onInvoke)
{
this.onInvoke = onInvoke;
}
public void Invoke(Result result)
{
this.onInvoke(result);
}
}
...
intent.PutExtra(CALLBACK_EXTRA, new CallbackWrapper(result => { ... }));
StartActivityForResult(intent);
The first problem is that when my callback gets deserialized from the intent bundle, I get the following exceptions:
System.NotSupportedException
Unable to activate instance of type CallbackWrapper from native handle 0xff...
System.MissingMethodException
No constructor found for CallbackWrapper::.ctor(System.IntPtr, Android.Runtime.JniHandleOwnership)
I add the constructor as explained in the exception:
class CallbackWrapper : Java.Lang.Object, ICallback
{
public CallbackWrapper(IntPtr handle, JniHandleOwnership transfer) : base(handle, transfer)
{
}
...
}
The exception is fixed, but now when the activity calls my handler, the onInvoke field is null. How do I get a reference to the onInvoke delegate that was used to create the Intent?
The solution - serialize a handle to the original object.
The first step is to enable object serialization. Serialization in Java is done using specially-named private methods, instead of through interface methods. Xamarin allows you to inject these methods into the generated Android callable wrappers using the Java.Interop.ExportAttribute attribute:
using Java.Interop;
class CallbackWrapper : Java.Lang.Object, ICallback
{
...
[Export("readObject", Throws = new[] { typeof(Java.IO.IOException), typeof(Java.Lang.ClassNotFoundException) })]
private void ReadObject(Java.IO.ObjectInputStream source)
{
}
[Export("writeObject", Throws = new[] { typeof(Java.IO.IOException), typeof(Java.Lang.ClassNotFoundException) })]
private void WriteObject(Java.IO.ObjectOutputStream destination)
{
}
}
Even if an ACW implements Serializable, the ACW itself has no useful fields - that why you need to serialize the managed state through the readObject/writeObject method pair.
Note that for this to work, your project needs to reference the Mono.Android.Export assembly, otherwise you'll get a build-time error.
The second part is getting a serializable reference to CallbackWrapper. This can be achieved using System.Runtime.InteropServices.GCHandle. The first step is to create a handle to the object and write it during serialization:
[Export("writeObject", Throws = new[] { typeof(Java.IO.IOException), typeof(Java.Lang.ClassNotFoundException) })]
private void WriteObject(Java.IO.ObjectOutputStream destination)
{
var handle = GCHandle.Alloc(this);
destination.WriteLong(GCHandle.ToIntPtr(handle).ToInt64());
}
The second step is deserialization:
[Export("readObject", Throws = new[] { typeof(Java.IO.IOException), typeof(Java.Lang.ClassNotFoundException) })]
private void ReadObject(Java.IO.ObjectInputStream source)
{
// deserialize GCHandle from stream
var handle = GCHandle.FromIntPtr(new IntPtr(source.ReadLong()));
// convert handle to object
var trueSelf = handle.Target as NativeValidationHandler;
// copy fields from original callback
this.onInvoke = trueSelf.onInvoke;
// free this handle
handle.Free();
}
The handle doesn't need to be a pinned handle, because we don't ever access the object's address, we just use the handle.
Note that in the above implementation you can only deserialize a callback once, because deserialization will free the handle. Alternatively you can allocate the handle once in the constructor and provide a Dispose method that frees that handle, if you wish to be able to deserialize the handle multiple times. Freeing the handle during deserialization also means that the object will never be collected if it's never deserialized, because the handle will prevent the object from being collected.
If you want to use Serializable than you are right. but i would recommend you to use Parcelable, because
Parcelable is a part of Android sdk and it's mainly made for parcelling purpose.
Parcelable is faster than Serializable because it doesn't use reflection while later does.
Although there is demerit that it has some boilerplate code.
Worth to read => https://android.jlelse.eu/parcelable-vs-serializable-6a2556d51538
I created a custom object in FIX44.xml .I want to call onMessage handler in receiver for same custom object using crack implementation but adding crack in fromApp of reciever does not call onMessage .Here is the code
#Override
public void fromApp(Message arg0, SessionID arg1) throws FieldNotFound, IncorrectDataFormat,
IncorrectTagValue, UnsupportedMessageType {
crack(arg0, arg1); // should calls onMessage(..,..) of custom object
}
public void onMessage(MyCustomObject message, SessionID sessionID)
throws FieldNotFound, UnsupportedMessageType, IncorrectTagValue {
//do something
}
Hello isha and welcome to Stack Overflow! I'm suspecting you are not having your class implement the MessageCracker interface (you did not include the whole class definition).
The correct use of this interface, and how to define the methods to crack your messages is described in the QuickFIX/J Receiving Messages documentation.
To quote the relevant parts, which includes an example:
Define your application like this:
import quickfix.Application;
import quickfix.MessageCracker;
public class MyApplication
extends MessageCracker implements quickfix.Application
QuickFIX/J version 1.16 or newer supports a new version of
MessageCracker that dynamically discovers message handling method
using either a method naming convention (similar to earlier versions
of QuickFIX/J) or by tagging handlers methods with the #Handler
annotation.
Examples...
import quickfix.Application;
import quickfix.MessageCracker;
public class MyApplication extends MessageCracker implements quickfix.Application
{
public void fromApp(Message message, SessionID sessionID)
throws FieldNotFound, UnsupportedMessageType, IncorrectTagValue {
crack(message, sessionID);
}
// Using annotation
#Handler
public void myEmailHandler(quickfix.fix50.Email email, SessionID sessionID) {
// handler implementation
}
// By convention (notice different version of FIX. It's an error to have two handlers for the same message)
// Convention is "onMessage" method with message object as first argument and SessionID as second argument
public void onMessage(quickfix.fix44.Email email, SessionID sessionID) {
// handler implementation
}
}
BaseTest.java:
private static ReportService reportService; // Calling report service interface
#BeforeSuite:
reportService = new ExtentReportService(getConfig()); // New instance of ExtentReportService.
#BeforeMethod:
reportService.startTest(testname); // Starting the test and passing the name and description of the test.
#AfterMethod:
reportService.endTest(); // Ending the test
#AfterSuite:
reportService.close(); // Closing the test
**ExtentReportService.java:** // Contains different extent API methods. (These are designed to be generic.)
protected static ExtentReports extent; // static instance of ExtentReports
protected static ExtentTest test; //static instance of ExtentTTest
#Override // StartTest method
startTest(Method method) {
testMetaData = getTestMetaData(method);
test=extent.startTest(testMetaData.getId(),testMetaData.getSummary());
}
#Override //End test method
endTest() {
extent.endTest(test);
extent.flush();
}
The above is my selenium code.
When I am executing my suite file with parallel="methods" and thread count="3", I am getting the following error: "com.relevantcodes.extentreports.ExtentTestInterruptedException: Close was called before test could end safely using EndTest.".
While debugging, I found that even before all endTest() in AfterMehtod were executed, AfterSuite was being called.
I tried different variations such that the code works, such as, removing static, calling endTest() in the test itself rather than after method, removing close() call from AfterSuite and many other variations. But still getting the same error.
I tried all the possible solutions given on the internet, but to no use.
Attaching a hierarchy file for the ExtentReport used in my project
I also the following solution given in StackOverflow:
Extent report :com.relevantcodes.extentreports.ExtentTestInterruptedException: Close was called before test could end safely using EndTest
Unsynchronized output
XMF file for parallel test.
ExtentReports Intialized in ExtentManager class using Singleton().
public class ExtentManager {
private static ExtentReports extent;
public static ExtentReports getInstance() {
if(extent == null) {
extent = new ExtentReports(System.getProperty("user.dir")+"\target\surefire-reports\html\extent.html", true, DisplayOrder.OLDEST_FIRST);
extent.loadConfig(new File(System.getProperty("user.dir")+"src\test\resources\extentconfig\ReportsConfig.xml"));
}
return extent;
}
}
Declared in TestBase class as global.
public ExtentReports repo= ExtentManager.getInstance();
public static ExtentTest test
Call startTest in public void onTestStart(ITestResult result)
test = repo.startTest(result.getName().toUpperCase());
Call endTest in CustomListener Class both in a)public void onTestFailure(ITestResult result); b)public void onTestSuccess(ITestResult result).
repo.endTest(test)
Call close() OR flush() in #AfterSuite in TestBase class but NOT both!
//repo.close();
repo.flush();
Note: I have ExtentReports ver-2.41.2, and TestNg ver-7.1.0.
After the above steps, error 'Getting closed before endTest call in Selenium using Extent Reports' got resolved.
Extent report generates each test successfully in the report.
Try it out!
I have the following code:
public static int smsCount = 0 ;
public void startListener()
{
SendListener smsListener;
smsListener = new SendListener() {
public boolean sendMessage(Message message) {
++smsCount;
return true;
}
};
SMS.addSendListener(smsListener);
}
When I use a debugger I see that the value of smsCount is increasing. However, for some reason, it returns zero when I try to access it from outside the class. Is there anything wrong with this code ? sendMessage is called whenever an SMS is sent.
To expand on John B's comment, and to be more specific are you accessing it from a different runtime (application) context? Each runtime context has its own global (and therefore) static namespace. To ensure an object is a global singleton you should use the RuntimeStore.
I've got a grails app with Service classes that inherit from Groovy's GroovyInterceptable:
class customerSerrvice implements GroovyInterceptable {
private List<Customer> customers
def invokeMethod(String name, args) {
log.debug "=======>INVOKING method [$name] with args:$args"
}
void foo() {
customers.each { doSomething(it) }
}
void doSomething(Customer cust) { log.debug "doSomething invoked with $cust" }
}
The above is a greatly simplified representation, but it gives you the idea. If I call foo() or doSomething() directly from another class, the invokeMethod gets called like it is supposed to. However, when foo() calls doSomething(), that call is not intercepted in invokeMethod.
If I change from
customers.each { doSomething(it) }
to
for(Customer cust: customers) { doSomething(cust) }
then the invokeMethod gets called just fine.
So is there something about closures and GroovyInterceptable that don't go together? Is there any way to get the invokeMethod to work with closures short of changing them all out?
Thanks
Confirmed as a bug, old link:
http://jira.codehaus.org/browse/GROOVY-4610, new link:
https://issues.apache.org/jira/browse/GROOVY-4610