mirror of
https://github.com/QuasarApp/QtAndroidTools.git
synced 2025-05-16 14:09:34 +00:00
Google account info passed from java to qml level
This commit is contained in:
parent
e2273b1f48
commit
61dce2a56a
@ -21,8 +21,8 @@
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
#include <QUrl>
|
||||
#include "QAndroidGoogleAccount.h"
|
||||
#include <android/bitmap.h>
|
||||
|
||||
QAndroidGoogleAccount *QAndroidGoogleAccount::m_pInstance = nullptr;
|
||||
|
||||
@ -31,8 +31,19 @@ QAndroidGoogleAccount::QAndroidGoogleAccount() : m_JavaGoogleAccount("com/falsin
|
||||
QtAndroid::androidActivity().object<jobject>())
|
||||
{
|
||||
m_pInstance = this;
|
||||
connect(&m_NetworkAccessManager, &QNetworkAccessManager::finished, this, &QAndroidGoogleAccount::AccountPhotoDownloaded);
|
||||
LoadLastSignedInAccountInfo();
|
||||
|
||||
if(m_JavaGoogleAccount.isValid())
|
||||
{
|
||||
const JNINativeMethod JniMethod[] = {
|
||||
{"loadedLastSignedInAccountInfo", "(Lcom/falsinsoft/qtandroidtools/AndroidGoogleAccount$AccountInfo;)V", reinterpret_cast<void *>(&QAndroidGoogleAccount::LoadedLastSignedInAccountInfo)}
|
||||
};
|
||||
QAndroidJniEnvironment JniEnv;
|
||||
jclass ObjectClass;
|
||||
|
||||
ObjectClass = JniEnv->GetObjectClass(m_JavaGoogleAccount.object<jobject>());
|
||||
JniEnv->RegisterNatives(ObjectClass, JniMethod, sizeof(JniMethod)/sizeof(JNINativeMethod));
|
||||
JniEnv->DeleteLocalRef(ObjectClass);
|
||||
}
|
||||
}
|
||||
|
||||
QObject* QAndroidGoogleAccount::qmlInstance(QQmlEngine *engine, QJSEngine *scriptEngine)
|
||||
@ -49,7 +60,74 @@ QAndroidGoogleAccount* QAndroidGoogleAccount::instance()
|
||||
return m_pInstance;
|
||||
}
|
||||
|
||||
bool QAndroidGoogleAccount::signIn()
|
||||
bool QAndroidGoogleAccount::signIn(bool lastSignedIn)
|
||||
{
|
||||
bool SignInSuccessfully;
|
||||
|
||||
if(lastSignedIn == true)
|
||||
{
|
||||
SignInSuccessfully = SignInToLastSignedInAccount();
|
||||
|
||||
if(SignInSuccessfully == false)
|
||||
{
|
||||
SignInSuccessfully = SelectSignInAccount();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
SignInSuccessfully = SelectSignInAccount();
|
||||
}
|
||||
|
||||
return SignInSuccessfully;
|
||||
}
|
||||
|
||||
void QAndroidGoogleAccount::UpdateLastSignedInAccountInfo(const QAndroidJniObject &AccountInfoObj)
|
||||
{
|
||||
if(AccountInfoObj.isValid())
|
||||
{
|
||||
const QAndroidJniObject PhotoObj = AccountInfoObj.getObjectField("photo", "Landroid/graphics/Bitmap;");
|
||||
|
||||
m_LastSignedInAccountInfo.Id = AccountInfoObj.getObjectField<jstring>("id").toString();
|
||||
m_LastSignedInAccountInfo.DisplayName = AccountInfoObj.getObjectField<jstring>("displayName").toString();
|
||||
m_LastSignedInAccountInfo.Email = AccountInfoObj.getObjectField<jstring>("email").toString();
|
||||
m_LastSignedInAccountInfo.FamilyName = AccountInfoObj.getObjectField<jstring>("familyName").toString();
|
||||
m_LastSignedInAccountInfo.GivenName = AccountInfoObj.getObjectField<jstring>("givenName").toString();
|
||||
|
||||
if(PhotoObj.isValid())
|
||||
{
|
||||
const QImage PhotoImage = AndroidBitmapToImage(PhotoObj);
|
||||
|
||||
if(PhotoImage.isNull() == false)
|
||||
{
|
||||
m_LastSignedInAccountPhoto = QPixmap::fromImage(PhotoImage);
|
||||
}
|
||||
}
|
||||
|
||||
emit lastSignedInAccountInfoChanged();
|
||||
}
|
||||
}
|
||||
|
||||
const QAndroidGoogleAccountInfo& QAndroidGoogleAccount::getLastSignedInAccountInfo() const
|
||||
{
|
||||
return m_LastSignedInAccountInfo;
|
||||
}
|
||||
|
||||
QPixmap QAndroidGoogleAccount::GetAccountPhoto() const
|
||||
{
|
||||
return m_LastSignedInAccountPhoto;
|
||||
}
|
||||
|
||||
bool QAndroidGoogleAccount::SignInToLastSignedInAccount()
|
||||
{
|
||||
if(m_JavaGoogleAccount.isValid())
|
||||
{
|
||||
return m_JavaGoogleAccount.callMethod<jboolean>("loadLastSignedInAccountInfo", "()Z");
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool QAndroidGoogleAccount::SelectSignInAccount()
|
||||
{
|
||||
if(m_JavaGoogleAccount.isValid())
|
||||
{
|
||||
@ -65,53 +143,6 @@ bool QAndroidGoogleAccount::signIn()
|
||||
return false;
|
||||
}
|
||||
|
||||
void QAndroidGoogleAccount::LoadLastSignedInAccountInfo()
|
||||
{
|
||||
if(m_JavaGoogleAccount.isValid())
|
||||
{
|
||||
const QAndroidJniObject AccountInfoObj = m_JavaGoogleAccount.callObjectMethod("getLastSignedInAccountInfo",
|
||||
"()Lcom/falsinsoft/qtandroidtools/AndroidGoogleAccount$AccountInfo;"
|
||||
);
|
||||
if(AccountInfoObj.isValid())
|
||||
{
|
||||
QString PhotoUrl;
|
||||
|
||||
m_LastSignedInAccountInfo.Id = AccountInfoObj.getObjectField<jstring>("id").toString();
|
||||
m_LastSignedInAccountInfo.DisplayName = AccountInfoObj.getObjectField<jstring>("displayName").toString();
|
||||
m_LastSignedInAccountInfo.Email = AccountInfoObj.getObjectField<jstring>("email").toString();
|
||||
m_LastSignedInAccountInfo.FamilyName = AccountInfoObj.getObjectField<jstring>("familyName").toString();
|
||||
m_LastSignedInAccountInfo.GivenName = AccountInfoObj.getObjectField<jstring>("givenName").toString();
|
||||
|
||||
PhotoUrl = AccountInfoObj.getObjectField<jstring>("photoUrl").toString();
|
||||
if(PhotoUrl.isEmpty() == false)
|
||||
{
|
||||
const QNetworkRequest PhotoDownloadRequest(PhotoUrl);
|
||||
m_NetworkAccessManager.get(PhotoDownloadRequest);
|
||||
}
|
||||
|
||||
emit lastSignedInAccountInfoChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const QAndroidGoogleAccountInfo& QAndroidGoogleAccount::getLastSignedInAccountInfo() const
|
||||
{
|
||||
return m_LastSignedInAccountInfo;
|
||||
}
|
||||
|
||||
QPixmap QAndroidGoogleAccount::GetAccountPhoto() const
|
||||
{
|
||||
return m_LastSignedInAccountPhoto;
|
||||
}
|
||||
|
||||
void QAndroidGoogleAccount::AccountPhotoDownloaded(QNetworkReply *pReply)
|
||||
{
|
||||
if(pReply->error() == QNetworkReply::NoError)
|
||||
{
|
||||
m_LastSignedInAccountPhoto = QPixmap(pReply->readAll());
|
||||
}
|
||||
}
|
||||
|
||||
void QAndroidGoogleAccount::ActivityResult(int RequestCode, int ResultCode, const QAndroidJniObject &Data)
|
||||
{
|
||||
Q_UNUSED(ResultCode)
|
||||
@ -121,13 +152,74 @@ void QAndroidGoogleAccount::ActivityResult(int RequestCode, int ResultCode, cons
|
||||
if(m_JavaGoogleAccount.isValid())
|
||||
{
|
||||
const bool SignInSuccessfully = m_JavaGoogleAccount.callMethod<jboolean>("signInIntentDataResult",
|
||||
"(Landroid/content/Intent;)V",
|
||||
"(Landroid/content/Intent;)Z",
|
||||
Data.object()
|
||||
);
|
||||
if(SignInSuccessfully == true)
|
||||
if(SignInSuccessfully == false)
|
||||
{
|
||||
LoadLastSignedInAccountInfo();
|
||||
emit signedIn(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void QAndroidGoogleAccount::LoadedLastSignedInAccountInfo(JNIEnv *env, jobject thiz, jobject accountInfo)
|
||||
{
|
||||
Q_UNUSED(env)
|
||||
Q_UNUSED(thiz)
|
||||
|
||||
if(m_pInstance != nullptr)
|
||||
{
|
||||
m_pInstance->UpdateLastSignedInAccountInfo(QAndroidJniObject(accountInfo));
|
||||
emit m_pInstance->signedIn(true);
|
||||
}
|
||||
}
|
||||
|
||||
// Copyright KDAB (BogDan Vatra)
|
||||
// https://www.kdab.com/qt-on-android-how-to-convert-qt-images-to-android-images-and-vice-versa-2/
|
||||
QImage QAndroidGoogleAccount::AndroidBitmapToImage(const QAndroidJniObject &JniBmp)
|
||||
{
|
||||
QAndroidJniEnvironment env;
|
||||
AndroidBitmapInfo info;
|
||||
if (AndroidBitmap_getInfo(env, JniBmp.object(), &info) != ANDROID_BITMAP_RESULT_SUCCESS)
|
||||
return QImage();
|
||||
|
||||
QImage::Format format;
|
||||
switch (info.format) {
|
||||
case ANDROID_BITMAP_FORMAT_RGBA_8888:
|
||||
format = QImage::Format_RGBA8888;
|
||||
break;
|
||||
case ANDROID_BITMAP_FORMAT_RGB_565:
|
||||
format = QImage::Format_RGB16;
|
||||
break;
|
||||
case ANDROID_BITMAP_FORMAT_RGBA_4444:
|
||||
format = QImage::Format_ARGB4444_Premultiplied;
|
||||
break;
|
||||
case ANDROID_BITMAP_FORMAT_A_8:
|
||||
format = QImage::Format_Alpha8;
|
||||
break;
|
||||
default:
|
||||
return QImage();
|
||||
}
|
||||
|
||||
void *pixels;
|
||||
if (AndroidBitmap_lockPixels(env, JniBmp.object(), &pixels) != ANDROID_BITMAP_RESULT_SUCCESS)
|
||||
return QImage();
|
||||
|
||||
QImage image(info.width, info.height, format);
|
||||
|
||||
if (info.stride == uint32_t(image.bytesPerLine())) {
|
||||
memcpy((void*)image.constBits(), pixels, info.stride * info.height);
|
||||
} else {
|
||||
uchar *bmpPtr = static_cast<uchar *>(pixels);
|
||||
const unsigned width = std::min(info.width, (uint)image.width());
|
||||
const unsigned height = std::min(info.height, (uint)image.height());
|
||||
for (unsigned y = 0; y < height; y++, bmpPtr += info.stride)
|
||||
memcpy((void*)image.constScanLine(y), bmpPtr, width);
|
||||
}
|
||||
|
||||
if (AndroidBitmap_unlockPixels(env, JniBmp.object()) != ANDROID_BITMAP_RESULT_SUCCESS)
|
||||
return QImage();
|
||||
|
||||
return image;
|
||||
}
|
||||
|
@ -24,9 +24,6 @@
|
||||
#pragma once
|
||||
|
||||
#include <QQuickImageProvider>
|
||||
#include <QNetworkAccessManager>
|
||||
#include <QNetworkRequest>
|
||||
#include <QNetworkReply>
|
||||
#include <QtAndroidExtras>
|
||||
#include <QQmlEngine>
|
||||
#include <QPixmap>
|
||||
@ -78,25 +75,27 @@ public:
|
||||
static QObject* qmlInstance(QQmlEngine *engine, QJSEngine *scriptEngine);
|
||||
static QAndroidGoogleAccount* instance();
|
||||
|
||||
Q_INVOKABLE bool signIn();
|
||||
Q_INVOKABLE bool signIn(bool lastSignedIn);
|
||||
|
||||
const QAndroidGoogleAccountInfo& getLastSignedInAccountInfo() const;
|
||||
|
||||
signals:
|
||||
void lastSignedInAccountInfoChanged();
|
||||
|
||||
private slots:
|
||||
void AccountPhotoDownloaded(QNetworkReply *pReply);
|
||||
void signedIn(bool signInSuccessfully);
|
||||
|
||||
private:
|
||||
const QAndroidJniObject m_JavaGoogleAccount;
|
||||
static QAndroidGoogleAccount *m_pInstance;
|
||||
const int m_SignInId = 9001;
|
||||
QAndroidGoogleAccountInfo m_LastSignedInAccountInfo;
|
||||
QNetworkAccessManager m_NetworkAccessManager;
|
||||
QPixmap m_LastSignedInAccountPhoto;
|
||||
|
||||
static void LoadedLastSignedInAccountInfo(JNIEnv *env, jobject thiz, jobject accountInfo);
|
||||
|
||||
void ActivityResult(int RequestCode, int ResultCode, const QAndroidJniObject &Data);
|
||||
void LoadLastSignedInAccountInfo();
|
||||
void UpdateLastSignedInAccountInfo(const QAndroidJniObject &AccountInfoObj);
|
||||
QImage AndroidBitmapToImage(const QAndroidJniObject &JniBmp);
|
||||
QPixmap GetAccountPhoto() const;
|
||||
bool SignInToLastSignedInAccount();
|
||||
bool SelectSignInAccount();
|
||||
};
|
||||
|
@ -29,6 +29,9 @@ import android.app.Activity;
|
||||
import android.content.Intent;
|
||||
import android.net.Uri;
|
||||
import android.util.Log;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.BitmapFactory;
|
||||
import android.os.AsyncTask;
|
||||
import android.content.pm.ActivityInfo;
|
||||
import android.content.pm.ResolveInfo;
|
||||
import android.content.ComponentName;
|
||||
@ -44,15 +47,16 @@ import com.google.android.gms.common.api.Scope;
|
||||
import com.google.android.gms.tasks.OnCompleteListener;
|
||||
import com.google.android.gms.tasks.Task;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.net.URL;
|
||||
|
||||
public class AndroidGoogleAccount
|
||||
{
|
||||
private final Activity mActivityInstance;
|
||||
private GoogleSignInClient mGoogleSignInClient;
|
||||
private GoogleSignInAccount mLastSignedInAccount;
|
||||
|
||||
public AndroidGoogleAccount(Activity ActivityInstance)
|
||||
{
|
||||
mLastSignedInAccount = GoogleSignIn.getLastSignedInAccount(ActivityInstance);
|
||||
mActivityInstance = ActivityInstance;
|
||||
getSignInClient(ActivityInstance);
|
||||
}
|
||||
@ -66,29 +70,9 @@ public class AndroidGoogleAccount
|
||||
mGoogleSignInClient = GoogleSignIn.getClient(ActivityInstance, SignInOptions);
|
||||
}
|
||||
|
||||
public AccountInfo getLastSignedInAccountInfo()
|
||||
public boolean loadLastSignedInAccountInfo()
|
||||
{
|
||||
AccountInfo Account = null;
|
||||
|
||||
if(mLastSignedInAccount != null)
|
||||
{
|
||||
Uri PhotoUrl;
|
||||
|
||||
Account = new AccountInfo();
|
||||
Account.id = mLastSignedInAccount.getId();
|
||||
Account.displayName = mLastSignedInAccount.getDisplayName();
|
||||
Account.email = mLastSignedInAccount.getEmail();
|
||||
Account.familyName = mLastSignedInAccount.getFamilyName();
|
||||
Account.givenName = mLastSignedInAccount.getGivenName();
|
||||
|
||||
PhotoUrl = mLastSignedInAccount.getPhotoUrl();
|
||||
if(PhotoUrl != null)
|
||||
Account.photoUrl = PhotoUrl.toString();
|
||||
else
|
||||
Account.photoUrl = new String();
|
||||
}
|
||||
|
||||
return Account;
|
||||
return loadLastSignedInAccountInfo(GoogleSignIn.getLastSignedInAccount(mActivityInstance));
|
||||
}
|
||||
|
||||
public Intent getSignInIntent()
|
||||
@ -98,27 +82,87 @@ public class AndroidGoogleAccount
|
||||
|
||||
public boolean signInIntentDataResult(Intent Data)
|
||||
{
|
||||
Task<GoogleSignInAccount> SignInTask = GoogleSignIn.getSignedInAccountFromIntent(Data);
|
||||
final Task<GoogleSignInAccount> SignInTask = GoogleSignIn.getSignedInAccountFromIntent(Data);
|
||||
|
||||
if(SignInTask.isSuccessful())
|
||||
try
|
||||
{
|
||||
try
|
||||
loadLastSignedInAccountInfo(SignInTask.getResult(ApiException.class));
|
||||
return true;
|
||||
}
|
||||
catch(ApiException e)
|
||||
{
|
||||
if(e.getStatusCode() == GoogleSignInStatusCodes.DEVELOPER_ERROR)
|
||||
{
|
||||
mLastSignedInAccount = SignInTask.getResult(ApiException.class);
|
||||
return true;
|
||||
}
|
||||
catch(ApiException e)
|
||||
{
|
||||
if(e.getStatusCode() == GoogleSignInStatusCodes.DEVELOPER_ERROR)
|
||||
{
|
||||
Log.d("AndroidGoogleAccount", "DEVELOPER_ERROR -> Have you signed your project on Android console?");
|
||||
}
|
||||
Log.d("AndroidGoogleAccount", "DEVELOPER_ERROR -> Have you signed your project on Android console?");
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean loadLastSignedInAccountInfo(final GoogleSignInAccount LastSignedInAccount)
|
||||
{
|
||||
if(LastSignedInAccount != null)
|
||||
{
|
||||
AccountInfo LastSignedInAccountInfo = new AccountInfo();
|
||||
final Uri PhotoUrl = LastSignedInAccount.getPhotoUrl();
|
||||
|
||||
LastSignedInAccountInfo.id = LastSignedInAccount.getId();
|
||||
LastSignedInAccountInfo.displayName = LastSignedInAccount.getDisplayName();
|
||||
LastSignedInAccountInfo.email = LastSignedInAccount.getEmail();
|
||||
LastSignedInAccountInfo.familyName = LastSignedInAccount.getFamilyName();
|
||||
LastSignedInAccountInfo.givenName = LastSignedInAccount.getGivenName();
|
||||
|
||||
if(PhotoUrl != null)
|
||||
{
|
||||
DownloadAccountPhotoTask DownloadAccountPhoto = new DownloadAccountPhotoTask(LastSignedInAccountInfo);
|
||||
DownloadAccountPhoto.execute(PhotoUrl.toString());
|
||||
}
|
||||
else
|
||||
{
|
||||
LastSignedInAccountInfo.photo = null;
|
||||
loadedLastSignedInAccountInfo(LastSignedInAccountInfo);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private class DownloadAccountPhotoTask extends AsyncTask<String, Void, Bitmap>
|
||||
{
|
||||
private AccountInfo mLastSignedInAccountInfo;
|
||||
|
||||
DownloadAccountPhotoTask(AccountInfo LastSignedInAccountInfo)
|
||||
{
|
||||
mLastSignedInAccountInfo = LastSignedInAccountInfo;
|
||||
}
|
||||
|
||||
protected Bitmap doInBackground(String... urls)
|
||||
{
|
||||
final String PhotoUrl = urls[0];
|
||||
Bitmap AccountPhoto = null;
|
||||
|
||||
try
|
||||
{
|
||||
InputStream PhotoStream = new java.net.URL(PhotoUrl).openStream();
|
||||
AccountPhoto = BitmapFactory.decodeStream(PhotoStream);
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
}
|
||||
|
||||
return AccountPhoto;
|
||||
}
|
||||
|
||||
protected void onPostExecute(Bitmap AccountPhoto)
|
||||
{
|
||||
mLastSignedInAccountInfo.photo = AccountPhoto;
|
||||
loadedLastSignedInAccountInfo(mLastSignedInAccountInfo);
|
||||
}
|
||||
}
|
||||
|
||||
public static class AccountInfo
|
||||
{
|
||||
public String id;
|
||||
@ -126,6 +170,8 @@ public class AndroidGoogleAccount
|
||||
public String email;
|
||||
public String familyName;
|
||||
public String givenName;
|
||||
public String photoUrl;
|
||||
public Bitmap photo;
|
||||
}
|
||||
|
||||
private static native void loadedLastSignedInAccountInfo(AccountInfo accountInfo);
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
QT += quick quickcontrols2 svg network
|
||||
QT += quick quickcontrols2 svg
|
||||
CONFIG += c++11
|
||||
|
||||
TARGET = QtAndroidToolsDemo
|
||||
|
@ -8,8 +8,20 @@ Page {
|
||||
id: page
|
||||
padding: 0
|
||||
|
||||
Connections {
|
||||
target: QtAndroidGoogleAccount
|
||||
onSignedIn: {
|
||||
if(signInSuccessfully === true)
|
||||
{
|
||||
accountPhoto.source = "image://LastSignedInAccountPhoto/";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Column {
|
||||
anchors.fill: parent
|
||||
width: parent.width * 0.9
|
||||
height: parent.height * 0.9
|
||||
anchors.centerIn: parent
|
||||
spacing: 5
|
||||
|
||||
Label {
|
||||
@ -63,15 +75,15 @@ Page {
|
||||
}
|
||||
|
||||
Image {
|
||||
id: accountPhoto
|
||||
width: 200
|
||||
height: 200
|
||||
source: "image://LastSignedInAccountPhoto/"
|
||||
}
|
||||
|
||||
Button {
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
text: "sigIn"
|
||||
onClicked: QtAndroidGoogleAccount.signIn()
|
||||
onClicked: QtAndroidGoogleAccount.signIn(true)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user