ãã®èšäºã§ã¯ãAndroidã§ã®éçºçµéšãå ±æããããšæããŸãã
éçºäžã®è£œåã®æ©èœã«å¯ŸããèŠä»¶ã«ãããããŸããŸãªæè¡çã¿ã¹ã¯ãçºçããŸããããã®äžã«ã¯ãäºçŽ°ãªããšãããŸããŸãªããã°ã§åãããšãéåžžã«ææ§ãªããšããããŠæçœãªãœãªã¥ãŒã·ã§ã³ããããŸããã .NETéçºè ãšããŠç§ããªãã¿ã®ãªããã®ã«åºäŒããŸããã 人çãå€§å¹ ã«ç°¡çŽ åããããŒã«ã®ååšã«ã€ããŠåŠã³ãŸããã ãã¹ãŠã®åå¿è ã®Androidãã¬ãŒã€ãŒãåæ§ã®æ¹æ³ã§åäœãããšæããŸãã ãã®ãããªèšäºã®éçºãæ€çŽ¢ãå®éšã«è²»ããæéã®æ倧3åã®1ãç¯çŽã§ããŸããã
ãããã£ãŠããã®æçš¿ã§ã¯ãè¿ éãã€æ£ç¢ºã«ã¢ããªã±ãŒã·ã§ã³ãäœæããã®ã«åœ¹ç«ã€ã¬ã·ããšãã³ãã®ã³ã¬ã¯ã·ã§ã³ã«æ³šç®ããŸãã
ãã®èšäºã¯åå¿è ã察象ãšããŠããŸãããçµéšè±å¯ãªéçºè ã¯æçšãªãã€ã³ããèŠã€ããããšãã§ããŸãã Androidã¢ããªã±ãŒã·ã§ã³ã®æ§ç¯ã®åºæ¬ãèªã¿ããã°ãããStartAndroidãªãœãŒã¹ãç¥ã£ãŠããŠãHelloWorldãå®è¡ã§ããããšãåæãšããŠããŸãã åæã«ãããªãã¯æ¬æ Œçãªã¢ããªã±ãŒã·ã§ã³ãäœæããçµéšããªãããã®æ¬ ç¹ã«å¯ŸåŠãå§ããã°ããã§ãã ç§ã«ãšã£ãŠãããã¯Androidåãã®æåã®ãããžã§ã¯ãã§ããã
éå§ãã
ç§ã®ããŒãããŒãšç§ã¯ãGoogle Playã®èå³æ·±ã補åãäœæããããšãé·ãéèããŠããŸããã ããæŽããæ¥ãã¿ã¯ã·ãŒåºåã§å¥ã®SMSãèªã¿ãªãããSMSã¹ãã ãåŠçããã¢ããªã±ãŒã·ã§ã³ãäœæãããšããã¢ã€ãã¢ãæµ®äžããŸããã å°èŠæš¡ãªããŒã ã«æ¯èŒçç°¡åã«å®è£ ã§ããå®çšçãªã¢ããªã±ãŒã·ã§ã³ããããããç§ãã¡ã«ãšã£ãŠã¯é¢çœããã«æããŸããã
次ã«ãç¹å®ã®èŠä»¶ã®ã»ãããéçºããã解決ãã¹ãã¿ã¹ã¯ã®ã»ããã圢æãããŸããã ãããã®æãèå³æ·±ããã®ïŒ
- ãããžã§ã¯ãã®æºå
- CMCã®ååŸãšè§£æ
- èµ·åé»è©±ã§ã®èªåèµ·åã¢ããªã±ãŒã·ã§ã³
- Webãªã¯ãšã¹ã
- ããŒã«ã«ããŒã¿ããŒã¹ã®ããŒã¿ã¹ãã¬ãŒãž
- èšå®ä¿å
- GoogleããŒã¯ã³èªèšŒ
- è³Œå ¥ã®ã¡ã«ããºã ã䜿çšãã
ãã®èšäºã§ã¯ã次ã®ç¹ã¯çç¥ãããŸãã
- ã¬ã€ã¢ãŠããšãã¶ã€ã³
- çŽç²ãªJavaã³ãŒãã«é¢ãããã¹ãŠ
- ã¢ããªã±ãŒã·ã§ã³ã¢ãŒããã¯ãã£
ãããžã§ã¯ãã®æºå
HelloWorldããããŠAndroidã¢ããªã±ãŒã·ã§ã³çšã®ãã³ãã¬ãŒããããžã§ã¯ããäœæããæ¹æ³ã¯æ¢ã«ç¥ã£ãŠããŸãã 次ã«ãããã«å¿ èŠãªãã®ãèŠãŠã¿ãŸãããã ãããã®ããŒã«ã®ååšãç¥ã£ãŠããã°ãã€ã³ã¿ãŒãããäžã§ãããã®äœ¿çšæ¹æ³ãç°¡åã«èŠã€ããããšãã§ããŸãã çµå±ã®ãšãããäž»ãªåé¡ã¯ãããŒã«ã®äœ¿çšæ¹æ³ãç解ããããšã§ã¯ãªããããŒã«ãååšããããšãèŠã€ããããšã§ãã
1ïŒãã©ãããã©ãŒã ã«äŸåããªãActionBarïŒç»é¢äžéšã®ã¡ãã¥ãŒïŒãå®è£ ããã«ã¯ã ActionBarSherlockãå¿ èŠã§ãã å ¬åŒãµã€ãããããŠã³ããŒããããœãŒã¹ã³ãŒãã®åœ¢åŒã§Workspaceã«ã€ã³ããŒãããŸãã ã©ã€ãã©ãªã«ããããã€ãã®ãªãœãŒã¹ã®éè² è·ã«ã¯æ¢ç¥ã®åé¡ããããããã©ã€ãã©ãªïŒjarãã¡ã€ã«ïŒã ãã§ã¯ååã§ã¯ãããŸããã
2ïŒSDK sdk \ extras \ google \ google_play_services \ libproject \ google-play-services_lib \ãããœãŒã¹ã®Google PlayãµãŒãã¹ã®åœ¢åŒã§ã¯ãŒã¯ã¹ããŒã¹ã«ã€ã³ããŒãããŸãã ããã¯ãè«æ±ãšæ¿èªã«å¿ èŠã«ãªããŸãã
3ïŒãããžã§ã¯ãã©ã€ãã©ãªã®libãã©ã«ããŒã«å ¥ããŸãïŒãã®åã«ãã€ã³ã¿ãŒãããã§ããããèŠã€ããŸãïŒã
* acra.jar-ã¢ããªã±ãŒã·ã§ã³ã¯ã©ãã·ã¥ã¬ããŒãã¡ã«ããºã ACRAãå®è£ ããŸãã
* android-support-v4.jar-å€ãããŒãžã§ã³ã®Androidãšã®äºææ§ãå®è£ ããŸãã
* roboguice-2.0.jarãroboguice-sherlock-1.5.jar-äŸåæ§æ³šå ¥ã®å®è£ çšãroboguiceã§ã®å®è£ ãå¿ èŠãªå Žåã
* ormlite-core.jarãormlite-android.jar- sqlite AndroidããŒã¹çšã®äººæ°ã®ããã軜éã ORM ã
* joda-time.jar-æ¥ä»ãæäœããããã®ã©ã€ãã©ãªã
* jdom.jarãgson.jar-JSONãæäœããããã
* checkout.jar-課éçšïŒãã®ã©ã€ãã©ãªãéžæããŸãããAPIãçŽæ¥æäœãããããCheckoutã®æ¹ã䟿å©ã§ãïŒã
CMCã®ååŸãšè§£æ
以äžã§ã¯ãAndroidã§4.4ïŒKitKatïŒãããäœãããŒãžã§ã³ã§å®è¡ãããã¡ãœããã瀺ããŸããããã¯ãGoogleããã®ããŒãžã§ã³ã§CMCåŠçã®ã¢ãããŒããæ ¹æ¬çã«å€æŽããããã§ãã KitKatã䜿çšããäœæ¥ã®èª¬æã¯ãã¢ããªã±ãŒã·ã§ã³ã§å®è£ ããããšãã«è¿œå ããŸãã
CMCã䜿çšããã«ã¯ããããã§ã¹ãã§èš±å¯ãå¿ èŠã§ãã
<uses-permission android:name="android.permission.RECEIVE_SMS" /> <uses-permission android:name="android.permission.WRITE_SMS" /> <uses-permission android:name="android.permission.READ_SMS" />
ã©ãã§
RECEIVE_SMS-CMCãåä¿¡ããã¢ããªã±ãŒã·ã§ã³ãžã®èš±å¯ã
READ_SMS-æºåž¯é»è©±ã®ã¡ã¢ãªããSMSãèªã¿åãèš±å¯ã å¿ èŠãªããšæãããŸããããã®èš±å¯ããªããšèšé²ã¯æ©èœããŸããã
WRITE_SMS-é»è©±ã®ã¡ã¢ãªã«CMCãæžã蟌ãèš±å¯ã
SmsBroadcastReceiverãåãå ¥ããCMCã€ãã³ããªã¹ããŒãäœæããŸãããã é»è©±æ©ãSMSãåä¿¡ããSMSãåŠçããããã®ã¡ã€ã³ããã»ã¹ã®å®è¡ãéå§ãããšåŒã³åºãããŸãã
SmsBroadcastReceiver
//BroadcastReceiver public class SmsBroadcastReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { // - , Bundle bundle = intent.getExtras(); // pdus - Object[] pdus = (Object[]) bundle.get("pdus"); if (pdus.length == 0) { return; // } // CMC Sms sms = SmsFromPdus(pdus, context); // , Boolean isClearFromSpam = SuperMegaMethodForResolving Spam(sms, context); if (!isClearFromSpam) { // - CMC abortBroadcast(); return; } } private Sms SmsFromPdus(Object[] pdus, Context context) { Sms sms = new Sms(); for (int i = 0; i < pdus.length; i++) { SmsMessage smsMessage = SmsMessage.createFromPdu((byte[]) pdus[i]); sms.Text += smsMessage.getMessageBody(); // (CMC "") } SmsMessage first = SmsMessage.createFromPdu((byte[]) pdus[0]);// sms.SenderId = first.getOriginatingAddress(); // Date receiveDate = new Date(first.getTimestampMillis()); // sms.RecieveDate = receiveDate; sms.Status = first.getStatus(); // (, , ) return sms; } } public class Sms{ public String SenderId; public String Text; public Date RecieveDate; public int Status; }
onReceiveã10ç§æªæºã§å®äºããããšãéåžžã«éèŠã§ãã ã¡ãœãããããé·ãæéå¶åŸ¡ãè¡ãå Žåãå®è¡ã¯äžæãããã€ãã³ãã¯ä»ã®ãã³ãã©ãŒã«åªå é äœã§ãã£ã¹ããããããŸãã
ç§ã®å ŽåãSuperMegaMethodForResolvingã¯ãé£çµ¡å ãªã¹ããšããŒã«ã«éä¿¡è ãªã¹ãã«SMSãååšãããã©ããã確èªããŸããããã«ã¯1ç§ãããããŸããã 次ã«ãå°çšã¹ããªãŒã ã«å¶åŸ¡ãäžããããonReceiveãabortBroadcastãåŒã³åºããŸããããã«ãããä»ã®ãã³ãã©ãŒãSMSïŒåºæ¬SMSã¢ããªã±ãŒã·ã§ã³ãå«ãïŒãåä¿¡ã§ããªããªããŸãã
次ã«ãCMCåä¿¡ã€ãã³ãã®SmsBroadcastReceiverã«çœ²åããå¿ èŠããããŸãã ãããè¡ãã«ã¯ããããã§ã¹ãã®ã¢ããªã±ãŒã·ã§ã³ãããã¯ã§ãSmsBroadcastReceiverãšããååã®android.provider.Telephony.SMS_RECEIVEDã€ãã³ããªã¹ããŒã宣èšããŸããããã¯ãSMS_RECEIVEDã·ã¹ãã ã€ãã³ãããªãã¹ã³ããåªå 床ã¯2147483631ã§ããåªå 床ã¯æ倧2 ^ 31ã§ãã åæã«ãGoogleã¯999ãã倧ããå€ã䜿çšããããšãæšå¥šããŠããŸãããããããå€ãã®ã¢ããªã±ãŒã·ã§ã³ã¯ãããã䜿çšããŸãã ãã®ã¢ããªã±ãŒã·ã§ã³ã¯ãç§ãç¥ã£ãŠããæé«ã®åªå é äœãæ±ããŸãã
<receiver android:name="su.Jalapeno.AntiSpam.SystemService.SmsBroadcastReceiver" android:enabled="true" android:exported="true" > <intent-filter android:priority="2147483631" > <action android:name="android.provider.Telephony.SMS_RECEIVED" /> </intent-filter> </receiver>
èµ·åé»è©±ã§ã®èªåèµ·åã¢ããªã±ãŒã·ã§ã³
ããã€ã¹ã®é»æºããªã³ã«ããåŸãã¢ããªã±ãŒã·ã§ã³ãèµ·åããå¿ èŠãããå ŽåããããŸããããšãã°ãéç¥ãéããŠæªç¢ºèªã®äžå¯©ãªSMSã®ååšããŠãŒã¶ãŒã«éç¥ããå Žåã§ãã
èµ·åããã«ã¯ããããã§ã¹ãã®èš±å¯ãå¿ èŠã§ãã
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
ã©ãã§
RECEIVE_BOOT_COMPLETED-ããŠã³ããŒãã€ãã³ãããªãã¹ã³ããæš©é
ãããŠã³ããŒããã€ãã³ãServiceBroadcastReceiverã®ãªã¹ããŒãäœæããŸãã
public class ServiceBroadcastReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { // - } }
ãã®äžã§ãé»è©±ããªã³ã«ããåŸãå¿ èŠãªã¢ã¯ã·ã§ã³ãå®è¡ããŸãã
次ã«ãServiceBroadcastReceiverãé»è©±ããŒãã€ãã³ãã«çœ²åããå¿ èŠããããŸãã ãããè¡ãã«ã¯ããããã§ã¹ãã®ã¢ããªã±ãŒã·ã§ã³ãããã¯ã§ãSmsBroadcastReceiverãšããååã®android.intent.action.BOOT_COMPLETEDã€ãã³ããªã¹ããŒã宣èšããŸãã
<receiver android:name="su.Jalapeno.AntiSpam.SystemService.ServiceBroadcastReceiver" android:exported="true" > <intent-filter> <action android:name="android.intent.action.BOOT_COMPLETED" /> </intent-filter> </receiver>
Webãªã¯ãšã¹ã
ãããã£ãŠãCMCãããããµãŒããŒã«æ¥ç¶ããå¿ èŠããããŸãã 次ã®ããã«ãããã§ã¹ããè£å®ããŸãã
<uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
ã©ãã§
ã€ã³ã¿ãŒããã-WebèŠæ±ãéä¿¡ããèš±å¯ã
ACCESS_NETWORK_STATE-ãããã¯ãŒã¯ã¹ããŒã¿ã¹ïŒæ¥ç¶ãããŠãããã©ããã3gãŸãã¯wifiïŒãèªã¿åãèš±å¯ã
ãªã¯ãšã¹ãã®äœæã¯ç°¡åã§ãããããã®å Žåãåºæ¬çãªAndroid httpã¯ã©ã€ã¢ã³ãorg.apache.http.client.HttpClientã䜿çšããŸãã
ããŒã«ã«ããŒã¿ããŒã¹ã®ããŒã¿ã¹ãã¬ãŒãž
ããã§èª¬æããããã«ãã¹ãŠãããŸã ã
èšå®ä¿å
Androidã¯SharedPreferencesã¡ã«ããºã ãæäŸãããããapp.configã* .iniããŸãã¯ã¢ããªã±ãŒã·ã§ã³ããŒã¿ããŒã¹ã䜿çšããŠã¢ããªã±ãŒã·ã§ã³èšå®ãä¿åããããšã¯ãããŸããã
GoogleããŒã¯ã³èªèšŒ
Googleã®ããã¥ã¡ã³ããªã©ãäœç³»çã§äžå®å šãªæ å ±ãäžè¶³ããŠãããããããã«æãæéãããããŸããã ãããã£ãŠãç§ãã¡ã®ã¿ã¹ã¯ã¯ãã¢ããªã±ãŒã·ã§ã³ã«é¢ãããŠãŒã¶ãŒæ å ±ãšç§å¯æ å ±ãå«ãã¢ããªã±ãŒã·ã§ã³ãä»ããŠGoogleãã眲åä»ãããŒã¯ã³ãååŸããããšã§ãã ããã«ãããããŒã¯ã³ãæ»æè ã«ãã£ãŠçæããããã®ã§ã¯ãªããšèããçç±ãåŸãããŸãã ãã®åé¡ã解決ããã«ã¯ã CrossClientAuthã¡ã«ããºã ã䜿çšããŸãã
以äžãå®è¡ããå¿ èŠããããŸãã
1ïŒã¢ããªã±ãŒã·ã§ã³èšŒææžãååŸããããã䜿çšããŠã¢ããªã±ãŒã·ã§ã³ã«çœ²åããŸãã ããã¯ããŠã£ã¶ãŒãã䜿çšããŠEclipseã«ç°¡åã«å®è£ ã§ããŸãã ããã±ãŒãžãšã¯ã¹ãããŒã©ãŒ-> AndroidããŒã«->眲åæžã¿ã¢ããªã±ãŒã·ã§ã³ããã±ãŒãžã®ãšã¯ã¹ããŒãã§ãããžã§ã¯ããå³ã¯ãªãã¯ããŸãã ãŠã£ã¶ãŒãã¯ãæ°ãã蚌ææžã¹ãã¢ã®äœæã蚌ææžã®çæãæå®ãããã¹ã¯ãŒãã§ä¿è·ãããã¹ãã¢ãžã®é 眮ãææ¡ããŸãã 蚌ææžã®ããã·ã¥ã¯å°æ¥å¿ èŠã«ãªããããå¿ããã«ä¿åããŠãã ããã
2ïŒ Googleã³ã³ãœãŒã«ã§ãããžã§ã¯ããäœæããŸãã 次ã«ãäœæãããããžã§ã¯ããéããå·ŠåŽã®ããã«ã®[ApiãšèªèšŒ]-> [è³æ Œæ å ±]ã¿ãã«ç§»åããŸãã ããã§ã¯ããµãŒããŒåŽãšAndroidã¯ã©ã€ã¢ã³ãçšã®ã¯ã©ã€ã¢ã³ãIDã®ãã¢ãäœæããå¿ èŠããããŸãã [æ°ããã¯ã©ã€ã¢ã³ãIDãäœæ]ãã¯ãªãã¯ããŸããAndroidã¢ããªã±ãŒã·ã§ã³ã®ã¯ã©ã€ã¢ã³ãIDãå¿ èŠã§ãã
ã¹ã¯ãªãŒã³ã·ã§ããã«ç€ºãããŠããããã«ãæ£ããããã±ãŒãžåãšèšŒææžã®æçŽãèšå ¥ããŠãã ããã äœæãå®äºãããšãçæãããæ å ±ãšã¯ã©ã€ã¢ã³ãIDãèšèŒããããã¬ãŒããååŸãããŸãã ãµãŒããŒäžã§å¿ èŠã§ãã
次ã«ãWebã¢ããªã±ãŒã·ã§ã³ã¿ã€ãã®æ°ããã¯ã©ã€ã¢ã³ãIDãäœæããŸãã ç§ã®å Žåãhttpãä»ããGoogle WebãªãœãŒã¹ãšã®ããåãããªããããã¢ãã¬ã¹ã¯ä»»æã«æå®ã§ããŸãã ãã®çµæãæ°ããã¯ã©ã€ã¢ã³ãIDãååŸããŸããããã¯ã¯ã©ã€ã¢ã³ãã§æ¢ã«å¿ èŠã§ãã
3ïŒ GoogleAuthUtilãªã©ãã¯ã©ã€ã¢ã³ãã³ãŒãå šäœãã€ã³ã¿ãŒãããäžã§èŠã€ããããšãã§ããŸãã éèŠãªãã€ã³ãã®ã¿ã«æ³šç®ããŸããScopeãæ£ããæ§æããæ¹æ³ãããã³IDãååŸããå Žæ
ã³ãŒã
// @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { if (requestCode == REQUEST_CODE_PICK_ACCOUNT) { if (resultCode == RESULT_OK) { Email = data.getStringExtra(AccountManager.KEY_ACCOUNT_NAME); getUsername(); } } super.onActivityResult(requestCode, resultCode, data); } private void pickUserAccount() { String[] accountTypes = new String[] { "com.google" }; Intent intent = AccountPicker.newChooseAccountIntent(null, null, accountTypes, false, null, null, null, null); startActivityForResult(intent, REQUEST_CODE_PICK_ACCOUNT); } // ( Try catch //WEB_CLIENT_ID Client ID for web application final private String WEB_CLIENT_ID = "1999999-aaaaaaaaaaaaaaaaaaaaaaaaa.apps.googleusercontent.com"; //"" Client id. String SCOPE = String.format("audience:server:client_id:%s", WEB_CLIENT_ID); // String token = GoogleAuthUtil.getToken(_activity, Email, SCOPE);
ããŒã¯ã³ããµãŒããŒã«è»¢éããããã«æ®ããŸã
4ïŒããŒã¯ã³ãæ€èšŒãããµãŒããŒã³ãŒã
Microsoft.IdentityModel.Tokens.JWT Nugetã䜿çšããŸãã 以äžã®ã³ãŒãã䜿çšãããšããŠãŒã¶ãŒã®GoogleIdãšãã®ã¡ãŒã«ãååŸã§ããŸãã
ã³ãŒã
public string GetUserIdByJwt(string jwt, out string userEmail) { userEmail = string.Empty; string userId = null; // Client ID (Client ID for web application) string audience = "111111111111111111-aaaaaaaaaaaaaaaaaaaaa.apps.googleusercontent.com"; // Client ID (Client ID for Android application) string azp = "1111111111111-aaaaaaaaaaaaaaaaaaaaaaaa.apps.googleusercontent.com"; var tokenHandler = new JWTSecurityTokenHandler(); SecurityToken securityToken = tokenHandler.ReadToken(jwt); var jwtSecurityToken = securityToken as JWTSecurityToken; userEmail = GetClaimValue(jwtSecurityToken, "email"); userId = GetClaimValue(jwtSecurityToken, "id"); var validationParameters = new TokenValidationParameters() { AllowedAudience = audience, ValidIssuer = "accounts.google.com", ValidateExpiration = true, // . // Google // Microsoft.IdentityModel ValidateSignature = false, }; try { // Exception, ClaimsPrincipal claimsPrincipal = tokenHandler.ValidateToken(jwtSecurityToken, validationParameters); //, Client Id bool allGood = ValidateClaim(jwtSecurityToken, "azp", azp) && ValidateClaim(jwtSecurityToken, "aud", audience); if (!allGood) { userId = null; } } catch { userId = null; } return userId; } // Claim private static bool ValidateClaim(JWTSecurityToken securityToken, string type, string value) { string claim = GetClaimValue(securityToken, type); if (claim == null) return false; return claim == value; } // Claim ( KeyValuePair) private static string GetClaimValue(JWTSecurityToken securityToken, string type) { var claim = securityToken.Claims.SingleOrDefault(x => x.Type == type); if (claim == null) return null; return claim.Value; }
è³Œå ¥ã®ã¡ã«ããºã ã䜿çšãã
éå§ããã«ã¯ã[ã³ã³ãã³ãã®è²©å£²]ã¿ãã®ã¢ããªã±ãŒã·ã§ã³ãããžã§ã¯ãã®Googleéçºã³ã³ãœãŒã«ã§å¿ èŠãªè£œåãäœæããå¿ èŠããããŸãã ã¯ã©ã€ã¢ã³ãã¯ã ãã§ãã¯ã¢ãŠãã®äŸã«åºã¥ããŠèšè¿°ããŸãã Checkoutã©ã€ãã©ãªãããå®å šã«ç解ããããã®ãè«æ±ã«é¢ããç§ã®ã³ãŒãã®æç²ã以äžã«ç€ºããŸãã
Applicationã¯ã©ã¹ã®å€æŽ
public class MyApplication extends Application { private static final Products products = Products.create().add(IN_APP, asList(" ", " 2 ")); private final Billing billing = new Billing(this, new Billing.Configuration() { @Nonnull @Override public String getPublicKey() { String base64EncodedPublicKey = " , API "; return base64EncodedPublicKey; } @Nullable @Override public Cache getCache() { return Billing.newCache(); } }); @Nonnull private final Checkout checkout = Checkout.forApplication(billing, products); @Nonnull private static MyApplication instance; public MyApplication() { instance = this; } @Override public void onCreate() { super.onCreate(); billing.connect(); } @Nonnull public static MyApplication get() { return instance; } @Nonnull public Checkout getCheckout() { return checkout; } }
賌å
¥ããã¢ã¯ãã£ããã£
public class BillingActivity extends RoboSherlockActivity { private Sku _skuAccess; @Nonnull protected final ActivityCheckout checkout = Checkout.forActivity(this, MyApplication.get().getCheckout()); @Nonnull protected Inventory inventory; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); _skuAccess = null; _activity = this; checkout.start(); checkout.createPurchaseFlow(new PurchaseListener()); inventory = checkout.loadInventory(); inventory.whenLoaded(new InventoryLoadedListener()); } @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); checkout.onActivityResult(requestCode, resultCode, data); } @Override protected void onDestroy() { checkout.stop(); checkout.destroyPurchaseFlow(); super.onDestroy(); } @Nonnull public ActivityCheckout getCheckout() { return checkout; } public void Buy(View view) { purchase(_skuAccess); } private void purchase(@Nonnull final Sku sku) { boolean billingSupported = checkout.isBillingSupported(IN_APP); if (!billingSupported) { return; } checkout.whenReady(new Checkout.ListenerAdapter() { @Override public void onReady(@Nonnull BillingRequests requests) { requests.purchase(sku, null, checkout.getPurchaseFlow()); } }); } private class PurchaseListener extends BaseRequestListener<Purchase> { @Override public void onSuccess(@Nonnull Purchase purchase) { onPurchased(); } private void onPurchased() { // - inventory.load().whenLoaded(new InventoryLoadedListener()); } @Override public void onError(int response, @Nonnull Exception ex) { // it is possible that our data is not synchronized with data on // Google Play => need to handle some errors if (response == ResponseCodes.ITEM_ALREADY_OWNED) { onPurchased(); } else { super.onError(response, ex); } } } private class InventoryLoadedListener implements Inventory.Listener { private String _purchaseOrderId; @Override public void onLoaded(@Nonnull Inventory.Products products) { final Inventory.Product product = products.get(IN_APP); if (product.isSupported()) { boolean isPurchased = InspectPurchases(product); // - } } private boolean InspectPurchases(Product product) { List<Sku> skus = product.getSkus(); Sku sku = skus.get(0); // final Purchase purchase = product.getPurchaseInState(sku, Purchase.State.PURCHASED); boolean isPurchased = purchase != null && !TextUtils.isEmpty(purchase.token); if (isPurchased) { // ? return true; } else { // - _skuAccess = sku; return false; } } } private abstract class BaseRequestListener<Req> implements RequestListener<Req> { @Override public void onError(int response, @Nonnull Exception ex) { } } }
ãããã«
ä»ã®ãšãããã¹ãŠã§ãã ããããåŽé¢ããã詳现ã«åæãããå Žå-èšäºãæžããŠãè£è¶³ããŸãã ãã®æçš¿ãåå¿è ã®Androidããã°ã©ããŒãå°ããªçæãç ŽããfireãèžãŸãªãããã«ããŠæéãç¯çŽããã®ã«åœ¹ç«ã€ããšãé¡ã£ãŠããŸãã ããã§å®æããã¢ããªã±ãŒã·ã§ã³ãè©Šãããšãã§ããŸã ã