JavaScriptã²ãŒã ã倧奜ãã§ããã¹ãŠã®ãã©ãããã©ãŒã ã«ç§»æ€ããããã«ã³ãŒããé²åŒŸåããããšããŠããŸãã 6ãæåãç§ã¯ãã§ã«Androidã¢ããªã±ãŒã·ã§ã³ã®ã¢ã»ã³ããªã«ã€ããŠæžããŠããŸããããä»æ¥ã¯ãã®ãããã¯ããã詳现ã«æããã«ããããšæããŸãã
PhoneGapãæŸæ£ããªããã°ãªããªãã£ãããšãããã«èŠåããŸãã 2ã€ã®ãããžã§ã¯ãã§ããã䜿çšããçµéšã¯ç§ãæ··ä¹±ãããŸããã ãHello Worldãã¢ããªã±ãŒã·ã§ã³ã§ã¯çŽ æŽãããä»äºãããŸããããã€ãã©ã€ã³åãããã¢ã»ã³ããªã§ã¯ããã¥ã¢ã³ã¹ãé£ç¶ããŠçŸããŸãã
PhoneGapãè¡ããªãã£ãçç±ïŒ
1.æåã¯ç©ºã§ãã åžžã«æ°ããã¢ãžã¥ãŒã«ãæ¥ç¶ããå¿ èŠããããŸãã
2.å€ãã®ã¢ãžã¥ãŒã«ã¯æ²ãã£ãŠæžãããŠããŸãã 圌ãã¯å€ããéå°ã«åãããäºæããªãåäœãããŸãã ããšãã°ãSMSãéä¿¡ããããã®Androidçšã®2ã€ã®ã¢ãžã¥ãŒã«ã®ãã¡ã1ã€ã¯æ©èœããŸããã§ããã
3. EMEIé»è©±ã®åä¿¡ãªã©ã®åºæ¬çãªåé¡ã¯è§£æ±ºãããŠããŸããã åžžã«çµäºããå¿ èŠããããŸãã

ç§ã¯ãŸã PhoneGapã®æ¬è³ªãç解ããŠããŸããã æåã¯ã1ã€ã®ãã¿ã³ããããŸããããããšãæåŸ ããŠããŸããããå®éã«ã¯äœãããŸããã åãã©ãããã©ãŒã ã®äžã«ãSDKãé 眮ããå¿ èŠããããŸãã åã¿ã¹ã¯ã®äžã§ãã¢ãžã¥ãŒã«ãæ€çŽ¢ããŠã€ã³ã¹ããŒã«ããŸãã ã¢ãžã¥ãŒã«èªäœãå¶éãããŠããŸãã 圌ãã¯ãã©ãããã©ãŒã ã®äžéšã§ã®ã¿äœããããããšãã§ããä»ã®ããã€ã¹ã§å¿ èŠãªå Žåã¯ãä»ã®ããã€ã¹ã§ãããè¡ãããšãã§ããã¢ãžã¥ãŒã«ãå床æ¢ãå¿ èŠããããŸãã 倧éã®ãŽããäžèŠãªãã®ããããŸãããæå°éã®ã³ã¹ãã§ãã«ããåéããããšèããŠããŸãã ããããã¹ãŠã®èŠå ã«ããããã€ãã£ãã«èšè¿°ã§ããŸãã ãããŠãããã§èœãšãç©ŽãåºãŠããŸãã
CocoonJSãè¡ããªãã£ãçç±ïŒ
CocoonJSã§ã¯ããŸãä»äºãããŠããªãã£ãã®ã§ãç¹å¥ãªè³ªåã¯ãããŸããã§ããã ãã£ã³ãã¹ã䜿çšãããã«ãã¯æ¬åœã«éãåäœããŸãã ããããäžè¬çã«ã¯ãCocoonJSã䜿çšããæå³ãããããŸããã§ããã 圌ã¯æ¯æãããŸãã
ä»ã®ãã©ãããã©ãŒã ããã³ä»ã®ãã¥ã¢ã³ã¹ã®ã¢ã»ã³ããªã«ã€ããŠã¯ãå¥ã®èšäºããããŸãããã®ãããã¯ãŸãã¯PhoneGapãããã¯ã«é¢ãããããªãè°è«ã¯ããã®ç¯å²å€ã§ãã
ãã€ã³ãã«è¡ããŸããã
ãŸããåºæ¬ããå§ããŸããã-ãã«ã¹ã¯ãªãŒã³HTMLããŒãžãå®è¡ãããŠããWebViewã onCreate MainActivityã§ã¯ã次ã®ããã«èšè¿°ããŸãã
vw = (WebView) findViewById(R.id.webview); vw.setVerticalScrollBarEnabled(false); // vw.setHorizontalScrollBarEnabled(false); // vw.getSettings().setJavaScriptEnabled(true); // JavaScript vw.getSettings().setDomStorageEnabled(true); // localStorage .. vw.getSettings().setSupportZoom(false); // , .. vw.getSettings().setSupportMultipleWindows(false); // . // .. SPA vw.addJavascriptInterface(new WebAppInterface(this), "API"); // JavaScript. // Java. JavaScript` API vw.loadUrl("file:///android_asset/index.html"); // vw.setWebViewClient(new WebViewClient());
ãã¹ãŠã®çŽäºã¯Javaã§è§£æ±ºãããŸãã BadaãŸãã¯SmartTVçšã«äœæããããšãå¿ããªãã§ãã ãã-JavaScriptã§ããªããžãæããããšãã§ããæšæºæ©èœãåžžã«ãããŸãã Androidã®å ŽåãWebAppInterfaceã¯ã©ã¹ã®ã€ã³ã¹ã¿ã³ã¹ãã¹ããŒããŸãããã¯ã©ã¹èªäœã¯æ¬¡ã®ããã«ãªããŸãã
public class WebAppInterface { Context mContext; /** Instantiate the interface and set the context */ WebAppInterface(Context c) { mContext = c; } /** , JavaScript */ @JavascriptInterface public void sendSms(String phoneNumber, String message) { ... - } }
èœãšãç©ŽïŒãã®ãããªããªããžã§ã®äœæ¥ã¯ãéåžžéåæãŸãã¯äºæž¬äžèœã§ãããé©ãã«æºã¡ãŠããå ŽåããããŸãã
Javaã«JavaScriptãçªç¶éç¥ããå¿ èŠãããå Žåãããã«å°éããæãç°¡åãªæ¹æ³ã¯URLãããã¯ããããšã§ãïŒ
vw.loadUrl("javascript: ... - JavaScript");
èœãšãç©ŽïŒãµã ã¹ã³ã®Androids> 4ã§ã¯ãDOMã¿ããã€ãã³ãäžã«ãèŠçŽ ãéã§åŒ·èª¿è¡šç€ºã§ããŸãã

ãã®ãã¥ã¢ã³ã¹ã«æ³šæããŠãã ããã å žåçãªãä¿è·ãã¯åœ¹ã«ç«ã¡ãŸããïŒ
* { -webkit-tap-highlight-color: rgba(255, 255, 255, 0); -webkit-focus-ring-color: rgba(255, 255, 255, 0); outline: none; -moz-user-select: -moz-none; -o-user-select: none; -khtml-user-select: none; -webkit-user-select: none; user-select: none; -webkit-text-size-adjust: none; }
ãã°ãåé¿ããã«ã¯ã次ãè¿œå ããå¿ èŠããããŸãã
if (document.addEventListener) { document.addEventListener("touchstart", function () { }, true); }
ããããããã¯åžžã«åé¡ã解決ãããšã¯éããŸããã ãããããã¬ã€ã¢ãŠãèªäœãåé¡ã«åœ±é¿ããŸãã ããšãã°ãSudokuãšTestã®2ã€ã®ã¢ããªã±ãŒã·ã§ã³ã䜿çšããŸãã æ°ç¬ã§ã¯ãããŒãã¯ããŒãã«ã§ã¬ã€ã¢ãŠããããŠãããããŒãã«ã§ã¯ãã®ãœãªã¥ãŒã·ã§ã³ã圹ç«ã¡ãŸããã ãã ãããã¹ãã§ã¯ãã¿ã³ã§ãã ãã¹ãŠãHTML5ã®ã»ãã³ãã£ã¯ã¹æšæºã«æºæ ããŠããããã§ããã¹ãŠãããŸãããã¯ãã§ãããå®éã«ã¯ã次ã®ãããªCSSãšã®ã³ã³ããçµäºããå¿ èŠããããŸãã
.some_button:focus, .some_button:focus:active { background-color: rgba(0, 0, 0, 0); }
ã¿ããã€ãã³ãããã¿ã³ããã¹ãäžã§æ£ç¢ºã«çºçããå Žåã¯ãéãéžæã衚瀺ãããªãããšã«ãæ°ä»ããŸããïŒããã¹ãã¯éåžžã«å€§ããããå¿ èŠããããŸãïŒã
èœãšãç©ŽïŒ Android <4ã§ã¯ããã©ã³ããã¯ãªãŒãããå¯èœæ§ããããŸãã

ãã°ã«å¯ŸåŠããæ¹æ³ã¯ããã§ãã¯ãè¡ããããã©ã³ããç¡å¹ã«ããããšã§ãã äžæ¹ããã©ã³ãèªäœã湟æ²ããŠããå ŽåããããŸãã
èœãšãç©ŽïŒ Androidã¯å€§æåãšå°æåãåºå¥ããŸãã
.jpgãªãœãŒã¹ã®ããŒãã®äžã§.JPGããç»åã倱ã£ãå Žåããã©ãŠã¶ã®éãã«æ°ä»ãããšã¯ã»ãšãã©ãããŸããããç»åã¯WebViewã«ããŒããããŸããã
èœãšãç©ŽïŒ Androidã¯äºçŽèªã«ææã§ãã
ããšãã°ãclassijizmãšãããã©ã«ããŒãã¢ã»ããã«ãããŸããã Androidã¯ãããžã§ã¯ãã®ãã«ããæåŠãããšã©ãŒãæ確ã«èª¬æã§ããŸããã§ããã klassijizmã«æ¹å-ç²åŸã ç¹°ãè¿ããŸãããåãAndroidã®éåžžã®ãã©ãŠã¶ãŒã§ã¯ããã®ãããªåé¡ã¯ãããŸããã§ããã
èœãšãç©ŽïŒ Androidã®ãªãŒãã£ãªã¿ã°ãæ©èœããŸããã
ããæ£ç¢ºã«ã¯ããã©ãŠã¶ã§ã¯æ©èœããŸãããWebViewå ã§äœ¿çšããå Žåã¯æ©èœããŸããã ãã®å¶éãåé¿ããããã«ãããªããžãæããŠãã€ãã£ãã³ãŒãã§æžãçŽãããšãã§ããŸãã onCreateã§è¿œå ïŒ
mp = new MediaPlayer();
ãŸããWebViewã§ã¯ãJavaScriptã€ã³ã¿ãŒãã§ãŒã¹ãæ¡åŒµããŠããŸãïŒ
@JavascriptInterface public void audio(String url) { try { soundClick = getAssets().openFd(url); mp.reset(); mp.setDataSource(soundClick.getFileDescriptor(), soundClick.getStartOffset(), soundClick.getLength()); mp.prepare(); mp.start(); } catch (IOException e) { e.printStackTrace(); } }
èœãšãç©ŽïŒ Androidãéãã代ããã«ãã¢ããªã±ãŒã·ã§ã³ãæå°åããŸãã ãããã£ãŠããªãŒãã£ãªã䜿çšããå Žåã¯ãå°ãªããšããµãŠã³ãããªãã«ããå¿ èŠããããŸãã
åé¡ã®æ¬è³ªã¯ãããªããã²ãŒã ãå®è¡ããŠãããšä»®å®ããããšã§ãã ãŠãŒã¶ãŒã¯ã¢ããªã±ãŒã·ã§ã³ãçµäºããŸããããå®è¡äžã®ã²ãŒã ã®é³ã¯èããç¶ããŸãã ãããã£ãŠãJavaããJavaScriptãæŒããŠãã²ãŒã ãåæ¢ããããã«èŠæ±ããå¿ èŠããããŸãã
@Override public void onBackPressed() { vw.loadUrl("javascript: windowClose();"); MainActivity.this.finish(); } @Override public void onPause() { super.onPause(); vw.loadUrl("javascript: windowClose();"); MainActivity.this.finish(); } @Override public void onResume() { super.onResume(); vw.loadUrl("javascript: windowOpen();"); } @Override public void onDestroy() { super.onDestroy(); vw.loadUrl("javascript: windowClose();"); MainActivity.this.finish(); }
MainActivity.this.finishïŒïŒ; ç§ã¯ããããæ©äŒã«ã¢ããªã±ãŒã·ã§ã³ãéããããšããŸãã ãããã£ãŠã次åAndroidãæåããåçŽã«èµ·åããäœã埩å ããããšããªãããšã確信ã§ããŸãã æ°ç¬ãªã©ã®ã²ãŒã ã§ã¯ãããã§ããªãããšã¯æããã§ãããã»ãšãã©ã®ã²ãŒã ã§ã¯å¯èœã§ãã ãããã¯éåžžã«åçŽã§ãïŒåãFlappyBirdsãŸãã¯TestsïŒã Androidããã¹ãŠãè¿ãããšããã®ãæããããšããå§ãããŸãã ä»ã®ãã°ã衚瀺ãããŸãã
èœãšãç©ŽïŒ onResumeã䜿çšããAndroidãã¢ããªã±ãŒã·ã§ã³ãæ£åžžã«åŸ©å ãããšã¯éããŸããã å®éãäžéšã®ããã€ã¹ã§ã¯åèµ·åã«åé¡ããããŸãã

ããšãã°ãã¿ã€ããŒãåæ¢ããããå¥è·¡çã«ãµã€ãºå€æŽã«å¿çããªãããšããããŸãã ãããã£ãŠãç解ã§ããªãç¶æ³ã§ã¯ããµã€ãºå€æŽãåŒã³åºããŠã¿ã€ããŒãå確èªããŠãã ããã
èœãšãç©ŽïŒã¢ããªã±ãŒã·ã§ã³ãæå°å/éããšã䞊è¡ããŠåäœããäºãã«å¹²æžããè€æ°ã®WebViewã衚瀺ãããå ŽåããããŸãã
ãã®ãããªåé¡ã確å®ã«åé¿ããããã«ããããã§ã¹ããè¿œå ããŸãã
<activity ... // WebView . android:configChanges="keyboardHidden|orientation|screenSize" ... // android:clearTaskOnLaunch="true" android:noHistory="true" android:launchMode="singleTask" >
JavaScriptã¢ããªã±ãŒã·ã§ã³ã®å€èŠ³ãããã«è¯ãããã«ã¯ãäžéšã®é»ãããŒãåé€ããŠãã«ã¹ã¯ãªãŒã³ã§å®è¡ããŸãã ãããè¡ãã«ã¯ããããã§ã¹ãã«è¿œå ããŸãã
<application ... android:theme="@android:style/Theme.NoTitleBar.Fullscreen">
èœãšãç©ŽïŒããŒã¿ãä¿åããlocalStorageã¯ãã¢ããªã±ãŒã·ã§ã³ãéããåŸã«ç Žæ£ãããŸãã
2ã€ã®åŒã³åºãã®éã«ããŒã¿ãä¿åããã«ã¯ããã€ãã£ãã®SharedPreferencesã«ããŒã¿ãä¿åããå¿ èŠããããŸãã ä¿åããŠèªã¿èŸŒãããã«2ã€ã®ããªããžãããŒã«ããŸãããïŒ
@JavascriptInterface public void saveSomeThing(String message, String id) { if(numberDataForSave > Integer.parseInt(id)) return; numberDataForSave = Integer.parseInt(id); SharedPreferences preferences = getSharedPreferences("com.example.something", MODE_PRIVATE); SharedPreferences.Editor editor = preferences.edit(); editor.putString("somethingID", message); editor.commit(); } @JavascriptInterface public String loadSomeThing() { SharedPreferences preferences = getSharedPreferences("com.example.something", MODE_PRIVATE); String message = preferences.getString("somethingID", ""); return message; }
èœãšãç©ŽïŒã¡ãœããã¯éåæã«åäœããŸãïŒãŸãã¯ç§ã«ã¯æããŸãããïŒïŒïŒã ã»ãŒããé »ç¹ã«åŒã³åºããšãããŒã¿ã®é åºãééã£ãŠããå¯èœæ§ããããŸãã
å®éããã°ã¯æ¬¡ã®ããã«ãªããŸããæåŸã®è¡ãä¿åãããã®ã§ã¯ãªããåã®è¡ãä¿åãããŸããã ãã®åé¡ã解決ããããã«ãJavaScriptãšãã€ãã£ãã³ãŒãã§ããŒã¿ã«çªå·ãä»ããŸãã ä¿åããã¡ãœããã«ã¯å€æ°numberDataForSaveããããä¿åãããããŒã¿ã®ã€ã³ããã¯ã¹ããã§ãã¯ããŸãã ã€ã³ããã¯ã¹ãæåŸã«ä¿åããããã®ããå°ããå ŽåãããŒã¿ã¯ç¡èŠãããŸãã
èœãšãç©ŽïŒéåžžãã¡ã€ã³ã¢ã¯ãã£ããã£ã®ã¬ã€ã¢ãŠãã«ã¯å€ãã®äœèšãªèŠçŽ ããããŸãã
å šç»é¢è¡šç€ºã®1ã€ã®WebViewã«ã€ããŠã¯ãããã»ã©å¿ èŠãããŸããã æ®ãããšã§ççž®ã§ããŸãïŒ
<?xml version="1.0" encoding="utf-8"?> <WebView xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/webview" android:layout_width="fill_parent" android:layout_height="fill_parent" android:scrollbars="none" />
èœãšãç©ŽïŒ SIMã«ãŒããªãã§SMSãéä¿¡ããŸããã SMSã¯æ¶ãããã³ãŒã«ããã¯ã¯trueãè¿ããŸããã
PhoneGapã䜿çšããŠããå ŽåãAndroidåãã®SMSéä¿¡ã¢ãžã¥ãŒã«ãæ²ãã£ãŠæžãããŠããå¯èœæ§ããããŸãïŒãããã«ããŠããç§ã¯å人çã«ãã®ãããªåé¡ã«ééããŸããïŒã ã©ã®çµæã§ãtrueãè¿ããŸãã ãããæ£åžžã«å®è£ ããã«ã¯ãJavaããJavaScriptã«SMSãéä¿¡ããããã®æ©ãé£ã³è¶ããŸãããã
@JavascriptInterface public void sendSms(String phoneNumber, String message) { SmsManager sms = SmsManager.getDefault(); sms.sendTextMessage(phoneNumber, null, message, sendSmsPendingIntent, null); }
ãããŠãMainActivityã¯ã©ã¹ã«ã¡ãœãããè¿œå ããŸãã
private PendingIntent registerSentSmsReceiver() { String SENT = "SMS_SENT"; PendingIntent sentPI = PendingIntent.getBroadcast(MainActivity.this, 0, new Intent(SENT), 0); sendSmsReceiver = new BroadcastReceiver() { public void onReceive(Context arg0, Intent arg1) { switch (getResultCode()) { case Activity.RESULT_OK: vw.loadUrl("javascript: smsSend(true);"); break; default: vw.loadUrl("javascript: smsSend(false);"); break; } } }; registerReceiver(sendSmsReceiver, new IntentFilter(SENT)); return sentPI; }
ã¢ããªã±ãŒã·ã§ã³ãæ°ããã¯ã©ã¹ã§ã¯ã©ãã·ã¥ããã®ãé²ãã«ã¯ãonDestroyãæŽæ°ããå¿ èŠããããŸãã
@Override public void onDestroy() { super.onDestroy(); if (sendSmsReceiver != null) { unregisterReceiver(sendSmsReceiver); } }
èšå®ã解é€ãããšãã¯ãsendSmsReceiverãåžžã«ãªãã«ããå¿ èŠããããŸãã
èœãšãç©ŽïŒ Samsungã®Androidã§ã¯ãã¿ããã€ãã³ãã§WebViewãé ããªããŸãã ããã«ã圌ã¯æãä¿æããªããæç»ãåæ¢ããããšããã§ããŸãã
ãã®ãã°ããéããããšã¯ã§ããŸããã 圌ãã¯ããããã£ãã ãããCocoonJSããã¢ãŒã·ã§ã³ã®çç±ã®1ã€ã«ãªããŸããã å¿ èŠã«å¿ããŠããã£ã³ãã¹èŠçŽ ãïŒãã¹ãŠåãããªããžã䜿çšããŠïŒãã€ãã£ãã«æžãæããããšãã§ããŸãããããã¯ãŽãã§ãã ãã¹ãŠãäžåºŠã«Javaã§èšè¿°ããæ¹ãè¯ãã§ãããã ãã ããããã§ããAPKãã¡ã€ã«ãåéããããšã¯çã«ããªã£ãŠããŸãã ãµã ã¹ã³ã«å ããŠããŸã ä»ã®ã¡ãŒã«ãŒããã®é»è©±ã®æããããããã«ã¯ãã¹ãŠãããã»ã©æªããªãããšãã§ããŸãã ãŸãããã®ç¹ã§åãTizenã§ãäžè¬çã«ãããšã話ã
Javaã®ã®ã¶ã®ã¶ã®ç¬éããaã³ããŸãã ãŸã ç§ã®JavaScriptãããã¡ã€ã«ã ãŸãããã¢ã¯ãã·ã¢èªãšèšäºããã®è±èªã§ãïŒèª°ããèå³ããããªãïŒã