delphi onActivityResult未从startActivityForResult调用(C++ Builder 11.2)

fnatzsnv  于 2023-04-05  发布在  其他
关注(0)|答案(1)|浏览(321)

我正在CBuilder中创建一个Android应用程序,它安装一个APK,然后重新启动已安装的应用程序。
我可以在我们的平板电脑(卡车运输应用程序)上单独完成这两项操作。但是,由于安装需要用户确认,这可能需要一段时间。问题是,我希望在启动应用程序之前,Intent完成结果。
下面是主代码,它调用APK安装Intent和方法onActivityResult(),它允许我退出while循环。然而,我从未真正退出while循环。
我见过覆盖onActivityResult()的 Delphi 代码,但我似乎无法让C
Builder允许我覆盖成员函数。
请原谅多个注解掉的代码,它们是我尝试过的方法,但也不起作用。我也留下了messageManager代码,但消息处理程序也从未被调用。

void __fastcall TForm5::Button3Tap(TObject *Sender, const TPointF &Point)
{
    //GetDirs();     Works, so comment out for now to concentrate on intent function
    UnicodeString filePath = 
       "/storage/emulated/0/Android/data/com.embarcadero.Immixt/files/Download/Immixt.apk";

    if (TFile::Exists(filePath)) {

        _di_JContext Context = TAndroidHelper::Context;

        // Create the intent to install the APK file
        // Set the path to the APK file in the app's data directory
        _di_JString ApkFilePath = StringToJString(filePath);
        UnicodeString mimeType = "application/vnd.android.package-archive";
        _di_JString mimeType1 = StringToJString(mimeType);

        // Create the intent to install the APK file
        intent = TJIntent::JavaClass->init();
        intent->setAction(TJIntent::JavaClass->ACTION_INSTALL_PACKAGE);

        //intent->setAction(TJIntent::JavaClass->ACTION_INSTALL_PACKAGE);
        intent->addFlags(TJIntent::JavaClass->FLAG_ACTIVITY_NEW_TASK);
        intent->addFlags(TJIntent::JavaClass->FLAG_GRANT_READ_URI_PERMISSION);
        intent->addFlags(TJIntent::JavaClass->FLAG_GRANT_WRITE_URI_PERMISSION);
        intent->putExtra(TJIntent::JavaClass->EXTRA_NOT_UNKNOWN_SOURCE, true);
        intent->putExtra(TJIntent::JavaClass->EXTRA_RETURN_RESULT, true);

        _di_Jnet_Uri Uri1;
        _di_JFile APKFile = TJFile::JavaClass->init(ApkFilePath);
        try {
           Uri1 = TAndroidHelper::JFileToJURI(APKFile);
        } catch (const Exception& e) {
            //CLog::d(TAG, e);
            _di_Jnet_Uri Uri1 = TJnet_Uri::JavaClass->parse(ApkFilePath);
        }

        //_di_Jnet_Uri Uri1 = TJnet_Uri::JavaClass->parse(ApkFilePath);
        intent->setDataAndType(Uri1, mimeType1);

        // Start the activity to install the APK file
        activityResult = -1;
        //Context->startActivity(intent);
        FMessageSubscriptionID = TMessageManager::DefaultManager->SubscribeToMessage(__classid(TMessageResultNotification), HandleActivityMessage);
        //TAndroidHelper::OnActivityResult = &onActivityResult;
        //TAndroidHelper::Activity->startActivityForResult(intent, 0);
        SharedActivity()->startActivityForResult(intent, 1234);

        /*
        TAndroidHelper::Activity->startActivityForResult(intent, 1234,
        [this](int requestCode, int resultCode, _di_JIntent data)
        {
            Form5->onActivityResult(requestCode, resultCode, data);
        });
        */

        while (activityResult == -1)
        {
            Sleep(100);
        }
        // Wait for the activity to complete
    }

/---------------------------------------------------------------------------------------

void onActivityResult(int i, int i1, Androidapi::Jni::Graphicscontentviewtext::_di_JIntent intent)
{
    TMessageManager::DefaultManager->Unsubscribe(__classid(TMessageResultNotification), Form5->FMessageSubscriptionID);
    Form5->FMessageSubscriptionID = 0;

    // For more info see https://github.com/zxing/zxing/wiki/Scanning-Via-Intent
    if (i == 1234)
    {
        if (i1 == TJActivity::JavaClass->RESULT_OK)
        {
            Form5->activityResult =0;
        }
        else if (i1 == TJActivity::JavaClass->RESULT_CANCELED)
        {
            Form5->activityResult =0;
        }
    }
}

我期望下面的代码等待,直到activityResult被更改为退出while循环。activityResultonActivityResult事件中被修改,根据所有文档,SharedActivity()->startActivityForResult(intent, 1234)应该调用该事件。但它从未这样做。

hmmo2u0o

hmmo2u0o1#

当然你不会得到事件。你的while循环阻塞了主UI线程处理新消息。
彻底摆脱while循环,它不属于这段代码。Intent异步的,它们应该在后台运行,而你继续做其他事情。所以,你应该完全退出Button3Tap()。(如果需要,请禁用您的UI),然后让RTL在以后准备好调用您注册的回调时调用它,此时,您可以根据需要继续您的工作(并重新启用您的UI)。
例如:

void __fastcall TForm5::Button3Tap(TObject *Sender,
    const TPointF &Point)
{
    ...
    // Start the activity to install the APK file
    FMessageSubscriptionID = TMessageManager::DefaultManager->SubscribeToMessage(__classid(TMessageResultNotification), HandleActivityMessage);
    SharedActivity()->startActivityForResult(intent, 1234);

    // disable UI if needed...
    // exit here
}

void __fastcall TForm5::HandleActivityMessage(System::TObject* const Sender,
    System::Messaging::TMessageBase* const M)
{
    TMessageResultNotification* notif = dynamic_cast<TMessageResultNotification*>(M);
    if (!notify)
        return;

    if (notify->RequestCode == 1234)
    {
        TMessageManager::DefaultManager->Unsubscribe(__classid(TMessageResultNotification), FMessageSubscriptionID);
        FMessageSubscriptionID = 0;

        // use notify->Value and notify->ResultCode as needed...

        // re-enable UI if needed...
    }
}

相关问题