用pyjnius在Python中创建Android Activity上下文

5
我正在使用以下代码将Braintree的下拉式UI支付方式导入到我的Python Kivy应用程序中。
from jnius import autoclass
from jnius import cast
from android import activity

Intent = autoclass('android.content.Intent')
PythonActivity = autoclass('org.renpy.android.PythonActivity')

DropInRequest = autoclass('com.braintreepayments.api.dropin.DropInRequest')

#Global instance
instance = None
REQUEST = 1
RESULT_OK = 1

def onBraintreeSubmit(token):
    global instance

    def on_activity_result(request, response, data):
        global instance
        if request == REQUEST:
            print response
            if response == RESULT_OK:
                result = instance.getParcelableExtra(instance.EXTRA_DROP_IN_RESULT)
                nonce = result.getPaymentMethodNonce()
                print nonce
                return nonce

    activity.bind(on_activity_result=on_activity_result)
    instance = DropInRequest()
    instance.clientToken(token)
    intent = instance.getIntent(activity.this)
    PythonActivity.mActivity.startActivityForResult(intent,REQUEST)

这里尝试模仿这段Java代码

DropInRequest dropInRequest = new DropInRequest()
    .clientToken(mClientToken);
startActivityForResult(dropInRequest.getIntent(context), DROP_IN_REQUEST);

@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);

    if (requestCode == DROP_IN_REQUEST) {
        if (resultCode == Activity.RESULT_OK) {
            DropInResult result = data.getParcelableExtra(DropInResult.EXTRA_DROP_IN_RESULT);
            String paymentMethodNonce = result.getPaymentMethodNonce().getNonce();
            // send paymentMethodNonce to your server
        } else if (resultCode == Activity.RESULT_CANCELED) {
            // canceled
        } else {
            // an error occurred, checked the returned exception
            Exception exception = (Exception) data.getSerializableExtra(DropInActivity.EXTRA_ERROR);
        }
    }
}

我的问题是我需要向DropInRequest类的getIntent函数发送一个Context,但我无法弄清楚如何使用python-for-android和pyjnius创建Activity Context。下面是getIntent的Java方法。

public Intent getIntent(Context context) {
    return new Intent(context, DropInActivity.class)
            .putExtra(EXTRA_CHECKOUT_REQUEST, this);
}

我认为我需要将这个内容添加到我的清单中,并使用com.braintreepayments.api.BraintreeBrowserSwitchActivity作为我的活动,但我不确定如何从中获取上下文。

<activity android:name="com.braintreepayments.api.BraintreeBrowserSwitchActivity"
    android:launchMode="singleTask">
    <intent-filter>
        <action android:name="android.intent.action.VIEW" />
        <category android:name="android.intent.category.DEFAULT" />
        <category android:name="android.intent.category.BROWSABLE" />
        <data android:scheme="${applicationId}.braintree" />
    </intent-filter>
</activity>

我认为应该调用这个类,它是一个BrowserSwitchActivity,我需要从BrowserSwitchActivity获取上下文。
package com.braintreepayments.api;

import com.braintreepayments.browserswitch.BrowserSwitchActivity;

/**
 * Helper Activity that captures the response when browser switch completes.
 */
public class BraintreeBrowserSwitchActivity extends BrowserSwitchActivity {
}

这里的作用是将类扩展到一个Activity类中

package com.braintreepayments.browserswitch;

import android.app.Activity;
import android.net.Uri;
import android.os.Bundle;
import android.support.annotation.Nullable;

/**
 * <a href="https://developer.android.com/guide/topics/manifest/activity-element.html#lmode">singleTask</a>
 * Activity used to receive the response from a browser switch. This Activity contains no UI and
 * finishes during {@link Activity#onCreate(Bundle)}.
 */
public class BrowserSwitchActivity extends Activity {

    private static Uri sReturnUri;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        sReturnUri = null;
        if (getIntent() != null && getIntent().getData() != null) {
            sReturnUri = getIntent().getData();
        }

        finish();
    }

    /**
     * @return the uri returned from the browser switch, or {@code null}.
     */
    @Nullable
    public static Uri getReturnUri() {
        return sReturnUri;
    }

    /**
     * Clears the return uri.
     */
    public static void clearReturnUri() {
        sReturnUri = null;
    }
}

我遇到了一个问题,如何从这个Activity中获取上下文?

更新:我已经改变了我的Python代码,在Java之外使用DropInRequest.getIntent()方法,在我的Python代码中使用以下代码。

from jnius import autoclass
from jnius import cast
from android import activity
from kivy.context import get_current_context

context = autoclass('android.content.Context')
Intent = autoclass('android.content.Intent')
Uri = autoclass('android.net.Uri')
PythonActivity = autoclass('org.kivy.android.PythonActivity')

DropInRequest = autoclass('com.braintreepayments.api.dropin.DropInRequest')
BrowserSwitchActivity = autoclass('com.braintreepayments.api.BraintreeBrowserSwitchActivity')

#Global instance
instance = None
REQUEST = 1
RESULT_OK = 1

def onBraintreeSubmit(token):
    global instance

    def on_activity_result(request, response, data):
        global instance
        if request == REQUEST:
            print response
            if response == RESULT_OK:
                result = instance.getParcelableExtra(instance.EXTRA_DROP_IN_RESULT)
                nonce = result.getPaymentMethodNonce()
                print nonce
                return nonce

    currentActivity = cast('android.app.Activity', PythonActivity.mActivity)
    context = cast('android.content.Context', currentActivity.getApplicationContext())
    activity.bind(on_activity_result=on_activity_result)
    instance = DropInRequest()
    instance.clientToken(token)
    mapintent = Intent()
    mapintent.setClassName(context,'com.braintreepayments.api.dropin.DropInRequest')
    mapintent.putExtra("com.braintreepayments.api.EXTRA_CHECKOUT_REQUEST","EXTRA_CHECKOUT_REQUEST")

    currentActivity.startActivityForResult(mapintent,REQUEST)

我将其添加到我的清单文件中

<activity android:name="com.braintreepayments.api.dropin.DropInRequest" >
    </activity>

我似乎正在取得进展,但当我运行应用程序时出现了这个错误。
java.lang.RuntimeException: Unable to instantiate activity ComponentInfo{org.test.myapp/com.braintreepayments.api.dropin.DropInRequest}: java.lang.ClassCastException: com.braintreepayments.api.dropin.DropInRequest cannot be cast to android.app.Activity

我已经追踪了一下,发现DropInRequest扩展的是Parcelable而不是activity...
1个回答

6
要使用pyjnius创建一个上下文,你需要按照以下方式进行转换。
PythonActivity = autoclass('org.kivy.android.PythonActivity')
currentActivity = cast('android.app.Activity', PythonActivity.mActivity)
context = cast('android.content.Context', currentActivity.getApplicationContext())

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接