1

Phonegap を使用した db アクセスに問題があります。phonegap Build を使用して複数のプラットフォームにデプロイしています。面白いことに、私のコードはエミュレータ (Ripple) では完全に動作しますが、デバイス (Samsung Galaxy SII with Android 4.0.3) では失敗します。

これは私の Index.html です:

<!DOCTYPE HTML>
<html>
<head>
  <script>
      function goToMain(url)
      {
        var url = url;
        var username=document.getElementById('username');
        var password=document.getElementById('password');
        if(username.value == '' && password.value== '')
        {
                   document.form.action = "./main.html";
        }
        else
        {
            alert('No válido');
        }
    return ;
      };


     // Wait for PhoneGap to load
    //
    document.addEventListener("deviceready", onDeviceReady, false);

    // PhoneGap is ready
    //
    function onDeviceReady() {
    var db = window.openDatabase("test", "1.0", "Test DB", 10000000);
    db.transaction(populateDB, errorCB, successCB);
    };

 // Transaction error callback
    //
    function errorCB(tx, err) {
    alert("Error processing SQL: "+err);
    };

    // Transaction success callback
    //
    function successCB() {
    };

    function isTableExists(tx, tableName, callback) {
    tx.executeSql('SELECT * FROM '+tableName, [], function(tx, resultSet) {
        if (resultSet.rows.length <= 0) {
            callback(false);
        } else {
            callback(true);
        }
    }, function(err) {
        callback(false);
    })
    };

    function populateDB(tx) {

     isTableExists(tx, "invoices", function(status) {
        if (!status) {
           tx.executeSql('CREATE TABLE IF NOT EXISTS "invoices" ("id" INTEGER PRIMARY KEY  AUTOINCREMENT  NOT NULL  UNIQUE , "month" INTEGER NOT NULL , "year" INTEGER, "client" INTEGER, "amount" FLOAT, "tax" FLOAT);');
    tx.executeSql('INSERT INTO "invoices" VALUES(1,1,2,1,1500,21);');
    tx.executeSql('INSERT INTO "invoices" VALUES(2,2,1,2,2500,16);');
    tx.executeSql('INSERT INTO "invoices" VALUES(3,10,1,3,3500,21);');
    tx.executeSql('INSERT INTO "invoices" VALUES(4,5,4,1,10500,21);');
    tx.executeSql('INSERT INTO "invoices" VALUES(5,4,2,2,15500,21);');
    tx.executeSql('INSERT INTO "invoices" VALUES(6,1,4,4,134200,21);');
        } 
    });

isTableExists(tx, "clients", function(status) {
        if (!status) {
          tx.executeSql('CREATE TABLE IF NOT EXISTS"clients" ("id" INTEGER PRIMARY KEY  AUTOINCREMENT  NOT NULL  UNIQUE , "name" VARCHAR);');
    tx.executeSql('INSERT INTO "clients" VALUES(1,"Alfonso");');
    tx.executeSql('INSERT INTO "clients" VALUES(2,"Alejandro");');
    tx.executeSql('INSERT INTO "clients" VALUES(3,"Ricardo");');
    tx.executeSql('INSERT INTO "clients" VALUES(4,"Víctor");');
        } 
    });



    isTableExists(tx, "months", function(status) {
        if (!status) {
       tx.executeSql('CREATE TABLE IF NOT EXISTS "months" ("id" INTEGER PRIMARY KEY  AUTOINCREMENT  NOT NULL  UNIQUE , "name" VARCHAR);');
    tx.executeSql('INSERT INTO "months" VALUES(1,"January");');
    tx.executeSql('INSERT INTO "months" VALUES(2,"February");');
    tx.executeSql('INSERT INTO "months" VALUES(3,"March");');

    tx.executeSql('INSERT INTO "months" VALUES(4,"April");');
    tx.executeSql('INSERT INTO "months" VALUES(5,"May");');
    tx.executeSql('INSERT INTO "months" VALUES(6,"June");');
    tx.executeSql('INSERT INTO "months" VALUES(7,"July");');
    tx.executeSql('INSERT INTO "months" VALUES(8,"August");');
    tx.executeSql('INSERT INTO "months" VALUES(9,"September");');
    tx.executeSql('INSERT INTO "months" VALUES(10,"October");');
    tx.executeSql('INSERT INTO "months" VALUES(11,"November");');
    tx.executeSql('INSERT INTO "months" VALUES(12,"December");');
        } 
    });

isTableExists(tx, "years", function(status) {
        if (!status) {
        tx.executeSql('CREATE TABLE IF NOT EXISTS "years" ("id" INTEGER PRIMARY KEY  AUTOINCREMENT  NOT NULL  UNIQUE , "year" INTEGER);');
    tx.executeSql('INSERT INTO "years" VALUES(1,2009);');
    tx.executeSql('INSERT INTO "years" VALUES(2,2010);');
    tx.executeSql('INSERT INTO "years" VALUES(3,2011);');
    tx.executeSql('INSERT INTO "years" VALUES(4,2012);');
        } 
    });
    }

  </script>
  <meta name="viewport" content="width=320; user-scalable=no">
  <meta http-equiv="Content-type" content="text/html; charset=utf-8">
  <title>Auth Demo</title>
  <link rel="stylesheet" href="jquery.mobile/jquery.mobile-1.0rc2.css"
 type="text/css" charset="utf-8">
  <script type="text/javascript" src="js/jquery-1.7.min.js"></script>
  <script type="text/javascript" charset="utf-8"
<script src="phonegap.js"></script> 
  <script src="jquery.mobile/jquery.mobile-1.0rc2.js"></script>
</head>
<body onload="init()">
<div id="loginPage" data-role="page">
<div data-role="header">
<h1>Demo</h1>
</div>
<div data-role="content">
<form id="loginForm" onsubmit="goToMain('./main.html')" method="post"
 action="" name="form">
  <div data-role="fieldcontain" class="ui-hide-label"> <label
 for="username">Username:</label> <input name="username" id="username"
 value="" placeholder="Username" type="text"> </div>
  <div data-role="fieldcontain" class="ui-hide-label"> <label
 for="password">Password:</label> <input name="password" id="password"
 value="" placeholder="Password" type="password"> </div>
  <input value="Login" id="submitButton" type="submit"> </form>
</div>
<div data-role="footer">
<h4>© Ontic</h4>
</div>
</div>
</body>
</html> 

ボタンをクリックすると、次の画面に移動し、そこで「未定義」エラーが自動的に表示されます。

        <!DOCTYPE html> 
    <html> 
        <head> 
        <meta name="viewport" content="width=device-width, initial-scale=1">    
        <title></title> 
        <link rel="stylesheet" href="js/jquery.mobile-1.0.min.css" />
        <script  src="js/jquery-1.6.4.min.js"></script>
        <script src="js/jquery.mobile-1.0.min.js"></script>
    <script src="phonegap.js"></script>

    <script>
    var dbShell;
    var s;
    var txt;
        document.addEventListener("deviceready", onDeviceReady, false);

    function onDeviceReady(){
        //First, open our db
        dbShell = window.openDatabase("test", "1.0", "Test DB", 10000000);
        //run transaction to create initial tables
    try
    {
        getEntries();
     }
        catch(err)
          {
          alert(err.code);
      } 
    }


    function getEntries() {
        dbShell.transaction(function(tx) {
        tx.executeSql("select id, name from clients",[],renderEntries,dbErrorHandler);
        tx.executeSql("select id, year from years",[],renderEntriesYears,dbErrorHandler);

        }, dbErrorHandler);
    }


    function dbErrorHandler(err){
        alert("DB Error: "+err.message + "\nCode="+err.code);
    }


    function renderEntries(tx,results){
    try{
        $("#entryText").html("<p>  You currently do not have any clients.</p>");
           s = "<p> These are your clients: </p>";
           for(var i=0; i<results.rows.length; i++) {
        alert("inside3");
        var  name= results.rows.item(i).name;
        var id = results.rows.item(i).id;
        s += "<li><a href=\"clientsinvoices.html?id="+id+"&ref=0\">" + name + "</a></li>";   
          }
        $("#linksList").html(s);
        $("#linksList").listview("refresh");

      }
        catch(err)
          {
          txt="There are no invoices for this client\n\n";
          txt+="Click OK to continue.\n\n";
          alert(txt);
      }

    }

    function renderEntriesYears(tx,results){
    try{
        $("#entryText").html("<p>  You currently do not have any clients.</p>");
           s += "<p> These are your years: </p>";
           for(var i=0; i<results.rows.length; i++) {
        var  name= results.rows.item(i).year;
        var id = results.rows.item(i).id;
        s += "<li><a href=\"clientsinvoices.html?id="+id+"&ref=1\">" + name + "</a></li>";   
          }
        $("#linksList").html(s);
        $("#linksList").listview("refresh");
      }
        catch(err)
          {
          alert("catchs");
          txt="There are no invoices for this year\n\n";
          txt+="Click OK to continue.\n\n";
          alert(txt);
      }
    }

    </script>
    </head> 
    <body > 

    <div data-role="page" id="mainPage" style="background-image:url('images/back.jpg');">

        <div data-role="header">
        <h1></h1>
        </div>

        <div data-role="content">  
            <div id="status"></div>  
        <ul id="linksList" data-role="listview" data-inset="true"></ul>
        </div>

        <div data-role="footer">
        <h4></h4>
        </div>


    </div>

    <div data-role="page" id="contentPage" style="background-image:url('images/back.jpg');" >

        <div data-role="header">
        <a href="#mainPage" data-rel="back">Home</a>
        <h1></h1>
        </div>

        <div data-role="content" id="entryText">
        </div>

    </div>

    </body>
    </html>
4

1 に答える 1

1

最後に、グーグルのおかげで見つけた回避策を使用して動作させることができました。これは動作するコードです:

索引.html

   <!DOCTYPE HTML>
      <html>
        <head>

        <script>
       /*
       * Licensed to the Apache Software Foundation (ASF) under one
       * or more contributor license agreements.  See the NOTICE file
       * distributed with this work for additional information
       * regarding copyright ownership.  The ASF licenses this file
       * to you under the Apache License, Version 2.0 (the
       * "License"); you may not use this file except in compliance
       * with the License.  You may obtain a copy of the License at
       *
       * http://www.apache.org/licenses/LICENSE-2.0
       *
       * Unless required by applicable law or agreed to in writing,
       * software distributed under the License is distributed on an
       * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
       * KIND, either express or implied.  See the License for the
       * specific language governing permissions and limitations
       * under the License.
       */
      var app = {
          // Application Constructor
          initialize: function() {
              this.bindEvents();
          },
          // Bind Event Listeners
          //
          // Bind any events that are required on startup. Common events are:
          // 'load', 'deviceready', 'offline', and 'online'.
          bindEvents: function() {
              document.addEventListener('deviceready', this.onDeviceReady, false);
          },
          // deviceready Event Handler
          //
          // The scope of 'this' is the event. In order to call the 'receivedEvent'
          // function, we must explicity call 'app.receivedEvent(...);'
          onDeviceReady: function() {

              app.receivedEvent('deviceready');

          },
          // Update DOM on a Received Event
          receivedEvent: function(id) {
               var db = window.openDatabase("test", "1.0", "Test DB", 10000000);
             db.transaction(populateDB, errorCB, successCB);
          }
      };
            function goToMain(url)
            {
            var url = url;
            var username=document.getElementById('username');
            var password=document.getElementById('password');
            if(username.value == '' && password.value== '')
            {
                             document.form.action = "main.html";
            }
            else
            {
                alert('No valid');
            }
        return ;
            };

       // Transaction error callback
          //
          function errorCB(tx, err) {
              alert("Error processing SQL: "+err);
          };

          // Transaction success callback
          //
          function successCB() { 
          };

        function isTableExists(tx, tableName, callback) {
              tx.executeSql('SELECT * FROM '+tableName, [], function(tx, resultSet) {
                  if (resultSet.rows.length <= 0) {
                      callback(false);
                  } else {
                      callback(true);
                  }
              }, function(err) {
                  callback(false);
              })
        };

        function populateDB(tx) {

         isTableExists(tx, "invoices", function(status) {
                  if (!status) {
                     tx.executeSql('CREATE TABLE IF NOT EXISTS "invoices" ("id" INTEGER PRIMARY KEY  AUTOINCREMENT  NOT NULL  UNIQUE , "month" INTEGER NOT NULL , "year" INTEGER, "client" INTEGER, "amount" FLOAT, "tax" FLOAT);');
        tx.executeSql('INSERT INTO "invoices" VALUES(1,1,2,1,1500,21);');
        tx.executeSql('INSERT INTO "invoices" VALUES(2,2,1,2,2500,16);');
        tx.executeSql('INSERT INTO "invoices" VALUES(3,10,1,3,3500,21);');
        tx.executeSql('INSERT INTO "invoices" VALUES(4,5,4,1,10500,21);');
        tx.executeSql('INSERT INTO "invoices" VALUES(5,4,2,2,15500,21);');
        tx.executeSql('INSERT INTO "invoices" VALUES(6,1,4,4,134200,21);');
                  } 
              });

      isTableExists(tx, "clients", function(status) {
                  if (!status) {
                    tx.executeSql('CREATE TABLE IF NOT EXISTS"clients" ("id" INTEGER PRIMARY KEY  AUTOINCREMENT  NOT NULL  UNIQUE , "name" VARCHAR);');
        tx.executeSql('INSERT INTO "clients" VALUES(1,"Alfonso");');
        tx.executeSql('INSERT INTO "clients" VALUES(2,"Alejandro");');
        tx.executeSql('INSERT INTO "clients" VALUES(3,"Ricardo");');
        tx.executeSql('INSERT INTO "clients" VALUES(4,"Víctor");');
                  } 
              });



        isTableExists(tx, "months", function(status) {
                  if (!status) {
                 tx.executeSql('CREATE TABLE IF NOT EXISTS "months" ("id" INTEGER PRIMARY KEY  AUTOINCREMENT  NOT NULL  UNIQUE , "name" VARCHAR);');
        tx.executeSql('INSERT INTO "months" VALUES(1,"January");');
        tx.executeSql('INSERT INTO "months" VALUES(2,"February");');
        tx.executeSql('INSERT INTO "months" VALUES(3,"March");');

        tx.executeSql('INSERT INTO "months" VALUES(4,"April");');
        tx.executeSql('INSERT INTO "months" VALUES(5,"May");');
        tx.executeSql('INSERT INTO "months" VALUES(6,"June");');
        tx.executeSql('INSERT INTO "months" VALUES(7,"July");');
        tx.executeSql('INSERT INTO "months" VALUES(8,"August");');
        tx.executeSql('INSERT INTO "months" VALUES(9,"September");');
        tx.executeSql('INSERT INTO "months" VALUES(10,"October");');
        tx.executeSql('INSERT INTO "months" VALUES(11,"November");');
        tx.executeSql('INSERT INTO "months" VALUES(12,"December");');
                  } 
              });

      isTableExists(tx, "years", function(status) {
                  if (!status) {
                    tx.executeSql('CREATE TABLE IF NOT EXISTS "years" ("id" INTEGER PRIMARY KEY  AUTOINCREMENT  NOT NULL  UNIQUE , "year" INTEGER);');
        tx.executeSql('INSERT INTO "years" VALUES(1,2009);');
        tx.executeSql('INSERT INTO "years" VALUES(2,2010);');
        tx.executeSql('INSERT INTO "years" VALUES(3,2011);');
        tx.executeSql('INSERT INTO "years" VALUES(4,2012);');
                  } 
              });


          }

        </script>

         <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
              <meta name="format-detection" content="telephone=no" />
              <meta name="viewport" content="user-scalable=no, initial-scale=1, maximum-scale=1, minimum-scale=1, width=device-width, height=device-height, target-densitydpi=device-dpi" />
               <link rel="stylesheet" href="jquery.mobile/jquery.mobile-1.0rc2.css"
       type="text/css" charset="utf-8">

       <link media="all" href="docucss.css" type= "text/css" rel="stylesheet" />

        <title>Mobile Bussiness App</title>
        <script type="text/javascript" src="cordova-2.2.0.js"></script>
              <script type="text/javascript">
                  app.initialize();
              </script>


      </head>
      <body>
      <div id="loginPage" data-role="page">
      <div data-role="header">
      <img src="images/login.jpg" alt="Login" height="42" width="42">
      <h1 class="title">Mobile Bussiness App</h1>


      </div>
      <div data-role="content">
      <form id="loginForm" onsubmit="goToMain('./main.html')" method="post"
       action="" name="form">
        <div data-role="fieldcontain" class="ui-hide-label"> <label
       for="username">Username:</label> <input name="username" id="username"
       value="" placeholder="Username" type="text"> </div>
        <div data-role="fieldcontain" class="ui-hide-label"> <label
       for="password">Password:</label> <input name="password" id="password"
       value="" placeholder="Password" type="password"> </div>
        <input value="Login" id="submitButton" type="submit"> </form>
      </div>
      <div data-role="footer">
      <h4>© MBA</h4>
      </div>
      </div>
      </body>
      </html> 

そしてmain.html:

<!DOCTYPE html> 
        <html> 
            <head> 
               <link rel="stylesheet" href="js/jquery.mobile-1.0.min.css" />

              <script type="text/javascript" src="js/xui-2.3.2.js"></script>

        <script>

        var dbShell;
        var s;

        /*
         * Licensed to the Apache Software Foundation (ASF) under one
         * or more contributor license agreements.  See the NOTICE file
         * distributed with this work for additional information
         * regarding copyright ownership.  The ASF licenses this file
         * to you under the Apache License, Version 2.0 (the
         * "License"); you may not use this file except in compliance
         * with the License.  You may obtain a copy of the License at
         *
         * http://www.apache.org/licenses/LICENSE-2.0
         *
         * Unless required by applicable law or agreed to in writing,
         * software distributed under the License is distributed on an
         * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
         * KIND, either express or impylied.  See the License for the
         * specific language governing permissions and limitations
         * under the License.
         */
        var app = {
            // Application Constructor
            initialize: function() {
                this.bindEvents();

            },
            // Bind Event Listeners
            //
            // Bind any events that are required on startup. Common events are:
            // 'load', 'deviceready', 'offline', and 'online'.
            bindEvents: function() {
                document.addEventListener('deviceready', this.onDeviceReady, false);
            },
            // deviceready Event Handler
            //
            // The scope of 'this' is the event. In order to call the 'receivedEvent'
            // function, we must explicity call 'app.receivedEvent(...);'
            onDeviceReady: function() {
                app.receivedEvent('deviceready');

            },
            // Update DOM on a Received Event
            receivedEvent: function(id) {
                dbShell = window.openDatabase("test", "1.0", "Test DB", 10000000);
                getEntries(); 
                    }
        };

        function getEntries() {
            //doLog("get entries");
            dbShell.transaction(function(tx) {
                tx.executeSql("select id, name from clients",[],renderEntries,dbErrorHandler);
            tx.executeSql("select id, year from years",[],renderEntriesYears,dbErrorHandler);

            }, dbErrorHandler);
        }


        function dbErrorHandler(err){
            alert("DB Error: "+err.message + "\nCode="+err.code);
        }


        function renderEntries(tx,results){
        try{
                $("#entryText").html("<p>  You currently do not have any clients.</p>");

               s = "<p class=\"title2\"> These are your clients: </p>";
               for(var i=0; i<results.rows.length; i++) {
            var  name= results.rows.item(i).name;
            var id = results.rows.item(i).id;
                s += "<li><a href=\"clientsinvoices.html?id="+id+"&ref=0\" data-transition=\"slide\" rel=\"external\">" + name + "</a></li>";   
        //  alert(s);
              }
            $("#linksList").html(s);
            $("#linksList").listview("refresh");

          }
            catch(err)
              {
              txt="There are no invoices for this client\n\n" + err;
              txt+="Click OK to continue.\n\n";
              alert(txt);
          }

        }

        function renderEntriesYears(tx,results){
           // doLog("render entries");
         // if (results.rows.length < 1) {
        try{
                $("#entryText").html("<p>  You currently do not have any clients.</p>");
          // } else {
               s += "<p class=\"title2\"> These are your years: </p>";
               for(var i=0; i<results.rows.length; i++) {
            var  name= results.rows.item(i).year;
            var id = results.rows.item(i).id;
                s += "<li><a href=\"clientsinvoices.html?id="+id+"&ref=1\" data-transition=\"slide\" rel=\"external\">" + name + "</a></li>";   
        //  alert(s);
              }
            $("#linksList").html(s);
            $("#linksList").listview("refresh");
          }
            catch(err)
              {
              txt="There are no invoices for this year\n\n"+ err;
              txt+="Click OK to continue.\n\n";
              alert(txt);
          }
        }

        </script>

          <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
                <meta name="format-detection" content="telephone=no" />

                <meta name="viewport" content="user-scalable=no, initial-scale=1,
                 maximum-scale=1, minimum-scale=1, width=device-width, 
                 height=device-height, target-densitydpi=device-dpi" />

                 <link rel="stylesheet" href="jquery.mobile/jquery.mobile-1.0rc2.css"
         type="text/css" charset="utf-8">

          <link media="all" href="docucss.css" type= "text/css" rel="stylesheet" />


          <title class="title">Mobile Business App</title>
          <script type="text/javascript" src="cordova-2.2.0.js"></script>
                <script type="text/javascript">
                    app.initialize();
                </script>


        </head> 
        <body > 

        <div  data-role="page" id="mainPage" style="background-image:url('images/back.jpg');">

               <h1 class="title">Clients And Years</h1>

            <div data-role="content">  
                <div id="status"></div>  
                <ul id="linksList" data-role="listview" data-inset="true"></ul>




            </div>



        </div>

        <div data-role="page" id="contentPage" style="background-image:url('images/back.jpg');" >

            <div data-role="header">
                  <a href="./index.html" data-rel="back">Home</a>
            </div>

            <div data-role="content" id="entryText">
            </div>

        </div>

        </body>
        </html>

私を助けてくれた皆さんに感謝します!

ご挨拶!

于 2012-12-21T10:01:12.187 に答える