Categories
discuss

Use Android AccountManager to do AppEngine login through UserService

I’m using Google AppEngine, and I’m using their UserService class to handle user accounts and logging in. I don’t need to access any information about their account – I’m just using it to differentiate users.

Now the website is mostly just a backend. I’m using an Android app for the frontend. I know you can access Google user accounts on the device using the AccountManager. It’s definitely the safest way to get a user to log in. And I got that much to work.

Where I’m stuck is passing the login information from the Android app to the AppEngine website. From what I’ve ready I should be using OAuth, and I see the walkthrough here for using it with Google APIs, but I don’t need to access an API, just to log in. I’ve been able to acquire an Authentication Token in the app, but I’m not sure how to pass it to the website, or if that’s even the right direction. Should I be using a specific OAuth login on the server, like this guy?

Any help would be greatly appreciated!

Here’s the relevant code:

Server (GAE):

UserService userService = UserServiceFactory.getUserService();
User user = userService.getCurrentUser();

if (user == null) {
    resp.sendRedirect(userService.createLoginURL(req.getRequestURI()));
    return;
} 

Client (Android):

AccountManager am = AccountManager.get(this);
Account[] accounts = am.getAccountsByType("com.google");

Bundle options = new Bundle();

am.getAuthToken(
        accounts[0],                     // Account retrieved using getAccountsByType()
        "Manage your tasks",            // Auth scope
        options,                        // Authenticator-specific options
        this,                           // Your activity
        new OnTokenAcquired(),          // Callback called when a token is successfully acquired
        new Handler(new OnError()));
//Now what!?

Answer

This blog post covered exactly what I needed.

For two alternate (and in my opinion less than ideal) solutions, check out this thread: Webservice credentials – OpenID/Android AccountManager?

Categories
discuss

Android: How to find views by type

Ok so I have a layout xml similar to the following example:

<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="@drawable/tile_bg" >

<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical"
    android:paddingTop="10dp" >

    <LinearLayout
        android:id="@+id/layout_0"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal" >

        <!-- view stuff here -->
    </LinearLayout>

    <!-- more linear layouts as siblings to this one -->

</LinearLayout>

I actually have about 7 LinearLayout items each with id increasing from layout_0 etc. I want to be able to get hold of all the LinearLayout items under the root LinearLayout. Do I need to put an id on the root one and find all others by id or can I get them by type.

The code I use to inflate the layout is:

View view = (View) inflater.inflate(R.layout.flight_details, container, false);

I read somewhere that you can iterate children of a ViewGroup but this is only a View.

What is the best way to get a bunch of children by type?

Answer

This should get you on the right track.

LinearLayout rootLinearLayout = (LinearLayout) findViewById(R.id.rootLinearLayout);
int count = rootLinearLayout.getChildCount();
for (int i = 0; i < count; i++) {
    View v = rootLinearLayout.getChildAt(i);
    if (v instanceof LinearLayout) {
        ...
    }
}
Categories
discuss

Passing options to chrome driver selenium

I am trying to disable the output to the console for chrome. If I pass the –start-maximized option it works fine. I may have the wrong command?

DesiredCapabilities capabilities = DesiredCapabilities.chrome();
capabilities.setCapability("chrome.switches", Arrays.asList("--silent"));
chrome = new ChromeDriver(_chromeservice,capabilities);

I also tried

 ChromeOptions options = new ChromeOptions();
 options.addArguments("silent");
 chrome = new ChromeDriver(options);

Output

Started ChromeDriver port=26703 version=23.0.1240.0 log=/Brett/workspace/TestNG/chromedriver.log [1214/161331:ERROR:ipc_sync_channel.cc(378)] Canceling pending sends [1214/161331:ERROR:ipc_sync_channel.cc(378)] Canceling pending sends [1214/161331:ERROR:ipc_sync_channel.cc(378)] Canceling pending sendsBlockquote

Answer

Hinted by this Chromedriver ticket (about the silent option), I looked in the source of ChromeDriverService.java, and found a reference to "webdriver.chrome.logfile".

After adding -Dwebdriver.chrome.logfile="/dev/null" to my java command, the logs became readable again: The usless ChromeDriver logs were gone, while theSystem.out.println calls and exceptions are still shown in the console.

I start java with the following parameters (Linux / Mac):

DIR=path/to/dir/containing/selenium/and/stuff
cd "$DIR" && java -cp "$DIR
:$DIR/output
:$DIR/bin/selenium-server-standalone-2.33.0.jar" 
-Dwebdriver.chrome.driver="$DIR/bin/chromedriver" 
-Dwebdriver.chrome.args="--disable-logging" 
-Dwebdriver.chrome.logfile="/dev/null" 
AllTests

If you’re on Windows:

set DIR=pathtodircontainingseleniumandstuff
cd "%DIR%" && java -cp "%DIR%;%DIR%output;%DIR%binselenium-server-standalone-2.33.0.jar" ^
-Dwebdriver.chrome.driver="%DIR%binchromedriver.exe" ^
-Dwebdriver.chrome.args="--disable-logging" ^
-Dwebdriver.chrome.logfile=NUL ^
AllTests

Explanation for the composition of my classpath (-cp): My tests are located in a directory at “$DIR/output”. The Selenium jar file is placed in “$DIR/bin/selenium-server-standalone-2.33.0.jar”. “AllTests” is the name of my class containing public static void main(String[] args) – this launches my tests.

The other parameters are self-explanatory, adjust it to your needs. For convenience (used in a shell/batch script), I’ve declared the common directory in a variable DIR.

Categories
discuss

Factory in Java when concrete objects take different constructor parameters

I’m trying to implement a Factory pattern in Java. I have a class called Shape which Circle and Triangle extends. The problem is that Shape constructor gets only 2 parameters while Circle gets 3 parameters and so is Triangle (which I won’t show in the code section because is identical to Circle). To demonstrate it better:

    private interface ShapeFactory{
        public Shape create(int x, int y);
    }

    private class CircleFactory implements ShapeFactory{
        public Shape create(float radius, int x, int y){ //error
            return new Circle(radius, x,y);
        }
    }

Any ideas how to overcome this problem? I must not recieve an input from user inside the factory (must be recieved from outside).

Thanks!

Answer

You have two options:

1) Abstract Factory:

RectangularShape extends Shape

RoundShape extends Shape

and RectangularShapeFactory and RoundShapeFactory

2) Builder (see also Item 2 in Effective Java)

public Shape {
    private final int x;
    private final int y;
    private final double radius;

    private Shape(Builder builder) {
        x = builder.x;
        y = builder.y;
        radius = builder.radius;
    }

    public static class Builder {
        private final int x;
        private final int y;
        private double radius;

        public Builder(int x, int y) {
            this.x = x;
            this.y = y;
        }

        public Builder radius(double radius) {
            this.radius = radius;
            return this;
        }

        public Shape build() {
            return new Shape(this);
        }    
    }
}

//in client code 

    Shape rectangle = new Shape.Builder(x,y).build();
    Shape circle = new Shape.Builder(x,y).radius(radiusValue).build();
Categories
discuss

Is there a way to explicitly control WiFi scan intervals in Android?

I am doing my Master thesis at the moment on WiFi positioning and in order to test my algorithms I needed to collect some data.

To do this I have written a short and very simple program for Android which simply collects the RSSI for all availible access points found by each scan and saves them to file. I have set up a BroadcastReceiver that listens on the event WifiManager.SCAN_RESULTS_AVAILABLE_ACTION and I use a Timer, here called tim, to initiate scans with a WifiManager, called wifi as follows:

tim.schedule(new TimerTask(){
        @Override
        public void run(){
            wifi.startScan();
        }
}, 0, 1000);

The problem I am having now is that the initiated scans don’t seem to happen every second even if I succeed in initiating them and every now and then there are other scans initiated from some other app that gets recorded as well.

Is there any easy way to scan on a set interval and not receive the scans initiated by some other app?

The whole app can be found on https://github.com/while/RSSIMiner if it helps in any way.

Answer

Is there any easy way to scan on a set interval?

If this doesn’t work well, I’m afraid not. From my experience, “hardware related” methods may not work exactly like their definition says. For example, I once created a small app which records your position every X minutes. So I call requestLocationUpdates with some minTime parameter. But my phone simply ignores the minTime value, and I get updates from the GPS as soon as they’re available, whcih is not what I wanted. I posted a question about it here, and got this answer, from which we learn that prior to jelly bean, devices may simply ignore this value…

So it may be something similar now. I’d try to run this code on the latest Android version. And I don’t understand that much in Wifi, but isn’t 1 second a too frequent interval for scans? Perhaps the system doesn’t ignore the scan request (So it returns true) but the hardware does?

Can we ignore the scans initiated by some other app?

As far as I know, it’s negative here too. There are no extras contained in the SCAN_RESULTS_AVAILABLE_ACTION broadcast so you can’t know which app initiated the scan.

The best solution will be to defnie your requirements. You can use the ScanResult.timestamp to determine if you should use this result or not. For example, if you’re trying to get the RSSI for each access point each second, you can compare the current BSSID to previous BSSIDs. If the current BSSID was included in a scan result from the last second, you can simply ignore it. Then, it doesn’t matter how many results you get.

Another, much more simple soltuion will be to create a boolean called scanInitiated and set it to true when starting a scan. When receiving the broacast, use the data only if scanInitiated is true, and then set it to false. This isn’t so reliable when the intervals are short, but for long intervals it will work great.

Source: stackoverflow
Text is available under the Creative Commons Attribution-ShareAlike License; additional terms may apply. By using this site, you agree to the Privacy Policy, and Copyright Policy. Content is available under CC BY-SA 3.0 unless otherwise noted. The answers/resolutions are collected from stackoverflow, are licensed under cc by-sa 2.5 , cc by-sa 3.0 and cc by-sa 4.0 © No Copyrights, All Questions are retrived from public domain..