Vaadin-14: checking if client is a mobile device - java

i am developing a webapp and i want to separate UIs for desktops and mobile devices, so i want to check wether the client using my app is a mobile device or not.
I tried to look online for official documentation or vaadin forum , but i couldn't find any useful information, since almost all of the solutions proposed in those answers are not implementable any more (the methods were removed).

You can use VaadinSession.getCurrent().getBrowser() to see if your client is a phone or not.
public boolean isMobileDevice() {
WebBrowser webBrowser = VaadinSession.getCurrent().getBrowser();
return webBrowser.isAndroid() || webBrowser.isIPhone() || webBrowser.isWindowsPhone();
}

If anyone is interested i found a way around CSS, even if i think it's a bit limited.
I used HttpServletRequest, VaadinService and VaadinServletRequest: I basically checked if words like "Mobile", "iPhone" or "Android" are in the request.
It's not an elegant solution, but it works. This is the code:
public static boolean isPhone(HttpServletRequest request) {
String url = request.getHeader("User-Agent");
return (url.contains("iPhone") || url.contains("Android"));
}

Related

Android BLE. Is it possible to use a regex as a filter to scan for Mac Address?

I have to build an App that scans for BLE devices, and return it's data.
The devices won't show on scan, unless I use a filter.
UUID is not an option, and the device does not broadcast it's name (It shows N/A when scanned with nrfConnect.
I am trying to scan it by MAC Address. BUT, I do not know the MAC Addresses, since it can be any device of it's kind, so the App won't previously know the MAC Address of the device.
I already know that the device have a prefix on it's Address which is F8:36:9B. The thing is the suffix. How can I (and if it is possible to) make a regex to pass as a parameter to find all possible matches of the Device MAC Address?
The regex per se, I have, ([A-Fa-f0-9]{2}:){2}[A-Fa-f0-9]{2}, which I got from Android Bluetooth ScanFilter Partial String Matching.
I just don't know how to implement it on the scanFilter.
ScanFilter filterMac = new ScanFilter.Builder().setDeviceAddress(/**THE_SUFIX_AND_REGEX*/).build();
Is it possible? If it is, then how?
Everything I tried, I get this error:
Error: invalid device address
I have tried generating all the possible matches using for loops and saving it to an ArrayList, and then adding it to the list of filters, but I get an OutOfMemoryException, since the result is over 16million possibilities.
Not possible with filters. You must filter yourself...like you did already
After a lot of struggle, I found a solution to my problem.
It does not answer the question per se, i.e. if it's possible to use a regex as a filter to scan for MAC Address.
But, I managed to properly scan for the devices I needed.
This is what I did:
First of all, I made a filter by name. Yes, name, the device have no name. So I had to think... What if, I filter by name, to scan for devices whose name == null?
private List<ScanFilter> scanFilters() {
List<ScanFilter> list = new ArrayList<ScanFilter>();
ScanFilter scanFilterName = new ScanFilter.Builder().setDeviceName(null).build();
list.add(scanFilterName);
return list;
}
Well, it worked! But, it returned me not only the devices I needed, but tons of other devices, alongside with them. It was a mess in my scan, so how to refine the filter to give me only those ones I needed?
The second filter (which wasn't on the scanFilters()method above, it was on the scanResult), was by MAC Address prefix (which is the same for my devices).
private Set<String> btDevice = new LinkedHashSet<String>();
private ScanCallback scanCallback = new ScanCallback() {
#Override
public void onScanResult(int callbackType, ScanResult result) {
BluetoothDevice device = result.getDevice();
ScanRecord record = result.getScanRecord();
byte[] dataByteArray = record.getBytes();
if (device.getAddress().startsWith("F8:36:9B")) {
btDevice.add(device.getAddress());
}
}
};
And voilá, I got a scan with only the devices I needed.
I still want to know if the main question is possible, i.e. if we can use a regex on the scanFilter(), to filter a range of something (in this case, MAC Address). So, if someone have a solution to this, please feel free to answer.
Thanks!

How to detect device name in Safari on iOS 13 using apache WebSession in Java?

I am working on an Apache Wicket WebApplication in Java. In this application I have a general method to detect the user device using the user agent. However, since the iOS 13 update my check is not working anymore for the iPad as the user agent returns MacIntel or Intel Mac for both, iPad and PC. I checked and found that this issue has already been discussed here:
Link 1
Link 2
Link 3
But these solutions are only for JavaScript. I need to handle this in Java (org.apache.wicket.protocol.http.WebSession). In the properties of the WebSession there exist no method for extracting the number of touch points. Can anybody help me getting the number of touch points or has another idea how to solve this issue. Thank you.
My current code looks like this:
public static boolean isTablet(WebSession pWebSession) {
String userAgent = pWebSession.getClientInfo().getUserAgent();
if (userAgent != null && (userAgent.contains("iPad")
|| (userAgent.contains("Android") && !userAgent.contains("Mobile")))
|| (userAgent.contains("PlayBook"))) {//BlackBerry tablet
return true;
}
return false;
}
You can try to use yauaa instead of Wicket internal user Agent which is quite old and therefore has been deprecated in version 8 and it will be removed for 9.

I am coding in Android Studio, and I need to fetch and display a specific line of data from a specific webpage

I am very new to coding in Java/Android Studio. I have everything setup that I have been able to figure out thus far. I have a button, and I need to put code inside of the button click event that will fetch information from a website, convert it to a string and display it. I figured I would have to use the html source code in order to do this, so I have installed Jsoup html parser. All of the help with Jsoup I have found only leads me up to getting the HTML into a "Document". And I am not sure if that is the best way to accomplish what I need. Can anyone tell me what code to use to fetch the html code from the website, and then do a search through the html looking for a specific match, and convert that match to a string. Or can anyone tell me if there is a better way to do this. I only need to grab one piece of information and display it.
Here is the piece of html code that contains the value I want:
writeBidRow('Wheat',-60,false,false,false,0.5,'01/15/2015','02/26/2015','All',' ',' ',60,'even','c=2246&l=3519&d=G15',quotes['KEH15'], 0-0);
I need to grab and display whatever value represents the quotes['KEH15'], in that html code.
Thank you in advance for your help.
Keith
Grabbing raw HTML is an extremely tedious way to access information from the web, bad practice, and difficult to maintain in the case that wherever you are fetching the info from changes their HTML.
I don't know your specific situation and what the data is that you are fetching, but if there is another way for you to fetch that data via an API, use that instead.
Since you say you are pretty new to Android and Java, let me explain something I wish had been explained to me very early on (although I am mostly self taught).
The way people access information across the Internet is traditionally through HTML and JavaScript (which is interpreted by your browser like Chrome or Firefox to look pretty), which are transferred over the internet using the protocol called HTTP. This is a great way for humans to communicate with computers that are far away, and the average person probably doesn't realize that there is more to the internet than this--your browser and the websites you can go to.
Although there are multiple methods, for the purpose of what I think you're looking for, applications communicate over the internet a slightly different way:
When an android application asks a server for some information, rather than returning HTML and JavaScript which is intended for human consumption, the server will (traditionally) return what's called JSON (or sometimes XML, which is very similar). JSON is a very simple way to get information about an object, and put it into a form that is readable easily by both humans (developers) and computers, and can be transmitted over the internet easily. For example, let's say you ask a server for some kind of "Video" object for an app that plays video, it may give you something like this:
{
"name": "Gangnam Style",
"metadata": {
"url": "https://www.youtube.com/watch?v=9bZkp7q19f0",
"views": 2000000000,
"ageRestricted": false,
"likes": 43434
"dislikes":124
},
"comments": [
{
"username": "John",
"comment": "10/10 would watch again"
},
{
"username": "Jane",
"number": "12/10 with rice"
}
]
}
That is very readable by us humans, but also by computers! We know the name is "Gangnam Style", the link of the video, etc.
A super helpful way to interact with JSON in Java and Android is Google's GSON library, which lets you cast a Java object as JSON or parse a JSON object to a Java object.
To get this information in the first place, you have to make a network call to an API, Application Programming Interface. Just a fancy term for communication between a server and a client. One very cool, free, and easy to understand API that I will use for this example is the OMDB API, which just spits back information about movies from IMDB. So how do you talk to the API? Well luckily they've got some nice documentation, which says that to get information on a movie we need to use some parameters in the url, like perhaps
http://www.omdbapi.com/?t=Interstellar
They want a title with the parameter "t". We could put a year, or return type, but this should be good to understand the basics. If you go to that URL in your browser, it spits back lots of information about Interstellar in JSON form. That stuff we were talking about! So how would you get this information from your Android application?
Well, you could use Android's built in HttpUrlConnection classes and research for a few hours on why your calls aren't working. But doesn't essentially every app now use networking? Why reinvent the wheel when virtually every valuable app out there has probably done this work before? Perhaps we can find some code online to do this work for us.
Or even better, a library! In particular, an open source library developed by Square, retrofit. There are multiple libraries like it (go ahead and research that out, it's best to find the best fit for your project), but the idea is they do all the hard work for you like low level network programming. Following their guides, you can reduce a lot of code work into just a few lines. So for our OMDB API example, we can set up our network calls like this:
//OMDB API
public ApiClient{
//an instance of this client object
private static OmdbApiInterface sOmdbApiInterface;
//if the omdbApiInterface object has been instantiated, return it, but if not, build it then return it.
public static OmdbApiInterface getOmdbApiClient() {
if (sOmdbApiInterface == null) {
RestAdapter restAdapter = new RestAdapter.Builder()
.setEndpoint("http://www.omdbapi.com")
.build();
sOmdbApiInterface = restAdapter.create(OmdbApiInterface.class);
}
return sOmdbApiInterface;
}
public interface OmdbApiInterface {
#GET("/")
void getInfo(#Query("t") String title, Callback<JsonObject> callback);
}
}
After you have researched and understand what's going on up there using their documentation, we can now use this class that we have set up anywhere in your application to call the API:
//you could get a user input string and pass it in as movieName
ApiClient.getOmdbApiClient().getInfo(movieName, new Callback<List<MovieInfo>>() {
//the nice thing here is that RetroFit deals with the JSON for you, so you can just get information right here from the JSON object
#Override
public void success(JsonObject movies, Response response) {
Log.i("TAG","Movie name is " + movies.getString("Title");
}
#Override
public void failure(RetrofitError error) {
Log.e("TAG", error.getMessage());
}
});
Now you've made an API call to get info from across the web! Congratulations! Now do what you want with the data. In this case we used Omdb but you can use anything that has this method of communication. For your purposes, I don't know exactly what data you are trying to get, but if it's possible, try to find a public API or something where you can get it using a method similar to this.
Let me know if you've got any questions.
Cheers!
As #caleb-allen said, if an API is available to you, it's better to use that.
However, I'm assuming that the web page is all you have to work with.
There are many libraries that can be used on Android to get the content of a URL.
Choices range from using the bare-bones HTTPUrlConnection to slightly higher-level HTTPClient to using robust libraries like Retrofit. I personally recommend Retrofit. Whatever you do, make sure that your HTTP access is asynchronous, and not done on the UI thread. Retrofit will handle this for you by default.
For parsing the results, I've had good results in the past using the open-source HTMLCleaner library - see http://htmlcleaner.sourceforge.net
Similar to JSoup, it takes a possibly-badly-formed HTML document and creates a valid XML document from it.
Once you have a valid XML document, you can use HTMLCleaner's implementation of the XML DOM to parse the document to find what you need.
Here, for example, is a method that I use to parse the names of 'projects' from a <table> element on a web page where projects are links within the table:
private List<Project> parseProjects(String html) throws Exception {
List<Project> parsedProjects = new ArrayList<Project>();
HtmlCleaner pageParser = new HtmlCleaner();
TagNode node = pageParser.clean(html);
String xpath = "//table[#class='listtable']".toString();
Object[] tables = node.evaluateXPath(xpath);
TagNode tableNode;
if(tables.length > 1) {
tableNode = (TagNode) tables[0];
} else {
throw new Exception("projects table not found in html");
}
TagNode[] projectLinks = tableNode.getElementsByName("a", true);
for(int i = 0; i < projectLinks.length; i++) {
TagNode link = projectLinks[i];
String projectName = link.getText().toString();
String href = link.getAttributeByName("href");
String projectIdString = href.split("=")[1];
int projectId = Integer.parseInt(projectIdString);
Project project = new Project(projectId, projectName);
parsedProjects.add(project);
}
return parsedProjects;
}
If you have permission to edit the webpage to add hyper link to specified line of that page you can use this way
First add code for head of line that you want to go there in your page
head your text if wanna
Then in your apk app on control click code enter
This.mwebview.loadurl("https:#######.com.html#target")
in left side of # enter your address of webpage and then #target in this example that your id is target.
Excuse me if my english lang. isn't good

How can I control the usage of a custom jar library?

I need a way to essentially secure my jar library to allow registered apps to use it in their projects and deny usage to apps that weren't approved by me.
It is fine if I hard code things in the lib for each distribution. I currently have this jar obfuscated.
What are good approaches to restrict the usage of a jar?
One idea was to lock the lib to a specific package so if the developer tries to use it in another project they can't. But I'm not sure if they can easily provide a custom fake Context to make it work...
To me the best approach if you would like your library to stay standalone (without involving the network for checking or downloading pieces of the library, I mean) would be to make mandatory the use of an initializer class that would receive a token from the client application.
This would be crackable as the token validity test would be performed by your lib: one may modify the lib in a way is would just skip that test, but this would be made harder by the obfuscation. But this is probably sufficient, unless using your lib without having registered it is a really critical issue.
So you would have something like:
boolean Initializer.initLib(String passcode)
That would prevent the lib to work unless passcode is correct.
You can make the obfuscation more efficient by avoiding checking that way:
public void initLib(String passcode) {
if (passcode == A_GIVEN_PUBLIC_STATIC_THAT_STORESTHE_CODE) {
// do the proper initializations
}
else {
throw new RuntimeException("Bad passcode, sorry!");
}
}
But doing that way instead:
public void initLib(String passcode) {
final char[] PASS_ENCRYPTED = "f5uhjgf56ik8kv214d5".toCharArray();
final char[] PASS_MINUSMASK = "bc".toCharArray();
final int PASS_SHIFT = 11;
final int PASS_MASK_MINUS = 2;
for (int ctr = 0; ctr < PASS_MINUSMASK.length; ++ctr) {
final char next = PASS_ENCRYPTED[PASS_SHIFT + ctr - PASS_MASK_MINUS];
if (passcode.charAt(ctr) != next - (PASS_MINUSMASK[ctr] - 'a')) {
// make the lib unusable by some inits. But it should look as a proper initialization
return;
}
}
// make the lib usable by some inits.
}
This looks stupid, but if you have a look at the obfuscated code, you will see a big difference. This code is just an example (it accepts "hi" as a valid passcode), any algorithm would be fine as long as its obfuscated version is not too straightforward to reverse.
Now the question is: what passcode?
As the library's protection concerns the developpers of the client apps that will use it, and not the final users of these apps, you cannot rely on any piece of data specific to the devices on which the applications will run. So no IMEI or anything like that.
If these developpers are trustworthy that's fine. A fixed passcode is sufficient.
But if they are subject to give this passcode to other people to allow them using your library, this is more difficult. In this case I don't think you can solve it without a real "industrial" process such as registering the client apps and their code checksums, for example. Such a process needs a specific design and cannot be solved "just by the code", but as it also has a cost (time, resources, involvment of the client...) you can only consider this if the use of library is very critical.
Can't you make your jar call your server with a specific code and the application name, to check if they are registered ?
When you build an Android app with a jar, that jar is compiled into the app and becomes a part of it. You can't just copy the jar out of the package and use it elsewhere. Unless I'm not understanding the question, this shouldn't be an issue you need to worry about.

Dropbox android sdk documentation

I have been doing some research, and for the life of me, I cannot find any documentation on how to use the android dropbox SDK. I have authenticated the user, but now I cannot figure out how the get the metadata (file entries) of a folder. I have looked at the Web docs, but the arguments in java are turned around, flipped over, and then some.
In objective-c, the methods are straight forward, and I understand what is going on. Must I port the code from objective-c to java?
As far as I can tell as of Sep 20, 2011, Dropbox still hasn't put the Android SDK documentation. Here are some workarounds:
This guy created his own version based on the official Dropbox SDK. https://github.com/mlamina/DropboxSDK-for-Android
This forum post gives some tips. In particular, they suggest looking at the Python documentation. http://forums.dropbox.com/topic.php?id=25318
[EDIT by anotheranon user]
My friend stumbled upon this official documentation from Dropbox. Don't even know how he found it. Since this thread is also where I gave up I would like to share!
You should be to find your answer here: https://www.dropbox.com/developers. Looks like the SDK is undocumented.
Try making the calls to the API directly.
In the SDK (DropboxSample), this will list the files in the Public folder of the user account:
In DropboxSample.java add:
public void displayFiles(DropboxAPI.Account account) {
if (account != null) {
DropboxAPI.Entry dbe = api.metadata("dropbox", "/Public", 10000, null, true);
List<Entry> contents = dbe.contents;
if (contents != null) {
for (Entry ent:contents) {
Toast.makeText(this, ent.fileName(), Toast.LENGTH_SHORT).show();
}
}
}
}
In LoginAsyncTask.java add:
mDropboxSample.displayFiles(mAccount);
below mDropboxSample.displayAccountInfo(mAccount);

Categories

Resources