How to get device from UDN?

classic Classic list List threaded Threaded
9 messages Options
Reply | Threaded
Open this post in threaded view
|

How to get device from UDN?

lbelloq
I've read that the way to work with devices across activities is to pass the UDN in the intent. Problem is, all the functions that get devices from the Registry use a UDN-type parameter and don't work with String parameters. And, of course, you can't put a UDN object into an Intent or a Bundle. I've tried using UDN.valueOf(udnFromIntent) and new UDN(uuidFromIntent) but both crash my app.
Is there anything I'm missing?
Thanks in advance.
L├ęster
Reply | Threaded
Open this post in threaded view
|

Re: How to get device from UDN?

Christian Bauer
Administrator
lbelloq wrote
I've tried using UDN.valueOf(udnFromIntent) and new UDN(uuidFromIntent) but both crash my app.
What does "crash my app" mean?
Reply | Threaded
Open this post in threaded view
|

Re: How to get device from UDN?

lbelloq
It means this:

09-05 10:27:19.905: E/AndroidRuntime(1454): FATAL EXCEPTION: main
09-05 10:27:19.905: E/AndroidRuntime(1454): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.clingupnptest4/com.example.clingupnptest4.ControlActivity}: java.lang.NullPointerException
09-05 10:27:19.905: E/AndroidRuntime(1454): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1956)
09-05 10:27:19.905: E/AndroidRuntime(1454): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1981)
09-05 10:27:19.905: E/AndroidRuntime(1454): at android.app.ActivityThread.access$600(ActivityThread.java:123)
09-05 10:27:19.905: E/AndroidRuntime(1454): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1147)
09-05 10:27:19.905: E/AndroidRuntime(1454): at android.os.Handler.dispatchMessage(Handler.java:99)
09-05 10:27:19.905: E/AndroidRuntime(1454): at android.os.Looper.loop(Looper.java:137)
09-05 10:27:19.905: E/AndroidRuntime(1454): at android.app.ActivityThread.main(ActivityThread.java:4424)
09-05 10:27:19.905: E/AndroidRuntime(1454): at java.lang.reflect.Method.invokeNative(Native Method)
09-05 10:27:19.905: E/AndroidRuntime(1454): at java.lang.reflect.Method.invoke(Method.java:511)
09-05 10:27:19.905: E/AndroidRuntime(1454): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784)
09-05 10:27:19.905: E/AndroidRuntime(1454): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551)
09-05 10:27:19.905: E/AndroidRuntime(1454): at dalvik.system.NativeStart.main(Native Method)
09-05 10:27:19.905: E/AndroidRuntime(1454): Caused by: java.lang.NullPointerException
09-05 10:27:19.905: E/AndroidRuntime(1454): at com.example.clingupnptest4.ControlActivity.onCreate(ControlActivity.java:49)
09-05 10:27:19.905: E/AndroidRuntime(1454): at android.app.Activity.performCreate(Activity.java:4465)
09-05 10:27:19.905: E/AndroidRuntime(1454): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1049)
09-05 10:27:19.905: E/AndroidRuntime(1454): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1920)
09-05 10:27:19.905: E/AndroidRuntime(1454): ... 11 more
For reference, my code is as follows:

    // This is in the first activity.
    @Override
    public void onListItemClick(ListView l, View v, int position, long id) {
    DeviceDisplay dispositivoTocado = listAdapter.getItem(position);
    Device dispositivo = dispositivoTocado.getDevice();
    UDN devUDN = dispositivo.getIdentity().getUdn();
    String deviceID = devUDN.toString();
    String devUUID = devUDN.getIdentifierString().toString();
    Intent i = new Intent("com.example.clingupnptest4.ControlActivity");
    i.putExtra("devID", deviceID);
    i.putExtra("UUID", devUUID);
    startActivity(i);
    }

    // And this is in the second activity, the one called by my intent
    // Declarations
        private AndroidUpnpService upnpService;
        private Device dispositivo;
        private Service servicio;
        private ServiceReference referencia;
        private ServiceConnection serviceConnection = new ServiceConnection() {
        public void onServiceConnected(ComponentName className, IBinder service) {
            upnpService = (AndroidUpnpService) service;
        }
        public void onServiceDisconnected(ComponentName className) {
            upnpService = null;
        }
    };

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_control);
        String deviceID = getIntent().getStringExtra("devID");
        String devUUID = getIntent().getStringExtra("UUID");
        UDN udntest = new UDN(devUUID);
        dispositivo = upnpService.getRegistry().getDevice(udntest, true);
    }
The last instruction of onCreate() is the one that crashes the app, I think. If I use
UDN udntest = UDN.valueOf(deviceID)
 the app crashes with the same error.
Maybe my service connection is wrong?
Thank you again.
Reply | Threaded
Open this post in threaded view
|

Re: How to get device from UDN?

Christian Bauer
Administrator
Well without knowing the exact line of code that produces the NPE, all of this is just speculation. You cut off the stack trace. Also use a debugger.
Reply | Threaded
Open this post in threaded view
|

Re: How to get device from UDN?

lbelloq
This post was updated on .
Alright, I made some changes to the code and got this line on the stack trace:
09-06 12:08:46.051: E/AndroidRuntime(18851): Caused by: java.lang.NullPointerException
09-06 12:08:46.051: E/AndroidRuntime(18851): at com.example.clingupnptest4.ControlActivity.onCreate(ControlActivity.java:56)
The line in question says:
registro = upnpService.getRegistry();
So I take my problem is I'm trying to get the Registry but my service instance (upnpService) is null.
I've defined the following in my code:
    private ServiceConnection serviceConnection = new ServiceConnection() {
        public void onServiceConnected(ComponentName className, IBinder service) {
            upnpService = (AndroidUpnpService) service;
        }
        public void onServiceDisconnected(ComponentName className) {
            upnpService = null;
        }
    };

// ...

    @Override
    public void onCreate(Bundle savedInstanceState) {
        // code
        Intent i = new Intent(this, AndroidUpnpServiceImpl.class);
        getApplicationContext().bindService(i, serviceConnection, Context.BIND_AUTO_CREATE);
        // more code
        UDN udntest = new UDN(devUUID);
        registro = upnpService.getRegistry();
        dispositivo = registro.getDevice(udntest, true);
        // even more code
    }
   
    public void onDestroy() {
    getApplicationContext().unbindService(serviceConnection);
    }
Is there anything I'm missing from upnpService's initialization? I've compared my code with the browsing example given Cling's tutorial and I can't see what's wrong.

EDIT. Eclipse's debugger confirms that in that line, upnpService is null instead of the AndroidUpnpService I was expecting. So my problem is that upnpService is not initializing correctly, but then I'm stumped on this.
Reply | Threaded
Open this post in threaded view
|

Re: How to get device from UDN?

bergstr
In reply to this post by Christian Bauer
the stacktrace does show that the NPE occurred in

ControlActivity.onCreate(ControlActivity.java:49)

Of course, only the OP knows where line 49 is. He tells us that he thinks it is this (why he THINKS I dont know, I agree he should better use a debugger and be sure)

dispositivo = upnpService.getRegistry().getDevice(udntest, true); 

so either upnpService or upnpService.getRegistry() are null. I am pretty sure its upnpService, as I cannot find a context.bindService anywhere. Of course, even then, he cannot rely that bindService completes before onCreate(), so theres more stuff to do.
Reply | Threaded
Open this post in threaded view
|

Re: How to get device from UDN?

lbelloq
I just used a debugger and I confirmed that upnpService is null. So my problem is that the service binding does not complete before onCreate() gets to that line. bindService() returns a boolean to indicate if the biding was successful; should I wait for the binding to complete with a simple
Boolean done = getApplicationContext().bindService(i, serviceConnection, Context.BIND_AUTO_CREATE);
?
Reply | Threaded
Open this post in threaded view
|

Re: How to get device from UDN?

bergstr
lbelloq wrote
Boolean done = getApplicationContext().bindService(i, serviceConnection, Context.BIND_AUTO_CREATE);
with that statement, you are not waiting for anything! You wil simply have to move the code that reads the registry into the onServiceConnected method. And you really should read the examples more closely
Reply | Threaded
Open this post in threaded view
|

Re: How to get device from UDN?

lbelloq
You're right. I moved all my Cling logic to the onServiceConnected() method and everything worked.
And now I realize there's a reason the interaction logic is in onServiceConnected() and not in onCreate().
Thank you for your help, patience and answers.
At least I now know to use the debugger before asking.