├── .github └── workflows │ ├── bintray-publish.yml │ └── gradle-build.yml ├── .gitignore ├── App integration flow.PNG ├── LICENSE ├── README.md ├── android-webui-sdk.iml ├── build.gradle ├── demoapp ├── .gitignore ├── build.gradle ├── demoapp.iml ├── proguard-rules.pro └── src │ ├── library │ ├── java │ │ └── com │ │ │ └── queue_it │ │ │ └── shopdemo │ │ │ ├── DeepActivity.java │ │ │ ├── FirstFragment.java │ │ │ ├── MainActivity.java │ │ │ ├── ResultActivity.java │ │ │ └── SecondFragment.java │ └── res │ │ └── layout │ │ ├── activity_deep.xml │ │ ├── activity_main.xml │ │ ├── activity_result.xml │ │ ├── content_deep.xml │ │ ├── fragment_first.xml │ │ └── fragment_second.xml │ ├── library_androidx │ ├── java │ │ └── com │ │ │ └── queue_it │ │ │ └── shopdemo │ │ │ ├── DeepActivity.java │ │ │ ├── FirstFragment.java │ │ │ ├── MainActivity.java │ │ │ ├── ResultActivity.java │ │ │ └── SecondFragment.java │ └── res │ │ └── layout │ │ ├── activity_deep.xml │ │ ├── activity_main.xml │ │ ├── activity_result.xml │ │ ├── content_deep.xml │ │ ├── fragment_first.xml │ │ └── fragment_second.xml │ └── main │ ├── AndroidManifest.xml │ ├── java │ └── com │ │ └── queue_it │ │ └── shopdemo │ │ └── TextValidator.java │ └── res │ ├── drawable │ ├── ic_check_black_24dp.xml │ ├── ic_error_black_24dp.xml │ ├── ic_play_arrow_white_48px.xml │ └── ic_replay_white_48px.xml │ ├── mipmap-hdpi │ └── ic_launcher.png │ ├── mipmap-mdpi │ └── ic_launcher.png │ ├── mipmap-xhdpi │ └── ic_launcher.png │ ├── mipmap-xxhdpi │ └── ic_launcher.png │ ├── mipmap-xxxhdpi │ └── ic_launcher.png │ ├── navigation │ └── nav_graph.xml │ ├── values-w820dp │ └── dimens.xml │ └── values │ ├── colors.xml │ ├── dimens.xml │ ├── strings.xml │ └── styles.xml ├── demowithprotectedapi ├── .gitignore ├── build.gradle ├── proguard-rules.pro └── src │ ├── androidTest │ └── java │ │ └── com │ │ └── example │ │ └── demowithprotectedapi │ │ └── ExampleInstrumentedTest.java │ ├── main │ ├── AndroidManifest.xml │ ├── java │ │ └── com │ │ │ └── example │ │ │ └── demowithprotectedapi │ │ │ ├── FirstFragment.java │ │ │ ├── MainActivity.java │ │ │ ├── api │ │ │ ├── Product.java │ │ │ ├── ProductFilter.java │ │ │ └── ProductsService.java │ │ │ ├── exceptions │ │ │ └── MustBeQueued.java │ │ │ ├── http │ │ │ ├── AddCookiesInterceptor.java │ │ │ ├── CookieStorage.java │ │ │ ├── QueueITInterceptor.java │ │ │ ├── ReceivedCookiesInterceptor.java │ │ │ └── UserAgentInterceptor.java │ │ │ └── repos │ │ │ ├── IProductRepository.java │ │ │ ├── ProductRepository.java │ │ │ └── RetrofitProductRepository.java │ └── res │ │ ├── drawable-v24 │ │ └── ic_launcher_foreground.xml │ │ ├── drawable │ │ └── ic_launcher_background.xml │ │ ├── layout │ │ ├── activity_main.xml │ │ ├── content_main.xml │ │ └── fragment_first.xml │ │ ├── menu │ │ └── menu_main.xml │ │ ├── mipmap-anydpi-v26 │ │ ├── ic_launcher.xml │ │ └── ic_launcher_round.xml │ │ ├── mipmap-hdpi │ │ ├── ic_launcher.webp │ │ └── ic_launcher_round.webp │ │ ├── mipmap-mdpi │ │ ├── ic_launcher.webp │ │ └── ic_launcher_round.webp │ │ ├── mipmap-xhdpi │ │ ├── ic_launcher.webp │ │ └── ic_launcher_round.webp │ │ ├── mipmap-xxhdpi │ │ ├── ic_launcher.webp │ │ └── ic_launcher_round.webp │ │ ├── mipmap-xxxhdpi │ │ ├── ic_launcher.webp │ │ └── ic_launcher_round.webp │ │ ├── navigation │ │ └── nav_graph.xml │ │ ├── values-night │ │ └── themes.xml │ │ └── values │ │ ├── colors.xml │ │ ├── dimens.xml │ │ ├── strings.xml │ │ └── themes.xml │ └── test │ └── java │ └── com │ └── example │ └── demowithprotectedapi │ └── ExampleUnitTest.java ├── documentation └── protected_apis.md ├── gradle.properties ├── gradle └── wrapper │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── library ├── .gitignore ├── build.gradle ├── library.iml ├── proguard-rules.pro └── src │ ├── library │ └── java │ │ └── com │ │ └── queue_it │ │ └── androidsdk │ │ ├── QueueActivity.java │ │ └── WaitingRoomStateBroadcaster.java │ ├── library_androidx │ └── java │ │ └── com │ │ └── queue_it │ │ └── androidsdk │ │ ├── QueueActivity.java │ │ └── WaitingRoomStateBroadcaster.java │ ├── main │ ├── AndroidManifest.xml │ ├── java │ │ └── com │ │ │ └── queue_it │ │ │ └── androidsdk │ │ │ ├── Error.java │ │ │ ├── IUriOverrider.java │ │ │ ├── IWaitingRoomStateBroadcaster.java │ │ │ ├── QueueActivityBase.java │ │ │ ├── QueueCache.java │ │ │ ├── QueueDisabledInfo.java │ │ │ ├── QueueITApiClient.java │ │ │ ├── QueueITApiClientListener.java │ │ │ ├── QueueITEngine.java │ │ │ ├── QueueITException.java │ │ │ ├── QueueITWaitingRoomProvider.java │ │ │ ├── QueueITWaitingRoomProviderListener.java │ │ │ ├── QueueITWaitingRoomView.java │ │ │ ├── QueueItEngineOptions.java │ │ │ ├── QueueListener.java │ │ │ ├── QueuePassedInfo.java │ │ │ ├── QueueService.java │ │ │ ├── QueueServiceListener.java │ │ │ ├── QueueTryPassResult.java │ │ │ ├── QueueUrlHelper.java │ │ │ ├── RedirectType.java │ │ │ ├── UriOverrideWrapper.java │ │ │ ├── UriOverrider.java │ │ │ └── UserAgentManager.java │ └── res │ │ ├── layout │ │ └── activity_queue.xml │ │ └── values │ │ └── strings.xml │ └── test │ ├── java │ └── com │ │ └── queue_it │ │ └── androidsdk │ │ └── UriOverriderTest.java │ └── resources │ └── robolectric.properties ├── publish.gradle └── settings.gradle /.github/workflows/bintray-publish.yml: -------------------------------------------------------------------------------- 1 | name: Publish to bintray on closed PR 2 | on: 3 | release: 4 | types: [released] 5 | 6 | jobs: 7 | gradle: 8 | strategy: 9 | matrix: 10 | os: [ubuntu-latest] 11 | runs-on: ${{ matrix.os }} 12 | steps: 13 | - uses: actions/checkout@v2 14 | # Export properties 15 | - name: Setup bintray credentials 16 | env: 17 | BINTRAY_APIKEY: ${{ secrets.BINTRAY_APIKEY }} 18 | run: | 19 | echo "bintray.user=queueitdevs" > ./local.properties 20 | echo "bintray.apiKey=${BINTRAY_APIKEY}" >> ./local.properties 21 | - uses: actions/setup-java@v1 22 | with: 23 | java-version: 11 24 | - uses: eskatos/gradle-command-action@v1 25 | with: 26 | arguments: assembleLibrary_androidx :library:assembleLibrary bintrayUpload -------------------------------------------------------------------------------- /.github/workflows/gradle-build.yml: -------------------------------------------------------------------------------- 1 | name: Run Gradle Build on Push 2 | on: push 3 | jobs: 4 | gradle: 5 | strategy: 6 | matrix: 7 | os: [ubuntu-latest] 8 | runs-on: ${{ matrix.os }} 9 | steps: 10 | - uses: actions/checkout@v2 11 | - name: Create local.properties 12 | run: echo "" >> ./local.properties 13 | - uses: actions/setup-java@v1 14 | with: 15 | java-version: 11 16 | - uses: eskatos/gradle-command-action@v1 17 | with: 18 | arguments: build -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .gradle 2 | /local.properties 3 | /.idea/workspace.xml 4 | /.idea/libraries 5 | .DS_Store 6 | /build 7 | /captures 8 | /.idea/caches/build_file_checksums.ser 9 | /.idea/caches/gradle_models.ser 10 | /.idea/codeStyles/Project.xml 11 | /.vs/android-webui-sdk/v16/.suo 12 | /.vs/slnx.sqlite 13 | /.vs/VSWorkspaceState.json 14 | /private_key_sender.asc 15 | /public_key_sender.asc 16 | .idea 17 | *.gpg 18 | **/build 19 | node_modules 20 | .classpath 21 | .project 22 | *.prefs 23 | dist -------------------------------------------------------------------------------- /App integration flow.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/queueit/android-webui-sdk/574a4e879eca8a715f9b7dcb2734e38a0ebfc466/App integration flow.PNG -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 Queue-it 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [ ![Download](https://maven-badges.herokuapp.com/maven-central/com.queue-it.androidsdk/library/badge.svg) ](https://repo1.maven.org/maven2/com/queue-it/androidsdk/) 2 | 3 | # Queue-it Android WebUI SDK 4 | 5 | Library for integrating Queue-it's virtual waiting room into an Android app written in java. 6 | 7 | ## Sample app 8 | 9 | A sample app to try out functionality in the library can be found on the [Releases](https://github.com/queueit/android-sdk/releases) page. 10 | This sample app uses the first approach of integration calling QueueITEngine run method. 11 | 12 | ## Installation 13 | 14 | Before starting please download the whitepaper "Mobile App Integration" from GO Queue-it Platform. 15 | This whitepaper contains the needed information to perform a successful integration. 16 | 17 | Using Gradle: 18 | 19 | ```gradle 20 | implementation 'com.queue-it.androidsdk:library:2.1.4' 21 | //For AndroidX 22 | //implementation 'com.queue-it.androidsdk:library-androidx:2.1.4' 23 | ``` 24 | 25 | ## How to use the library (Mobile SDK integration only, no API protection) 26 | 27 | As the App developer, you must manage the state (whether the user was previously queued up or not) inside the app's storage. 28 | 29 | After you have received the **onQueuePassed** callback, the app must remember to keep the state, possibly with a date/time expiration. 30 | When the user wants to navigate to specific screens on the app which needs Queue-it protection, your code check this state/variable, and only call SDK methods / **QueueITEngine.run** in the case where the user did not previously queue up. 31 | 32 | Please note that when the user clicks back to navigate back to a protected screen, the same check needs to be done. 33 | 34 | ### Simple SDK integration using run method. 35 | The simplest mobile SDK integration requires you to call one method, run() before showing the protected screen and potentially calling server API which needs peak traffic protection. 36 | Invoke QueueITEngine as per example below. Parameters `layoutName`, `language` and `options` are optional. 37 | 38 | ```java 39 | QueueITEngine engine = new QueueITEngine(YourActivity.this, customerId, eventIdOrAlias, layoutName, language, 40 | new QueueListener() { 41 | 42 | // This callback will be called when the user has been through the queue. 43 | // Here you should store session information, so user will only be sent to queue again if the session has timed out. 44 | @Override 45 | public void onQueuePassed(QueuePassedInfo queuePassedInfo) { 46 | } 47 | 48 | // This callback will be called just before the webview (hosting the queue page) will be shown. 49 | // Here you can change some relevant UI elements. 50 | @Override 51 | public void onQueueViewWillOpen() { 52 | } 53 | 54 | // This callback will be called when the queue used (event alias ID) is in the 'disabled' state. 55 | // Most likely the application should still function, but the queue's 'disabled' state can be changed at any time, 56 | // so session handling is important. 57 | @Override 58 | public void onQueueDisabled(QueueDisabledInfo queueDisabledInfo) { 59 | } 60 | 61 | // This callback will be called when the mobile application can't reach Queue-it's servers. 62 | // Most likely because the mobile device has no internet connection. 63 | // Here you decide if the application should function or not now that is has no queue-it protection. 64 | @Override 65 | public void onQueueItUnavailable() { 66 | } 67 | 68 | // This callback will be called when the mobile application can't reach Queue-it's servers. 69 | // It can be any one of these scenarios: 70 | // 1) Queue-it's servers can't be reached (connectivity issue). 71 | // 2) SSL connection error if custom queue domain is used having an invalid certificate. 72 | // 3) Client receives HTTP 4xx response. 73 | // In all these cases is most likely a misconfiguration of the queue settings: 74 | // Invalid customer ID, event alias ID or cname setting on queue (GO Queue-it portal -> event settings). 75 | @Override 76 | public void onError(Error error, String errorMessage) { 77 | } // Called on connectivity problems 78 | 79 | // This callback will be called after a user clicks a close link in the layout and the WebView closes. 80 | // The close link is "queueit://close". Whenever the user navigates to this link, the SDK intercepts the navigation 81 | // and closes the WebView. 82 | @Override 83 | public void onWebViewClosed(){ 84 | } 85 | 86 | // This callback will be called when the user clicks on a link to restart the session. 87 | // The link is 'queueit://restartSession'. Whenever the user navigates to this link, the SDK intercepts the navigation, 88 | // closes the WebView, clears the URL cache and calls this callback. 89 | // In this callback you would normally call run/runWithToken/runWithKey in order to restart the queueing. 90 | @Override 91 | public void onSessionRestart(QueueITEngine queueITEngine) { 92 | } 93 | }); 94 | 95 | try { 96 | engine.run(YourActivity.this); 97 | } 98 | catch (QueueITException e) { } // Gets thrown when a request is already in progress. In general you can ignore this. 99 | ``` 100 | 101 | 102 | 103 | ![App Integration Flow](https://github.com/queueit/android-webui-sdk/blob/master/App%20integration%20flow.PNG "App Integration Flow") 104 | 105 | 106 | ### QueueITEngine options 107 | 108 | The QueueITEngine can be configured if you use the `options` argument in it's constructor. Here's an example. 109 | 110 | ```java 111 | QueueItEngineOptions options = new QueueItEngineOptions(); 112 | // Use this if you want to disable the back button when the waiting room is shown 113 | options.setBackButtonDisabledFromWR(true); 114 | ``` 115 | 116 | ## Mobile SDK integration with tryPass and showQueue methods: 117 | 118 | If you need finner granularity control over the mobile integration, you can use tryPass and showQue instead of just using run method which will open a webview to the Queue when needed. 119 | 120 | This provides you more control of the logic before potentially opening the webview and showing the Queue page, as well as more control over the webview showing the queue page. 121 | 122 | ### Checking status of Waiting room 123 | 124 | It is possible to get the status of a waiting room to make sure it is ready to be visited. To do this, one of the below methods from **QueueITWaitingRoomProvider** class could be used. 125 | 126 | - tryPass 127 | - tryPassWithEnqueueToken 128 | - tryPassWithEnqueueKey 129 | 130 | Calling any of these methods will result in executing **onSuccess** or **onFailure** callbacks. These two callbacks must be provided by implementing **QueueITWaitingRoomProviderListener** interface and passed to the constructor of **QueueITWaitingRoomProvider** class, and will lead to below: 131 | 132 | - If **isPassedThrough()** retuns true, queueittoken and more information will be available as an argument to **OnSuccess** function with type of **QueueTryPassResult**. 133 | - If **isPassedThrough()** returns false, it means that the waiting room is active. The waitingroom page should be shown to the visitor by calling **showQueue** method of the **QueueITWaitingRoomView**, then the visitor will wait for its turn. The **showQueue** method needs **QueryTryPassResult** object from **OnSuccess** function. 134 | 135 | ## Showing the queue page to visitor 136 | 137 | When waiting room is queueing the visitors, each visitor has to visit the waiting room page once. The queue page could be shown to visitors when it is necessary using **showQueue** method of **QueueITWaitingRoomView** class. 138 | Before calling **showQueue**, the status of the waiting room should be already retrieved as described in [Get waiting room status](#Get-waiting-room-status) to make sure that the waiting room is ready. 139 | 140 | sample code for showing the queue page: 141 | 142 | ```java 143 | QueueITWaitingRoomView queueITWaitingRoomView = new QueueITWaitingRoomView(MainActivity.this, queueListener, queueItEngineOptions); 144 | queueITWaitingRoomView.showQueue(_queuePassedInfo.getQueueUrl(), _queuePassedInfo.getTargetUrl()); 145 | ``` 146 | ## Mobile SDK Integration with proteced API (Queue-it connector on server side): 147 | If your application is using an API that's protected by a Queue-it connector (KnownUser) you can check out [this documentation](https://github.com/queueit/android-webui-sdk/blob/master/documentation/protected_apis.md). 148 | 149 | ## Required permissions 150 | 151 | ```xml 152 | 153 | 154 | ``` 155 | 156 | ## Activities to include in your manifest 157 | 158 | ```xml 159 | 160 | ``` -------------------------------------------------------------------------------- /android-webui-sdk.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /build.gradle: -------------------------------------------------------------------------------- 1 | // Top-level build file where you can add configuration options common to all sub-projects/modules. 2 | 3 | buildscript { 4 | repositories { 5 | google() 6 | mavenCentral() 7 | maven { 8 | url "https://plugins.gradle.org/m2/" 9 | } 10 | } 11 | dependencies { 12 | classpath 'com.android.tools.build:gradle:7.1.1' 13 | classpath 'com.github.dcendents:android-maven-gradle-plugin:2.1' 14 | classpath "io.codearte.gradle.nexus:gradle-nexus-staging-plugin:0.22.0" 15 | classpath "de.marcphilipp.gradle:nexus-publish-plugin:0.4.0" 16 | } 17 | } 18 | apply plugin: 'io.codearte.nexus-staging' 19 | 20 | Properties localProps = new Properties() 21 | if (rootProject.file("local.properties").exists()) { 22 | localProps.load(rootProject.file("local.properties").newDataInputStream()) 23 | } 24 | 25 | subprojects { 26 | tasks.withType(Javadoc).all { enabled = false } 27 | } 28 | 29 | allprojects { 30 | repositories { 31 | google() 32 | mavenCentral() 33 | } 34 | 35 | ext { 36 | groupId = 'com.queue-it.androidsdk' 37 | libraryName = 'com.queue_it.androidsdk' 38 | libraryDescription = 'Android SDK to integrate with Queue-it' 39 | libraryVersion = "2.1.7" 40 | organization = "Queue-it" 41 | organizationUrl = "https://queue-it.com" 42 | 43 | artifact = 'library' 44 | siteUrl = "https://github.com/queueit/android-webui-sdk" 45 | gitUrl = "https://github.com/queueit/android-webui-sdk.git" 46 | 47 | licenseName = 'MIT' 48 | licenseUrl = 'MIT' 49 | allLicenses = ["MIT"] 50 | var = '7.0.0-alpha05' 51 | extraProperties = localProps 52 | 53 | OSSRH_USERNAME = localProps.getProperty("OSSRH_USERNAME") ?: System.getenv("OSSRH_USERNAME") 54 | OSSRH_PASSWORD = localProps.getProperty("OSSRH_PASSWORD") ?: System.getenv("OSSRH_PASSWORD") 55 | PGP_KEY = localProps.getProperty("PGP_KEY") ?: System.getenv("PGP_KEY") 56 | PGP_PASSWORD = localProps.getProperty("PGP_PASSWORD") ?: System.getenv("PGP_PASSWORD") 57 | } 58 | } 59 | 60 | task clean(type: Delete) { 61 | delete rootProject.buildDir 62 | } -------------------------------------------------------------------------------- /demoapp/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /demoapp/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.application' 2 | 3 | android { 4 | compileSdkVersion 30 5 | buildToolsVersion "30.0.3" 6 | 7 | defaultConfig { 8 | applicationId "com.queue_it.shopdemo" 9 | minSdkVersion 15 10 | targetSdkVersion 30 11 | versionCode 1 12 | versionName "1.0" 13 | } 14 | buildTypes { 15 | release { 16 | minifyEnabled false 17 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 18 | } 19 | } 20 | 21 | 22 | flavorDimensions "androidx" 23 | productFlavors{ 24 | library_androidx 25 | //Note that this requires useAndroidx=false 26 | library 27 | } 28 | lint { 29 | abortOnError false 30 | checkReleaseBuilds false 31 | } 32 | } 33 | 34 | dependencies { 35 | implementation fileTree(dir: 'libs', include: ['*.jar', '*.aar']) 36 | //implementation project(path: ':library') 37 | //library_androidxImplementation 'com.queue-it.androidsdk:library-androidx:2.0.34' 38 | library_androidxImplementation project(path: ':library') 39 | //libraryImplementation 'com.queue-it.androidsdk:library:2.0.34' 40 | libraryImplementation project(path: ':library') 41 | 42 | testImplementation 'junit:junit:4.13' 43 | 44 | library_androidxImplementation 'androidx.appcompat:appcompat:1.2.0' 45 | library_androidxImplementation 'androidx.constraintlayout:constraintlayout:2.0.4' 46 | library_androidxImplementation 'androidx.navigation:navigation-fragment:2.3.3' 47 | library_androidxImplementation 'androidx.navigation:navigation-ui:2.3.3' 48 | 49 | libraryImplementation 'com.google.android.material:material:1.3.0' 50 | //noinspection GradleCompatible 51 | libraryImplementation 'com.android.support:appcompat-v7:28.0.0' 52 | } 53 | -------------------------------------------------------------------------------- /demoapp/demoapp.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 10 | 11 | 12 | 13 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | -------------------------------------------------------------------------------- /demoapp/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # By default, the flags in this file are appended to flags specified 3 | # in C:\Users\MortenBrixPedersen\AppData\Local\Android\Sdk/tools/proguard/proguard-android.txt 4 | # You can edit the include path and order by changing the proguardFiles 5 | # directive in build.gradle. 6 | # 7 | # For more details, see 8 | # http://developer.android.com/guide/developing/tools/proguard.html 9 | 10 | # Add any project specific keep options here: 11 | 12 | # If your project uses WebView with JS, uncomment the following 13 | # and specify the fully qualified class name to the JavaScript interface 14 | # class: 15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 16 | # public *; 17 | #} 18 | -------------------------------------------------------------------------------- /demoapp/src/library/java/com/queue_it/shopdemo/DeepActivity.java: -------------------------------------------------------------------------------- 1 | package com.queue_it.shopdemo; 2 | 3 | import android.os.Bundle; 4 | import com.google.android.material.floatingactionbutton.FloatingActionButton; 5 | import com.google.android.material.snackbar.Snackbar; 6 | 7 | import android.support.v7.app.AppCompatActivity; 8 | import android.support.v7.widget.Toolbar; 9 | import android.view.View; 10 | 11 | public class DeepActivity extends AppCompatActivity { 12 | 13 | @Override 14 | protected void onCreate(Bundle savedInstanceState) { 15 | super.onCreate(savedInstanceState); 16 | setContentView(R.layout.activity_deep); 17 | Toolbar toolbar = findViewById(R.id.toolbar); 18 | setSupportActionBar(toolbar); 19 | 20 | FloatingActionButton fab = findViewById(R.id.fab); 21 | fab.setOnClickListener(new View.OnClickListener() { 22 | @Override 23 | public void onClick(View view) { 24 | Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG) 25 | .setAction("Action", null).show(); 26 | } 27 | }); 28 | } 29 | } -------------------------------------------------------------------------------- /demoapp/src/library/java/com/queue_it/shopdemo/FirstFragment.java: -------------------------------------------------------------------------------- 1 | package com.queue_it.shopdemo; 2 | 3 | import android.os.Bundle; 4 | import android.support.annotation.NonNull; 5 | import android.support.v4.app.Fragment; 6 | import android.view.LayoutInflater; 7 | import android.view.View; 8 | import android.view.ViewGroup; 9 | 10 | 11 | public class FirstFragment extends Fragment { 12 | 13 | @Override 14 | public View onCreateView( 15 | LayoutInflater inflater, ViewGroup container, 16 | Bundle savedInstanceState 17 | ) { 18 | // Inflate the layout for this fragment 19 | return inflater.inflate(R.layout.fragment_first, container, false); 20 | } 21 | 22 | public void onViewCreated(@NonNull View view, Bundle savedInstanceState) { 23 | super.onViewCreated(view, savedInstanceState); 24 | 25 | view.findViewById(R.id.button_first).setOnClickListener(new View.OnClickListener() { 26 | @Override 27 | public void onClick(View view) { 28 | // NavHostFragment.findNavController(FirstFragment.this) 29 | // .navigate(R.id.action_FirstFragment_to_SecondFragment); 30 | } 31 | }); 32 | } 33 | } -------------------------------------------------------------------------------- /demoapp/src/library/java/com/queue_it/shopdemo/ResultActivity.java: -------------------------------------------------------------------------------- 1 | package com.queue_it.shopdemo; 2 | 3 | import android.content.Intent; 4 | import android.os.Bundle; 5 | import com.google.android.material.floatingactionbutton.FloatingActionButton; 6 | 7 | import android.support.v4.content.res.ResourcesCompat; 8 | import android.support.v7.app.AppCompatActivity; 9 | import android.view.View; 10 | import android.widget.ImageView; 11 | import android.widget.TextView; 12 | 13 | 14 | public class ResultActivity extends AppCompatActivity { 15 | @Override 16 | protected void onCreate(Bundle savedInstanceState) { 17 | super.onCreate(savedInstanceState); 18 | setContentView(R.layout.activity_result); 19 | 20 | String result; 21 | boolean success; 22 | if (savedInstanceState == null) { 23 | Bundle extras = getIntent().getExtras(); 24 | if (extras == null) { 25 | result = null; 26 | success = false; 27 | } else { 28 | result = extras.getString("result"); 29 | success = extras.getBoolean("success"); 30 | } 31 | } else { 32 | result = (String) savedInstanceState.getSerializable("result"); 33 | success = (Boolean) savedInstanceState.getSerializable("success"); 34 | } 35 | 36 | final TextView resultText = (TextView)findViewById(R.id.result_text); 37 | final ImageView checkedImageView = (ImageView)findViewById(R.id.image_view_checked); 38 | final FloatingActionButton retry_button = (FloatingActionButton)findViewById(R.id.retry_button); 39 | 40 | resultText.setText(result); 41 | if (success){ 42 | checkedImageView.setImageDrawable(ResourcesCompat.getDrawable(getResources(), R.drawable.ic_check_black_24dp, null)); 43 | } else { 44 | checkedImageView.setImageDrawable(ResourcesCompat.getDrawable(getResources(), R.drawable.ic_error_black_24dp, null)); 45 | } 46 | 47 | retry_button.setOnClickListener(new View.OnClickListener() { 48 | @Override 49 | public void onClick(View v) { 50 | Intent intent = new Intent(ResultActivity.this, MainActivity.class); 51 | startActivity(intent); 52 | finish(); 53 | } 54 | }); 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /demoapp/src/library/java/com/queue_it/shopdemo/SecondFragment.java: -------------------------------------------------------------------------------- 1 | package com.queue_it.shopdemo; 2 | 3 | import android.os.Bundle; 4 | import android.support.annotation.NonNull; 5 | import android.support.v4.app.Fragment; 6 | import android.view.LayoutInflater; 7 | import android.view.View; 8 | import android.view.ViewGroup; 9 | 10 | public class SecondFragment extends Fragment { 11 | 12 | @Override 13 | public View onCreateView( 14 | LayoutInflater inflater, ViewGroup container, 15 | Bundle savedInstanceState 16 | ) { 17 | // Inflate the layout for this fragment 18 | return inflater.inflate(R.layout.fragment_second, container, false); 19 | } 20 | 21 | public void onViewCreated(@NonNull View view, Bundle savedInstanceState) { 22 | super.onViewCreated(view, savedInstanceState); 23 | 24 | view.findViewById(R.id.button_second).setOnClickListener(new View.OnClickListener() { 25 | @Override 26 | public void onClick(View view) { 27 | // NavHostFragment.findNavController(SecondFragment.this) 28 | // .navigate(R.id.action_SecondFragment_to_FirstFragment); 29 | } 30 | }); 31 | } 32 | } -------------------------------------------------------------------------------- /demoapp/src/library/res/layout/activity_deep.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | 13 | 14 | 20 | 21 | 22 | 23 | 24 | 25 | 32 | 33 | -------------------------------------------------------------------------------- /demoapp/src/library/res/layout/activity_main.xml: -------------------------------------------------------------------------------- 1 | 2 | 12 | 13 | 18 | 19 | 25 | 26 | 30 | 31 | 35 | 36 | 42 | 48 | 49 | 50 | 56 | 62 | 63 | 64 | 70 | 76 | 77 | 78 | 84 | 90 | 91 | 92 | 98 | 104 | 105 | 106 | 112 | 118 | 119 | 120 | 126 | 127 | 131 | 137 | 138 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 157 | 158 | 159 | 160 | 161 | -------------------------------------------------------------------------------- /demoapp/src/library/res/layout/activity_result.xml: -------------------------------------------------------------------------------- 1 | 2 | 12 | 13 | 18 | 19 | 24 | 25 | 29 | 30 | 35 | 36 | 43 | 44 | 50 | 51 | 52 | 53 | 59 | 60 | 61 | 62 | 63 | -------------------------------------------------------------------------------- /demoapp/src/library/res/layout/content_deep.xml: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /demoapp/src/library/res/layout/fragment_first.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | 18 | 19 |