I want to pass a Listener through a System Service in Android. I created my Listener Interface using AIDL.
Content of IStatusBarLostFocusCallback.aidl:
package com.android.internal.statusbar;
interface IStatusBarLostFocusCallback {
void onLostFocus();
}
then I extended Androids IStatusBarService.aidl with following Function:
void setStatusBarLostFocusCallback(in IStatusBarLostFocusCallback listener);
and also imported my Interface (in the same directory)
import com.android.internal.statusbar.IStatusBarLostFocusCallback;
In Androids StatusBarManagerService, I extended this Interface since I read to do this in this Thread: Android remote service callbacks like this:
public interface StatusBarLostFocusCallback extends IStatusBarLostFocusCallback {
public void onLostFocus();
}
Now I want to set the Listener with the setStatusBarLostFocusCallback which is defined in IStatusBarService.aidl and implemented in StatusBarManagerService.java.
However, when I try to compile the Framework, I get the following Error
out/target/common/obj/JAVA_LIBRARIES/framework_intermediates/src/core/java/com/android/internal/statusbar/IStatusBarService.java:287: cannot find symbol
symbol : class IStatusBarLostFocusCallback
location: package com.android.internal.statusbar
com.android.internal.statusbar.IStatusBarLostFocusCallback _arg0;
What have I missed. Do I have to write a .java for the IStatusBarLostFocusCallback? If so, what should be in there?
you try as described like this ?
If yes, and this didn't work, you may implement methods from aidl like this, for example:
TelephonyManager telephonyManager = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
Class aClass = Class.forName(telephonyManager.getClass().getName());
Method method = aClass.getDeclaredMethod("getITelephony");
method.setAccessible(true);
ITelephony telephonyService = (ITelephony) method.invoke(telephonyManager);
telephonyService.endCall();
I managed it now. I forgot to add my AIDL to the Build in /frameworks/base/Android.mk (I did forget to mention I am building the Source).
I now no longer extend the Interface but implement it like this:
mBarService.setStatusBarLostFocusCallback(new IStatusBarLostFocusCallback.Stub(){
public void onLostFocus(){
mHasStatusbarFocus = false;
}
});
Related
I need to use an interface from the Android Camera class that is not exported in the SDK. It is setup like this
//interface defined as
public interface Camera$CameraMetaDataCallback {
void onCameraMetaData(byte[] data, Camera camera);
};
//set callback defined
class Camera {
...
public final void setMetadataCb(CameraMetaDataCallback cb)
{
mCameraMetaDataCallback = cb;
native_setMetadataCb(cb!=null);
}
...
}
I can get the interface class I am assuming with
val CameraMetaDataCallback = Class.forName("Camera\$CameraMetaDataCallback").kotlin
and the method with
val CameraSetMetadataCb = Camera::class.java.getMethod("setMetadataCb", CameraMetaDataCallback.java)
but how do I actually use the interface object and set a callback?
You'd use cameraSetMetadataCb.invloke(objectToCallItOn, param1, param2, param3, ...) That calls the method referred to by the cameraSetMetadataCb object using objectToCallOn as the this pointer and passes the given parameters. But as I mentioned in comments above- you really don't want to do this, unless you have total control over the hardware it runs on. Any change, even a minor patch, to the OS can change this function's signature or remove it entirely and break your app.
I have an interface which is being implemented in some 20-30 classes. I have added a new new method to this interface.
Is there any shortcut in Android Studio to override this method in all the sub classes? Or do I need to manually go to all the classes and
implement manually?
If you use Java 8, then there's new interface feature called "default method" you may try using:
https://docs.oracle.com/javase/tutorial/java/IandI/defaultmethods.html
Ya, There is a way to achive such things by making your method DEFAULT inside your Interface.
For Example :
public interface oldInterface {
public void existingMethod();
default public void newDefaultMethod() {
System.out.println("New default method"
" is added in interface");
}
}
The following class will compile successfully in Java JDK 8,
public class oldInterfaceImpl implements oldInterface {
public void existingMethod() {
// existing implementation is here…
}
}
If you create an instance of oldInterfaceImpl:?
oldInterfaceImpl obj = new oldInterfaceImpl ();
// print “New default method add in interface”
obj.newDefaultMethod();
I need a little help with my Interface. I think that i doesn't understand them at all.
So i created this interface to notify every classes that implements it when a certain event occurs.
public interface OnColorsChangeListener {
void onColorsChangeListener(ColorsProp colorsProp);
}
My class that hold the interface:
private OnColorsChangeListener mCallback;
... // other code
// the event occurs here so i call:
mCallback.onColorsChangeListener(mProps);
// but of course here i get an NPE becouse this is undefined in this class.. well, with some replies here i'll understand better how to use that for reach my point
The class that implements it:
public class ClassTest implements OnColorsChangeListener {
... // other code
#Override
public void onColorsChangeListener(ColorsProp colorsProp) {
Log.d(TAG, "Color changed! " + colorsProp.color);
}
i put this in 4/5 classes to be notified in the same time for the color change. I'm quite sure the reason is that I didn't understand very well how them works, so can anyone point me to the right direction? Thank you!
Explanation by example:
You have to instantiate your callback, & it has to be an instance of your class
private OnColorsChangeListener mCallback;
mCallback = new ClassTest();
mCallback.onColorsChangeListener(mProps);
However if you want multiple callbacks you will need to use the Observer pattern.
Simple example:
private List<OnColorsChangeListener> mCallbacks = new ArrayList<OnColorsChangeListener>();
mCallbacks.add(new ClassTest());
mCallbacks.add(new OtherClass());
for(OnColorsChangeListener listener : mCallbacks) {
listener.onColorsChangeListener(mProps);
}
Obviously if you have the class, somewhere else you would not new it up, you would use that reference:
mCallbacks.add(mClassTest);
Observer Pattern Wikipedia
An interface is just a way to group together a bunch of related methods. Implementing this interface then requires you to implement all the methods grouped together by the interface.
The Java Tutorials has a good read on the subject:
What is an interface?
Here's a Stackoverflow thread regarding listener interfaces in android:
How to create our own Listener interface in android?
In short, you don't use the interface directly since it only specifies which methods implementing classes are supposed to implement.
Well, I'm at a dilemma here. I made my own class that uses the Bluetooth class from android but I'm not sure where to put it. Extending the android Bluetooth class seems like a good idea but I need to override the onActivityResult() which is only available to an activity class. So, where would I put my class so that I have access to onActivityResult() (keeping in mind the idea here is to use as few dependencies as possible)?
In other words, I want to move the Bluetooth code from the main activity to a separate class.
You should to use separate file for each class. You can create a folder "engine". For example: com.mycorp.myapp.engine. You can get access to onActivityResult() very simple. For example: MainActivity.onActivityResult(). Note: function should be public.
Or you can pass your activity to your CustomBluetooth's constructor.
public class CustomBluetooth {
private Activity mActivity;
/* Constructor */
public CustomBluetooth (Activity pActivity ) {
super();
this.mActivity = pActivity;
}
/* Your functions */
public int getResult() {
return this.mActivity.onActivityResult();
}
}
Alex. P.S. Sorry for my English:)
Add an interface to your Bluetooth class and implement the interface in your activity.
I just switched over from iPhone to Android and am looking for something similar to where in the iPhone SDK, when a class finishes a certain task, it calls delegate methods in objects set as it's delegates.
I don't need too many details. I went through the docs and didn't find anything (the closest I got was "broadcast intents" which seem more like iOS notifications).
Even if someone can point me to the correct documentation, it would be great.
Thanks!
Never mind... found the answer here :)
http://www.javaworld.com/javaworld/javatips/jw-javatip10.html
Pasting from the article so as to preserve it:
Developers conversant in the event-driven programming model of MS-Windows and the X Window System are accustomed to passing function pointers that are invoked (that is, "called back") when something happens. Java's object-oriented model does not currently support method pointers, and thus seems to preclude using this comfortable mechanism. But all is not lost!
Java's support of interfaces provides a mechanism by which we can get the equivalent of callbacks. The trick is to define a simple interface that declares the method we wish to be invoked.
For example, suppose we want to be notified when an event happens. We can define an interface:
public interface InterestingEvent
{
// This is just a regular method so it can return something or
// take arguments if you like.
public void interestingEvent ();
}
This gives us a grip on any objects of classes that implement the interface. So, we need not concern ourselves with any other extraneous type information. This is much nicer than hacking trampoline C functions that use the data field of widgets to hold an object pointer when using C++ code with Motif.
The class that will signal the event needs to expect objects that implement the InterestingEvent interface and then invoke the interestingEvent() method as appropriate.
public class EventNotifier
{
private InterestingEvent ie;
private boolean somethingHappened;
public EventNotifier (InterestingEvent event)
{
// Save the event object for later use.
ie = event;
// Nothing to report yet.
somethingHappened = false;
}
//...
public void doWork ()
{
// Check the predicate, which is set elsewhere.
if (somethingHappened)
{
// Signal the even by invoking the interface's method.
ie.interestingEvent ();
}
//...
}
// ...
}
In that example, I used the somethingHappened predicate to track whether or not the event should be triggered. In many instances, the very fact that the method was called is enough to warrant signaling the interestingEvent().
The code that wishes to receive the event notification must implement the InterestingEvent interface and just pass a reference to itself to the event notifier.
public class CallMe implements InterestingEvent
{
private EventNotifier en;
public CallMe ()
{
// Create the event notifier and pass ourself to it.
en = new EventNotifier (this);
}
// Define the actual handler for the event.
public void interestingEvent ()
{
// Wow! Something really interesting must have occurred!
// Do something...
}
//...
}
That's all there is to it. I hope use this simple Java idiom will make your transition to Java a bit less jittery.
The pendant for kotlin.
Define your interface: In my example I scan a credit card with an external library.
interface ScanIOInterface {
fun onScannedCreditCard(creditCard: CreditCard)
}
Create a class where you can register your Activity / Fragment.
class ScanIOScanner {
var scannerInterface: ScanIOInterface? = null
fun startScanningCreditCard() {
val creditCard = Library.whichScanCreditCard() //returns CreditCard model
scannerInterface?.onScannedCreditCard(creditCard)
}
}
Implement the interface in your Activity / Fragment.
class YourClassActivity extends AppCompatActivity, ScanIOInterface {
//called when credit card was scanned
override fun onScannedCreditCard(creditCard: CreditCard) {
//do stuff with the credit card information
}
//call scanIOScanner to register your interface
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
val scanIOScanner = ScanIOScanner()
scanIOScanner.scannerInterface = this
}
}
CreditCard is a model and could be define however you like. In my case it includes brand, digits, expiry date ...
After that you can call scanIOScanner.startScanningCreditCard() wherever you like.
The main content of this video tutorial is to show how to use interfaces to delegate methods / data exchange between different Fragments and activities, but it is great example to learn how delegate pattern can be implemented in Java for Android.
Java callback is not the same thing like ios delegate, in ios you can use a callback almost the same way like in Android. In Android there is startActivityForResult that can help you to implement the tasks for what ios delegate is used.
I believe ListAdapter is a example of delegation pattern in Android.
Kotlin's official Delegation pattern:
interface Base {
fun print()
}
class BaseImpl(val x: Int) : Base {
override fun print() { print(x) }
}
class Derived(b: Base) : Base by b
fun main() {
val b = BaseImpl(10)
Derived(b).print()
}
See: https://kotlinlang.org/docs/delegation.html