티스토리 뷰

1. In App Billing SDK 설치

- SDK Manager 실행

- System Settings 탭 -> android SDK 탭 -> SDK Tools 의 Google play Billing Library 설치


2. 설치된 Billing SDK util과 aidl 개발 프로젝트로 이동

- SDK Manager를 보면 설치되는 Android SDK 설치 경로를 설정 가능.

- 설정된 경로로 이동.

- AppData > Local > Android > sdk > extras > google > play_billing > samples > trivialDrive 로 이동.

- src > com > example > android > trivialdrivesample 안의 util 폴더를 복사

- 개발 프로젝트의 java의 하위 폴더로 이동.

- src > com > android > vending > billing 안의 IInAppBillingService.aidl 복사

- 개발 프로젝트의 java와 같은 위치에 aidl 폴더 생성

- com.android.vending.billing 패키지 생성

- IInAppBillingService.aidl 복사

<!-- 팩토리 이름을 com.android.vending.billing 이 아닌, com 생성, 그 안에 android 생성, 그 안에 vending 생성, 그 안에 billing 생성, 그 안에 IInAppBillingService.aidl 를 복사해야 함. -->

< 최종적으로 개발 프로젝트에 추가 된 모습 >


3. permission 설정

- manifests에 아래의 permission 추가

<uses-permission android:name="com.android.vending.BILLING"/>


4. Helper Class 설계

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
public abstract class cInAppBillingHelper
{
    private String          PUBLIC_KEY;
 
    private final int       REQUEST_CODE = 1001;
 
    private Activity        mActivity;
    private IInAppBillingService    mService;
    private IabHelper       mHelper;
 
    public cInAppBillingHelper(Activity _act, String _public_key)
    {
        mActivity           = _act;
        PUBLIC_KEY          = _public_key;
        init();
    }
 
    ServiceConnection mServiceConn = new ServiceConnection()
    {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service)
        {
            mService        = IInAppBillingService.Stub.asInterface(service);
        }
 
        @Override
        public void onServiceDisconnected(ComponentName name)
        {
            mService        = null;
        }
    };
 
    public void init()
    {
        // 패키지를 명시적으로 설정. ( => 모든 버전의 안드로이드에서 작동시키기 위함.)
        Intent              intent = new Intent("com.android.vending.billing.InAppBillingService.BIND");
        intent.setPackage("com.android.vending");
        mActivity.bindService(intent, mServiceConn, Context.BIND_AUTO_CREATE);
 
        mHelper             = new IabHelper(mActivity, PUBLIC_KEY);
        mHelper.enableDebugLogging(true);
 
        mHelper.startSetup(new IabHelper.OnIabSetupFinishedListener()
        {
            @Override
            public void onIabSetupFinished(IabResult result)
            {
                if (!result.isSuccess())
                {
                    // TODO:: 구매오류처리 (토스트 하나 띄우고 결제팝업 종료시키면 됨)
                    Toast.makeText(mActivity, "구매 실패", Toast.LENGTH_SHORT).show();
                }
                // 구매목록을 초기화하는 메서드.
                // v3으로 넘어오면서 구매기록이 모두 남게 되는데, 재구매 가능한 상품( 게임에서는 코인같은 아잍메은 ) 구매후 삭제해줘야 함.
                // 이 메서드는 상품 구매전 혹은 후에 반드시 호출해야한다. ( 재구매가 불가능한 1회성 아이템의경우 호출하면 안됨. )
                AlreadyPurchaseItems();
            }
        });
    }
 
    public void destroy()
    {
        if (mServiceConn != null)
            mActivity.unbindService(mServiceConn);
    }
 
    public void AlreadyPurchaseItems()
    {
        try
        {
            Bundle          ownedItems = mService.getPurchases(3, mActivity.getPackageName(), "inapp"null);
            int             response = ownedItems.getInt("RESPONSE_CODE");
 
            if (response == 0)
            {
                ArrayList purchaseDataList  = ownedItems.getStringArrayList("INAPP_PURCHASE_DATA_LIST");
                String[] tokens = new String[purchaseDataList.size()];
 
                for (int i = 0; i < purchaseDataList.size(); ++i)
                {
                    String purchaseData = (String)purchaseDataList.get(i);
                    JSONObject jo   = new JSONObject(purchaseData);
                    tokens[i]   = jo.getString("purchaseToken");
                    // 여기서 tokens를 모두 컨슘 해주기
                    mService.consumePurchase(3, mActivity.getPackageName(), tokens[i]);
                }
            }
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
    }
 
    public void buy(String _item)
    {
        try
        {
            Bundle buyIntentBundle  = mService.getBuyIntent(3, mActivity.getPackageName(), _item, "inapp""test");     // 부정 방지를 위해 임의로 토큰 생성.
            PendingIntent pendingIntent = buyIntentBundle.getParcelable("BUY_INTENT");
 
            if (pendingIntent != null)
            {
                mHelper.launchPurchaseFlow(mActivity, mActivity.getPackageName(), REQUEST_CODE, mPurchaseFinishedListener, "test");
            }
            else
            {
                // 결제가 막혔다면
                Toast.makeText(mActivity, "구매 실패", Toast.LENGTH_SHORT).show();
            }
        }
        catch (Exception e)
        {
            Toast.makeText(mActivity, "구매 실패", Toast.LENGTH_SHORT).show();
            e.printStackTrace();
        }
    }
 
    IabHelper.OnIabPurchaseFinishedListener mPurchaseFinishedListener   = new IabHelper.OnIabPurchaseFinishedListener()
    {
        @Override
        public void onIabPurchaseFinished(IabResult result, Purchase info)
        {
            if (result.isFailure())
            {
                AlreadyPurchaseItems();
            }
            else
            {
                Toast.makeText(mActivity, "구매!", Toast.LENGTH_SHORT).show();
                // 여기서 아이템 추가 해주면 됨.
                addInventory();
                AlreadyPurchaseItems();
            }
        }
    };
 
    // TODO:: 무명 클래스로 Override
    public abstract void addInventory();
 
    public void activityResult(int _requestCode, int _resultCode, Intent _data)
    {
        // IabHelper가 null값인 경우 리턴.
        if (mHelper == null)
            return;
 
        // IabHelper가 데이터를 핸들링하도록 데이터 전달.
        if (!mHelper.handleActivityResult(_requestCode, _resultCode, _data))
            return;
    }
}
cs


5. Activity 설계

- In App Billing을 수행 할 Activity를 만들고, 4에서 만든 Helper Class의 인스턴스를 생성한다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
mHelper             = new cInAppBillingHelper(this"PUBLIC_KEY")
{
    @Override
    public void addInventory()
    {
        cUserData.getInstance().getTicketInstance().addCount(10);
    }
};
 
@Override
protected void onDestroy()
{
    super.onDestroy();
    mHelper.destroy();
}
 
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data)
{
    mHelper.activityResult(requestCode, resultCode, data);
    super.onActivityResult(requestCode, resultCode, data);
}
 
private void buyItem()
{
    switch (mItem)
    {
        case 0:
            mHelper.buy("android.test.purchased");
            //mHelper.buy("test_01");
            break;
    }
}
cs


<!-- 참고 글 -->

http://gamexg.tistory.com/10

http://javaexpert.tistory.com/617

http://dev.team-slogup.net/android-in-app-billing/

http://ggam.net/bbs/board.php?bo_table=unity3d&wr_id=190



댓글
  • 프로필사진 NE_Leader 4. Helper Class 설계의 104번 라인이 틀렸습니다.

    launchPurchaseFlow 메소드의 파라미터가 틀렸습니다. 다음부터 공개하실때 한 번 더 체크하세요.

    https://developer.android.com/google/play/billing/billing_integrate.html
    2016.11.17 14:46 신고
댓글쓰기 폼
공지사항
최근에 달린 댓글
Total
18,383
Today
4
Yesterday
7
«   2018/10   »
  1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30 31      
글 보관함