0
<%@ page import="com.day.cq.wcm.mobile.api.device.*"%>
<% 
Device device = slingRequest.adaptTo(Device.class);

if(device != null) {
        DeviceGroup deviceGroup = device.getDeviceGroup();

        String userAgent = device.getUserAgent();
        out.write("  Test\n");
    }

%>  

device variable is always null. This question is asked on Adobe forum but nobody had answered that. It would be appreciated if you can share your experience in solving this problem.

Note: The slingRequest is already defined in global.jsp

Zahid
  • 88
  • 7
  • 1
    Is this something that you used to do in earlier versions and that stopped working in AEM 6.1 or something you haven't done before? It doesn't look like the `Device` class is adaptable from a request object OOTB. At least it's not mentioned [in the docs](https://docs.adobe.com/docs/en/aem/6-1/develop/platform/sling-adapters.html). Looking at the Javadoc for this package, I can see a `DeviceMapper` interface, which has a method with the right signature and might be available as an OSGi service. I can't verify this at the moment as I don't have an AEM instance at hand. – toniedzwiedz Jan 30 '16 at 10:55
  • Javadoc here: https://docs.adobe.com/docs/en/aem/6-1/ref/javadoc/com/day/cq/wcm/mobile/api/device/package-summary.html – toniedzwiedz Jan 30 '16 at 11:02
  • Thanks toniedzwiedz for the reply. I will try your suggestion. Appreciate your help. – Zahid Feb 01 '16 at 15:26
  • What information are you trying to retrieve from the `Device` instance? I did find an implementation of the `DeviceMapper` exposed as an OSGi service but I'm having a hard time making it return something meaningful. Most likely because of the mappings I have on my instance and that I don't use on the project. I also managed to adapt to `DeviceGroup`, as Shivani suggested in her answer. Are you sure you need a specific device? – toniedzwiedz Feb 01 '16 at 18:40
  • Basically I am creating a component that renders the content based on the OS and Device. In future I may use more info. I believe it is using wurfl.xml (database) for mapping device so I don't have to manually filter using regex....you know what I mean – Zahid Feb 01 '16 at 18:42
  • It sounds a bit strange to be rendering different content based on the device used. It's going to be hard to index and your users might get odd search results. Not sure about the reason you're doing this but if it's just for the looks, I'd go with responsive styling or maybe a mobile site. If it's to serve relevant content to specific types of users, maybe Target would be a better fit. Anyway, doing it at the back-end sounds like something I'd personally avoid in general. BTW, you might want to take a look at AEM Apps. There's some neat new stuff in AEM 6.1 – toniedzwiedz Feb 01 '16 at 18:46
  • Initially I thought of doing it on client side using javascript but then I realized that throwing all the content on client side would make page very heavy for mobile. I don't want this page to be indexed for search engine. I mean there are ways to get User-Agent on back-end but I thought of using the sophisticated wurfl database which can used for lot of things. – Zahid Feb 01 '16 at 18:52
  • Haven't used that one. I'll post an answer explaining how to use the mapper but I don't have a property database at hand to test the solution end to end. – toniedzwiedz Feb 01 '16 at 18:55
  • Could you please provide me the implementation for DeviceMapper. Thank you – Zahid Feb 01 '16 at 19:03

2 Answers2

4

I am working on the same thing right now. You can't get the device from the request directly ,firstly get the DeviceGroup then from that bring out whatever you want.

final DeviceGroup deviceGroup =slingRequest.adaptTo(DeviceGroup.class); if(deviceGroup!=null)deviceGroup.drawHead(pageContext);

Shivani Garg
  • 735
  • 13
  • 37
  • Thank you Shivani for reply. Could you please also post the code from fetching device object from deviceGroup? – Zahid Feb 01 '16 at 15:25
  • zadd,adobe document says that you can get device like the way you did.But it dont work.Can you explain your usecase,so that i can find out some way to do that.In short,why you need device object. – Shivani Garg Feb 05 '16 at 13:21
0

Just tried this on my instance and:

Device device = request.adaptTo(Device.class);

returns null, while:

DeviceGroup deviceGroup = request.adaptTo(DeviceGroup.class);

on the other hand, gets me a reference to a valid DeviceGroup object.

If you need a device and not a group, try using DeviceMapper. It appears that the DeviceMapper is indeed available as a service implemented by com.day.cq.wcm.mobile.core.impl.devicemapper.DeviceMapperImpl

Therefore, in you JSP, you can simply write:

<%@ page import="com.day.cq.wcm.mobile.api.device.DeviceMapper" %>

...

<%
  DeviceMapper deviceMapper = sling.getService(DeviceMapper.class);
  Device device = deviceMapper.getDeviceInstance(slingRequest);
%>

And that should give you the right object provided that all of the relevant configurations are right.

However, if possible, you should try to avoid placing such logic in your JSP. This kind of code should be encapsulated in an adapter factory or preferably a Sling Model. That way you'll be able to get rid of all of your code from the presentation layer and just read simple properties in the JSP.

You may also want to take a look at the com.day.cq.wcm.mobile.core.MobileUtil.class that might just fit your particular use case.

I'd also like to point out that writing back-end code to target a specific device (as opposed to a group) seems a bit strange. Before introducing a bunch of classes to detect the device, think if the same result can be achieved using appropriate styling, a mobile site version, Target (if the purpose is to serve different content to users with different devices). Or maybe you should just go for AEM Apps

toniedzwiedz
  • 17,895
  • 9
  • 86
  • 131