3

次のコードを使用して、このユーザーがプレミアム ユーザーであるかどうかを調べています。ユーザーがアプリ課金で購入したかどうかの天気。しかし、このメソッド isPremium() を呼び出すと、初回のみ正しい結果が得られますが、初めて実行すると、常に間違った結果が得られます。IInAppBillingService の mService 変数が null です。誰かがその理由を教えてもらえますか。コードは以下の通りです。

public boolean isPremium() {
        boolean mIsPremium = false;
        Log.d(TAG, "::isPremium:" + "mService:"+mService);
        if(mService==null){
            return mIsPremium;
        }

        try {
            Bundle ownedItems = mService.getPurchases(3, getPackageName(),
                    "inapp", null);
            if (ownedItems != null) {
                int response = ownedItems.getInt("RESPONSE_CODE");
                if (response == 0) {
                    ArrayList ownedSkus = ownedItems
                            .getStringArrayList("INAPP_PURCHASE_ITEM_LIST");
                    ArrayList purchaseDataList = ownedItems
                            .getStringArrayList("INAPP_PURCHASE_DATA_LIST");
                    ArrayList signatureList = ownedItems
                            .getStringArrayList("INAPP_DATA_SIGNATURE");
                    String continuationToken = ownedItems
                            .getString("INAPP_CONTINUATION_TOKEN");

                    for (int i = 0; i < purchaseDataList.size(); ++i) {
                        String signature = null;
                        String purchaseData = (String) purchaseDataList.get(i);
                        if (signatureList != null)
                            signature = (String) signatureList.get(i);
                        String sku = (String) ownedSkus.get(i);
                        Log.d(TAG, "::isPremium:" + "sku:" + sku);
                        Log.d(TAG, "::isPremium:" + "purchaseData:"
                                + purchaseData);
                        Log.d(TAG, "::isPremium:" + "signature:" + signature);
                        if (sku.equalsIgnoreCase(SKU_PREMIUM)) {
                            Log.d(TAG, "::isPremium:" + "Already Purchased");
                            return true;
                        }

                        // do something with this purchase information
                        // e.g. display the updated list of products owned by
                        // user
                    }

                    // if continuationToken != null, call getPurchases again
                    // and pass in the token to retrieve more items
                }
            }
        } catch (RemoteException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        return mIsPremium;
    }

以下は、サービスを初期化するコードです。私がサービスに来るたびに。「onServiceConnected」ログのみを取得します。ログ ":onServiceDisconnected:" を取得しませんでした

ServiceConnection mServiceConn = new ServiceConnection() {
        @Override
        public void onServiceDisconnected(ComponentName name) {
            Log.d(TAG, "::onServiceDisconnected:" + "");
            mService = null;
        }

        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            Log.d(TAG, "::onServiceConnected:" + "");
            mService = IInAppBillingService.Stub.asInterface(service);

        }
    };

では、初めて mService が null になる理由を教えてください。1回だけ呼び出す必要がありますか? 私のサービスは切断されていますか?しかし、ログには表示されませんでした。

4

1 に答える 1

1

あなたの質問であなたが言ったことによると:

しかし、このメソッド isPremium() を呼び出すと、それは正しい結果をもたらしますが、最初の後にそれを行うと。

あなたの mService はおそらく最初はバインドされていませんが、2 回目の呼び出しではバインドされています。サービスをバインドすると、確立されるまでに時間がかかります。そのため、おそらく 2 回目にアクセスすると、mService に値があり、isPremium にも値があります。

このリンク (Binder クラスの拡張)を見ると、例ではブール値を使用してmBound、サービスが次のようにバインドされているかどうかを確認します。

サービス側

public class IInAppBillingService extends Service {
    // Binder given to clients
    private final IBinder mBinder = new LocalBinder();


    public class LocalBinder extends Binder {
        IInAppBillingService getService() {
        // Return this instance of IInAppBillingService so clients can call public methods
        return IInAppBillingService.this;
        }
    }

    @Override
    public IBinder onBind(Intent intent) {
        return mBinder;
    }

    /** method for clients */
    public Bundle getPurchases(...) {
      //...
    }
}

活動面では

public class BindingActivity extends Activity {
    IInAppBillingService mService;
    boolean mBound = false;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
    }

    @Override
    protected void onStart() {
        super.onStart();
        // Bind to IInAppBillingService
        Intent intent = new Intent(this, IInAppBillingService.class);
        bindService(intent, mConnection, Context.BIND_AUTO_CREATE);
    }

    @Override
    protected void onStop() {
        super.onStop();
        // Unbind from the service
        if (mBound) {
            unbindService(mConnection);
            mBound = false;
        }
    }


    public void doStuff(View v) {
        if (mBound) {
            if(isPremium()){
                 //...
            }
        }
    }

    /** Defines callbacks for service binding, passed to bindService() */
    private ServiceConnection mConnection = new ServiceConnection() {

        @Override
        public void onServiceConnected(ComponentName className,
             IBinder service) {
            // We've bound to IInAppBillingService, cast the IBinder and get IInAppBillingServiceinstance
            //The connection has been established
            LocalBinder binder = (LocalBinder) service;
            mService = binder.getService();
            //You can use a boolean or you can call to isPremium if you are going to use it once, depends of your scenario
            mBound = true;
        }

        @Override
        public void onServiceDisconnected(ComponentName arg0) {
            mBound = false;
        }
    };
}

isPremium 関数のみを投稿しましたが、mService を初期化する方法は投稿していません。上記のリンクでバインダー クラスを拡張していない場合は、別の方法を見つけることができます。

于 2013-04-29T09:20:23.517 に答える