flutter app untuk unitstock
Não pode escolher mais do que 25 tópicos Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') e podem ter até 35 caracteres.
 
 
 
 
 

366 linhas
13 KiB

  1. import 'dart:async';
  2. import 'dart:convert';
  3. import 'dart:io';
  4. import 'package:flutter/services.dart';
  5. import 'package:flutter/material.dart';
  6. import 'package:flushbar/flushbar.dart';
  7. import 'package:http/io_client.dart';
  8. import 'package:in_app_update/in_app_update.dart';
  9. import 'package:url_launcher/url_launcher.dart';
  10. import '../main.dart';
  11. import 'package:location/location.dart';
  12. import 'package:permission_handler/permission_handler.dart' as pHandler;
  13. import 'Prefs.dart';
  14. import 'package:oauth2/oauth2.dart' as oauth2;
  15. class Util{
  16. bool tokenValidity = true;
  17. bool useLocal = false;
  18. getMinAppVer()async{
  19. var req = await JsonDataGetRaw(null,'${prefs.getString(keyClass.hostAddress)}/app/min_ver/');
  20. return req;
  21. }
  22. launchURL(String url) async {
  23. if (await canLaunch(url)) {
  24. await launch(url);
  25. } else {
  26. throw 'Could not launch $url';
  27. }
  28. }
  29. updateDialog(context)async{
  30. WidgetsBinding.instance.addPostFrameCallback((_) async {
  31. await showDialog(
  32. context: context,
  33. builder: (BuildContext context) {
  34. return WillPopScope(
  35. onWillPop: (){
  36. return null;
  37. },
  38. child: AlertDialog(
  39. title: Text('App version is too old'),
  40. content: Text('Please update the application'),
  41. actions: <Widget>[
  42. TextButton(
  43. child: Text('Update',style: TextStyle(color: Colors.blue),),
  44. onPressed: ()async{
  45. try{
  46. AppUpdateInfo _updateInfo;
  47. _updateInfo = await InAppUpdate.checkForUpdate();
  48. if(_updateInfo?.updateAvailability == 2){
  49. await InAppUpdate.performImmediateUpdate();
  50. }
  51. else throw {"message":"manual Update"};
  52. }
  53. catch(e){
  54. await Future.delayed(Duration(milliseconds: 500));
  55. await launchURL('https://play.google.com/store/apps/details?id=com.thamringroup.unitstocks');
  56. }
  57. },
  58. ),
  59. ],
  60. ),
  61. );
  62. },
  63. barrierDismissible: false,
  64. );
  65. });
  66. }
  67. getOauth2Client() async {
  68. bool resetClient = false;
  69. oauth2.Credentials restData = (prefs.getString(keyClass.rest_data)!=null&&prefs.getString(keyClass.rest_data).contains("accessToken"))?oauth2.Credentials.fromJson(prefs.getString(keyClass.rest_data)):null;
  70. if(restData == null)resetClient = true;
  71. else{
  72. if(DateTime.now().isAfter(restData.expiration))resetClient = true;
  73. }
  74. oauth2.Client client;
  75. if(resetClient||!tokenValidity){
  76. final tokenEndpoint = Uri.parse(prefs.getString(keyClass.restTokenAddress));
  77. if(prefs.getString(keyClass.client_credential)==null){
  78. client = await initRest();
  79. }
  80. else{
  81. var clients = JsonDecoder().convert(prefs.getString(keyClass.client_credential));
  82. client = await oauth2.clientCredentialsGrant(tokenEndpoint, clients["id"], clients["secret"],httpClient: http);
  83. prefs.setString(keyClass.rest_data, client.credentials.toJson());
  84. }
  85. }
  86. else {
  87. if (prefs.getString(keyClass.client_credential) == null) {
  88. client = await initRest();
  89. }
  90. else {
  91. var clients = JsonDecoder().convert(prefs.getString(keyClass.client_credential));
  92. client = new oauth2.Client(restData, identifier: clients["id"],
  93. secret: clients["secret"],
  94. httpClient: http);
  95. }
  96. }
  97. return client;
  98. }
  99. JsonDataPostRaw(Map jsonData, String url,{secure:true,timeout:false}) async{
  100. var httpClient;
  101. const JsonDecoder decoder = const JsonDecoder();
  102. var headers = {'Content-type': 'application/json'};
  103. try {
  104. var response;
  105. if(secure) {
  106. httpClient = await getOauth2Client();
  107. oauth2.Credentials tokenRestData = oauth2.Credentials.fromJson(prefs.getString(keyClass.rest_data));
  108. headers["Authorization"] =
  109. "bearer ${tokenRestData.accessToken}";
  110. }
  111. else {
  112. httpClient = http;
  113. }
  114. if (timeout)
  115. response = await httpClient.post(
  116. Uri.parse(url), headers: headers,
  117. body: json.encode(jsonData)).timeout(
  118. const Duration(seconds: 10));
  119. else
  120. response = await httpClient.post(
  121. Uri.parse(url), headers: {'Content-type': 'application/json'},
  122. body: json.encode(jsonData));
  123. if(response.statusCode == 403) tokenValidity = false;
  124. if(htmlErrorTitle(response.body.toString())!=""){
  125. return {"STATUS":(response.statusCode != 200)?0:1,"DATA":htmlErrorTitle(response.body.toString())};
  126. }
  127. final Map data = decoder.convert(response.body);
  128. try{data["DATA"] = decoder.convert(data["DATA"]);}catch(e){}
  129. return data;
  130. } on TimeoutException catch(e){
  131. return {"STATUS":0,"DATA":"Request Timeout"};
  132. }
  133. on HandshakeException catch(e){
  134. if(useLocal){
  135. return {"STATUS":0,"DATA":"Not Connected to Server. $e"};
  136. }
  137. else{
  138. useLocal = true;
  139. http = IOClient(HttpClient(context: clientContext));
  140. return await JsonDataPostRaw(jsonData, url,timeout:timeout,secure: secure);
  141. }
  142. }
  143. on Exception catch(exception){
  144. print(url);
  145. // Toast("Not Connected to Server", Colors.red);
  146. return {"STATUS":0,"DATA":"Not Connected to Server. $exception"};
  147. }
  148. }
  149. JsonDataGetRaw(Map jsonData, String url,{secure:true,timeout:false}) async{
  150. var httpClient;
  151. const JsonDecoder decoder = const JsonDecoder();
  152. var headers = {'Content-type': 'application/json'};
  153. try {
  154. var response;
  155. if(secure) {
  156. httpClient = await getOauth2Client();
  157. oauth2.Credentials tokenRestData = oauth2.Credentials.fromJson(prefs.getString(keyClass.rest_data));
  158. headers["Authorization"] =
  159. "bearer ${tokenRestData.accessToken}";
  160. }
  161. else {
  162. httpClient = http;
  163. }
  164. if(jsonData!= null&&jsonData.length!=0) {
  165. url = url + '?';
  166. for (var i in jsonData.keys) {
  167. url = url + i + '=' + jsonData[i] + '&';
  168. }
  169. url = url.substring(0, url.length - 1);
  170. }
  171. if (timeout)
  172. response = await httpClient.get(
  173. Uri.parse(url), headers: headers,
  174. ).timeout(const Duration(seconds: 10));
  175. else
  176. response = await httpClient.get(
  177. Uri.parse(url), headers: {'Content-type': 'application/json'},
  178. );
  179. if(response.statusCode == 403) tokenValidity = false;
  180. if(htmlErrorTitle(response.body.toString())!=""){
  181. return {"STATUS":(response.statusCode != 200)?0:1,"DATA":htmlErrorTitle(response.body.toString())};
  182. }
  183. final Map data = decoder.convert(response.body);
  184. try{data["DATA"] = decoder.convert(data["DATA"]);}catch(e){}
  185. return data;
  186. } on TimeoutException catch(e){
  187. return {"STATUS":0,"DATA":"Request Timeout"};
  188. }
  189. on HandshakeException catch(e){
  190. if(useLocal){
  191. return {"STATUS":0,"DATA":"Not Connected to Server. $e"};
  192. }
  193. else{
  194. useLocal = true;
  195. http = IOClient(HttpClient(context: clientContext));
  196. return await JsonDataPostRaw(jsonData, url,timeout:timeout,secure: secure);
  197. }
  198. }
  199. on Exception catch(exception){
  200. print(url);
  201. // Toast("Not Connected to Server", Colors.red);
  202. return {"STATUS":0,"DATA":"Not Connected to Server. $exception"};
  203. }
  204. }
  205. JsonDataPutRaw(Map jsonData, String url,{secure:true,timeout:false}) async{
  206. var httpClient;
  207. const JsonDecoder decoder = const JsonDecoder();
  208. var headers = {'Content-type': 'application/json'};
  209. try {
  210. var response;
  211. if(secure) {
  212. httpClient = await getOauth2Client();
  213. oauth2.Credentials tokenRestData = oauth2.Credentials.fromJson(prefs.getString(keyClass.rest_data));
  214. headers["Authorization"] =
  215. "bearer ${tokenRestData.accessToken}";
  216. }
  217. else {
  218. httpClient = http;
  219. }
  220. if (timeout)
  221. response = await httpClient.put(
  222. Uri.parse(url), headers: headers,
  223. body: json.encode(jsonData)).timeout(
  224. const Duration(seconds: 10));
  225. else
  226. response = await httpClient.put(
  227. Uri.parse(url), headers: {'Content-type': 'application/json'},
  228. body: json.encode(jsonData));
  229. if(response.statusCode == 403) tokenValidity = false;
  230. if(htmlErrorTitle(response.body.toString())!=""){
  231. return {"STATUS":(response.statusCode != 200)?0:1,"DATA":htmlErrorTitle(response.body.toString())};
  232. }
  233. final Map data = decoder.convert(response.body);
  234. try{data["DATA"] = decoder.convert(data["DATA"]);}catch(e){}
  235. return data;
  236. } on TimeoutException catch(e){
  237. return {"STATUS":0,"DATA":"Request Timeout"};
  238. }
  239. on HandshakeException catch(e){
  240. if(useLocal){
  241. return {"STATUS":0,"DATA":"Not Connected to Server. $e"};
  242. }
  243. else{
  244. useLocal = true;
  245. http = IOClient(HttpClient(context: clientContext));
  246. return await JsonDataPostRaw(jsonData, url,timeout:timeout,secure: secure);
  247. }
  248. }
  249. on Exception catch(exception){
  250. print(url);
  251. // Toast("Not Connected to Server", Colors.red);
  252. return {"STATUS":0,"DATA":"Not Connected to Server. $exception"};
  253. }
  254. }
  255. htmlErrorTitle(String html){
  256. // FlutterLogs.logInfo("TAG", "subTag", html);
  257. try{
  258. if(html.contains('<title>')) {
  259. String titleElement = html.substring(html.indexOf("<title>")+7,html.indexOf("<\/title>"));
  260. return titleElement;
  261. }
  262. return '';
  263. }
  264. catch(e){
  265. return '';
  266. }
  267. }
  268. initRest()async{
  269. try{
  270. if(prefs.getString(keyClass.client_credential)==null){
  271. prefs.setString(keyClass.client_credential, json.encode({
  272. "id": "IZ4W8u8YZmLtUV0p1zd-_A..",
  273. "secret" : "AQ16v4bzGWm9AsWHvUcu2Q.."
  274. }).toString());
  275. }
  276. return await getOauth2Client();
  277. }
  278. catch(e){
  279. print(e);
  280. print("error fetching Rest token");
  281. }
  282. }
  283. showLoading(context,{dissmissable=false,onwillpop}){
  284. showDialog(
  285. context: context,
  286. builder: (BuildContext context) {
  287. return WillPopScope(
  288. onWillPop: onwillpop??()async{return true;},
  289. child: new Center(
  290. child: new CircularProgressIndicator(),
  291. ),
  292. );
  293. },
  294. barrierDismissible: dissmissable,
  295. );
  296. }
  297. permissionCheck(context,pHandler.Permission permissionType,ifGranted,{customMessage=''})async{
  298. pHandler.PermissionStatus permission = await permissionType.status;
  299. if(permission!= pHandler.PermissionStatus.granted &&context != null){
  300. if(permission== pHandler.PermissionStatus.denied || permission== pHandler.PermissionStatus.restricted){
  301. showFlushbar(context,'${permissionType.toString().substring(permissionType.toString().lastIndexOf('.')+1)} permission is needed$customMessage. Please grant the permission!');
  302. await Future.delayed(Duration(seconds: 3));
  303. permission = await permissionType.request();
  304. }
  305. if(permission== pHandler.PermissionStatus.permanentlyDenied) {
  306. showFlushbar(context,'It seems, your system security explicitly denied access to your ${permissionType.toString().substring(permissionType.toString().lastIndexOf('.')+1)} permission. Please MANUALLY enable it in setings!');
  307. await Future.delayed(Duration(seconds: 3));
  308. pHandler.openAppSettings();
  309. SystemChannels.platform.invokeMethod('SystemNavigator.pop');
  310. }
  311. if(permission== pHandler.PermissionStatus.denied || permission== pHandler.PermissionStatus.restricted){
  312. showFlushbar(context,'${permissionType.toString().substring(permissionType.toString().lastIndexOf('.')+1)} permission is needed$customMessage. Please grant the permission!');
  313. await Future.delayed(Duration(seconds: 3));
  314. permission = await permissionType.request();
  315. }
  316. await permissionCheck(context,permissionType,ifGranted);
  317. }
  318. else{
  319. await ifGranted();
  320. }
  321. }
  322. showFlushbar(context,text,{color:Colors.grey}){
  323. Flushbar(
  324. message: "$text",
  325. backgroundColor: color,
  326. duration: Duration(seconds: 5),
  327. )..show(context);
  328. }
  329. streamLocation(context)async{
  330. print('checking location');
  331. await permissionCheck(context,pHandler.Permission.locationWhenInUse,()async{
  332. location.changeSettings(accuracy: LocationAccuracy.high);
  333. bool gpsEnabled = false;
  334. if(await location.serviceEnabled()){
  335. gpsEnabled = await location.serviceEnabled();
  336. }
  337. else{
  338. print('requesting gps');
  339. gpsEnabled = await location.requestService();
  340. await streamLocation(context);
  341. }
  342. // print([gpsEnabled,permissionEnabled]);
  343. if(gpsEnabled){
  344. if(locationStream==null){
  345. locationStream = location.onLocationChanged.listen((LocationData event) {
  346. currentPosisiton = event;
  347. });
  348. }
  349. }
  350. },customMessage: " to locate your REAL location");
  351. }
  352. }