串接Google Play In-app-billing 易犯的 ... - 小鰻的Android學習筆記
文章推薦指數: 80 %
因此程式碼內的應用程式產品內ID值又要再改一次,再重新上傳一個新的草稿APK。
更糟的是︰ 如果你的APP有做package name控管,那麼你的package name ...
Thursday,April12,2012
串接GooglePlayIn-app-billing易犯的錯誤
撰寫時間︰2012/04/1311:41
更新時間︰2012/11/0511:04
文章更新次數︰11
一、前言
之前提到,
臺灣目前雖然無法購買付費型APP,
但卻可以使用In-app-billing機制來獲利。
GooglePlay的In-app-billing機制很完善,
因此在機制底下的規矩也很多。
新手在串接時,
可能因此發生了一堆奇奇怪怪的錯誤。
這邊我把遇到的問題跟大家分享,
這些都是我很寶貴的出錯經驗。
二、文章開始
我在串接GooglePlayin-app-billing時發生過的問題及錯誤如下︰
1.關於應用程式產品內ID值的問題
(1)應用程式產品內ID沒有照規則走
雖然GooglePlayIn-app-billingDocument已經很明確的教導我們ID值的命名規則是︰
產品IDs是以唯一性的方式跨越應用程式命名空間。
產品ID必須啟始字元必須為小寫或數字,而且組成的字串也都只能有小寫(a-z)、數字(0-9)、下
底線(_)和小數點(.)。
以"android.test"開頭的產品ID命名被保留,任何以android.test開頭的命名方式皆不可用。
附帶一
提,當您在建立產品ID後,是無法修改的,而且您也無法重覆使用同一組產品ID。
有時候為了搶時間,這個ID值沒有照規範走就定義在程式碼中並上傳成草稿APK至GooglePlayPublisher。
直到要在Publisher後臺添加應用程式產品內ID值時,才發現自己沒有遵照規範。
因此程式碼內的應用程式產品內ID值又要再改一次,再重新上傳一個新的草稿APK。
更糟的是︰
如果你的APP有做packagename控管,那麼你的packagename一定會超出控管。
因為同樣的packagename的APP,即使你從後臺刪除又重新上傳,GooglePlay都會把它們當成是同一隻APP。
這使得你packagename需要重新命名才能完成上傳,因而packagename已經不是你原本希望的名稱了。
(2)設定Publisher後臺應用程式產品內ID值的[受管理]與[不受管理]分類時請小心!
由於應用程式產品內ID值分成受管理和不受管理類,
這個值如果沒有設定好就儲存或發佈,
後來發現設定錯了,
即使刪除,
都不能再在同一個APP內設定同一個產品ID了。
這很麻煩,
因為程式還要為了這個不小心的錯誤,
重新改程式碼中對應的ID值、重新上傳草稿APK、重新測試…
2.點擊購買流程,iap視窗彈出「這個版本的應用程式還無法用付款功能。
」
這算是一個新手錯誤。
如果查看一下LOG,收到的LOG應該是RESULT_DEVELOPER_ERROR
官方文件對這個LOG的定義如下︰
此回應指出您的APP試圖發送iap請求,但是APP的AnddroidManifest.xml裡卻沒有宣告
com.android.vending.BILLING權限。
也可能是因為應用程式沒有正確的被簽署,或者您發送了一個非正確格式的請求,像是忘了傳
Bundle的key值或者是使用了一個無法被識別的請求類型。
官方文件曾經說,
要測試iap內容,
有幾個條件需要實作︰
(1)手機的primaryaccount要設成testaccount
如果不是,請重設為原廠設定,這是官方建議我們的。
(2)testaccount要設定在GooglePlayPublisher的編輯個人資料的測試帳戶底下。
因為是測試iap,因此我們上傳的草稿apk不用被發佈,只要儲存即可。
但是應用程式內產品ID一定要被發佈。
但是這樣要怎麼找的到這些沒有被發佈的應用程式內ID呢?
答案就是要將手機的account設到這邊當成testaccount。
(3)androidManifest.xml裡要宣告
(4)請確認裝置上的版編、版號、keystore與上傳的草稿APK的版編、版號、keystore一致
因為我們不能用debug.keystore上傳app,
因此,在做內部測試時,
請確認線上的草稿app的keystore是和裝置上要測試的版本的keystore是一致的。
官方文件TestingIn-appBilling單元有提到︰
上傳您的草稿APP至發佈網站。
您無需發佈您的APP才能執行端點測試和真實產品ID的消費。
您僅需以草稿的方式將您的APP上傳。
然而,
您必須將您的APP簽署上那把你平時釋出APP時,專用的金鑰。
而且,您上傳的APP版號必須和你裝置上要執行測試的APP的版號一致。
如果想知道關於如
何上傳APP至Android市集,請見Uploading
applications。
我曾經將草稿APK上傳了,
但是就是一直回應我這個版本的應用程式還無法用付款功能。
我將這行AndroidManifest.xml裡的宣告改變位置,
然後將packagename和應用程式內產品ID全部重新定義過,
也都無法解決,
最後才發現我裝置上的APK的版編版號沒有和線上的『已發佈』APK一致。
這些細節如果沒仔細去看,
真的會很折磨人。
註︰
2012/11/05
有時候為了不要讓服務直接上線(還在內測階段),會上一隻假的APK檔上架GooglePlay來測試裝置上DEBUG模式的真實APK。
如果上傳的假APK裡AndroidManifest屬性和手上實測的DEBUG模式真實APK裡的AndroidManifest屬性差太多,可能也會造成即使線上和手上裝置版本號一致,但仍show出此版本無法購買的問題。
此時建議直接再上傳一個新版號做測試即可。
3.payload很好用,但是使用它是有條件的。
我們知道在requestPurchase時,
可以附一個payload給GooglePlay,
屆時如果交易成功,
傳回來的Json裡面會傳回這個payload。
因此這個payload變得很好用,
因為我們可以拿這個值來做虛擬幣加值的依據之類的。
但,
這個payload只會在正式金流交易下回傳過來,
如果你請求購買的應用程式內產品ID是android.test.purchased之類的,
很抱歉,
傳回來的Json是不會附帶這個payload的。
4.不要將你的購買成功後的程式動作放在Response_OK後面。
@Override
publicvoidonRequestPurchaseResponse(RequestPurchaserequest,
ResponseCoderesponseCode){
if(Consts.DEBUG){
Log.d(TAG,"331"+request.mProductId+":"+responseCode);
}
//付費成功不是在這裡處理。
這裡只是一般購買請求GooglePlay是否答應的接收處
if(responseCode==ResponseCode.RESULT_OK){
if(Consts.DEBUG){
Log.d(TAG,"335purchasewassuccessfullysenttoserver");
}
//MainActivity.addMoney();//不是在這裡加值
//logProductActivity(request.mProductId,"sendingpurchaserequest");
}elseif(responseCode==ResponseCode.RESULT_USER_CANCELED){
if(Consts.DEBUG){
Log.d(TAG,"340usercanceledpurchase");
}
//logProductActivity(request.mProductId,"dismissedpurchasedialog");
}else{
if(Consts.DEBUG){
Log.d(TAG,"346purchasefailed");
}
//logProductActivity(request.mProductId,"requestpurchasereturned"+responseCode);
}
}
在官方的iap教學文檔中,
我們實作了PurchaseObserver。
這個PurchaseObserver被呼叫的時間點,
是在GooglePlay對iap購買交易有完成的成功回應時,
在ResponseHandler.java呼叫purchaseResponse(),
找我們實作的PurchaseObserver底下去執行程式相關的動作。
但是,
ResponseCode.RESULT_OK只是代表我們可以執行iap購買,
不代表交易成功了。
還記得in-app-billing交易流程圖嗎?
ResponseCode.RESULT_OK只是這個交易flow的第2條而已。
真正表示你交易成功會發生在第7點︰PURCHASE_STATE_CHANGED。
因此交易成功要在onPurchaseStateChange()函式裡實作,
程式如下︰
@Override
publicvoidonPurchaseStateChange(PurchaseStatepurchaseState,StringitemId,
intquantity,longpurchaseTime,StringdeveloperPayload){
if(Consts.DEBUG){
Log.d(TAG,"286onPurchaseStateChange()itemId:"+itemId+""+purchaseState);
}
//if(developerPayload==null){
//logProductActivity(itemId,purchaseState.toString());
//}else{
//logProductActivity(itemId,purchaseState+"\n\t"+developerPayload);
//}
//購買完成會呼叫這裡
if(purchaseState==PurchaseState.PURCHASED){
Log.w(TAG,"297onPurchaseStateChange:PURCHASED");
//Toast.makeText(IapPage.this,R.string.purchased_success,Toast.LENGTH_SHORT).show();
MainActivity.addMoney(purchaseTime,developerPayload);
//mOwnedItems.add(itemId);
}
5.老王不能自己買瓜
剛開始串接IAP的新手有時候會遇到「找不到項目」的錯誤,
看LOG回覆的錯誤訊息,並且參照Reference通常都能找出錯誤原因,
我曾遇過的錯誤是因為RESULT_ERROR,查了一下In-appBillingReference後,發現問題是因為我自己是販售者,我仍然又用販售者的身份去購買in-appBilling的商品,自己跟自己買東西,這件事在GoogleWallet是不被允許的。
因此,如果你現在用TestAccount購買商品,記得手機登入的PrimaryAccount不能跟販售者的account相同。
6.別急
許多人在設定和實作的過程中,都急著想看到可以購買的結果。
但是,如果你是第1次為這隻APP發佈in-app-billing商品時,
Google是需要花時間去處理的(我的實測是2個小時候才找的到該商品,因為中午吃了一個便當,今天吃7-11的義大利麵)。
所以,你發佈出去不代表馬上就能找到應用程式內商品,
等一下他們吧!
註︰最近Google好像不提供不發佈APK、僅發佈iab商品測試消費了,
一定要將apk發佈,才能找的到iab商品(見下圖)。
2012/08/14
三、結論
就是這些了。
這些經驗花了我半年+卡住數次得來。
它們都是我在串接GooglePlayiap時常遇到的錯誤。
如果之後還有機會遇到任何的錯誤,
我會把經驗分享上來。
(當然會希望不要再有了!!)
只希望之後大家在串接時,
不要再犯我犯過的錯了。
四、附註
1.官方的SampleCode主程式中unregisterobserver時的時間點錯了
(範例文件將unregister放在onStop()去執行),
因為我們不知道系統什麼時候會讓Activity進入onStop()狀態,
造成原本應該監聽iap後續動作的observer被系統終止了。
這會造成交易完成後,我們實作的observer有時候會無法順利被呼叫。
最好是移到onDestroy()再去執行ResponseHandler.unregister(myPurchaseObserver);
張貼者:
Unknown
於
9:15PM
EmailThisBlogThis!SharetoTwitterSharetoFacebookSharetoPinterest
標籤:
Android,
in-apppurchase
19comments:
samlu
said...
不同應用還是可以用相同的productID.http://support.google.com/googleplay/android-developer/bin/answer.py?hl=en&answer=1072599"ProductIDsareuniqueacrossalltheitemsforthesameapplicationandcannotbereusedinthefuture."
April16,2012at8:33AM
Unknown
said...
感謝Sam大!
April17,2012at2:59AM
阿檬
said...
我利用最新版本的googleplay的inapp範例,我只是分析用戶是不是購買完全版本,google郤把所有購買方式合併在一起,我搞了Dungeons.java一個星期,結果都不知如何抽起publicbooleanisEnabled中,分析是不是購買完全版本,求謝解答
June10,2012at2:07AM
阿檬
said...
另外我已經可以在checkout看到我的購買,但google的範例總是第一次彈出找不到項目,按下確定後會轉回我正確的購買項目,很古怪
June10,2012at2:10AM
Unknown
said...
Dear阿檬,抱歉今天才看到留言,我不太懂你完全版本這件事的整個businesslogic,可能再麻煩你寄信來跟我說明。
另外,第1次彈找不到項目,第2次顯示正確購買這件事我也遇過,你現在登入手機的帳戶是不是跟販售者帳戶相同?
August13,2012at8:38PM
阿法貝塔
said...
Dear小鰻我想請問一下目前的GooglePlay的In-app-billing是否可以正常使用我自己也有看到某家公司使用GoogleWallet放在app裡面來當In-app-billing使用所以是否還是被鎖起來的狀況謝謝回答
October5,2012at1:29AM
Sparks
said...
感謝寫出這麼詳細的筆記。
。
這裡面的問題我基本上都遇到過了。
按照你撰寫的方法應該很快能夠解決了。
!感謝,感謝。
October16,2012at2:53AM
Unknown
said...
Dear阿法貝塔應該是還能用哦!
October18,2012at1:47AM
owen
said...
小鰻你好!我想請問一下,我測試iapv3的範例,不過會跳出錯誤為:"這一版的應用程是為提供googlePlay結帳功能..."你所說的注意事項我都有確認請問一下還有要注意的嗎??
December17,2012at12:53AM
nevinchen
said...
owen.1.YoushouldinstalledthesignedversionAPKonyourdevice.Debugmodeisnotallowed.2.You'llneedtowaitacoupleofhoursbeforetheAPPisreadyinGoogleplay
November26,2013at11:11AM
nevinchen
said...
Thiscommenthasbeenremovedbytheauthor.
November26,2013at11:11AM
nevinchen
said...
Thiscommenthasbeenremovedbytheauthor.
November26,2013at11:11AM
nevinchen
said...
Thiscommenthasbeenremovedbytheauthor.
November26,2013at11:12AM
nevinchen
said...
Thiscommenthasbeenremovedbytheauthor.
November26,2013at11:12AM
nevinchen
said...
Thiscommenthasbeenremovedbytheauthor.
November26,2013at11:12AM
nevinchen
said...
Thiscommenthasbeenremovedbytheauthor.
November26,2013at11:12AM
nevinchen
said...
Thiscommenthasbeenremovedbytheauthor.
November26,2013at11:12AM
LittleLittle
said...
太感謝了,省了半天debug
November27,2014at2:02AM
Unknown
said...
你好,我这边用测试账号账号测试支付,点击购买后弹出Error:retrievinginformationfromserver[DF-DIC-02].求解答是哪里出问题了。
谢谢
December21,2014at6:45PM
PostaComment
NewerPost
OlderPost
Home
Subscribeto:
PostComments(Atom)
TotalPageviews
讚一個
索引
Android
(142)
UXdesign
(5)
AWS
(3)
Arduino
(2)
文章列表
►
2018
(3)
►
March
(2)
►
January
(1)
►
2017
(1)
►
January
(1)
►
2016
(2)
►
February
(1)
►
January
(1)
►
2015
(9)
►
December
(1)
►
September
(1)
►
June
(2)
►
May
(2)
►
April
(1)
►
January
(2)
►
2014
(18)
►
December
(5)
►
November
(1)
►
October
(2)
►
September
(4)
►
August
(2)
►
July
(1)
►
June
(2)
►
April
(1)
►
2013
(8)
►
December
(2)
►
October
(1)
►
September
(1)
►
June
(1)
►
May
(3)
▼
2012
(36)
►
November
(1)
►
September
(2)
►
August
(2)
►
July
(1)
►
May
(5)
▼
April
(7)
不要怕犯錯
2款作品皆進入前50大
開啟Eclipse右側灰色標註
Eclipse要使用nativelibrary
從BluetoothChat範例程式學藍芽連線原理
串接GooglePlayIn-app-billing易犯的錯誤
SurfaceView的onSurfaceDestroy()的系統呼叫時機
►
March
(3)
►
February
(13)
►
January
(2)
►
2011
(52)
►
December
(13)
►
November
(5)
►
October
(8)
►
September
(6)
►
August
(5)
►
July
(6)
►
June
(1)
►
May
(2)
►
April
(3)
►
February
(1)
►
January
(2)
►
2010
(61)
►
December
(9)
►
November
(4)
►
October
(3)
►
September
(3)
►
August
(6)
►
July
(14)
►
June
(22)
SearchThisBlog
Followers
ysl的程式天堂-Android應用開發‧研究‧與諮詢
Loading...
Lucifer-Heosphoros
Lucifer-Heosphoros
[Cmder]解決在GIT目錄下Cmder暴卡(hang住、卡住、lag住)問題
5yearsago
延伸文章資訊
- 1將應用程式內金流機制整合進您的APP裡。 - 极客分享
[Android in-app billing第2篇]Implementing In-app Billing實作應用程式 ... 並且,您必須擁有Google Checkout Merchant...
- 2整合Google Play Billing Library 的流程 - DroidParadise
3. 開始在Developer Console 中建立應用程式內商品,並記得啟用。 4. 參考範例開始實作應用程式內購買。 5. 若有使用ProGuard 也請記得 ...
- 3Android 實作IAP 內購式商品(Selling In-app Products)(2/2)
本篇為實戰篇,概念篇請看In-app Billing(App內付款) 概念。 ... 點選"新增應用程式"; 輸入應用程式名稱; 點選"準備商店資訊".
- 4建立應用程式內產品- Play 管理中心說明 - Google Support
如要提供應用程式內產品,您必須在應用程式的APK 資訊清單檔案中宣告 com.android.vending.BILLING 權限。如果您在全球發行應用程式,仍可以在所有國家/地區發布使用 ...
- 5PnSDK - Android SDK接入文档
请在文档的引导下,进行必要的编码,SDK开发包请与技术人员联系后获取。 接入准备. 工程必须使用Android 最新SDK 编译. APK包必须签名,提交Google ...