mirror of
https://github.com/QuasarApp/QtAndroidTools.git
synced 2025-04-26 13:04:32 +00:00
replace the com.google.android.gms:play-services-ads:16.+ to com.google.android.gms:play-services-ads:19.+
800 lines
55 KiB
HTML
800 lines
55 KiB
HTML
<!DOCTYPE html>
|
|
<html>
|
|
<head>
|
|
<meta charset="utf-8">
|
|
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
|
|
<title>QtAndroidTools library documentation</title>
|
|
<meta name="description" content="Free responsive HTML template for your documentation">
|
|
<meta name="author" content="valthemes.com">
|
|
<meta name="format-detection" content="telephone=no">
|
|
<link href='https://fonts.googleapis.com/css?family=Open+Sans:400,300,600,700&subset=latin,cyrillic' rel='stylesheet' type='text/css'>
|
|
<link rel="stylesheet" type="text/css" href="css/style.css">
|
|
<link rel="stylesheet" type="text/css" href="css/prettify.css">
|
|
<link rel="stylesheet" type="text/css" href="css/normalize.css" >
|
|
</head>
|
|
<body>
|
|
<header>
|
|
<div class="container">
|
|
<div class="row">
|
|
<div class="col-lg-2 col-xs-12 left">
|
|
<div id="logo">
|
|
<img src="images/logo.svg" alt="logo">
|
|
</div>
|
|
</div>
|
|
<div class="col-lg-8 col-md-7 col-xs-12">
|
|
<div class="slogan">
|
|
QtAndroidTools is a library that allows to simplify access to some native Android features from QML.
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</header>
|
|
<section class="content">
|
|
<div class="container">
|
|
<div class="content-wrap">
|
|
<div class="row">
|
|
<aside>
|
|
<div class="menu-box">
|
|
<h4>Navigation</h4>
|
|
<nav>
|
|
<ul>
|
|
<li><a href="#HowToIntegrate" class="current">How To Integrate</a></li>
|
|
<li><a href="#ApkExpansionFiles">ApkExpansionFiles</a></li>
|
|
<li><a href="#AppPermissions">AppPermissions</a></li>
|
|
<li><a href="#AdMobBanner">AdMobBanner</a></li>
|
|
<li><a href="#AdMobInterstitial">AdMobInterstitial</a></li>
|
|
<li><a href="#AdMobRewardedVideo">AdMobRewardedVideo</a></li>
|
|
<li><a href="#ApkInfo">ApkInfo</a></li>
|
|
<li><a href="#Images">Images</a></li>
|
|
<li><a href="#Notification">Notification</a></li>
|
|
<li><a href="#Screen">Screen</a></li>
|
|
<li><a href="#BatteryState">BatteryState</a></li>
|
|
<li><a href="#SignalStrength">SignalStrength</a></li>
|
|
<li><a href="#PlayStore">PlayStore</a></li>
|
|
<li><a href="#GoogleAccount">GoogleAccount</a></li>
|
|
<li><a href="#GoogleDrive">GoogleDrive</a></li>
|
|
<li><a href="#Sharing">Sharing</a></li>
|
|
<li><a href="#UserMessagingPlatform">UserMessagingPlatform</a></li>
|
|
<li><a href="#Audio">Audio</a></li>
|
|
<li><a href="#System">System</a></li>
|
|
</ul>
|
|
</nav>
|
|
</div>
|
|
</aside>
|
|
<div class="content-info">
|
|
<div class="section-txt" id="HowToIntegrate">
|
|
<h3>How To Integrate</h3>
|
|
<ul>
|
|
<li>Place QtAndroidTools lib to your project dir and include it in .pro file<br />
|
|
<pre class="prettyprint">include(QtAndroidTools/QtAndroidTools.pri)</pre>
|
|
</li>
|
|
<li>Assign in you .pro file varialble ANDROID_PACKAGE_SOURCE_DIR before include QtAndroidTools/QtAndroidTools.pri, for ex.<br />
|
|
<pre class="prettyprint">ANDROID_PACKAGE_SOURCE_DIR = $$PWD/android</pre>
|
|
</li>
|
|
<li>Always before include QtAndroidTools/QtAndroidTools.pri add the define labels for specify the library tools you want to include/exclude from your project compilation:<br />
|
|
<pre class="prettyprint">DEFINES += \
|
|
QTAT_APP_PERMISSIONS \
|
|
QTAT_APK_EXPANSION_FILES \
|
|
QTAT_APK_INFO \
|
|
QTAT_SCREEN \
|
|
QTAT_SYSTEM \
|
|
QTAT_BATTERY_STATE \
|
|
QTAT_SIGNAL_STRENGTH \
|
|
QTAT_IMAGES \
|
|
QTAT_NOTIFICATION \
|
|
QTAT_ADMOB_BANNER \
|
|
QTAT_ADMOB_INTERSTITIAL \
|
|
QTAT_ADMOB_REWARDED_VIDEO \
|
|
QTAT_PLAY_STORE \
|
|
QTAT_GOOGLE_ACCOUNT \
|
|
QTAT_GOOGLE_DRIVE \
|
|
QTAT_SHARING \
|
|
QTAT_USER_MESSAGING_PLATFORM \
|
|
QTAT_AUDIO</pre>
|
|
</li>
|
|
<li>In the <i>main()</i> body insert the call for initialize the library<br />
|
|
<pre class="prettyprint">QtAndroidTools::initializeQmlTools();</pre>
|
|
</li>
|
|
|
|
</ul>
|
|
</div>
|
|
<div class="section-txt" id="ApkExpansionFiles">
|
|
<h3>ApkExpansionFiles</h3>
|
|
<p>Help in manage the apk expansion files download</p>
|
|
<p>Apk upload size limit is currently 100MB but in case your app require more data the Android Console allow to "attach" two files connected to your app. Official documentation about this feature is <a href="https://developer.android.com/google/play/expansion-files" target="_blank">here</a>, is <u>strongly suggested</u> to read it for allow a better comprension about how to use this tool. Usually the expansion files are downloaded by the Google Play together with the main app but in case the user delete it or some other problem occurs and the file will not be available anymore the app have to download again usually at startup. In this phase is required the java code of the two libraries explained in the documentation, the <i>Google Play Licensing Library</i> and the <i>Google Play APK Expansion Library</i>. However, at the time this post was written, there are a couple of problems. The official documentation suggest to get these libraries through the Android SDK Manager and then create two modules using the libraries just obtained. The problem here is the code of there libraries is very very old and use some deprecated dependencies making difficult the compilation using Qt Creator. It exist an updated version of these two libraries always developed by Google <a href="https://github.com/google/play-apk-expansion" target="_blank">here</a> and <a href="https://github.com/google/play-licensing" target="_blank">here</a>. However also these two latest libraries are not supported by a long time and doesn't work very well in the latest versions of Android, from 8 and above. For this reasons this tool implement the two updated version community supported <a href="https://github.com/bolein/better-apk-expansion" target="_blank">better-apk-expansion</a> and <a href="https://github.com/bolein/better-licensing" target="_blank">better-licensing</a> that make the same job but are updated enough for support the new notify feature of Android 8. I only made a small modify for support the Qt multi language engine. In the version inside the tool the java library ask to the C++ level for the info text to use in the Android notify label allowing the Qt language selector to select the correct language string.</p>
|
|
<p>Remember for have the download library working as expected you have to set the following permission in your app:</p>
|
|
<pre class="prettyprint"><manifest ...>
|
|
<!-- Required to access Google Play Licensing -->
|
|
<uses-permission android:name="com.android.vending.CHECK_LICENSE" />
|
|
|
|
<!-- Required to download files from Google Play -->
|
|
<uses-permission android:name="android.permission.INTERNET" />
|
|
|
|
<!-- Required to keep CPU alive while downloading files
|
|
(NOT to keep screen awake) -->
|
|
<uses-permission android:name="android.permission.WAKE_LOCK" />
|
|
|
|
<!-- Required to poll the state of the network connection
|
|
and respond to changes -->
|
|
<uses-permission
|
|
android:name="android.permission.ACCESS_NETWORK_STATE" />
|
|
|
|
<!-- Required to check whether Wi-Fi is enabled -->
|
|
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
|
|
|
|
<!-- Required to read and write the expansion files on shared storage -->
|
|
<uses-permission
|
|
android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
|
|
|
|
<!-- Required to start download service in foreground -->
|
|
<uses-permission android:name="android.permission.FOREGROUND_SERVICE"/>
|
|
|
|
...
|
|
</manifest></pre>
|
|
<p>Also note, in case your Android app is target for version 23 or above you have to explicitly ask for the <i>WRITE_EXTERNAL_STORAGE</i> permission cause this is one of the "dangerous" permission. You can use the other <a href="#AppPermissions">AppPermissions</a> tool available in this library. Also you have to correctly the various part of the library by addicting these lines inside your <i>AndroidManifest.xml</i> file:</p>
|
|
<pre class="prettyprint"><application>
|
|
.....
|
|
<service android:name="com.google.android.vending.expansion.downloader.impl.DownloaderService" android:enabled="true"/>
|
|
<receiver android:name="com.google.android.vending.expansion.downloader.impl.DownloaderService$AlarmReceiver" android:enabled="true"/>
|
|
</application></pre>
|
|
<p><u>Please note from now it's assumed you have read the documentation</u> and already know the type and the format of expansion files is possible to upload and how the licensing engine work. First initialization is the following:</p>
|
|
<pre class="prettyprint">QtAndroidApkExpansionFiles.base64PublicKey = "app_public_key_here";
|
|
QtAndroidApkExpansionFiles.salt = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20];
|
|
QtAndroidApkExpansionFiles.main.version = 1;
|
|
QtAndroidApkExpansionFiles.main.size = 123456789;
|
|
QtAndroidApkExpansionFiles.patch.version = 1;
|
|
QtAndroidApkExpansionFiles.patch.size = 123456789;</pre>
|
|
<p>The <i>base64PublicKey</i> can be found in the Android Console app info and the <i>salt</i> is a random array of 20 bytes you have to generate by yourself. This is required for encrypt your data stored of the server. <i>Version</i> and <i>size</i> is required for identify your main and patch file. You can upload only the main file (and then you have to set only the <i>main</i> fields), these info are used to check if the current expansion files eventually already present in the device correspond in term of version number and file size.</p>
|
|
<p>Once configured the basic info you can check the operation to make by calling the following function:</p>
|
|
<pre class="prettyprint">QtAndroidApkExpansionFiles.startDownloadFiles()</pre>
|
|
<p>If this function will return:</p>
|
|
<pre class="prettyprint">QtAndroidApkExpansionFiles.APKEF_NO_DOWNLOAD_REQUIRED</pre>
|
|
<p>mean your expansion file are already available in the device than there is nothing to do, you can proceed with the app execution. In case of return:</p>
|
|
<pre class="prettyprint">QtAndroidApkExpansionFiles.APKEF_DOWNLOAD_STARTED
|
|
QtAndroidApkExpansionFiles.APKEF_LVL_CHECK_REQUIRED</pre>
|
|
<p>mean the apk expansion files download is started than you have to manage the download progress info. A download notify will be showed in the system status bar but your app should also show a progress control to inform the user regarding the operation in progress and that he have to wait. All other return codes are basically error conditions, check the library sources to see all the possible error types.</p>
|
|
<img src="images/apkexpansionfiles1.png">
|
|
<p>During download phase the tool generate two signals updating you about current status as follow:</p>
|
|
<pre class="prettyprint">Connections {
|
|
target: QtAndroidApkExpansionFiles
|
|
function onDownloadStateChanged(newState)
|
|
{
|
|
switch(newState)
|
|
{
|
|
case QtAndroidApkExpansionFiles.STATE_COMPLETED:
|
|
...
|
|
break;
|
|
case QtAndroidApkExpansionFiles.STATE_FAILED_UNLICENSED:
|
|
case QtAndroidApkExpansionFiles.STATE_FAILED_FETCHING_URL:
|
|
case QtAndroidApkExpansionFiles.STATE_FAILED_SDCARD_FULL:
|
|
case QtAndroidApkExpansionFiles.STATE_FAILED_CANCELED:
|
|
case QtAndroidApkExpansionFiles.STATE_FAILED:
|
|
...
|
|
break;
|
|
}
|
|
}
|
|
onDownloadProgress: {
|
|
var time = new Date(timeRemaining);
|
|
downloadProgressBar.to = overallTotal;
|
|
downloadProgressBar.value = overallProgress;
|
|
downloadSizeLabel.text = (overallProgress / (1024*1024)).toFixed(2) + "MB/" + (overallTotal / (1024*1024)).toFixed(2) + "MB";
|
|
downloadTimeLabel.text = "Time left: ";
|
|
if(timeRemaining > 1000 * 60 * 60)
|
|
downloadTimeLabel.text += ("0" + time.getHours()).substr(-2) + ":" + ("0" + time.getMinutes()).substr(-2);
|
|
else
|
|
downloadTimeLabel.text += ("0" + time.getMinutes()).substr(-2) + ":" + ("0" + time.getSeconds()).substr(-2);
|
|
}
|
|
}</pre>
|
|
<p><i>onDownloadStateChanged</i> have the <i>newState</i> param informing about the download state changed. Check the sources for all the possible values. <i>onDownloadProgress</i> report info about the download process like current size and time left. Once download completed or if your expansion files are already available is possible to retrieve the full path of both files by use the following functions:</p>
|
|
<pre class="prettyprint">QtAndroidApkExpansionFiles.mainFileName()
|
|
QtAndroidApkExpansionFiles.patchFileName()</pre>
|
|
<p>During download phase always is possible to abort, stop and restart download by using the functions below:</p>
|
|
<pre class="prettyprint">QtAndroidApkExpansionFiles.abortDownload()
|
|
QtAndroidApkExpansionFiles.pauseDownload()
|
|
QtAndroidApkExpansionFiles.continueDownload()</pre>
|
|
<p>A specific note regarding the function <i>getString()</i>. It return an info string connected with the current download status and some other info. It's used internally to pass correct language string to the java library but you can use also for the main interface as in demo example.</p>
|
|
</div>
|
|
<div class="section-txt" id="AppPermissions">
|
|
<h3>AppPermissions</h3>
|
|
<p>This tool allow to request Android app permissions in an easier way.</p>
|
|
<p>From Android version 23 (Marshmallow) there are a list of special permission called "dangerous" because are directly connected to personal data of the user like calendar, contacts list and so on (official documentation <a href="https://developer.android.com/guide/topics/permissions/overview" target="_blank">here</a>). If your app is target for this version and above and your manifest file contains one of the dangerous permissions you have to explicitly get the user authorization for have such permission granted. In the demo app four of these dangerous permission will be requested as follow:</p>
|
|
<img src="images/apppermissions1.png">
|
|
<p>There are two functions for request permissions, one accept a list of permissions for allow a unique request for all and another can be used to ask for a single permission only. In this example the multiple request function will be used as follow:</p>
|
|
<pre class="prettyprint">import QtAndroidTools 1.0
|
|
...
|
|
readonly property var permissionsNameList: ["android.permission.WRITE_EXTERNAL_STORAGE","android.permission.READ_CALENDAR","android.permission.READ_PHONE_STATE","android.permission.READ_CONTACTS"]
|
|
...
|
|
QtAndroidAppPermissions.requestPermissions(permissionsNameList)</pre>
|
|
<p>The call of this function will have a result to show the system message informing the user the app require the specific permissions and ask for approval:</p>
|
|
<img src="images/apppermissions2.png">
|
|
<p>Once the user will finish to make the choice a signal will be generated with a list of struct as param as follow:</p>
|
|
<pre class="prettyprint">Connections {
|
|
target: QtAndroidAppPermissions
|
|
function onRequestPermissionsResults(results)
|
|
{
|
|
for(var i = 0; i < results.length; i++)
|
|
{
|
|
if(results[i].granted === true)
|
|
{
|
|
setPermissionGranted(results[i].name, true);
|
|
}
|
|
else
|
|
{
|
|
if(QtAndroidAppPermissions.shouldShowRequestPermissionInfo(results[i].name) === true)
|
|
{
|
|
if(results[i].name === permissionsNameList[0])
|
|
requestPermissionWRITE_EXTERNAL_STORAGE.open();
|
|
else if(results[i].name === permissionsNameList[1])
|
|
requestPermissionREAD_CALENDAR.open();
|
|
else if(results[i].name === permissionsNameList[2])
|
|
requestPermissionREAD_PHONE_STATE.open();
|
|
else if(results[i].name === permissionsNameList[3])
|
|
requestPermissionREAD_CONTACTS.open();
|
|
}
|
|
else
|
|
{
|
|
setPermissionGranted(results[i].name, false);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}</pre>
|
|
<p>Each item in the list contain the param <i>name</i> containing the permission string name and the boolean field <i>granted</i> informing if the user allowed the app to get the permission or not. Please note, if you app will be target under version 23 this signal will be emitted immediately without show any messagebox and, obviously, with all the permission automatically granted. This for allow the code working in the same way independently by the Android target version selected. In case the user don't granted a permission this special call is used in the code:</p>
|
|
<pre class="prettyprint">QtAndroidAppPermissions.shouldShowRequestPermissionInfo(...)</pre>
|
|
<p>This function is quite particular and return true only in the case a first attempt to ask to permission has been denied. Basically it "suggest" to show a message to the user explaining why your app need the specific permission before retry to ask for permission again:</p>
|
|
<img src="images/apppermissions3.png">
|
|
<p>Once explained the reasons you can ask again for the same permission by using this time the single request function:</p>
|
|
<pre class="prettyprint">QtAndroidAppPermissions.requestPermission(...)</pre>
|
|
<p>Now please note a very important particular. Theoretically you can ask for the same permission infinitely, however from the second time you ask for the same permission the system message window will appear as following:</p>
|
|
<img src="images/apppermissions4.png">
|
|
<p>As you can note in this case there is a checkbox allowing the user to not be annoyed by your request anymore (<i>Don't ask again</i>). If the user will check it and will deny the request again any next request for the permission will be automatically denied without show any message than be careful in decide when ask for permission and, above all, to explain very clearly why you need that permission. After the second try the signal reporting the choice result will be generated again with the updated situation:</p>
|
|
<img src="images/apppermissions5.png">
|
|
</div>
|
|
<div class="section-txt" id="AdMobBanner">
|
|
<h3>AdMobBanner</h3>
|
|
<p>This tool allow to show AdMob banner inside QML app.</p>
|
|
<p>Official documentation about AdMob banner is <a href="https://developers.google.com/admob/android/banner" target="_blank">here</a>, please <u>read before continue</u> for understand the options exported by the tool. Remember for allow banner to be loaded your app need the following permissions:</p>
|
|
<pre class="prettyprint">android.permission.INTERNET
|
|
android.permission.ACCESS_NETWORK_STATE
|
|
android.permission.WRITE_EXTERNAL_STORAGE</pre>
|
|
<p>In add of this you have to install the AdMob required packages through Android SDK Manager. The packages you have to install are the following:</p>
|
|
<ul>
|
|
<li>Google Repository</li>
|
|
<li>Google Play services</li>
|
|
<li>Support Repository </li>
|
|
</ul>
|
|
<p>Than you have to add the following dependencies into your app gradle file:</p>
|
|
<pre class="prettyprint">dependencies {
|
|
....
|
|
implementation 'com.google.android.gms:play-services-ads:19.+'
|
|
}</pre>
|
|
<p>Banner is showed inside the following QML item:</p>
|
|
<pre class="prettyprint">import QtAndroidTools 1.0
|
|
|
|
QtAndroidAdMobBanner {
|
|
id: banner
|
|
unitId: "admob-banner-unit-id"
|
|
type: QtAndroidAdMobBanner.TYPE_BANNER
|
|
keywords: ["keyword_1", "keyword_2", "keyword_3"]
|
|
nonPersonalizedAds: false
|
|
}</pre>
|
|
<p>The <i>unitId</i> is the string generated when you create a new ad unit inside the AdMob site. It's used to identify the ad connected to your app. Using this id you can know how much you earn from this ad unit. The <i>keywords</i> property is an optional list of keywords needed for better targeting the banner ad. The <i>nonPersonalizedAds</i> property is optional (default is false). Set this property to true impose to AdMob to don't use collected user personal data for ads targeting. The property <i>type</i> is the banner type you want to show. Possible values are:</p>
|
|
<pre class="prettyprint">TYPE_BANNER
|
|
TYPE_FULL_BANNER
|
|
TYPE_LARGE_BANNER
|
|
TYPE_MEDIUM_RECTANGLE
|
|
TYPE_SMART_BANNER
|
|
TYPE_WIDE_SKYSCRAPER</pre>
|
|
<p>This item generate the following signals informing regarding the ad status:</p>
|
|
<pre class="prettyprint">onLoadError
|
|
onLoading
|
|
onLoaded
|
|
onClosed
|
|
onClicked</pre>
|
|
<p>The only signal passing a param is onLoadError, called in case of problem in loading ad. The param is <i>errorId</i> and possible values are:</p>
|
|
<pre class="prettyprint">ERROR_INTERNAL
|
|
ERROR_NETWORK
|
|
ERROR_INVALID_REQUEST
|
|
ERROR_NO_FILL</pre>
|
|
<p>When you want to load and show the banner you have to call the <i>show()</i> function and for hide the <i>hide()</i> functions (banner is the id name of the item in the example above). Function <i>reload()</i> force reload of a new banner.</p>
|
|
<pre class="prettyprint">banner.show()
|
|
banner.hide()
|
|
banner.reload()</pre>
|
|
<p>Please note the banner is a native android view over the QML window, that's mean will stay over anything painted into in and you can not place nothing over the banner.</p>
|
|
<img src="images/admobbanner1.png">
|
|
</div>
|
|
<div class="section-txt" id="AdMobInterstitial">
|
|
<h3>AdMobInterstitial</h3>
|
|
<p>This tool allow to show AdMob interstitial inside QML app.</p>
|
|
<p>Official documentation about AdMob interstitial is <a href="https://developers.google.com/admob/android/interstitial" target="_blank">here</a>, please <u>read before continue</u> for understand the options exported by the tool. Remember for allow interstitial to be loaded your app need the following permissions:</p>
|
|
<pre class="prettyprint">android.permission.INTERNET
|
|
android.permission.ACCESS_NETWORK_STATE
|
|
android.permission.WRITE_EXTERNAL_STORAGE</pre>
|
|
<p>In add of this you have to install the AdMob required packages through Android SDK Manager. The packages you have to install are the following:</p>
|
|
<ul>
|
|
<li>Google Repository</li>
|
|
<li>Google Play services</li>
|
|
<li>Support Repository </li>
|
|
</ul>
|
|
<p>Than you have to add the following dependencies into your app gradle file:</p>
|
|
<pre class="prettyprint">dependencies {
|
|
....
|
|
implementation 'com.google.android.gms:play-services-ads:19.+'
|
|
}</pre>
|
|
<p>Interstitial ad show on full screen but you have to define the AdMob <i>unitId</i> using the item as follow:</p>
|
|
<pre class="prettyprint">QtAndroidAdMobInterstitial {
|
|
id: interstitial
|
|
unitId: "admob-interstitial-unit-id"
|
|
nonPersonalizedAds: false
|
|
}</pre>
|
|
<p>The <i>unitId</i> is the string generated when you create a new ad unit inside the AdMob site. It's used to identify the ad connected to your app. Using this id you can know how much you earn from this ad unit. The <i>nonPersonalizedAds</i> property is optional (default is false). Set this property to true impose to AdMob to don't use collected user personal data for ads targeting.</p>
|
|
<p>This item generate the following signals informing regarding the ad status:</p>
|
|
<pre class="prettyprint">onLoadError
|
|
onLoading
|
|
onLoaded
|
|
onClosed
|
|
onClicked</pre>
|
|
<p>The only signal passing a param is onLoadError, called in case of problem in loading ad. The param is <i>errorId</i> and possible values are:</p>
|
|
<pre class="prettyprint">ERROR_INTERNAL
|
|
ERROR_NETWORK
|
|
ERROR_INVALID_REQUEST
|
|
ERROR_NO_FILL</pre>
|
|
<p>Item have two function as follow:</p>
|
|
<pre class="prettyprint">interstitial.load()
|
|
interstitial.show()</pre>
|
|
<p>The interstitial have to be loaded before show and since loading is not immediate you have to preload a bit in advance before the time to show. You can follow the loading status through the item signals. Once revecied the <i>onLoaded</i> signal this mean your new interstitial is ready to be showed.</p>
|
|
<img src="images/admobinterstitial1.png">
|
|
<p>This type of ad have a button allowing the user to close it than you just have to wait about the user choice. Remember also in this case the ad window will go over the QML window and you can not paint anithing on top of it.</p>
|
|
<img src="images/admobinterstitial2.png">
|
|
</div>
|
|
<div class="section-txt" id="AdMobRewardedVideo">
|
|
<h3>AdMobRewardedVideo</h3>
|
|
<p>This tool allow to show AdMob Rewarded Video inside QML app.</p>
|
|
<p><b>IMPORTANT NOTE:</b> The current implementation of Rewarded Video API have to be used with only a single instance of the tool cause only one video can be loaded at a time. However a new set of API allowing multiple video loaded at the same time is going to be released (currently are still in beta). This is the reasons current implementation of this tool allow multiple instances. When the new API set will be released this tool code will be updated and change will be totally transparent from application side.</p>
|
|
<p>Official documentation about AdMob Rewarded Video is <a href="https://developers.google.com/admob/android/rewarded-video" target="_blank">here</a>, please <u>read before continue</u> for understand the options exported by the tool. Remember for allow video to be loaded your app need the following permissions:</p>
|
|
<pre class="prettyprint">android.permission.INTERNET
|
|
android.permission.ACCESS_NETWORK_STATE
|
|
android.permission.WRITE_EXTERNAL_STORAGE</pre>
|
|
<p>In add of this you have to install the AdMob required packages through Android SDK Manager. The packages you have to install are the following:</p>
|
|
<ul>
|
|
<li>Google Repository</li>
|
|
<li>Google Play services</li>
|
|
<li>Support Repository </li>
|
|
</ul>
|
|
<p>Than you have to add the following dependencies into your app gradle file:</p>
|
|
<pre class="prettyprint">dependencies {
|
|
....
|
|
implementation 'com.google.android.gms:play-services-ads:19.+'
|
|
}</pre>
|
|
<p>Rewarded Video ad show on full screen but you have to define the AdMob <i>unitId</i> using the item as follow:</p>
|
|
<pre class="prettyprint">QtAndroidAdMobRewardedVideo {
|
|
id: rewardedVideo
|
|
unitId: "admob-rewarded-video-unit-id"
|
|
nonPersonalizedAds: false
|
|
}</pre>
|
|
<p>The <i>unitId</i> is the string generated when you create a new ad unit inside the AdMob site. It's used to identify the ad connected to your app. Using this id you can know how much you earn from this ad unit. The <i>nonPersonalizedAds</i> property is optional (default is false). Set this property to true impose to AdMob to don't use collected user personal data for ads targeting.</p>
|
|
<p>This item generate the following signals informing regarding the ad status:</p>
|
|
<pre class="prettyprint">onRewarded
|
|
onLoadError
|
|
onLoading
|
|
onLoaded
|
|
onOpened
|
|
onClosed
|
|
onStarted
|
|
onCompleted
|
|
onLeftApplication</pre>
|
|
<p>The only two signals passing a param is onLoadError and onRewarded. The first is called in case of problem in loading ad. The param is <i>errorId</i> and possible values are:</p>
|
|
<pre class="prettyprint">ERROR_INTERNAL
|
|
ERROR_NETWORK
|
|
ERROR_INVALID_REQUEST
|
|
ERROR_NO_FILL</pre>
|
|
<p>The record is called for inform about the rewarded values. It have two params, <i>type</i> and <i>amount</i>. Check the official documentation for know the value meaning.
|
|
<p>Item have two function as follow:</p>
|
|
<pre class="prettyprint">rewardedVideo.load()
|
|
rewardedVideo.show()</pre>
|
|
<p>The video have to be loaded before show and since loading is not immediate you have to preload a bit in advance before the time to show. You can follow the loading status through the item signals. Once revecied the <i>onLoaded</i> signal this mean your new video is ready to be played.</p>
|
|
<img src="images/rewardedvideo1.png">
|
|
<p>This type of ad have a button allowing the user to close it than you just have to wait about the user choice. Remember also in this case the ad window will go over the QML window and you can not paint anithing on top of it.</p>
|
|
<img src="images/rewardedvideo2.png">
|
|
<p>After the user close the video you'll receive the rewarded info.</p>
|
|
</div>
|
|
<div class="section-txt" id="Images">
|
|
<h3>Images</h3>
|
|
<p>This tool allow to retrieve the device albums and images</p>
|
|
<p>There are only the following functions, the first return the list of device albums and the second return the list of all images inside the album (full absolute path of each image):</p>
|
|
<pre class="prettyprint">import QtAndroidTools 1.0
|
|
|
|
QtAndroidImages.getAlbumsList()
|
|
QtAndroidImages.getAlbumImagesList(albumId)</pre>
|
|
<p>In particular the first function return an array of structures with the following two properties:</p>
|
|
<pre class="prettyprint">album.id
|
|
album.name</pre>
|
|
<p>As is possible easily undertand the first id the <i>id</i> of the album (to use as param for the second function) and the second is the <i>name</i> of the album as saved in the Android device.</p>
|
|
<img src="images/images1.png">
|
|
</div>
|
|
<div class="section-txt" id="Notification">
|
|
<h3>Notification</h3>
|
|
<p>This tool will show Android system notifications.</p>
|
|
<p>As usual for better understand how to use notification is strongly reccomended to read the official documentation <a href="https://developer.android.com/guide/topics/ui/notifiers/notifications" target="_blank">here</a>.</p>
|
|
<p>The tool <i>QtAndroidNotification</i> allow to compose and show a system notification in a very easy way as follow:</p>
|
|
<pre class="prettyprint">QtAndroidNotification {
|
|
id: notification
|
|
title: "Notification title"
|
|
text: "This is the notification content"
|
|
expandableText: "This is a very very very very very very very very very very long expandable content"
|
|
channelName: "Notification channel"
|
|
smallIconName: "notification_icon_name"
|
|
largeIconSource: ":/images/logo.jpg"
|
|
}</pre>
|
|
<p>Available notification properties are the the following:</p>
|
|
<ul>
|
|
<li><i>title</i> : title of the notification.</li>
|
|
<li><i>text</i> : main content of the notification. This filed is mandatory and is limited to one line size.</li>
|
|
<li><i>expandableText</i> : in case you need to show a text longer than a line you can set this property with your full text. Based to the Android version the result will be a little different but, in any case, this part will be showed in addition of the text content.</li>
|
|
<li><i>channelName</i> : in Android 8.0 and above notification have to be associated to a channel, this for allow user to disable notifications associated to the specific channel. This is a mandatory value.</li>
|
|
<li><i>smallIconName</i> : another mandatory value. Basically this is the special format icon showed on system bar connected to the notification. You can find many tools allow to make this icon in the right format. Unfortunately, for support old Android verion, is not possible to pass this icon from Qt resource or from a image file on storage but have to be mandatorily use the apk drawable folders. For try to simplify you don't need to get the full app path but you simply can insert the name of the icon file (without extension) you set into drawable folder (check the demo source).</li>
|
|
<li><i>largeIconSource</i> : large icon you can show into notification. You can use an image from Qt resource system of from a file.</li>
|
|
</ul>
|
|
<p>In case you need to show a progress bar in the notification there are available the following additional properties:</p>
|
|
<ul>
|
|
<li><i>progressBar.max</i> : the max value of the progress bar.</li>
|
|
<li><i>progressBar.current</i> : The current value of the progress bar between zero and the max value.</li>
|
|
<li><i>progressBar.indeterminate</i> : boolean value for set the prograss bar in the indeterminate state. The result is an indicator that has the same style as the progress bar above, except the progress bar is a continuous animation that does not indicate completion.</li>
|
|
</ul>
|
|
<p>The progress bar is showed if you set the max value with a value greater than zero. For hide the progress bar set zero to both max nad current properties value.</p>
|
|
<p>The following methods can be called:</p>
|
|
<pre class="prettyprint">show()
|
|
cancel()</pre>
|
|
<p>Once set all the required properties you can show the notification by calling the corresponding function. The notification can be read and cleared directly by the user you can remove from app by using the <i>cancel()</i> call. For update the nodifcation information or the progress bar level you have to call the <i>show()</i> function again. If the user will touch over the notification the app will be ported on foreground or opened if previously closed.</p>
|
|
<img src="images/notification1.png">
|
|
<img src="images/notification2.png">
|
|
</div>
|
|
<div class="section-txt" id="ApkInfo">
|
|
<h3>ApkInfo</h3>
|
|
<p>This tool will return info about the apk containing the executed app.</p>
|
|
<p>The info regarding the app apk can be read directly from the <i>QtAndroidApkInfo</i> item as follow:</p>
|
|
<pre class="prettyprint">QtAndroidApkInfo.firstInstallTime
|
|
QtAndroidApkInfo.lastUpdateTime
|
|
QtAndroidApkInfo.packageName
|
|
QtAndroidApkInfo.versionCode
|
|
QtAndroidApkInfo.versionName
|
|
QtAndroidApkInfo.requestedPermissions</pre>
|
|
<p>Explanation about fields above can be found in the official Android documentation <a href="https://developer.android.com/reference/android/content/pm/PackageInfo" target="_blank">here</a>. The tool export only the most important info but if you need to have some additional data you can easily add you code by using JNI interface as showed in the sources.</p>
|
|
<img src="images/apkinfo1.png">
|
|
</div>
|
|
<div class="section-txt" id="BatteryState">
|
|
<h3>BatteryState</h3>
|
|
<p>This allow monitoring the battery level and state.</p>
|
|
<p>This tool install a listener for monitor the battery level and on charge state. There is nothing difficult in use since there are only two properties as follow:</p>
|
|
<pre class="prettyprint">import QtAndroidTools 1.0
|
|
|
|
QtAndroidBatteryState.level
|
|
QtAndroidBatteryState.onCharge</pre>
|
|
<p>Both properties support QML value binding than you can assign to a control for show always the updated value as in the demo example.</p>
|
|
<img src="images/batterystate1.png">
|
|
</div>
|
|
<div class="section-txt" id="Screen">
|
|
<h3>Screen</h3>
|
|
<p>This tool allow to change screen orientation.</p>
|
|
<p>Currently there is only one call for change screen orientation as follow:</p>
|
|
<pre class="prettyprint">import QtAndroidTools 1.0
|
|
|
|
QtAndroidScreen.setOrientation(orientaion)</pre>
|
|
<p>Possible values are the following:</p>
|
|
<ul>
|
|
<li>SCREEN_ORIENTATION_LANDSCAPE</li>
|
|
<li>SCREEN_ORIENTATION_REVERSE_LANDSCAPE</li>
|
|
<li>SCREEN_ORIENTATION_SENSOR_LANDSCAPE</li>
|
|
<li>SCREEN_ORIENTATION_PORTRAIT</li>
|
|
<li>SCREEN_ORIENTATION_REVERSE_PORTRAIT</li>
|
|
<li>SCREEN_ORIENTATION_SENSOR_PORTRAIT</li>
|
|
</ul>
|
|
<p>Check official Android documentation about behaviour of each value.</p>
|
|
<img src="images/screen1.png">
|
|
</div>
|
|
<div class="section-txt" id="SignalStrength">
|
|
<h3>SignalStrength</h3>
|
|
<p>This tool allow to monitoring the strength of the phone signal.</p>
|
|
<p>This tool install a listener for monitor the phone signal. Remember for allow the library to work in this case the app need to have the following permission:</p>
|
|
<pre class="prettyprint">android.permission.READ_PHONE_STATE</pre>
|
|
<p>There are two properties reporting the strength of the phone signal in row number and based to the conventional states as follow:</p>
|
|
<pre class="prettyprint">import QtAndroidTools 1.0
|
|
|
|
QtAndroidSignalStrength.signalStrength
|
|
QtAndroidSignalStrength.signalLevel</pre>
|
|
<p>Signal level possible states are the following:</p>
|
|
<ul>
|
|
<li>LEVEL_GREAT</li>
|
|
<li>LEVEL_GOOD</li>
|
|
<li>LEVEL_MODERATE</li>
|
|
<li>LEVEL_POOR</li>
|
|
<li>LEVEL_NONE</li>
|
|
</ul>
|
|
<p><b>PLEASE NOTE:</b> the report the the signal strength change doesn't arrive immediately but, instead, require some seconds to be updated after the change. Don't worry if you don't see an immediate update, just wait a little.</p>
|
|
<img src="images/signalstrength1.png">
|
|
</div>
|
|
<div class="section-txt" id="PlayStore">
|
|
<h3>PlayStore</h3>
|
|
<p>This tool allow to open Play Store app details and developer apps list.</p>
|
|
<pre class="prettyprint">import QtAndroidTools 1.0
|
|
|
|
QtAndroidPlayStore.openAppDetails(packageName)
|
|
QtAndroidPlayStore.openDeveloperAppList(developerName)</pre>
|
|
<p>The first call open the Play Store app with the details page of the package name app provided (in the format "com.company.appname").</p>
|
|
<p>NOTE: it's possible to call this method without any param, in this case the tool will use the app package name automatically.</p>
|
|
<p>The second call will open Play Store listing all the apps connected with the developer name passed in the param.</p>
|
|
</div>
|
|
<div class="section-txt" id="GoogleAccount">
|
|
<h3>GoogleAccount</h3>
|
|
<p>This tool allow to signin using one of the Google accounts currently registered in the device. Please, read carefully the official documentation for knwo how the sigin procedure work <a href="https://developers.google.com/identity/sign-in/android" target="_blank">here</a>. The tool export the basic methods for easily signin to the last signed account or a new one as the official documentation explain:</p>
|
|
<pre class="prettyprint">import QtAndroidTools 1.0
|
|
|
|
QtAndroidGoogleAccount.signIn(scopeName)
|
|
QtAndroidGoogleAccount.signInSelectAccount(scopeName)
|
|
QtAndroidGoogleAccount.signOut()
|
|
QtAndroidGoogleAccount.revokeAccess()</pre>
|
|
<p>The second method <i>signInSelectAccount</i> allow to select one of the registered accounts to signin. If only one Google account is present in the device it will be selected automatically. In case of more than one accounts the system activity will start for allow user to select the desired account. Once signedin the app, at each next start, will have only to call the first method to be signedin again with the same account without any other request to user. If you want to signedout and allow to request again the user permission just use the last two methods. After call the signin procedure you have to wait for result through the following signals:</p>
|
|
<pre class="prettyprint">onSignedIn
|
|
onSignedOut</pre>
|
|
<p>The first signal have the <i>signInSuccessfully</i> param informing about the operation result. Once signed successfull you can read the account info using the following fields:</p>
|
|
<pre class="prettyprint">QtAndroidGoogleAccount.signedInAccount.id
|
|
QtAndroidGoogleAccount.signedInAccount.displayName
|
|
QtAndroidGoogleAccount.signedInAccount.email
|
|
QtAndroidGoogleAccount.signedInAccount.familyName
|
|
QtAndroidGoogleAccount.signedInAccount.givenName
|
|
QtAndroidGoogleAccount.signedInAccount.photo</pre>
|
|
<p>The <i>photo</i> field export the binary image of the account. For show in a standard Image control you can use the generic image provider as follow:</p>
|
|
<pre class="prettyprint">QtAndroidTools.insertImage("AccountPhoto", QtAndroidGoogleAccount.signedInAccount.photo);
|
|
accountPhoto.source = "image://QtAndroidTools/AccountPhoto";</pre>
|
|
<p>For know which type of scopes use for signin you have to check the documentation cause it changes based to the Google resource you want to access in.</p>
|
|
<img src="images/googleaccount1.png">
|
|
</div>
|
|
<div class="section-txt" id="GoogleDrive">
|
|
<h3>GoogleDrive</h3>
|
|
<p>This tool export a basic set of methods for work with Google Drive.</p>
|
|
<p><b>PLEASE NOTE:</b> be very careful in using these methods cause you risk deleting some important files from user's Google drive. It's important to <b>TEST VERY WELL</b> your app before release. I take no responsibility for any damage that can be done using these methods.</p>
|
|
<p>For know how to use these methods and how to configure the Google drive access you have to read the official documentation <a href="https://developers.google.com/drive/api/v3/about-sdk" target="_blank">here</a>. As first operation you have to authenticate your app by using the corresponding methods:</p>
|
|
<pre class="prettyprint">QtAndroidGoogleDrive.authenticate(appName, scopeName)</pre>
|
|
<p>The method return a bool value informing the result of the operation. Scope is used to declare the type of access you want to get for Google Drive. The user must authorize the type of access requested before being able to operate. The list of possible scopes is the following, for use of each scope read the documentation <a href="https://developers.google.com/drive/api/v3/about-auth" target="_blank">here</a>:</p>
|
|
<ul>
|
|
<li>SCOPE_DRIVE</li>
|
|
<li>SCOPE_DRIVE_APPDATA</li>
|
|
<li>SCOPE_DRIVE_FILE</li>
|
|
<li>SCOPE_DRIVE_METADATA</li>
|
|
<li>SCOPE_DRIVE_METADATA_READONLY</li>
|
|
<li>SCOPE_DRIVE_PHOTOS_READONLY</li>
|
|
<li>SCOPE_DRIVE_READONLY</li>
|
|
<li>SCOPE_DRIVE_SCRIPTS</li>
|
|
</ul>
|
|
<p>Once got the authorization to access the following methods are available:</p>
|
|
<pre class="prettyprint">QtAndroidGoogleDrive.getFilesList(query)
|
|
QtAndroidGoogleDrive.getRootId()
|
|
QtAndroidGoogleDrive.downloadFile(fileId, localFilePath)
|
|
QtAndroidGoogleDrive.uploadFile(localFilePath, mimeType, parentFolderId)
|
|
QtAndroidGoogleDrive.createFolder(name, parentFolderId)
|
|
QtAndroidGoogleDrive.isFolder(fileId)
|
|
QtAndroidGoogleDrive.moveFile(fileId, folderId)
|
|
QtAndroidGoogleDrive.deleteFile(fileId)</pre>
|
|
<p>The first method return an array of structs listing the drive files as showed in the example:</p>
|
|
<pre class="prettyprint">var filesList = QtAndroidGoogleDrive.getFilesList();
|
|
var rootId = QtAndroidGoogleDrive.getRootId();
|
|
|
|
filesListModel.clear();
|
|
for(var i = 0; i < filesList.length; i++)
|
|
{
|
|
var data = filesList[i];
|
|
var parentId = "null";
|
|
|
|
if(data.parents.length > 0)
|
|
{
|
|
if(data.parents[0] === rootId)
|
|
parentId = "root";
|
|
else
|
|
parentId = data.parents[0];
|
|
}
|
|
|
|
filesListModel.append({ "id": data.id,
|
|
"name": data.name,
|
|
"mimeType": data.mimeType,
|
|
"parentId": parentId
|
|
});
|
|
}</pre>
|
|
<p>The param <i>query</i> is optional. If you don't pass it the method return the list of all files inside the drive. In case you need a more specific search the documentation about how to use the query is <a href="https://developers.google.com/drive/api/v3/search-files" target="_blank">here</a>. All the files and folder have a string id, the method <i>getRootId()</i> return the id of the root folder. Is possible to download a drive file or upload inside drive. The <i>localFilePath</i> is a full path of the file to upload/download including the file name (also for download). The remaining methods allow to manage the drive files. Remember for download a file you must to have granted the WRITE_EXTERNAL_STORAGE permission. Two signals are used to update info regarding the download/upload operations as follow:</p>
|
|
<pre class="prettyprint">Connections {
|
|
target: QtAndroidGoogleDrive
|
|
function onDownloadProgressChanged(state, progress)
|
|
{
|
|
switch(state)
|
|
{
|
|
case QtAndroidGoogleDrive.STATE_MEDIA_IN_PROGRESS:
|
|
break;
|
|
case QtAndroidGoogleDrive.STATE_MEDIA_COMPLETE:
|
|
break;
|
|
}
|
|
}
|
|
function onUploadProgressChanged(state, progress)
|
|
{
|
|
switch(state)
|
|
{
|
|
case QtAndroidGoogleDrive.STATE_INITIATION_STARTED:
|
|
break;
|
|
case QtAndroidGoogleDrive.STATE_INITIATION_COMPLETE:
|
|
break;
|
|
case QtAndroidGoogleDrive.STATE_MEDIA_IN_PROGRESS:
|
|
break;
|
|
case QtAndroidGoogleDrive.STATE_MEDIA_COMPLETE:
|
|
break;
|
|
}
|
|
}
|
|
}</pre>
|
|
<p>Both signal have tow params <i>state</i> and <i>progress</i>.</p>
|
|
</div>
|
|
<div class="section-txt" id="Sharing">
|
|
<h3>Sharing</h3>
|
|
<p>This tool allow to use the Android sharing feature for share file, text and binary data.</p>
|
|
<p>For know how to configure and use the app for manage sharing data you have to carefully read the official documentation <a href="https://developer.android.com/training/sharing" target="_blank">here</a> for simple data and <a href="https://developer.android.com/training/secure-file-sharing" target="_blank">here</a> for files. As you can read the "standard" way should be do create a dedicated activity fo each sharing data type but, cause Qt for android have only a single activity loading the native code, my solution is to use this unique main activity for all tha cases and check during startup phase if the activity has been launched for sharing purposes. Than inside the AndroidManifest.xml activity section you can add the required action based to the data you want to share (the following is from the demo app code):</p>
|
|
<pre class="prettyprint"><intent-filter>
|
|
<action android:name="android.intent.action.SEND"/>
|
|
<category android:name="android.intent.category.DEFAULT"/>
|
|
<data android:mimeType="text/plain"/>
|
|
</intent-filter>
|
|
<intent-filter>
|
|
<action android:name="android.intent.action.SEND"/>
|
|
<category android:name="android.intent.category.DEFAULT"/>
|
|
<data android:mimeType="image/*"/>
|
|
</intent-filter>
|
|
<intent-filter>
|
|
<action android:name="android.intent.action.PICK"/>
|
|
<category android:name="android.intent.category.DEFAULT"/>
|
|
<category android:name="android.intent.category.OPENABLE"/>
|
|
<data android:mimeType="image/*"/>
|
|
</intent-filter></pre>
|
|
<p>Regarding the file sharing provider the code is the following:</p>
|
|
<pre class="prettyprint"><provider android:name="androidx.core.content.FileProvider"
|
|
android:authorities="${applicationId}.qtandroidtoolsfileprovider"
|
|
android:grantUriPermissions="true"
|
|
android:exported="false">
|
|
<meta-data android:name="android.support.FILE_PROVIDER_PATHS" android:resource="@xml/sharedfilepaths"/>
|
|
</provider></pre>
|
|
<p>You can name the <i>resource</i> as you prefer but don't change the <i>authorities</i> name cause the tool refer to this label (qtandroidtoolsfileprovider) for configure the correct resource.</p>
|
|
<p>For share simple data from your app to other apps the following function are available:</p>
|
|
<pre class="prettyprint">QtAndroidSharing.shareText(text)
|
|
QtAndroidSharing.shareBinaryData(mimeType, dataFilePath)</pre>
|
|
<p>A system window will be showed with all the apps able to receive the data type you want to share as follow:</p>
|
|
<img src="images/sharing1.png">
|
|
<p>Once the user will select the preferred one the data will be transfered automatically.</p>
|
|
<p>In case you want to ask for a file shared by other apps the procedure is a bit different. At first you have to use the following function with the param the file mime type you need:</p>
|
|
<pre class="prettyprint">QtAndroidSharing.requestSharedFile(mimeType)</pre>
|
|
<p>Anothe different systme window will show the apps able to share the file type you need:</p>
|
|
<img src="images/sharing2.png">
|
|
<p>The selection will open the app sharing the file and the user have to choose the file or cancel the operation. Both actions will return the two events as follow:</p>
|
|
<pre class="prettyprint">Connections {
|
|
target: QtAndroidSharing
|
|
function onRequestedSharedFileReadyToSave(mimeType, name, size)
|
|
{
|
|
}
|
|
function onRequestedSharedFileNotAvailable()
|
|
{
|
|
}
|
|
}</pre>
|
|
<p>The second event will inform thet the requested file is not available for various reasons (probably the user cancelled the operation). The first event will export three params named <i>name</i>, <i>size</i> and <i>mimeType</i> with info regarding the user selected file. Please note in this phase the file has not been imported yet. The info will help you to "decide" if the selected file can be imported (for example if the selected file is too much big in size). If you decide the file is correct you have to call the function to import and save somewhere in your app space:</p>
|
|
<pre class="prettyprint">QtAndroidSharing.saveRequestedSharedFile(filePath)</pre>
|
|
<p>In case you are not interested to have the file you have to cancel the operation by call:</p>
|
|
<pre class="prettyprint">QtAndroidSharing.closeRequestedSharedFile()</pre>
|
|
<p>Now the opposite part, that's mean reply to shared requested from other apps. As explained in the first part of this section the activity receiving the request is always the main one. This mean the only way to know if our app has been lanuched from another app asking for share something is to check on startup phase as follow:</p>
|
|
<pre class="prettyprint">Component.onCompleted: {
|
|
if(QtAndroidTools.activityAction === QtAndroidTools.ACTION_SEND)
|
|
{
|
|
if(QtAndroidTools.activityMimeType === "text/plain")
|
|
{
|
|
}
|
|
else if(QtAndroidTools.activityMimeType.startsWith("image") === true)
|
|
{
|
|
}
|
|
}
|
|
else if(QtAndroidTools.activityAction === QtAndroidTools.ACTION_PICK)
|
|
{
|
|
}
|
|
}</pre>
|
|
<p>Currently the supported actions are the following:</p>
|
|
<pre class="prettyprint">QtAndroidTools.ACTION_NONE
|
|
QtAndroidTools.ACTION_SEND
|
|
QtAndroidTools.ACTION_SEND_MULTIPLE
|
|
QtAndroidTools.ACTION_PICK</pre>
|
|
<p>For the first two requests (ACTION_SEND and ACTION_SEND_MULTIPLE) you can receive the shared data sent to you by using the following functions:</p>
|
|
<pre class="prettyprint">QtAndroidSharing.getReceivedSharedText()
|
|
QtAndroidSharing.getReceivedSharedBinaryData()
|
|
QtAndroidSharing.getReceivedMultipleSharedBinaryData()</pre>
|
|
<p>For the action requesting to share a file (ACTION_PICK) you have to show a window for allow the user to select the file he want to import into the requesting app. In the demo app we have only one file to share that the choose is only if you want or not the file:</p>
|
|
<img src="images/sharing3.png">
|
|
<p>After the user made a selection you have to reply by using the following function:</p>
|
|
<pre class="prettyprint">QtAndroidSharing.shareFile(fileAvailable, mimeType, filePath)</pre>
|
|
<p>In case the user want the file you have to set the <i>fileAvailable</i> as true and provide the other params. In the opposite case (the user refused) you have to call this function by set the first param as false without provide the other params.</p>
|
|
</div>
|
|
<div class="section-txt" id="UserMessagingPlatform">
|
|
<h3>UserMessagingPlatform</h3>
|
|
<p>Under the Google <a href="https://www.google.com/about/company/user-consent-policy/" target="_blank">EU User Consent Policy</a>, you must make certain disclosures to your users in the European Economic Area (EEA) along with the UK and obtain their consent to use cookies or other local storage, where legally required, and to use personal data (such as AdID) to serve ads. This policy reflects the requirements of the EU ePrivacy Directive and the General Data Protection Regulation (GDPR).</p>
|
|
<p>This tool support the use of the UMP SDK but for a clear explanation about how to use this SDK and how to configure the consent form you have to read the official guide <a href="https://developers.google.com/admob/ump/android/quick-start" target="_blank">here</a>. At first you must to request the consent form that can be or not be available for the zone your current user is:</p>
|
|
<pre class="prettyprint">Connections {
|
|
target: QtAndroidUserMessagingPlatform
|
|
function onConsentFormRequestResult(eventId)
|
|
{
|
|
switch(eventId)
|
|
{
|
|
case QtAndroidUserMessagingPlatform.CONSENT_FORM_INFO_UPDATE_FAILURE:
|
|
....
|
|
break;
|
|
case QtAndroidUserMessagingPlatform.CONSENT_FORM_NOT_AVAILABLE:
|
|
....
|
|
break;
|
|
case QtAndroidUserMessagingPlatform.CONSENT_FORM_LOAD_SUCCESS:
|
|
....
|
|
break;
|
|
case QtAndroidUserMessagingPlatform.CONSENT_FORM_LOAD_FAILURE:
|
|
....
|
|
break;
|
|
}
|
|
}
|
|
|
|
QtAndroidUserMessagingPlatform.requestConsentForm()</pre>
|
|
|
|
<p>Once request process finish the signal <i>consentFormRequestResult()</i> is emitted with the results. Any event different from CONSENT_FORM_LOAD_SUCCESS means the form is not available for various reasons. Once obtained the form is necessary to check if it must be showed to the user. You can get such information as follow:</p>
|
|
<pre class="prettyprint">QtAndroidUserMessagingPlatform.consentStatus()</pre>
|
|
<p>Possible returned values are:</p>
|
|
<pre class="prettyprint">QtAndroidUserMessagingPlatform.CONSENT_FORM_STATUS_UNKNOWN
|
|
QtAndroidUserMessagingPlatform.CONSENT_FORM_STATUS_REQUIRED
|
|
QtAndroidUserMessagingPlatform.CONSENT_FORM_STATUS_NOT_REQUIRED
|
|
QtAndroidUserMessagingPlatform.CONSENT_FORM_STATUS_OBTAINED</pre>
|
|
<p>If the status is different from CONSENT_FORM_STATUS_REQUIRED you don't need to show the form. On the contrary, in case of form required or if the user want to change his preferences you can show the form using the call:</p>
|
|
<pre class="prettyprint">QtAndroidUserMessagingPlatform.showConsentForm()</pre>
|
|
<p>The event <i>consentFormClosed()</i> will inform you when the user closed the form and your app is ready to go. After the user accepted the form some data will be saved in the device and the form will not be required anymore. However if you want to reset these data for restart from scratch you can use the call:</p>
|
|
<pre class="prettyprint">QtAndroidUserMessagingPlatform.resetConsentInformation()</pre>
|
|
<p>This will clean all saved data.</p>
|
|
</div>
|
|
<div class="section-txt" id="Audio">
|
|
<h3>Audio</h3>
|
|
<p>This tool allow to get the audio focus and be notified when audio is requested by another application (typical when a call comes in).</p>
|
|
<p>You can request and abandon the audio focus using the following calls. If you don't get the audio focus you will not be advised if some other apps request the focus. This is important because, for example, if you are generating a sound and a call comes in, your sound will be generated in parallel with the voice of the call itself. Using this feature you must stop the sound when you lose focus and resume when the focus returns to your application.</p>
|
|
<pre class="prettyprint">QtAndroidAudio.requestFocus()
|
|
QtAndroidAudio.abandonFocus()</pre>
|
|
<p>Once the focus has been acquired, the following variable indicates whether the focus is present or lost.</p>
|
|
<pre class="prettyprint">QtAndroidAudio.focus</pre>
|
|
</div>
|
|
<div class="section-txt" id="System">
|
|
<h3>System</h3>
|
|
<p>Currently this tool export only the system paths.</p>
|
|
<pre class="prettyprint">import QtAndroidTools 1.0
|
|
|
|
QtAndroidSystem.dataLocation
|
|
QtAndroidSystem.configLocation
|
|
QtAndroidSystem.downloadLocation
|
|
QtAndroidSystem.musicLocation
|
|
QtAndroidSystem.moviesLocation
|
|
QtAndroidSystem.picturesLocation</pre>
|
|
<p>For documentation about each path value refer to the official documentation <a href="https://doc.qt.io/qt-5/qstandardpaths.html" target="_blank">here</a>.</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
<div class="footer-area">
|
|
<div class="container">
|
|
<div class="row"> Copyright (c) 2018 Fabio Falsini</div>
|
|
</div>
|
|
</div>
|
|
<footer>
|
|
<div class="container">
|
|
<div class="row">
|
|
<div class="col-lg-12 center">
|
|
Developed by valthemes.com © 2016. All rights reserved.
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</footer>
|
|
<script src="js/jquery.min.js"></script>
|
|
<script src="js/prettify.min.js"></script>
|
|
<script src="js/scripts.min.js"></script>
|
|
</body>
|
|
</html> |