Delphi XE7のAndroidアプリケーションで通信状態を判定するには

Delphi XE7のAndroidアプリケーションで通信状態が、モバイル通信かWi-Fi通信か未接続かを判定する方法を紹介します。

モバイル通信の時は送受信するデータのサイズを小さくしてアプリケーションのレスポンスを良くするなどの工夫ができます。

メニューの「プロジェクト」→「オプション」→「使用する権限」から「ネットワーク状態へのアクセス」にチェックを入れます。

01

Androidのandroid.net.ConnectivityManagerクラスとandroid.net.NetworkInfoクラスを使用するため、ブリッジファイルを作成します。

Java2OP.exe -classes android.net.ConnectivityManager android.net.NetworkInfo -unit Androidapi.JNI.Interfaces

ボタンを押したときに、通信状態を表示するプログラムです。

uses
  Androidapi.JNIBridge,
  Androidapi.Helpers,
  Androidapi.JNI.JavaTypes,
  Androidapi.JNI.GraphicsContentViewText,
  Androidapi.JNI.Interfaces;

procedure TForm1.Button1Click(Sender: TObject);
var
  ConnectivityManagerObj: JObject;
  ConnectivityManager: JConnectivityManager;
  NetworkInfo: JNetworkInfo;
  NetworkType: Integer;
begin
  ConnectivityManagerObj := SharedActivityContext.getSystemService
    (TJContext.JavaClass.CONNECTIVITY_SERVICE);
  ConnectivityManager := TJConnectivityManager.Wrap
    ((ConnectivityManagerObj as ILocalObject).GetObjectID);

  NetworkInfo := ConnectivityManager.getActiveNetworkInfo();
  if NetworkInfo = nil then
  begin
    ShowMessage('未接続');
    Exit;
  end;

  NetworkType := NetworkInfo.getType;
  if NetworkType = TJConnectivityManager.JavaClass.TYPE_WIFI then
  begin
    ShowMessage('Wi-Fiデータ通信');
  end
  else if NetworkType = TJConnectivityManager.JavaClass.TYPE_MOBILE then
  begin
    ShowMessage('モバイルデータ通信');
  end;
end;

ボタンを押すと、通信状態が表示されます。

02

Delphi XE7のRESTコンポーネントを使って、天気予報を取得する

Delphi XE7のRESTコンポーネントを使って、天気予報を取得する方法を紹介します。

天気予報の情報は、「お天気Webサービス」から取得します。

サービスの使用を見るとわかるように、指定されたURLにアクセスすると、JSON形式で天気概況情報が返されます。

FireMonkeyマルチプラットフォームアプリケーションを新規に作成します。

00

01

フォームに次のコンポーネントを配置します。

  • 地域IDを入力するTEditコンポーネント
  • 処理を実行するTButtonコンポーネント
  • 実行結果を表示するTMemoコンポーネント
  • 取得情報を表示するTLabelコンポーネント
  • TRESTRequestコンポーネント
  • TRESTResponseコンポーネント
  • TRESTClientコンポーネント

03

ボタンを押したときの処理を記述します。

procedure TForm1.Button1Click(Sender: TObject);
begin
  RESTRequest1.ResetToDefaults;
  RESTClient1.ResetToDefaults;
  RESTResponse1.ResetToDefaults;

  RESTClient1.BaseURL := 'http://weather.livedoor.com/';
  RESTRequest1.Resource := 'forecast/webservice/json/v1?city={CITY}';
  RESTRequest1.Params.AddItem('CITY', Edit1.Text,
    TRESTRequestParameterKind.pkURLSEGMENT);
  RESTRequest1.Execute;
end;

RESTRequest1のResourceプロパティに設定しているURLにはCITYパラメータが含まれています。

  RESTRequest1.Resource := 'forecast/webservice/json/v1?city={CITY}';

パラメータの値は、RESTRequest1.Params.AddItemで設定します。
Edit1に入力されている値を設定しています。

  RESTRequest1.Params.AddItem('CITY', Edit1.Text,
    TRESTRequestParameterKind.pkURLSEGMENT);

RESTRequest1のOnAfterExecuteイベントを追加します。

procedure TForm1.RESTRequest1AfterExecute(Sender: TCustomRESTRequest);
const
  KEYS: array [0 .. 2] of string = ('dateLabel', 'telop', 'date');
var
  JSONValue: TJSONValue;
  Forecasts: TJSONArray;
  Forecast: TJSONValue;
  Key: string;
begin
  Memo1.Lines.Clear;;
  Label1.Text := 'URI: ' + Sender.GetFullRequestURL + ' Execution time: ' +
    IntToStr(Sender.ExecutionPerformance.TotalExecutionTime) + 'ms';
  if Assigned(RESTResponse1.JSONValue) then
  begin
    JSONValue := RESTResponse1.JSONValue;
    Forecasts := JSONValue.GetValue<TJSONArray>('forecasts');
    for Forecast in Forecasts do
    begin
      for Key in KEYS do
      begin
        Memo1.Lines.Add(Format('%s=%s',
          [Key, Forecast.GetValue<TJSONString>(Key).ToString]));
      end;
    end;
  end;
end;

返されたデータを適切な型に変換して表示しています。

RESTRequest1のHTTPProtocolErrorイベントを追加します。

procedure TForm1.RESTRequest1HTTPProtocolError(Sender: TCustomRESTRequest);
begin
  Memo1.Lines.Add(Sender.Response.StatusText);
  Memo1.Lines.Add(Sender.Response.Content);
end;

アプリケーションを実行します。

Windows / MAC OS X / Android / iOS のすべてのプラットフォームで動作可能です。

win1

win2

android1

android2

mac1

mac2

DelphiのJSON関連の記事

Delphi XE7のAndroidアプリケーションでTBitmapを作成するとエラーになる

開発環境はDelphi XE7 Update1、プラットフォームはAndroidで発生する問題です。
メインスレッド以外でTBitmapを作成すると例外が発生します。

procedure TForm1.Button1Click(Sender: TObject);
begin
  TThread.CreateAnonymousThread(
    procedure
    var
      Bmp: TBitmap;
    begin
      Bmp := TBitmap.Create(100, 100);
    end).Start;
end;

$A2355201 で初回の例外が発生しました。例外クラスは EBitmapSizeTooBig メッセージは ‘ビットマップ サイズが大きすぎます。’。 プロセス Project1.apk (22537)

この問題はRAD Studio Quality Portalにも登録されています。

例外が発生する箇所はTBitmap.SetSizeメソッドの中なので、SetSizeメソッドを実行しても同じように例外が発生します。

procedure TForm1.Button1Click(Sender: TObject);
begin
  TThread.CreateAnonymousThread(
    procedure
    var
      Bmp: TBitmap;
    begin
      Bmp := TBitmap.Create;
      Bmp.SetSize(100, 100); //ここで例外発生
    end).Start;
end;

AndroidでWebブラウザのリンクをクリックするとDelphiアプリケーションを起動する

AndroidでWebブラウザのリンクをクリックするとDelphiアプリケーションを起動する方法を紹介します。

Delphiアプリケーションの作成

アプリケーションが起動したときに、リンクのURLを取得してブラウザコンポーネントに表示します。

procedure TForm1.FormCreate(Sender: TObject);
var
  Intent: JIntent;
  Uri: JString;
begin
  Intent := SharedActivity.getIntent;
  if TJIntent.JavaClass.ACTION_VIEW.equals(Intent.getAction) then
  begin
    Uri := Intent.getDataString;
    FWebBrowser.URL := JStringToString(Uri);
  end;
end;

AndroidManifest.template.xmlの編集

AndroidManifest.xmlにインテントフィルタを設定します。

プロジェクトファイルのあるフォルダーに「AndroidManifest.template.xml」というファイルがあります。
この「AndroidManifest.template.xml」をテキストエディタで開きます。

次のコードを追加します。

        <intent-filter>
            <action android:name="android.intent.action.VIEW" />
            <category android:name="android.intent.category.DEFAULT" />
            <category android:name="android.intent.category.BROWSABLE" />
            <data android:scheme="http" android:host="www.gesource.jp" android:path="/" />
        </intent-filter>

dataタグで、アプリケーションを起動するリンクを設定しています。
「https://www.gesource.jp/」のリンクをクリックしたとき、Delphiアプリケーションでリンクを開くことができます。

001

002

リンクは「http」に限られているわけではありません。
dataタグを次のようにすると、「test://hello」のリンクをクリックしたときに、アプリケーションを起動します。

<data android:scheme="test" android:host="hello" />

003