任何人都知道如何在IabHelper设置开始时修复此NullPointerException
?
java.lang.NullPointerException
at android.app.ApplicationPackageManager.queryIntentServicesAsUser(ApplicationPackageManager.java:559)
at android.app.ApplicationPackageManager.queryIntentServices(ApplicationPackageManager.java:571)
at IabHelper.startSetup(IabHelper.java:266)
at MyApplication.createIABHelper(MyApplication.java:256)
at MyApplication.onCreate(MyApplication.java:156)
at android.app.Instrumentation.callApplicationOnCreate(Instrumentation.java:1000)
at android.app.ActivityThread.handleBindApplication(ActivityThread.java:4391)
at android.app.ActivityThread.access$1300(ActivityThread.java:141)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1294)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:5041)
at java.lang.reflect.Method.invokeNative(Method.java)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:816)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:582)
at dalvik.system.NativeStart.main(NativeStart.java)
由于其他问题,我的IabHelper代码略有修改,所以这里是startSetup方法:
public void startSetup(final OnIabSetupFinishedListener listener) {
// If already set up, can't do it again.
checkNotDisposed();
if (mSetupDone) throw new IllegalStateException("IAB helper is already set up.");
// Connection to IAB service
logDebug("Starting in-app billing setup.");
mServiceConn = new ServiceConnection() {
@Override
public void onServiceDisconnected(ComponentName name) {
logDebug("Billing service disconnected.");
mService = null;
}
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
if (mDisposed) return;
logDebug("Billing service connected.");
mService = IInAppBillingService.Stub.asInterface(service);
String packageName = mContext.getPackageName();
try {
logDebug("Checking for in-app billing 3 support.");
// check for in-app billing v3 support
int response = mService.isBillingSupported(3, packageName, ITEM_TYPE_INAPP);
if (response != BILLING_RESPONSE_RESULT_OK) {
if (listener != null) listener.onIabSetupFinished(new IabResult(response,
"Error checking for billing v3 support."));
// if in-app purchases aren't supported, neither are subscriptions.
mSubscriptionsSupported = false;
return;
}
logDebug("In-app billing version 3 supported for " + packageName);
// check for v3 subscriptions support
response = mService.isBillingSupported(3, packageName, ITEM_TYPE_SUBS);
if (response == BILLING_RESPONSE_RESULT_OK) {
logDebug("Subscriptions AVAILABLE.");
mSubscriptionsSupported = true;
} else {
logDebug("Subscriptions NOT AVAILABLE. Response: " + response);
}
mSetupDone = true;
} catch (RemoteException e) {
if (listener != null) {
listener.onIabSetupFinished(new IabResult(IABHELPER_REMOTE_EXCEPTION,
"RemoteException while setting up in-app billing."));
}
e.printStackTrace();
return;
}
if (listener != null) {
listener.onIabSetupFinished(new IabResult(BILLING_RESPONSE_RESULT_OK, "Setup successful."));
}
}
};
Intent serviceIntent = getExplicitIapIntent();
PackageManager pm = mContext.getPackageManager();
List<ResolveInfo> intentServices = pm.queryIntentServices(serviceIntent, 0);
if (intentServices != null && !intentServices.isEmpty()) {
//this was replaced per this comment http://stackoverflow.com/a/24202135/704836
//if (!mContext.getPackageManager().queryIntentServices(serviceIntent, 0).isEmpty()) {
// service available to handle that Intent
mContext.bindService(serviceIntent, mServiceConn, Context.BIND_AUTO_CREATE);
} else {
// no service available to handle that Intent
if (listener != null) {
listener.onIabSetupFinished(
new IabResult(BILLING_RESPONSE_RESULT_BILLING_UNAVAILABLE,
"Billing service unavailable on device."));
}
}
}
NullPointerException
发生在List<ResolveInfo> intentServices = pm.queryIntentServices(serviceIntent, 0);
有什么想法吗?
感谢。
编辑:这是getExplicitIapIntent
的代码:
/**
* From http://stackoverflow.com/a/26318757/704836
* @return
*/
private Intent getExplicitIapIntent() {
PackageManager pm = mContext.getPackageManager();
Intent implicitIntent = new Intent("com.android.vending.billing.InAppBillingService.BIND");
implicitIntent.setPackage("com.android.vending");
List<ResolveInfo> resolveInfos = pm.queryIntentServices(implicitIntent, 0);
// Is somebody else trying to intercept our IAP call?
if (resolveInfos == null || resolveInfos.size() != 1) {
return null;
}
ResolveInfo serviceInfo = resolveInfos.get(0);
String packageName = serviceInfo.serviceInfo.packageName;
String className = serviceInfo.serviceInfo.name;
ComponentName component = new ComponentName(packageName, className);
Intent iapIntent = new Intent();
iapIntent.setComponent(component);
return iapIntent;
}
编辑:我还应该指出,根据crashlytics,100%发出此错误的设备都是根深蒂固的。所以也许这与试图绕过必须支付功能的人有关。
编辑:我尝试传递null
而非serviceIntent
并获得以下例外:
java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String android.content.Intent.resolveTypeIfNeeded(android.content.ContentResolver)' on a null object reference
at android.app.ApplicationPackageManager.queryIntentServicesAsUser(ApplicationPackageManager.java:644)
at android.app.ApplicationPackageManager.queryIntentServices(ApplicationPackageManager.java:656)
at IabHelper.startSetup(IabHelper.java:266)
在该例外情况下,行号与我收到的报告不同,所以我不确定它是否相同。
编辑:我认为上次编辑时遇到的异常可能与我为5.0.2设备获得的异常几乎相同。以下是5.0.2报告之一: java.lang.NullPointerException
Attempt to invoke virtual method 'java.lang.String android.content.Intent.resolveTypeIfNeeded(android.content.ContentResolver)' on a null object reference
android.app.ApplicationPackageManager.queryIntentServicesAsUser (ApplicationPackageManager.java:645)
android.app.ApplicationPackageManager.queryIntentServices (ApplicationPackageManager.java:657)
IabHelper.startSetup (IabHelper.java:266)
编辑:我继续修改代码,以便在serviceIntent
为空时抛出异常并且我已经从我的Beta版测试人员那里收到了一些报告。所有100%根设备,所以我猜他们的设备没有正确的com.android.vending.billing.InAppBillingService.BIND。
编辑:一旦代码发布,100%的根设备就会下降到80%左右。无论如何我有机会对用户进行故障排除,事实证明getExplicitIntent方法有时可以在kitkat下返回null(不知道哪个其他版本)所以我继续并添加了一个答案,我如何更改代码。
答案 0 :(得分:0)
你有方法queryIntentServicesAsUser()的代码吗?仔细研究后,看起来你发送queryIntentServices的变量之一可能是导致NullPointer。
答案 1 :(得分:0)
那么最后解决这个问题的正确方法是什么? serviceIntent为null - 这意味着有人想破解?我们让app在这种情况下崩溃了吗?
答案 2 :(得分:0)
我终于发现一个用户获得了一个空的意图,他没有对应用内购买做任何狡猾的事情。他在kitkat。修复是这样的:
if (OSUtils.lollipopOrHigher) {
serviceIntent = getExplicitIapIntent();
} else {
serviceIntent = new Intent("com.android.vending.billing.InAppBillingService.BIND");
serviceIntent.setPackage("com.android.vending");
}
另一种选择是检查null然后尝试非棒棒糖方法。