web-dev-qa-db-fra.com

Le schéma d'URL personnalisé Android refuse de fonctionner/Comment revenir à l'application Android après OAuth

edit, s'il vous plaît voir ma 2ème réponse ci-dessous cette question pour un affichage beaucoup plus concis et simple du problème


J'ai enfin atteint mon esprit. Je travaille sur une application multiplateforme (IOS et Android) utilisant du titane et me connectant à l'API Salesforce via des appels inactifs. J'ai passé 3 jours et 20 heures sur cette question et je suis toujours bloqué. Tout soutien serait extrêmement apprécié! Alors, plongeons directement dans.

Ce que je veux que cela fasse: L'application démarre, vérifie si l'utilisateur a reçu un jeton à l'aide de l'autorisation oauth2, sinon donne à l'utilisateur l'écran de connexion à Salesforce. L'utilisateur entre les informations d'identification et clique sur le bouton "autoriser" et sur puis nous sommes redirigés vers l'application .

Le problème: D'après la description de ce que je veux qu'il fasse au-dessus de tout, tout fonctionne à l'exception de la dernière ligne en gras. Une fois que l'utilisateur a cliqué sur le bouton "autoriser", nous recevons cette erreur de schéma d'URL inconnue:

 error

Le code: Le code est composé de 3 zones importantes différentes

  • mon fichier index.js qui est l'endroit où l'appel de connexion à Salesforce est effectué 
  • mon fichier AuthService.js qui est l'endroit où les informations sur l'URL de salesforce sont appelées dans le fichier index.js
  • mon tiapp.xml où la configuration est conservée pour le schéma d'URL personnalisé Android

index.js

var Auth = require('AuthService');

Auth.openLogin();

AuthService.js Seule la fonction "openLogin" est vraiment importante ici.

var loginWindow;

module.exports = {

  get: function () {
    console.log("made it into the auth.get function");
    return Ti.App.Properties.getObject('auth');
  },

  set: function (data) {
    Ti.App.Properties.setObject('auth', data);
    console.log("auth set function was executed!!!");
  },

  erase: function () {
    Ti.App.Properties.removeProperty('auth');
  },

  openLogin: function () {

    console.log("made it into openLogin!!");


   var webview = Titanium.UI.createWebView({url:'https://login.salesforce.com/services/oauth2/authorize' +
      '?response_type=token&display=touch' +
      '&redirect_uri=testapp://app.open' +
      '&client_id=' + Ti.App.Properties.getString('salesforce_client_id')});


      //console.log("Webview URL: " + webview.getUrl());

    loginWindow = Titanium.UI.createWindow();
    loginWindow.add(webview);
    loginWindow.open({modal:true});



    // attempt to log url to console here
    //console.log("this is the webview URL during callback: " +  webview.getUrl());

  },

  closeLogin: function () {
    loginWindow.close();
  }

};

tiapp.xml Je n'inclus ma section Android que par souci de brièveté

<Android xmlns:Android="http://schemas.Android.com/apk/res/Android"> 
        <manifest Android:versionCode="1" Android:versionName="1.00">
            <uses-permission Android:name="Android.permission.INTERNET"></uses-permission>
            <uses-permission Android:name="Android.permission.ACCESS_NETWORK_STATE"></uses-permission>
            <uses-permission Android:name="Android.permission.ACCESS_COARSE_LOCATION"></uses-permission>
            <uses-permission Android:name="Android.permission.ACCESS_FINE_LOCATION"></uses-permission>
            <uses-permission Android:name="Android.permission.ACCESS_WIFI_STATE"></uses-permission>
        </manifest>


        <activity
      Android:name=".TesterActivity"
      Android:exported="true"
      Android:label="@string/app_name" >
      <intent-filter>
          <data Android:Host="app.open" Android:scheme="testapp" />
          <action Android:name="Android.intent.action.VIEW" />
          <category Android:name="Android.intent.category.BROWSABLE" />
          <category Android:name="Android.intent.category.DEFAULT" />
      </intent-filter>
  </activity>

    </Android>

URL de rappel enregistrée auprès de Salesforce:  enter image description here

Ce que j’ai essayé: Je me suis promené moi-même en bleu sur cette question. La plupart de mes modifications ont été apportées à mon "tiapp.xml" en modifiant les propriétés et les valeurs de ces propriétés dans la balise Android, ainsi que de nombreux ajustements à la valeur "redirect_rui" dans mon fichier "AuthService.js" et dans Salesforce. champ "url de rappel" (puisque ces valeurs doivent correspondre ou vous obtenez une erreur de non concordance uri). 

Voici quelques solutions que j'ai examinées et tentées afin de résoudre mon problème: https://Gist.github.com/jasonkneen/5736738

Schéma url personnalisé Android ..?

Comment implémenter mon propre schéma d'URI sur Android

Juste pour en nommer quelques-uns. 

Journal de la console lors de l'exécution de l'application:

[INFO] :   Emulator is booted
[INFO] :   SD card not required, skipping mount check
[INFO] :   Emulator ready!
[INFO] :   Creating unsigned apk
[INFO] :   Processing /Users/michael.kellogg/Documents/Appcelerator_Studio_Workspace/tester/build/Android/src
[INFO] :   Writing unsigned apk: /Users/michael.kellogg/Documents/Appcelerator_Studio_Workspace/tester/build/Android/bin/app-unsigned.apk
[INFO] :   Using MD5withRSA signature algorithm
[INFO] :   Signing apk: /Library/Java/JavaVirtualMachines/jdk1.8.0_72.jdk/Contents/Home/bin/jarsigner "-sigalg" "MD5withRSA" "-digestalg" "SHA1" "-keystore" "/Users/michael.kellogg/Library/Application Support/Titanium/mobilesdk/osx/5.1.2.GA/Android/dev_keystore" "-storepass" "*******" "-signedjar" "/Users/michael.kellogg/Documents/Appcelerator_Studio_Workspace/tester/build/Android/bin/tester.apk" "/Users/michael.kellogg/Documents/Appcelerator_Studio_Workspace/tester/build/Android/bin/app-unsigned.apk" "tidev"
[INFO] :   Aligning Zip file: /Users/michael.kellogg/Android-sdk/build-tools/23.0.2/zipalign "-v" "4" "/Users/michael.kellogg/Documents/Appcelerator_Studio_Workspace/tester/build/Android/bin/tester.apk" "/Users/michael.kellogg/Documents/Appcelerator_Studio_Workspace/tester/build/Android/bin/tester.apkz"
[INFO] :   Writing build manifest: /Users/michael.kellogg/Documents/Appcelerator_Studio_Workspace/tester/build/Android/build-manifest.json
[INFO] :   Making sure the adb server is running
[INFO] :   Installing apk: /Users/michael.kellogg/Documents/Appcelerator_Studio_Workspace/tester/build/Android/bin/tester.apk
[INFO] :   App successfully installed
[INFO] :   Starting app: com.test.test/.TesterActivity
[INFO] :   Application pid: 1160
[INFO] :   Project built successfully in 3m 8s 295ms
[INFO] :   art: Late-enabling JIT
[INFO] :   art: JIT created with code_cache_capacity=2MB compile_threshold=1000
[INFO] :   TiApplication: (main) [2,2] checkpoint, app created.
[INFO] :   TiApplication: (main) [1067,1069] Titanium 5.1.2 (2015/12/16 19:00 ca822b2)
[INFO] :   art: Background sticky concurrent mark sweep GC freed 15623(973KB) AllocSpace objects, 11(384KB) LOS objects, 41% free, 2MB/3MB, paused 2.142ms total 105.631ms
[INFO] :   TiApplication: (main) [383,1452] Titanium Javascript runtime: v8
[INFO] :   TiRootActivity: (main) [0,0] checkpoint, on root activity create, savedInstanceState: null
[WARN] :   TiTempFileHelper: (main) [189,189] The external temp directory doesn't exist, skipping cleanup
[INFO] :   TiRootActivity: (main) [0,0] checkpoint, on root activity resume. activity = com.test.test.TesterActivity@a298e02
[WARN] :   V8Object: (KrollRuntimeThread) [1039,1228] Runtime disposed, cannot set property 'userAgent'
[INFO] :   made it into openLogin!!
[INFO] :   OpenGLRenderer: Initialized EGL, version 1.4
[WARN] :   EGL_emulation: eglSurfaceAttrib not implemented
[WARN] :   OpenGLRenderer: Failed to set EGL_SWAP_BEHAVIOR on surface 0xb4d32b20, error=EGL_SUCCESS
[INFO] :   WebViewFactory: Loading com.Android.webview version 44.0.2403.119 (code 246011900)
[WARN] :   System: ClassLoader referenced unknown path: /system/app/webview/lib/arm
[INFO] :   LibraryLoader: Time to load native libraries: 36 ms (timestamps 588-624)
[INFO] :   LibraryLoader: Expected native library version number "",actual native library version number ""
[INFO] :   LibraryLoader: Expected native library version number "",actual native library version number ""
[INFO] :   chromium: [INFO:library_loader_hooks.cc(120)] Chromium logging enabled: level = 0, default verbosity = 0
[INFO] :   BrowserStartupController: Initializing chromium process, singleProcess=true
[WARN] :   art: Attempt to remove non-JNI local reference, dumping thread
[ERROR] :  SysUtils: ApplicationContext is null in ApplicationStatus
[WARN] :   chromium: [WARNING:resource_bundle.cc(285)] locale_file_path.empty()
[ERROR] :  libEGL: validate_display:255 error 3008 (EGL_BAD_DISPLAY)
[ERROR] :  libEGL: validate_display:255 error 3008 (EGL_BAD_DISPLAY)
[ERROR] :  eglCodecCommon: glUtilsParamSize: unknow param 0x00008d57
[WARN] :   AudioManagerAndroid: Requires BLUETOOTH permission
[ERROR] :  DataReductionProxySettingListener: No DRP key due to exception:Java.lang.ClassNotFoundException: com.Android.webview.chromium.Drp
[WARN] :   art: Attempt to remove non-JNI local reference, dumping thread
[WARN] :   AwContents: onDetachedFromWindow called when already detached. Ignoring
[WARN] :   art: Attempt to remove non-JNI local reference, dumping thread
[WARN] :   art: Attempt to remove non-JNI local reference, dumping thread
[WARN] :   art: Attempt to remove non-JNI local reference, dumping thread
[WARN] :   art: Attempt to remove non-JNI local reference, dumping thread
[WARN] :   art: Attempt to remove non-JNI local reference, dumping thread
[WARN] :   art: Attempt to remove non-JNI local reference, dumping thread
[WARN] :   chromium: [WARNING:data_reduction_proxy_config.cc(423)] SPDY proxy OFF at startup
[WARN] :   EGL_emulation: eglSurfaceAttrib not implemented
[WARN] :   OpenGLRenderer: Failed to set EGL_SWAP_BEHAVIOR on surface 0xb4d32b40, error=EGL_SUCCESS
[WARN] :   art: Attempt to remove non-JNI local reference, dumping thread
[WARN] :   art: Attempt to remove non-JNI local reference, dumping thread
[INFO] :   art: Background sticky concurrent mark sweep GC freed 7564(860KB) AllocSpace objects, 25(988KB) LOS objects, 0% free, 11MB/11MB, paused 1.603ms total 308.766ms
[WARN] :   art: Attempt to remove non-JNI local reference, dumping thread
[WARN] :   art: Attempt to remove non-JNI local reference, dumping thread
[WARN] :   art: Attempt to remove non-JNI local reference, dumping thread
[WARN] :   art: Attempt to remove non-JNI local reference, dumping thread
[INFO] :   art: Background partial concurrent mark sweep GC freed 1948(144KB) AllocSpace objects, 3(8MB) LOS objects, 22% free, 13MB/17MB, paused 1.658ms total 271.298ms
[WARN] :   art: Attempt to remove non-JNI local reference, dumping thread
[WARN] :   art: Attempt to remove non-JNI local reference, dumping thread
[WARN] :   art: Attempt to remove non-JNI local reference, dumping thread
[WARN] :   art: Attempt to remove non-JNI local reference, dumping thread
[WARN] :   art: Attempt to remove non-JNI local reference, dumping thread
[WARN] :   art: Attempt to remove non-JNI local reference, dumping thread
[WARN] :   art: Attempt to remove non-JNI local reference, dumping thread
[WARN] :   art: Attempt to remove non-JNI local reference, dumping thread
[WARN] :   art: Attempt to remove non-JNI local reference, dumping thread
[WARN] :   art: Attempt to remove non-JNI local reference, dumping thread
[WARN] :   art: Attempt to remove non-JNI local reference, dumping thread
[WARN] :   art: Attempt to remove non-JNI local reference, dumping thread
[WARN] :   art: Attempt to remove non-JNI local reference, dumping thread
[WARN] :   art: Attempt to remove non-JNI local reference, dumping thread
[WARN] :   art: Attempt to remove non-JNI local reference, dumping thread
[INFO] :   art: Background partial concurrent mark sweep GC freed 148(6KB) AllocSpace objects, 13(36MB) LOS objects, 17% free, 19MB/23MB, paused 1.205ms total 327.978ms
[WARN] :   art: Attempt to remove non-JNI local reference, dumping thread
[WARN] :   art: Attempt to remove non-JNI local reference, dumping thread
[WARN] :   art: Attempt to remove non-JNI local reference, dumping thread
[WARN] :   art: Attempt to remove non-JNI local reference, dumping thread
[WARN] :   art: Attempt to remove non-JNI local reference, dumping thread
[INFO] :   art: Background partial concurrent mark sweep GC freed 91(3KB) AllocSpace objects, 5(14MB) LOS objects, 22% free, 13MB/17MB, paused 1.228ms total 201.595ms
[WARN] :   art: Attempt to remove non-JNI local reference, dumping thread
[WARN] :   art: Attempt to remove non-JNI local reference, dumping thread
[WARN] :   art: Attempt to remove non-JNI local reference, dumping thread
[WARN] :   art: Attempt to remove non-JNI local reference, dumping thread
[WARN] :   art: Attempt to remove non-JNI local reference, dumping thread
[WARN] :   art: Attempt to remove non-JNI local reference, dumping thread
[WARN] :   art: Suspending all threads took: 15.737ms
[INFO] :   art: Background sticky concurrent mark sweep GC freed 261(13KB) AllocSpace objects, 2(5MB) LOS objects, 0% free, 25MB/25MB, paused 18.832ms total 174.330ms
[WARN] :   art: Attempt to remove non-JNI local reference, dumping thread
[INFO] :   art: Background partial concurrent mark sweep GC freed 98(20KB) AllocSpace objects, 7(19MB) LOS objects, 26% free, 11MB/15MB, paused 3.244ms total 302.681ms
[WARN] :   art: Attempt to remove non-JNI local reference, dumping thread
[WARN] :   BindingManager: Cannot call determinedVisibility() - never saw a connection for the pid: 1160
[WARN] :   art: Attempt to remove non-JNI local reference, dumping thread
[INFO] :   art: Background sticky concurrent mark sweep GC freed 11512(602KB) AllocSpace objects, 0(0B) LOS objects, 4% free, 14MB/15MB, paused 1.739ms total 174.806ms
[WARN] :   art: Attempt to remove non-JNI local reference, dumping thread
[INFO] :   art: Background partial concurrent mark sweep GC freed 301(32KB) AllocSpace objects, 2(5MB) LOS objects, 25% free, 11MB/15MB, paused 2.370ms total 274.103ms
[WARN] :   EGL_emulation: eglSurfaceAttrib not implemented
[WARN] :   OpenGLRenderer: Failed to set EGL_SWAP_BEHAVIOR on surface 0x9d719f80, error=EGL_SUCCESS
[WARN] :   art: Attempt to remove non-JNI local reference, dumping thread
[WARN] :   art: Attempt to remove non-JNI local reference, dumping thread
[INFO] :   art: Background sticky concurrent mark sweep GC freed 358(19KB) AllocSpace objects, 0(0B) LOS objects, 0% free, 17MB/17MB, paused 6.593ms total 277.832ms
[WARN] :   art: Attempt to remove non-JNI local reference, dumping thread
[WARN] :   art: Attempt to remove non-JNI local reference, dumping thread
[INFO] :   art: Background partial concurrent mark sweep GC freed 148(5KB) AllocSpace objects, 3(8MB) LOS objects, 18% free, 17MB/21MB, paused 7.547ms total 414.524ms
[WARN] :   art: Attempt to remove non-JNI local reference, dumping thread
[WARN] :   art: Attempt to remove non-JNI local reference, dumping thread
[WARN] :   art: Attempt to remove non-JNI local reference, dumping thread
[INFO] :   art: Background sticky concurrent mark sweep GC freed 30(608B) AllocSpace objects, 1(2MB) LOS objects, 0% free, 23MB/23MB, paused 2.321ms total 159.615ms
[WARN] :   art: Attempt to remove non-JNI local reference, dumping thread
[WARN] :   art: Attempt to remove non-JNI local reference, dumping thread
[INFO] :   art: Background partial concurrent mark sweep GC freed 36(1168B) AllocSpace objects, 5(14MB) LOS objects, 21% free, 14MB/18MB, paused 1.626ms total 197.175ms
[WARN] :   art: Attempt to remove non-JNI local reference, dumping thread
[WARN] :   art: Attempt to remove non-JNI local reference, dumping thread
[WARN] :   art: Attempt to remove non-JNI local reference, dumping thread
[INFO] :   art: Background sticky concurrent mark sweep GC freed 21(448B) AllocSpace objects, 0(0B) LOS objects, 0% free, 20MB/20MB, paused 37.280ms total 96.680ms
[INFO] :   art: Background partial concurrent mark sweep GC freed 34(960B) AllocSpace objects, 4(11MB) LOS objects, 30% free, 8MB/12MB, paused 1.475ms total 106.381ms
[WARN] :   art: Attempt to remove non-JNI local reference, dumping thread
[WARN] :   art: Attempt to remove non-JNI local reference, dumping thread
[WARN] :   art: Attempt to remove non-JNI local reference, dumping thread
[WARN] :   art: Attempt to remove non-JNI local reference, dumping thread
[WARN] :   art: Attempt to remove non-JNI local reference, dumping thread
[WARN] :   art: Attempt to remove non-JNI local reference, dumping thread
[INFO] :   art: Background partial concurrent mark sweep GC freed 56(3KB) AllocSpace objects, 3(8MB) LOS objects, 21% free, 14MB/18MB, paused 3.001ms total 243.577ms
[WARN] :   art: Attempt to remove non-JNI local reference, dumping thread
[WARN] :   BindingManager: Cannot call determinedVisibility() - never saw a connection for the pid: 1160
[WARN] :   BindingManager: Cannot call determinedVisibility() - never saw a connection for the pid: 1160
[WARN] :   BindingManager: Cannot call determinedVisibility() - never saw a connection for the pid: 1160
[INFO] :   I/TiWebChromeClient.console: (main) [21796,21796] Not allowed to load local resource: file:///Android_asset/webkit/Android-weberror.png (0:data:text/html,chromewebdata)
[INFO] :   art: Background sticky concurrent mark sweep GC freed 337(53KB) AllocSpace objects, 1(2MB) LOS objects, 6% free, 17MB/18MB, paused 43.249ms total 82.260ms
[WARN] :   art: Attempt to remove non-JNI local reference, dumping thread
[WARN] :   art: Attempt to remove non-JNI local reference, dumping thread
[WARN] :   art: Attempt to remove non-JNI local reference, dumping thread
[INFO] :   art: Background partial concurrent mark sweep GC freed 82(11KB) AllocSpace objects, 3(8MB) LOS objects, 21% free, 14MB/18MB, paused 1.613ms total 159.713ms
[WARN] :   art: Attempt to remove non-JNI local reference, dumping thread
[WARN] :   art: Attempt to remove non-JNI local reference, dumping thread
[WARN] :   art: Attempt to remove non-JNI local reference, dumping thread
[WARN] :   art: Attempt to remove non-JNI local reference, dumping thread
[WARN] :   art: Attempt to remove non-JNI local reference, dumping thread
[WARN] :   art: Attempt to remove non-JNI local reference, dumping thread
[INFO] :   art: Background sticky concurrent mark sweep GC freed 27(544B) AllocSpace objects, 1(2MB) LOS objects, 6% free, 17MB/18MB, paused 21.912ms total 68.965ms
[WARN] :   art: Attempt to remove non-JNI local reference, dumping thread
[INFO] :   art: Background partial concurrent mark sweep GC freed 39(1056B) AllocSpace objects, 3(8MB) LOS objects, 21% free, 14MB/18MB, paused 1.523ms total 136.698ms
[WARN] :   art: Attempt to remove non-JNI local reference, dumping thread
[WARN] :   art: Attempt to remove non-JNI local reference, dumping thread
[WARN] :   art: Attempt to remove non-JNI local reference, dumping thread
[WARN] :   art: Attempt to remove non-JNI local reference, dumping thread
[WARN] :   art: Attempt to remove non-JNI local reference, dumping thread
[ERROR] :  Surface: getSlotFromBufferLocked: unknown buffer: 0xaad48dc0
[INFO] :   art: Background partial concurrent mark sweep GC freed 40(1104B) AllocSpace objects, 5(14MB) LOS objects, 25% free, 11MB/15MB, paused 3.871ms total 157.623ms
[INFO] :   APSAnalyticsService: Analytics Service Started
[INFO] :   APSAnalyticsService: Stopping Analytics Service
-- End application log -------------------------------------------------------
11
Mike Kellogg

Après quelque chose comme 64 heures de recherches sur Internet et d'innombrables tentatives, j'ai finalement trouvé une solution à ce problème. Yay moi! Je dois admettre que je suis un peu honteux du temps qu’il a fallu pour résoudre ce problème.

Problème rencontré: Impossible de trouver un moyen de revenir à l'application Android après l'autorisation Salesforce (le schéma d'URL personnalisé était extrêmement pénible avec Android).

Solution: Après une recherche dans les environs, j'ai trouvé un exemple de code de salesforce qui correspond à ce que j'essayais de faire ici: 

https://developer.salesforce.com/page/Developing_Mobile_Applications_with_Force.com_and_Appcelerator_Titanium

Voici le lien github fourni dans l'article ci-dessus qui contient le code indispensable:

https://github.com/appcelerator-developer-relations/Force

TLDR: La vraie clé était de NE PAS utiliser un schéma d'URL personnalisé avec Android et Titanium. Au lieu de cela, le code github répertorié ci-dessus ouvre la page d'authentification dans une vue Web puis, à l'aide d'écouteurs, ferme cette vue Web après la fin de l'authentification et ouvre la vue dont vous avez besoin. 

Explication: Pour revenir à mon application sur IOS, il me suffisait d'ajouter quelques lignes à mon fichier tiapp.xml afin d'utiliser un schéma d'URL personnalisé. Cela a fonctionné très rapidement et simplement sans aucun mal de tête. Naturellement, j'ai supposé qu'un schéma d'URL personnalisé était la solution avec Android, n'est-ce pas simple? faux. Comme indiqué ci-dessus, j'ai passé de nombreuses heures à essayer de créer en vain un système d'URL personnalisé sur Android. Il semble y avoir beaucoup d'informations en ligne sur les schémas d'URL personnalisés Android, mais aucun d'eux n'a fonctionné pour moi et croyez-moi, j'ai essayé beaucoup de choses (après tout, c'était environ 64 heures). Finalement, j'ai juste essayé de trouver un exemple de code en ligne qui faisait ce que je voulais. C'était celui que j'ai trouvé. 

5
Mike Kellogg

En termes de configuration du manifeste pour la reconnaissance de schéma, vous devriez obtenir quelque chose qui ressemble à ce qui suit

<manifest ...>
    ...
    <application ...>
        ...
        <activity ...
            Android:exported="true"> <!-- Make it exported -->
            <intent-filter>
                <action Android:name="Android.intent.action.MAIN" />
                <category Android:name="Android.intent.category.LAUNCHER" />
            </intent-filter>
            <intent-filter Android:label="...">
                <action Android:name="Android.intent.action.VIEW" />
                <category Android:name="Android.intent.category.DEFAULT" />
                <category Android:name="Android.intent.category.BROWSABLE" />
                <data Android:scheme="testapp" />
                <data Android:Host="app" /> <!-- cover all your bases -->
                <data Android:Host="app.open" />
            </intent-filter>
        </activity>
    </application>
</manifest>

J'aurais alors une méthode dans cette activité qui pourrait vérifier si votre schéma est dans l'intention. Quelque chose comme ce qui suit:

protected void onCreate(final Bundle savedInstanceState) {
    ...
    checkIntent( getIntent() );
} 

protected void onNewIntent(final Intent intent) {
    ...
    checkIntent( intent );
}

private void checkIntent(Intent intent) {
    if ( intent.getDataString() != null && Intent.ACTION_VIEW.equals(intent.getAction()) ) {
        //If we reached here we have some kind of deep link or custom schema
        //so lets identify which schema
        if ( "testapp".equals(data.getScheme().toLowerCase()) ) {
            //my tests were able to reach here
        }
    }
}

Un quirk des androïdes est que, avec les versions ultérieures, l’utilisateur doit montrer son intention . Cela signifie de manière réaliste que taper une URL dans le navigateur et appuyer sur Go ne fonctionneront pas. Cela n'est déclenché que lorsqu'un utilisateur clique sur un lien ou que vous déclenchez une intention. Lorsque vous souhaitez uniquement détecter la redirection à partir de votre propre WebView (et non des navigateurs externes), vous pouvez contourner ce problème:

myWebView.setWebViewClient( new WebViewClient() {

    @Override
    public boolean shouldOverrideUrlLoading(WebView view, String url) {
        if (url.startsWith("testapp://")) {
            Intent intent = new Intent(Intent.ACTION_VIEW);
            intent.setData( Uri.parse(url) );
            view.getContext().startActivity( intent );
            return true; //with return true, the webview wont try rendering the url
        }
        return false;
    }

} );
7
Nick Cardoso

Impossible de le mettre en commentaire, créant ainsi une réponse. Je vous demanderais de bien vouloir essayer et voir si cela aide.

<Android xmlns:Android="http://schemas.Android.com/apk/res/Android">
<manifest>
    <application Android:icon="@drawable/appicon" Android:label="MyApp" Android:name="MyApplication">
        <activity Android:label="MyApp" Android:name=".MyApplicationActivity">
            <intent-filter>
                <action Android:name="Android.intent.action.MAIN"/>
                <category Android:name="Android.intent.category.LAUNCHER"/>
            </intent-filter>
            <intent-filter>
                <action Android:name="Android.intent.action.VIEW" />
                <category Android:name="Android.intent.category.DEFAULT" />
                <category Android:name="Android.intent.category.BROWSABLE" />
                <data Android:scheme="mytestapplication" />
            </intent-filter>
        </activity>
    </application>
</manifest>

Pouvez-vous essayer ceci et voir si cela fonctionne? Vous pouvez également consulter l'entrée TiApp.xml mentionnée dans ce Git Post .

Vous demander d’essayer de nous le faire savoir, si cela ne fonctionne pas, alors nous pouvons peut-être essayer quelque chose d’autre.

2
Soumya

Il existe certaines solutions de contournement qui me paraissent légitimes. Ainsi, avec shouldOverrideUrlLoading(), le WebViewClient permet de remplacer onErrorRecieved() et en fait, il passe failingUrl en argument.

private val webViewClient = object : WebViewClient() {

        @Suppress("OverridingDeprecatedMember")
        override fun onReceivedError(view: WebView?, errorCode: Int, description: String?, failingUrl: String?) {
            if (failingUrl != null) {
                handleCallbackUrl(Uri.parse(failingUrl))
            }
        }

        override fun shouldOverrideUrlLoading(view: WebView?, request: WebResourceRequest?) = when {
            handleCallbackUrl(request?.url) -> true
            else -> super.shouldOverrideUrlLoading(view, request)
        }
}
0
Ivan