ããã°ãã¯ã芪æãªãhabrayuzeryã
ãã®èšäºã§ã¯ãAndroidã§ã®éçºçµéšãå
±æããããšæããŸãã
éçºäžã®è£œåã®æ©èœã«å¯ŸããèŠä»¶ã«ãããããŸããŸãªæè¡çã¿ã¹ã¯ãçºçããŸããããã®äžã«ã¯ãäºçްãªããšãããŸããŸãªããã°ã§åãããšãéåžžã«ææ§ãªããšããããŠæçœãªãœãªã¥ãŒã·ã§ã³ããããŸããã .NETéçºè
ãšããŠç§ããªãã¿ã®ãªããã®ã«åºäŒããŸããã 人çã倧å¹
ã«ç°¡çŽ åããããŒã«ã®ååšã«ã€ããŠåŠã³ãŸããã ãã¹ãŠã®åå¿è
ã®Androidãã¬ãŒã€ãŒãåæ§ã®æ¹æ³ã§åäœãããšæããŸãã ãã®ãããªèšäºã®éçºãæ€çŽ¢ãå®éšã«è²»ããæéã®æå€§3åã®1ãç¯çŽã§ããŸããã
ãããã£ãŠããã®æçš¿ã§ã¯ãè¿
éãã€æ£ç¢ºã«ã¢ããªã±ãŒã·ã§ã³ãäœæããã®ã«åœ¹ç«ã€ã¬ã·ããšãã³ãã®ã³ã¬ã¯ã·ã§ã³ã«æ³šç®ããŸãã
ãã®èšäºã¯åå¿è
ã察象ãšããŠããŸãããçµéšè±å¯ãªéçºè
ã¯æçšãªãã€ã³ããèŠã€ããããšãã§ããŸãã Androidã¢ããªã±ãŒã·ã§ã³ã®æ§ç¯ã®åºæ¬ãèªã¿ããã°ããã
StartAndroidãªãœãŒã¹ãç¥ã£ãŠããŠãHelloWorldãå®è¡ã§ããããšã
åæãšããŠããŸãã åæã«ãããªãã¯æ¬æ Œçãªã¢ããªã±ãŒã·ã§ã³ãäœæããçµéšããªãããã®æ¬ ç¹ã«å¯ŸåŠãå§ããã°ããã§ãã ç§ã«ãšã£ãŠãããã¯Androidåãã®æåã®ãããžã§ã¯ãã§ããã
éå§ãã
ç§ã®ããŒãããŒãšç§ã¯ãGoogle Playã®è峿·±ã補åãäœæããããšãé·ãéèããŠããŸããã ããæŽããæ¥ãã¿ã¯ã·ãŒåºåã§å¥ã®SMSãèªã¿ãªãããSMSã¹ãã ãåŠçããã¢ããªã±ãŒã·ã§ã³ãäœæãããšããã¢ã€ãã¢ãæµ®äžããŸããã å°èŠæš¡ãªããŒã ã«æ¯èŒçç°¡åã«å®è£
ã§ããå®çšçãªã¢ããªã±ãŒã·ã§ã³ããããããç§ãã¡ã«ãšã£ãŠã¯é¢çœããã«æããŸããã
次ã«ãç¹å®ã®èŠä»¶ã®ã»ãããéçºããã解決ãã¹ãã¿ã¹ã¯ã®ã»ããã圢æãããŸããã ãããã®æãè峿·±ããã®ïŒ
ãã®èšäºã§ã¯ã次ã®ç¹ã¯çç¥ãããŸãã
- ã¬ã€ã¢ãŠããšãã¶ã€ã³
- çŽç²ãª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ãåŠçããããã®ã¡ã€ã³ããã»ã¹ã®å®è¡ãéå§ãããšåŒã³åºãããŸãã
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ãååŸããå Žæ
ããŒã¯ã³ããµãŒããŒã«è»¢éããããã«æ®ããŸã
4ïŒããŒã¯ã³ãæ€èšŒãããµãŒããŒã³ãŒã
Microsoft.IdentityModel.Tokens.JWT
Nugetã䜿çšããŸãã 以äžã®ã³ãŒãã䜿çšãããšããŠãŒã¶ãŒã®GoogleIdãšãã®ã¡ãŒã«ãååŸã§ããŸãã
ã³ãŒã public string GetUserIdByJwt(string jwt, out string userEmail) { userEmail = string.Empty; string userId = null;
賌å
¥ã®ã¡ã«ããºã ã䜿çšãã
éå§ããã«ã¯ã[ã³ã³ãã³ãã®è²©å£²]ã¿ãã®ã¢ããªã±ãŒã·ã§ã³ãããžã§ã¯ãã®
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() {
ãããã«
ä»ã®ãšãããã¹ãŠã§ãã ããããåŽé¢ããã詳现ã«åæãããå Žå-èšäºãæžããŠãè£è¶³ããŸãã ãã®æçš¿ãåå¿è
ã®Androidããã°ã©ããŒãå°ããªçæãç ŽããfireãèžãŸãªãããã«ããŠæéãç¯çŽããã®ã«åœ¹ç«ã€ããšãé¡ã£ãŠããŸãã
ããã§å®æããã¢ããªã±ãŒã·ã§ã³ã詊ãããšãã§ã
ãŸã ã