Bonjour,

Principe :
J'ai une application javaScipt + html + php qui fonctionne. C'est un core "métier" qui tourne sur toute plateforme via un browser.
Mon but est d'en faire une apk native avec une webview qui appelle mon code.
Cet apk mettra à disposition de mon code des fonctionnalités spécifiques des smartphones/tablettes : sms, gps précis, si possible authentification...

J'ai codé ce wrapper, cela fonctionne MAIS :
Je m'use dans la granularité des versions d'android, les deprecated, les @Overrides...
Et aussi avec les manifest, ressources...
Avec les versions antérieures de visual sudio, je pouvais envoyer directement l'apk sur mon tél connecté en USB. Je n'y arrive plus.

Je cherche quelqu'un qui :
  • pourrait faire cela à ma place
  • sera beaucoup plus efficace que moi
  • connaîtra les différentes version d'android et permettra de déterminer la plus basse possible en fonction des fonctionnalités souhaités
  • me permettra de me consacrer à la partie "métier"
  • une rémunération modeste est envisageable


Merci de de vos éventuels retours !

Voici l'état des choses :

mainActivity
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
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
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
import android.annotation.SuppressLint;
import android.content.ActivityNotFoundException;
import android.content.Context;
import android.content.Intent;
import android.os.BatteryManager;
import android.os.Build;
import android.os.Bundle;
import android.speech.RecognizerIntent;
import android.telephony.SmsManager;
import android.webkit.ConsoleMessage;
import android.webkit.JavascriptInterface;
import android.webkit.PermissionRequest;
import android.webkit.WebChromeClient;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.widget.Toast;
 
import androidx.annotation.RequiresApi;
import androidx.appcompat.app.AppCompatActivity;
 
import java.util.ArrayList;
 
public class MainActivity extends AppCompatActivity
{   public WebView webview;
    private final int REQ_CODE_SPEECH_INPUT=1;
    public static ArrayList<String> sttResults;
    TTSManager ttsManager = null;
    @RequiresApi(api = Build.VERSION_CODES.M)
    @SuppressLint("JavascriptInterface")
    @Override
    protected void onCreate(Bundle savedInstanceState)
    {   super.onCreate(savedInstanceState);
 
        ttsManager = new TTSManager();
        ttsManager.init(this);
 
        setContentView(R.layout.activity_main);
        webview=findViewById(R.id.webview);
        WebSettings webSettings = webview.getSettings();
        webview.setWebChromeClient(new WebChromeClient() {
            @Override
            public boolean onConsoleMessage(ConsoleMessage consoleMessage) {
                android.util.Log.d("WebView", Integer.toString(consoleMessage.lineNumber())+"->"+consoleMessage.message());
                return true;
            }
            @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
            public void onPermissionRequest(PermissionRequest request) {
                request.grant(request.getResources());
            }
        });
        webSettings.setJavaScriptEnabled(true);
        webSettings.setDomStorageEnabled(true);
        webSettings.setAppCacheEnabled(false);
        webSettings.setCacheMode(WebSettings.LOAD_NO_CACHE);
 
        try
        {   webview.addJavascriptInterface(new osAction(), "osAction");
        }
        catch(Exception e)
        {
            meToast(e.toString());
        }
        webview.loadUrl("https://www.xxx.fr?clear=true");
    }
    @Override
    public void onDestroy()
    {   super.onDestroy();
        ttsManager.shutDown();
    }
 
    public class osAction
    {   @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
    @JavascriptInterface
 
    public String action(String cmd, String param1, String param2)
    {   //Toast.makeText(MainActivity.this,cmd+param1+param2,Toast.LENGTH_SHORT).show();
        String ret="";
        switch (cmd)
        {   case "BAT":
            BatteryManager bm=(BatteryManager) getSystemService(BATTERY_SERVICE);
            int batLevel=bm.getIntProperty(BatteryManager.BATTERY_PROPERTY_CAPACITY);
            ret=batLevel+"%";
            break;
            case "TTS":
                ttsManager.initQueue(param1);
                break;
            case "SMS":
                SmsManager manager = SmsManager.getDefault();
                manager.sendTextMessage(param1, null, param2, null, null);
                // En dessous, envoi du SMS délégué à l'application standard qui permet de modifier avant envoi manuel
                // Intent sms = new Intent(Intent.ACTION_SENDTO, Uri.parse("smsto:0610254587"));
                // sms.putExtra("sms_body", "Ceci est un sms de test");
                // startActivity(sms);
                break;
            case "OSV":
                ret="Android";
                break;
            case "STT":
                ret=promptSpeechInput();
                break;
            case "NET":
                String networkStatus = NetworkUtil.getNetworkStatus(MainActivity.this);
                ret = networkStatus;
                Toast.makeText(MainActivity.this, ret, Toast.LENGTH_LONG).show();
                break;
            default:
                ret="cmdError:["+cmd+"]";
                break;
        }
        return(ret);
    }
    }
 
    private String promptSpeechInput()
    {	String ret="VOID";
        Intent intent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH);
        intent.putExtra(RecognizerIntent.EXTRA_LANGUAGE, "fr-FR");
        //intent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL, RecognizerIntent.LANGUAGE_MODEL_FREE_FORM);
        //intent.putExtra(RecognizerIntent.EXTRA_LANGUAGE, Locale.getDefault().getDisplayLanguage());
        intent.putExtra(RecognizerIntent.EXTRA_PROMPT, "Vous pouvez parler ...");
        try
        {	startActivityForResult(intent, REQ_CODE_SPEECH_INPUT);
            meToast("xx"+ret);
        }
        catch (ActivityNotFoundException a)
        {	ret="BAD";
        }
        return(ret);
    }
 
    private void meToast(String msg)
    {   Context context = getApplicationContext();
        int duration = Toast.LENGTH_SHORT;
        Toast.makeText(context, msg, duration).show();
    }
 
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data)
    {	super.onActivityResult(requestCode, resultCode, data);
        switch (requestCode)
        {   case REQ_CODE_SPEECH_INPUT:
            if (resultCode == RESULT_OK && null != data) {
                sttResults = data.getStringArrayListExtra(RecognizerIntent.EXTRA_RESULTS);
                for (String _string : sttResults) {
                    Integer i;
                    String out = "";
                    meToast(_string);
                    String meChar;
                    for (i = 0; i < _string.length(); i++)
                    {   meChar = _string.substring(i, i + 1);
                        if (meChar!=" ")
                        {       out += meChar;
                        }
                    }
                    if (out != "")
                    {   String att = "javascript:keyInsert('" + out + "')";
                        webview.loadUrl(att);
                    }
                }
            }
            default:
                break;
        }
    }
}
manifest
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    tools:ignore="ExtraText">
 
    <uses-feature android:name="android.hardware.camera" />
 
    <uses-feature android:name="android.permission.write_external_storage" />
    <uses-feature android:name="android.permission.read_external_storage" />
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.CAMERA" />
    <uses-permission android:name="android.permission.RECORD_AUDIO" />
    <uses-permission android:name="android.webkit.PermissionRequest" />
    <uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
    <uses-permission android:name="android.permission.SEND_SMS" />
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
 
 
    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:networkSecurityConfig="@xml/network_security_config"
        android:theme="@style/AppTheme">
        <activity
            android:name=".MainActivity"
            android:label="@string/app_name"
            android:screenOrientation="landscape"
            android:theme="@style/AppTheme.NoActionBar">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
 
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>
</manifest>
Il y aussi jes .java TTSManager et NetworkUtil qu'il ne me semble pas nécessaire de mettre ici