Question

I am trying to implement the in app billing and I am using http://www.anddev.org/advanced-tutorials-f21/simple-inapp-billing-payment-t52060.html as my example. I have copied every file in the tutorial and only changed the name of the package. I changed my manifest so that it looks exactly like the one in the tutorial (mine has a few more things in there). As I was debugging I noticed that in my version the BillinService class was never called.

In the tutorial the Billing service's onCreate method is called after BillingHelper.setCompletedHandler is called

protected static void setCompletedHandler(Handler handler){
        mCompletedHandler = handler;
}

However after it is called in my program it just continues.

Here is my review.class

package com.cellphone;

import org.apache.http.client.ResponseHandler;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.BasicResponseHandler;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.params.BasicHttpParams;
import org.apache.http.params.HttpConnectionParams;
import org.apache.http.params.HttpParams;

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.os.Handler;
import android.text.Html;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;

import com.cellphone.BillingHelper;
import com.cellphone.astralweb.R;

public class Review extends Activity implements OnClickListener {
    private Context mContext;
    private static final String TAG = "BillingService";
    static SharedPreferences prefs;
    static boolean lite;
    private Button purchaseButton;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        // TODO Auto-generated method stub
        super.onCreate(savedInstanceState);

        setContentView(R.layout.reviewpage);
        prefs = getSharedPreferences("Settings", 0);
        lite = prefs.getBoolean("isLite", true);
        String iflite = "";
        if (lite) {
            iflite = "-lite";
        }
        TextView msg1 = (TextView) findViewById(R.id.tvreview);
        msg1.setText(Html
                .fromHtml(cleanhtml(getText("http://www.cellphonesolutions.net/upgrade-"
                        + getResources().getString(R.string.Country) + iflite))));

        purchaseButton = (Button) findViewById(R.id.btntowebsite);
        purchaseButton.setOnClickListener(this);
        mContext = this;
        startService(new Intent(mContext, BillingService.class));
        BillingHelper.setCompletedHandler(mTransactionHandler);

    }

    public Handler mTransactionHandler = new Handler() {
        public void handleMessage(android.os.Message msg) {
            Log.i(TAG, "Transaction complete");
            Log.i(TAG, "Transaction status: "
                    + BillingHelper.latestPurchase.purchaseState);
            Log.i(TAG, "Item purchased is: "
                    + BillingHelper.latestPurchase.productId);

            if (BillingHelper.latestPurchase.isPurchased()) {
                System.out.println("hi");
            }
        };

    };

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
        case R.id.btntowebsite:
            if (BillingHelper.isBillingSupported()) {
                BillingHelper.requestPurchase(mContext,
                        "android.test.purchased");
                // android.test.purchased or android.test.canceled or
                // android.test.refunded or com.blundell.item.passport
            } else {
                Log.i(TAG, "Can't purchase on this device");
                purchaseButton.setEnabled(false); // XXX press button before
                                                    // service started will
                                                    // disable when it shouldnt
            }

            break;
        default:
            // nada
            Log.i(TAG, "default. ID: " + v.getId());
            break;
        }

    }

    public String cleanhtml(String original) {
        String finalText = original.replaceAll("<![^>]*>", "");

        return finalText;
    }

    public String getText(String uri) {
        HttpParams httpParams = new BasicHttpParams();
        // 30seconds and it stops
        HttpConnectionParams.setConnectionTimeout(httpParams, 30000);
        HttpConnectionParams.setSoTimeout(httpParams, 30000);
        DefaultHttpClient client1 = new DefaultHttpClient(httpParams);
        HttpGet request = new HttpGet(uri);

        ResponseHandler<String> responseHandler = new BasicResponseHandler();
        try {
            String response_str = client1.execute(request, responseHandler);
            return response_str;

        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
            return "";

        }
    }

    @Override
    protected void onDestroy() {
        BillingHelper.stopService();
        super.onDestroy();
    }
}

Because the BillingService is never called when I first create my review class, the BillingHelper.instantiateHelper is never called

protected static void instantiateHelper(Context context, IMarketBillingService service) {
    mService = service;
    mContext = context;
}

so my mService and mContext come up null when I try to press my button.

Thank you for helping me out.

EDIT here is my manifest

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.cellphone.astralweb" android:versionCode="1" android:versionName="1.0">
    <uses-sdk android:minSdkVersion="4" />
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"></uses-permission>
    <uses-permission android:name="android.permission.INTERNET"></uses-permission>
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="com.android.vending.BILLING" />



    <application android:theme="@style/CustomTheme" android:icon="@drawable/icon_paid" android:label="@string/app_name">
        <uses-library android:name="com.google.android.maps" />
        <activity android:name="com.cellphone.Splash" android:label="@string/app_name" android:screenOrientation="portrait">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <activity android:name="com.cellphone.LocationServiceNotification" android:screenOrientation="portrait"
            android:label="@string/app_name" android:theme="@android:style/Theme.Dialog">
            <intent-filter>
                <action android:name="com.cellphone.LOCATIONSERVICENOTIFICATION" />
                <category android:name="android.intent.category.DEFAULT" />
            </intent-filter>
        </activity>

        <activity android:name="com.cellphone.Registration" android:label="@string/app_name" android:screenOrientation="portrait">
            <intent-filter>
                <action android:name="com.cellphone.REGISTRATION" />
                <category android:name="android.intent.category.DEFAULT" />
            </intent-filter>
        </activity>
        <activity android:name="com.cellphone.CreateAccount" android:label="@string/app_name" android:screenOrientation="portrait"  android:windowSoftInputMode="stateHidden">
            <intent-filter>
                <action android:name="com.cellphone.CREATEACCOUNT" />
                <category android:name="android.intent.category.DEFAULT" />
            </intent-filter>
        </activity>
<activity android:name="com.cellphone.Activate" android:label="@string/app_name" android:screenOrientation="portrait">
            <intent-filter>
                <action android:name="com.cellphone.ACTIVATE" />
                <category android:name="android.intent.category.DEFAULT" />
            </intent-filter>
        </activity>
        <activity android:name="com.cellphone.ImTracking" android:label="@string/app_name" android:screenOrientation="portrait" android:windowSoftInputMode="stateAlwaysHidden">
            <intent-filter>
                <action android:name="com.cellphone.IMTRACKING" />
                <category android:name="android.intent.category.DEFAULT" />
            </intent-filter>
        </activity>
        <activity android:name="com.cellphone.SpecialAdapter" android:label="@string/app_name" android:screenOrientation="portrait">
            <intent-filter>
                <action android:name="com.cellphone.SPECIALADAPTER" />
                <category android:name="android.intent.category.DEFAULT" />
            </intent-filter>
        </activity>
        <activity android:name="com.cellphone.AddPerson" android:label="@string/app_name" android:screenOrientation="portrait">
            <intent-filter>
                <action android:name="com.cellphone.ADDPERSON" />
                <category android:name="android.intent.category.DEFAULT" />
            </intent-filter>
        </activity>
        <activity android:name="com.cellphone.TrackingMe" android:label="@string/app_name" android:screenOrientation="portrait" android:windowSoftInputMode="stateAlwaysHidden">
            <intent-filter>
                <action android:name="com.cellphone.TRACKINGME" />
                <category android:name="android.intent.category.DEFAULT" />
            </intent-filter>
        </activity>
        <activity android:name="com.cellphone.InviteFollower" android:label="@string/app_name" android:screenOrientation="portrait">
            <intent-filter>
                <action android:name="com.cellphone.INVITEFOLLOWER" />
                <category android:name="android.intent.category.DEFAULT" />
            </intent-filter>
        </activity>
        <activity android:name="com.cellphone.Settings" android:label="@string/app_name" android:screenOrientation="portrait">
            <intent-filter>
                <action android:name="com.cellphone.SETTINGS" />
                <category android:name="android.intent.category.DEFAULT" />
            </intent-filter>
        </activity>
        <activity android:name="com.cellphone.TabPage" android:label="@string/app_name" android:theme="@android:style/Theme.NoTitleBar" android:screenOrientation="portrait" android:windowSoftInputMode="stateHidden">
            <intent-filter>
                <action android:name="com.cellphone.TABPAGE" />
                <category android:name="android.intent.category.DEFAULT" />
            </intent-filter>
        </activity>
        <activity android:name="com.cellphone.Review" android:label="@string/app_name" android:theme="@android:style/Theme.NoTitleBar" android:screenOrientation="portrait">
            <intent-filter>
                <action android:name="com.cellphone.REVIEW" />
                <category android:name="android.intent.category.DEFAULT" />
            </intent-filter>
        </activity>
            <activity android:name="com.cellphone.help" android:label="@string/app_name" android:theme="@android:style/Theme.NoTitleBar" android:screenOrientation="portrait">
            <intent-filter>
                <action android:name="com.cellphone.HELP" />
                <category android:name="android.intent.category.DEFAULT" />
            </intent-filter>
        </activity>
        <activity android:name="com.cellphone.Maps" android:label="@string/app_name" android:theme="@android:style/Theme.NoTitleBar" android:screenOrientation="portrait">
            <intent-filter>
                <action android:name="com.cellphone.MAPS" />
                <category android:name="android.intent.category.DEFAULT" />
            </intent-filter>
        </activity>
        <activity android:name="com.cellphone.HelloItemizedOverlay" android:label="@string/app_name" android:theme="@android:style/Theme.NoTitleBar" android:screenOrientation="portrait">
            <intent-filter>
                <action android:name="com.cellphone.HELLOITEMIZEDOVERLAY" />
                <category android:name="android.intent.category.DEFAULT" />
            </intent-filter>
        </activity>
                <activity android:name="com.cellphone.History" android:label="@string/app_name" android:theme="@android:style/Theme.NoTitleBar" android:screenOrientation="portrait">
            <intent-filter>
                <action android:name="com.cellphone.HISTORY" />
                <category android:name="android.intent.category.DEFAULT" />
            </intent-filter>
        </activity>

                <activity android:name="com.cellphone.MyCustomLocationOverlay" android:label="@string/app_name" android:theme="@android:style/Theme.NoTitleBar" android:screenOrientation="portrait">
            <intent-filter>
                <action android:name="com.cellphone.MYCUSTOMLOCATIONOVERLAY" />
                <category android:name="android.intent.category.DEFAULT" />
            </intent-filter>
        </activity>
        <service android:name="com.cellphone.UpdateLocation" android:label="@string/app_name" android:theme="@android:style/Theme.NoTitleBar" android:screenOrientation="portrait">
            <intent-filter>
                <action android:name="com.cellphone.UPDATELOCATION" />
                <category android:name="android.intent.category.DEFAULT" />
                </intent-filter>        
        </service>


        <service android:name=".BillingService" />

        <receiver android:name=".BillingReceiver">
            <intent-filter>
                <action android:name="com.android.vending.billing.IN_APP_NOTIFY" />
                <action android:name="com.android.vending.billing.RESPONSE_CODE" />
                <action android:name="com.android.vending.billing.PURCHASE_STATE_CHANGED" />            
            </intent-filter>
        </receiver> 

    </application>

    </manifest>
Was it helpful?

Solution

The problem was in my manifest, I named my service wrong it should be

<service android:name="com.cellphone.BillingService" />

not <service android:name=".BillingService" />

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top