タス デザイン グループ

Read Article

定期的にサーバにアクセスする

AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.fxos.androidtips36"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="14"
        android:targetSdkVersion="15" />

    <uses-permission android:name="android.permission.INTERNET" />

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@android:style/Theme.NoTitleBar" >
        <activity
            android:name="com.example.fxos.androidtips36.MainActivity"
            android:label="@string/app_name"
            android:launchMode="singleTask" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

        <service android:name="com.example.fxos.androidtips36.TimerService" />
    </application>

</manifest>

activity_main.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context=".MainActivity" >

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal" >

        <Button
            android:id="@+id/buttonIntervalStart"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:onClick="onClick"
            android:text="@string/button_start" />

        <Button
            android:id="@+id/buttonIntervalStop"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:onClick="onClick"
            android:text="@string/button_stop" />
    </LinearLayout>

    <TextView
        android:id="@+id/textResult"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/text_initial_value"
        android:textAppearance="?android:attr/textAppearanceMedium" />

</LinearLayout>

MainActivity.java

package com.example.fxos.androidtips36;

import android.app.Activity;
import android.app.AlarmManager;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.view.View;
import android.widget.TextView;

public class MainActivity extends Activity {
    private static final int REQUEST_CODE = 0x10;

    private static final long INTERVAL = 5000;

    private Intent mIntent;

    private PendingIntent mOperation;

    private AlarmManager mAlarmManager;

    private TextView mTextResult;

    private OperationReceiver mOperationReceiver;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        mTextResult = (TextView)findViewById(R.id.textResult);

        // set AlarmManager
        mAlarmManager = (AlarmManager)getSystemService(ALARM_SERVICE);

        // set service
        mIntent = new Intent(this, TimerService.class);
        mOperation = PendingIntent.getService(this, REQUEST_CODE, mIntent,
                PendingIntent.FLAG_CANCEL_CURRENT);

        // receiver to receive service result
        mOperationReceiver = new OperationReceiver();
    }

    public void onClick(View view) {
        switch (view.getId()) {
            case R.id.buttonIntervalStart:
                // start repeat
                mAlarmManager.setRepeating(AlarmManager.RTC, System.currentTimeMillis(), INTERVAL,
                        mOperation);
                view.setEnabled(false);
                break;
            case R.id.buttonIntervalStop:
                // stop repeat
                mAlarmManager.cancel(mOperation);
                findViewById(R.id.buttonIntervalStart).setEnabled(true);
                break;
        }
    }

    protected void onResume() {
        super.onResume();
        registerReceiver(mOperationReceiver, new IntentFilter(TimerService.ACTION_REFLESH));
    }

    protected void onPause() {
        super.onPause();
        unregisterReceiver(mOperationReceiver);
    }

    protected void onDestroy() {
        super.onDestroy();
        mAlarmManager.cancel(mOperation);
    }

    class OperationReceiver extends BroadcastReceiver {
        @Override
        public void onReceive(Context context, Intent intent) {
            // set result value
            mTextResult.setText(intent.getStringExtra(TimerService.EXTRA_REFLESH_VALUE));
        }
    }
}

TimerService.java

package com.example.fxos.androidtips36;

import android.app.IntentService;
import android.content.Intent;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;

public class TimerService extends IntentService {
    private static final String TAG = TimerService.class.getSimpleName();

    public static final String ACTION_REFLESH = "com.example.intent.REFLESH";

    public static final String EXTRA_REFLESH_VALUE = "com.example.extra.REFLESH_VALUE";

    private static final String INTERVAL_ACCESS_SITE = "http://ntp-a1.nict.go.jp/cgi-bin/time";

    public TimerService() {
        super(TAG);
    }

    @Override
    protected void onHandleIntent(Intent intent) {
        HttpURLConnection connection = null;
        InputStream is = null;
        try {
            // connect interval access site
            URL url = new URL(INTERVAL_ACCESS_SITE);
            connection = (HttpURLConnection)url.openConnection();
            switch (connection.getResponseCode()) {
                case HttpURLConnection.HTTP_OK:
                    // get result
                    is = connection.getInputStream();
                    ByteArrayOutputStream bos = new ByteArrayOutputStream();
                    byte[] buffer = new byte[1000];
                    int size = 0;
                    while ((size = is.read(buffer, 0, buffer.length)) != -1) {
                        bos.write(buffer, 0, size);
                    }

                    // convert to string
                    String result = new String(bos.toByteArray(), 0, bos.size(), "UTF-8");

                    // send broadcast
                    Intent resultIntent = new Intent(ACTION_REFLESH);
                    resultIntent.putExtra(EXTRA_REFLESH_VALUE, result);
                    sendBroadcast(resultIntent);

                    break;
                default:
                    android.util.Log.d("MainActivity", "access failure.");
            }
        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (is != null) {
                try {
                    is.close();
                } catch (IOException e) {
                }
            }
        }
    }

}

manifest.webapp

{
  "name": "interval_access",
  "description": "36_interval_access",
  "launch_path": "/index.html",
  "type": "privileged",
  "icons": {
    "64": "/img/icon/app-icon64.png",
    "128": "/img/icon/app-icon128.png"
  },
  "developer": {
    "name": "TAS Design Group",
    "url": "http://tasdg.co.jp/"
  },
  "permissions": {
    "systemXHR": {}
  },
  "default_locale": "ja"
}

CSS (style/style.css)

@charset "UTF-8";

html {
  height: 100%;
  font-size: 62.5%;
}

body {
  margin: 0;
  height: 100%;
  display: block;
  overflow: hidden;
  font-family: sans-serif;
}

index.html

<!DOCTYPE html>
<html lang="ja" dir="ltr">
<head>
  <meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1">
  <meta charset="utf-8">
  <title>Interval Access</title>
  <link rel="stylesheet" href="style/style.css">
  <script src="js/main.js"></script>
  <script src="js/worker.js"></script>
</head>
<body>
  <section>
    <header>
      <h1>Interval Access</h1>
    </header>
    <article>Access to following server every 5sec on background thread.</article>
    <input id='name' value='http://ntp-a1.nict.go.jp/cgi-bin/time'>
    <p>
    <button id='btn'>start</button>
    <button id='stop'>stop</button>
    <p>
    <div id='msg'></div>
  </section>
</body>
</html>

main.js

window.addEventListener('load', function() {

  var worker = new Worker('js/worker.js');
  worker.onmessage = function(e) {
    document.getElementById('msg').innerHTML = e.data;
  };

  document.getElementById('btn').onclick = function() {
    var servername = document.getElementById('name').value;
    worker.postMessage( {'name': servername} );
  };
  document.getElementById('stop').onclick = function() {
    worker.postMessage( {'stop': true } );
  };

});

worker.js

const INTERVAL = 5000;

var intervalid = 0;
addEventListener('message', function(e) {

  if (e.data.stop) {
    clearInterval(intervalid);
    return;
  } else if (intervalid !== 0) {
    clearInterval(intervalid);
  }
  intervalid = setInterval(function() {
    getserver(e.data.name);
  }, INTERVAL);
});

function getserver(servername) {
  var xhr = new XMLHttpRequest({
    mozSystem: true
  });
  xhr.open('GET', servername, true);
  xhr.onreadystatechange = function() {
    if ((xhr.readyState == 4) && (xhr.status == 200)) {
      postMessage(xhr.responseText);
    }
  };
  xhr.send(null);
}
Return Top