Java Question How to use code with lambda?

DonManfred

Expert
Licensed User
Longtime User
I was asked to help creating a wrapper for TapKey Securitykeys.

They provide sample Androidapplication in which they are using lambda.

https://developers.tapkey.io/mobile/android/getting_started/

The Example app can be found here: https://github.com/tapkey/android-s...src/main/java/net/tpky/demoapp/authentication

In the mainactivity it starts with a check.
https://github.com/tapkey/android-s.../main/java/net/tpky/demoapp/MainActivity.java
B4X:
public class MainActivity extends AppCompatActivity
        implements NavigationView.OnNavigationItemSelectedListener {

    private static final String TAG = MainActivity.class.getSimpleName();

    private UserManager userManager;
    private Auth0PasswordIdentityProvider passwordIdentityProvider;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        /*
         * Retrieve the TapkeyServiceFactory singleton.
         */
        App app = (App) getApplication();
        TapkeyServiceFactory tapkeyServiceFactory = app.getTapkeyServiceFactory();

        ConfigManager configManager = tapkeyServiceFactory.getConfigManager();
        userManager = tapkeyServiceFactory.getUserManager();
        passwordIdentityProvider = app.getPasswordIdentityProvider();

        /*
         * When no user is signed in, redirect to login LoginActivity
         */
        if(!userManager.hasUsers()){
            Intent intent = new Intent(this, LoginActivity.class);
            startActivity(intent);
            finish();
            return;
        }

        setContentView(R.layout.activity_main);
        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);

        DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
        ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
                this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close);
        drawer.addDrawerListener(toggle);
        toggle.syncState();

        NavigationView navigationView = (NavigationView) findViewById(R.id.nav_view);
        navigationView.setNavigationItemSelectedListener(this);

        View headerView = navigationView.getHeaderView(0);
        TextView usernameTextView = (TextView) headerView.findViewById(R.id.nav_header__username);

        /*
         * Get the username of first user and display it in side menu. The first user is used here,
         * because we don't support multi-user yet anyways.
         */
        User firstUser = userManager.getFirstUser();
        if(firstUser != null){
            usernameTextView.setText(firstUser.getIpUserName());
        }

        /*
         * Verify, that app is compatible
         */
        configManager.getAppState(CancellationTokens.None)

                // asynchronously receive the operation result on the UI thread
                .continueOnUi((Func1<ConfigManager.AppState, Void, Exception>) appState -> {

                    // some time might have passed and maybe the activity is already finishing.
                    if (isFinishing())
                        return null;


                    switch (appState) {

                        // SDK Version is not supported anymore
                        case CLIENT_TOO_OLD:

                            new AlertDialog.Builder(MainActivity.this)
                                    .setMessage(R.string.main_app_too_old)
                                    .setPositiveButton(R.string.app_too_old_button, new DialogInterface.OnClickListener() {
                                        public void onClick(DialogInterface dialog, int id) {
                                            finish();
                                        }
                                    })
                                    .setOnDismissListener(dialogInterface -> {

                                        // TODO: Redirect to the app store, to let the user
                                        // download the latest app version.

                                        finish();
                                    })
                                    .create()
                                    .show();

                            break;

                        // This version of the SDK is still supported but is short before expiring and should be updated.
                        case CLIENT_UPDATE_SUGGESTED:

                            new AlertDialog.Builder(MainActivity.this)
                                    .setMessage(R.string.newer_app_available)
                                    .setPositiveButton(R.string.newer_app_available_button, null)
                                    .create()
                                    .show();

                            break;

                        case CLIENT_VERSION_OK:
                        default:
                    }

                    return null;
                })

                // Handle exceptions raised in async code.
                .catchOnUi(e -> {

                    // Handle error
                    Log.e(TAG, "failed to fetch app state: ", e);
                    return null;
                })

                // Make sure, no exceptions get lost.
                .conclude();
    }

How can i use such code in my wrapper?

Do i need to develop the library with Android Studio? As of now i am using Eclipse for syntaxhelp and SLC to compile.

I can into an error in SLC for sure

E:\B4ALibs.workspace\TapKeySDK\src\de\donmanfred\TapKeyAppwrapper.java:60: error: lambda expressions are not supported in -source 7
AsyncSchedulers.setSchedulerInterceptor((x, name) -> AsyncSchedulerUtils.applyLogging(x, name, 500, 10000));
^
(use -source 8 or higher to enable lambda expressions)
1 error

javac 11.0.1

Error.

Any suggestions/hints?

PD: The Device used is using Android 7+
 
Last edited:

moster67

Expert
Licensed User
Longtime User
I am not at home now but you should be able to replace the Lamda with an Anonymous class. After that you can compile with SLC.
 

moster67

Expert
Licensed User
Longtime User
Try the modified MainActivity.java class I have attached.

As a general note, I think it is much easier to work and wrap libs with Android Studio.
In this case, in Android Studio, you can simply highlight the "->" sign and then type ALT + ENTER and you get an option to automatically convert Lamda into an Anonymous class. Now you can compile with SLC.
 

Attachments

  • MainActivity.java
    8.8 KB · Views: 408

DonManfred

Expert
Licensed User
Longtime User
As a general note, I think it is much easier to work and wrap libs with Android Studio.
I tried to follow the Tutorial about Android Studio and i failed. I was using a recent AS though.
Can you upload a AS-Project with a small example wrapper? Or help me configuring AS or the build scripts using a Remotedesktopconnection (would like to donate for a bit help to get started)?
In this case, in Android Studio, you can simply highlight the "->" sign and then type ALT + ENTER and you get an option to automatically convert Lamda into an Anonymous class.
in the beginning i was not sure that i understand what a anonymous class is. But after using this "trick" i know better. Thank you for this tip! At least i could use AS now to convert the code to not use lamda :)
The code in the example main was just an example. It was more important to adapt the Authproviderclass.

I now converted the java files in AS to use anonymous classes and then i copied over the files to my Eclipse project. And, hopefully, i do come futher now. I´ll inform you...

Many thanks for this - really useful - hint :)
 
Top