2

概要:

このアプリケーションはUIApplicationを拡張し、起動時に登録されるSMSリスナークラスを持っています。基準に一致するメッセージを受信したら、メッセージを処理してから、ローカルのSQLiteデータベースに保存し、Webサーバーにアップロードします。その段階でUIアプリケーションが開いていなくても、SMSを受信した後できるだけ早くこれを行うことが重要です。

問題:

SMSListenerインスタンスがバックグラウンドで実行されていて、UIApplicationインスタンスがアクティブになっておらず、SQLiteデータベースにアクセスしたい場合、またはHTTP接続を作成しようとすると、「アプリケーションインスタンスなし」例外がスローされます。

望ましい結果:

UIApplicationがアクティブでない場合でも、SMSListenerバックグラウンドスレッドからのすべてのメッセージを処理、保存、およびアップロードする必要があります。現在、SMSListenerバックグラウンドスレッドはメッセージをRuntimeStoreに保存します。UIアプリケーションが起動すると、RuntimeStoreからメッセージを読み取り、データベースに保存します。ただし、これは最適なソリューションではありません。Webサーバーとの同期は、UIアプリケーションが次に開かれたときにのみ発生するためです。メッセージが受信されたときに同期することが重要です。

アプリケーションの擬似コード:

メインクラスは、起動をチェックしてSMSListenerインスタンスを作成するか、RuntimeStoreからインスタンスを取得します。

public class OurAppUi extends UiApplication {
public static void main(String[] args) {
    if (args != null && args.length > 0 && args[0].endsWith("gui")) {
        // Create a new instance of the application and make the currently
        // running thread the application's event dispatch thread.
        OurAppUi theApp = new OurAppUi();
        theApp.enterEventDispatcher();
    } else {
        // Entered through the alternate application entry point
        SmsListener.waitForSingleton();
    }
}
}

SMSListenerクラスは、着信メッセージをリッスンし、RuntimeStoreシングルトンモデルを利用します。これは期待どおりに機能しています。

public class SmsListener implements javax.wireless.messaging.MessageListener {
public static SmsListener waitForSingleton() {
    //Ensure this is a singleton instance.
    //Open RuntimeStore and obtain the reference of BackgroundListener
    RuntimeStore store = RuntimeStore.getRuntimeStore();
    Object obj = store.get(ID_BACKGROUND_LISTENER);

    //If obj is null, there is no current reference to BackgroundListener
    //Start a new instance of BackgroundLIstener if one is not running
    if(obj == null) {
        store.put(ID_BACKGROUND_LISTENER, new SmsListener());
        return (SmsListener)store.get(ID_BACKGROUND_LISTENER);
    } else {
        return(SmsListener)obj;
    }
}

public void notifyIncomingMessage(MessageConnection conn) {
    new Thread() {
        MessageConnection connection;
        Thread set (MessageConnection con) {
            this.connection = con;
            return (this);
        }

        public void run() {
            try {
                Message m = connection.receive();
                String msg = null;

                if (m instanceof TextMessage) {
                    TextMessage tm = (TextMessage)m;
                    msg = tm.getPayloadText();
                }
                // Process the SMS
                SMSObject sms = processSMS(msg);
                // Save to DataBase { Exception is Thrown Here }
                SQLManager.getInstance().save(sms);
                // Upload to Web Server { Exception is Thrown Here }
                WebServer.upload(sms);

            } catch(Exception error) {
            }
        }
    }.set(conn).start();

}
}

SmsListenerインスタンスがSQLiteデータベースにアクセスしようとした場合、またはHTTP接続を作成しようとした場合、「アプリケーションインスタンスなし」例外がスローされます。

public final class SQLManager {
private SQLManager() {
    try {
        db = OpenOrCreateDatabase();
    } catch (MalformedURIException e) {
        Debug.log(TAG, "Get connection: URI: " + e.getMessage());   
    } catch (ControlledAccessException e) {
        Debug.log(TAG, "Get connection: Controlled Access: " + e.getMessage()); 
    } catch (DatabasePathException e) {
        Debug.log(TAG, "Get connection: Database Path: " + e.getMessage()); 
    } catch (DatabaseIOException e) {
        Debug.log(TAG, "Get connection: Database IO: " + e.getMessage());   
    } catch (Exception e) {
        Debug.log(TAG, e);  
    }
}

public static synchronized SQLManager getInstance() {
    if (instance == null) {
        instance = new SQLManager();
    }
    return instance;
}
}

SMSListenerと同じシングルトンモデルを使用してSQLiteインスタンスをRuntimeStoreに保存しようとしましたが、UIアプリケーションが保存されたDBインスタンスにアクセスしようとしたときにエラーが発生しました。

4

1 に答える 1