Download PDF
Download page Android インストゥルメンテーションのカスタマイズ.
Android インストゥルメンテーションのカスタマイズ
Android SDK を使用して Android アプリケーションをインストゥルメント化すると、SDK によって公開される API を使用して、コントローラ UI に表示されるアプリケーションのデータをカスタマイズすることもできます。
エージェントは情報を報告する前にローカルバッファにイベントに関するデータを保存するため、慎重に API を使用することをお勧めします。
データの追加タイプの収集
Instrumentation
クラスには、モバイル RUM を使用して収集および集約できるアプリケーションデータの種類を拡張できる追加のメソッドがあります。作成できる拡張には、次の 6 つの基本タイプがあります。
データのタイプ | 説明 | 仕様 | データが表示される場所 |
---|---|---|---|
情報ポイント | メソッドが呼び出される頻度と実行される時間。 |
| |
カスタムタイマー | コード内の任意のイベントシーケンスが、 複数のメソッドにまたがる場合でも、時間を計測。 |
| |
カスタムメトリック | 収集する整数ベースのデータ。 |
| |
ユーザデータ | 有用と思われる任意の文字列キーと値のペア |
| |
トピックパス(パンくずリスト) | クラッシュのコンテキスト。 |
| |
ユーザインタラクション | ユーザがボタンを押したとき、リストをクリックしたとき、およびテキストを選択したときにキャプチャ。 |
|
情報ポイント、カスタムタイマー、カスタムメトリック、ユーザデータを設定した場合、モバイルエージェントはモバイルビーコンでそのデータをパッケージ化します。通常、ビーコンは、インストゥルメント化されたアプリケーションが HTTP 要求を送信したとき、またはクラッシュ後にアプリケーションが再起動したときに、カスタムデータが収集され、これらのイベントが少なくとも 5 分間発生しなかった場合に送信されます。カスタムデータはその時点で送信されます。
情報ポイント
情報ポイントを使用すると、独自のコードがどのように実行されているかを追跡できます。メソッドが呼び出される頻度、実行にかかる時間、および例外がスローされたかどうかを確認できます。情報ポイントを設定する最も簡単な方法は、@InfoPoint
注釈を使用することです。例:
@InfoPoint
public void infoPointMethod(String arg1, int arg2, long value) {
System.out.println("Executing infoPointMethod!");
}
CallTracker
インターフェイスを使用して手動で実行することもできます。たとえば、downloadImage
メソッドに関する情報を収集するには、次のようなコードを使用できます。
private void downloadImage(URL url) {
CallTracker tracker =
Instrumentation.beginCall("com.example.android.awesomeapp.ImageDownloader", "downloadImage")
.withArguments(url);
try {
//download image.
tracker.reportCallEnded()
} catch(Exception e) {
//handle exception thrown
tracker.reportCallEndedWithException(e);
}
}
この情報は、コントローラ UI の [Custom Data] ビューに表示されます。
カスタムタイマー
カスタムタイマーでは、startTimer
と stopTimer
を使用して、複数のメソッドにまたがる場合でも、コード内の任意のイベントシーケンスの時間を測定できます。
public class MyActivity extends Activity {
@Override
protected void onStart(){
Instrumentation.startTimer("Time Spent on MyActivity");
//your code here.
}
@Override
protected void onStop(){
Instrumentation.stopTimer("Time Spent on MyActivity");
//your code here.
}
}
メソッド startTimer(String)
および stopTime(String)
はさまざまなスレッドから呼び出すことができます。同じ名前値を使用して startTimer
を再度呼び出すと、名前付きタイマーがリセットされます。
この情報は、コントローラ UI の [Custom Data] ビューに表示されます。
Custom Metrics
任意の整数ベースのデータをエージェントに渡すことができます。reportMetric
コールの最初のパラメータは、メトリックをコントローラ UI に表示する場合の名前です。メトリック名には、英数字とスペースのみを使用します。不正な文字は、ASCII 16 進値に置き換えられます。
たとえば、ユーザが UI のチェックアウトボタンをクリックした回数を追跡するには、次のようなコードを使用できます。
findViewById(R.id.checkout_button).setOnClickListener(new View.OnClickListener(){
@Override
public void onClick(View view){
//run your checkout routine.
Instrumentation.reportMetric("Checkout Count", 1);
}
});
この情報は、コントローラ UI の [Custom Data] ビューに表示されます。
ユーザ データ
有用と思われる任意の文字列キーと値のペアを設定できます。setUserData
コールの最初のパラメータは、使用するキーです。これはアプリケーション全体で一意である必要があります。2 番目はキーに割り当てる値です。
例:
void onUserLoggedIn(String userid) {
Instrumentation.setUserData("User ID", userid);
...
}
この情報は、[Network Request Analyze] で確認でき、取得可能なクラッシュスナップショットに追加されます。キーと値はそれぞれ 2048 文字に制限されています。
また、次のメソッドを使用して、他のデータ型(Long、Boolean、Double、Date)の値を含むユーザデータを設定することもできます。
トピックパス(パンくずリスト)
トピックパスを使用すると、ユーザエクスペリエンスのコンテキストでクラッシュの場所を特定できます。問題が発生したときに、トピックパスを設定します。その後のある時点でアプリケーションがクラッシュした場合、トピックパスはクラッシュレポートとともに表示されます。
トピックパスを残すには、次の 2 つの方法があります。
次のメソッドを使用すると、トピックパスがクラッシュレポートのみで報告されます。
public static void leaveBreadcrumb(java.lang.String breadcrumb)
public static void leaveBreadcrumb(java.lang.String breadcrumb, int mode)
ここで、mode
は次のいずれかです。
CRASHES_ONLY
CRASHES_AND_SESSIONS
breadcrumb
が 2048 文字を超えている場合は、切り捨てられます。空の場合、トピックパスは記録されません。各クラッシュレポートには、最近の 99 件のトピックパスが表示されます。
クラッシュ レポート コールバックの追加
モバイル RUM を使用している場合、コードの他の部分(Google Analytics など)がモバイル RUM が収集するクラッシュレポート情報を使用できるようにすることがあります。サマリークラッシュ情報を渡すことができるようにするには、クラッシュレポートのランタイムコールバックを設定します。Android エージェントがクラッシュを検出および報告した場合にコールバックを取得するには、コードに次のインターフェイスを実装する必要があります。
public interface CrashReportCallback {
void onCrashesReported(Collection<CrashReportSummary> summaries);
}
通常は 1 つしかない場合でも、複数のクラッシュが発生する可能性があるため、個々のコールバックの代わりに収集して送信します。
メソッド onCrashesReported
は、クラッシュ発生後のエージェントの次の初期化中に呼び出されます。
このコールバックはアプリケーションの UI スレッドで呼び出されるため、作業は別の作業スレッドで実行する必要があります。
各 CrashReportSummary
に次のプロパティがあります。
public class CrashReportSummary {
public final String crashId;
public final String exceptionClass;
public final String exceptionMessage;
}
Google Analytics などの別の分析ツールに情報を送信する場合は、3 つのプロパティすべてを含めることをお勧めします。exceptionClass
および exceptionMessage
は、クラッシュを迅速に識別するのに役立ちますが、詳細な情報を得るためには、crashId
を使用して AppDynamics コントローラ UI でクラッシュを調べることができます。
たとえば、クラッシュ情報を Android のロガーに出力するには、次の CrashReportCallback
クラスを実装できます。
public static class MyCrashReportCallback implements CrashReportCallback {
@Override
public void onCrashesReported(Collection<CrashReportSummary> summaries) {
for (CrashReportSummary crash : summaries) {
Log.e("MyApp", "Crash Detected: " + crash.exceptionClass + " : " + crash.exceptionMessage + " (" + crash.crashId + ")");
}
}
}
AgentConfiguration オブジェクトを使用してコールバックを設定します。
final AgentConfiguration config = AgentConfiguration.builder()
.withAppKey(appKey)
.withContext(context)
.withCrashCallback(new MyCrashReportCallback())
.build();
コールバックは、メインスレッドで、クラッシュ後の次の初期化中に呼び出されます。詳しくは、Android SDK API の最新の Java ドキュメントを参照してください。
エラーと例外のレポート
Instrumentation
クラスの reportError
メソッドを使用して例外を報告できます。報告された例外は、セッション詳細に表示されます。
また、問題に対して次の重大度レベルの 1 つを設定することもできます。重大度レベルを使用すると、[Code Issues Dashboard] または [Code Issues Analyze] でエラーをフィルタリングできます。
ErrorSeverityLevel.INFO
ErrorSeverityLevel.WARNING
ErrorSeverityLevel.CRITICAL
次の例では、API を使用して考えられる例外を報告し、ファイルへの書き込み時に重大度レベルをErrorSeverityLevel.CRITICAL
(クリティカル)に設定します。
private void writeToFile(String filePath, String data) {
try {
OutputStream outputStream = new FileOutputStream(filePath);
Writer outputStreamWriter = new OutputStreamWriter(outputStream);
outputStreamWriter.write(data);
outputStreamWriter.close();
} catch (IOException e) {
Log.e("Exception", "File write failed: " + e.toString());
Instrumentation.reportError(e, ErrorSeverityLevel.CRITICAL);
}
}
ハイブリッドサポートの設定
デフォルトでは、Android エージェントは Android WebViews をインストゥルメント化します。Android エージェントは、JavaScript エージェントを WebViews に注入することでこれを実行できます。この機能の概要と説明については、「ハイブリッド アプリケーションのサポート」を参照してください。
ハイブリッドサポートのランタイム設定
次のコード例では、JavaScript エージェントのインジェクションを無効にしています。クライアントがこのフラグに false
を受け取ると、JavaScript エージェントは無効になります。そのため、WebViews はインストゥルメント化されず、Ajax 要求は監視されません。
Instrumentation.start(
AgentConfiguration.builder()
.withAppKey(getString(R.string.app_key))
.withContext(applicationContext)
.withJSAgentInjectionEnabled(false)
.build())
インジェクションは、新しい WKWebView の作成時に発生します。このため、このフラグが false
に設定されているときに WKWebView が作成された場合、その特定の WKWebView は、 その後フラグが true
に設定されてもインストゥルメント化されません。
Ajax コールの収集およびレポートは、デフォルトでは無効になっています。Ajax コールのインジェクションおよび収集とレポートを有効にするには、次に示すようにインストゥルメンテーションの構成でメソッド jsAgentEnabled
に true
を渡します。
Instrumentation.start(
AgentConfiguration.builder()
.withAppKey(getString(R.string.app_key))
.withContext(applicationContext)
.withJSAgentAjaxEnabled(true)
.build())
プログラムによるセッションの制御
デフォルトでは、ユーザが非アクティブになってからモバイルセッションが終了します。たとえば、ユーザがアプリケーションを開くと、セッションは開始され、ユーザが設定した期間にアプリケーションを使用しなくなった後にのみ終了します。ユーザがアプリケーションの再使用を開始すると、新しいセッションが開始されます。
ただし、セッションの期間を定義するのに非アクティブな期間を設定する代わりに、次の API を使用して、セッションの開始と終了をプログラムで制御できます。
void startNextSession()
インストゥルメンテーション クラスからメソッド startNextSession
を呼び出すと、現在のセッションが終了し、新しいセッションが開始されます。API を使用すると、セッションを定義してフレーム化することができます。これにより、ビジネス目標と予想されるユーザフローをより厳密に合わせることができます。たとえば、API を使用して、製品の購入を追跡するセッションを定義したり、新しいユーザを登録したりすることができます。
この API を過剰に使用すると、セッションが調整されます(過剰使用は Android エージェントごとに 1 分あたり 10 コールを超えた場合になりますが、変更される可能性があります)。API を使用しない場合、セッションは、ユーザが非アクティブになった後、デフォルトの終了にフォールバックします。
プログラムによって制御されるセッションの例
次のコード例では、現在のセッションが終了し、チェックアウトが行われると新しいセッションが開始されます。
public void checkoutCart(){
if (currentCartItems!=null && currentCartItems.size()>0){
CheckoutTask checkoutReq = new CheckoutTask();
checkoutReq.execute(getEndpoint() + "cart/co");
currentCartItemsMap.clear();
convertItemsMaptoList();
Instrumentation.startNextSession();
} else {
displayToast("There are no items in the cart");
}
}
セッションフレームの開始と終了
SessionFrame
API を使用して、セッションアクティビティに表示されるセッションフレームを作成できます。セッションフレームは、セッション中にユーザが実行している内容のコンテキストを提供します。この API を使用すると、ユーザ画面の命名方法が向上し、ビジネスコンテキスト内のユーザフローを記録できます。
使用例
次に、SessionFrame
API の一般的なユースケースを示します。
- 1 つのアクティビティが複数の機能を実行し、個々の機能をより詳細に追跡します。
- ユーザフローは、複数のアクティビティまたはユーザのインタラクションに及びます。たとえば、API を使用してセッションフレーム「Login」、「Product Selection」、および「Purchase」を作成して、ユーザが購入のためにフローを記録することができます。
- ユーザの操作に基づいて動的情報をキャプチャし、オーダー ID などのセッションフレームに名前を付けることができます。
SessionFrame API
次の表に、セッションフレームで使用できる 3 つのメソッドを示します。
クラス | メソッド | [説明(Description)] |
---|---|---|
Instrumentation |
JAVA
| セッションフレームを開始して名前を付けるには、これを使用します。 セッションフレームをネーミングすると、のフレームを簡単に識別して追跡できます。Sessions Dialog. |
SessionFrame |
JAVA
| セッションフレームを開始して名前を付けるには、これを使用します。 セッションフレームをネーミングすると、のフレームを簡単に識別して追跡できます。Sessions Dialog. |
SessionFrame |
JAVA
| セッションフレームを終了します。startSessionFrame から返された SessionFrame オブジェクトからこのメソッドを呼び出すことができます。 |
セッションフレームの例
次の例では、ShoppingCartActivity
クラスが SessionFrame
API を使用し、チェックアウトプロセス中にユーザーアクティビティを追跡しています。
public class ShoppingCartActivity extends Activity {
SessionFrame checkoutSessionFrame;
public void onCheckoutCartButtonClicked() {
// The user starts the checkout by clicking the checkout button.
// This may be after they have updated the quantities of items in the cart, etc.
checkoutSessionFrame = Instrumentation.startSessionFrame("Checkout");
}
public void onConfirmOrderButtonClicked() {
// Once they have confirmed payment info and shipping information, and they
// are clicking the "Confirm" button to start the backend process of checking out,
// we may know more information about the order itself, such as an order ID.
checkoutSessionFrame.updateName("Checkout: Order ID " + orderId);
}
public void onProcessOrderCompleted() {
// Once the order is processed, the user is done "checking out", so we end the session frame.
checkoutSessionFrame.end();
checkoutSessionFrame = null;
}
public void onCheckoutCanceled() {
// If the user cancels or returns to the cart, you'll want to end the session frame also, or else it will be
// left open and appear to have never ended.
checkoutSessionFrame.end();
checkoutSessionFrame = null;
}
}
カスタム HTTP ライブラリの使用
基盤となる実装がサポートされているいずれかのネットワークライブラリによって処理されると、Android エージェントは自動的にネットワーク要求を検出します。Android エージェントがカスタムライブラリからの要求を検出するようにするには、HttpRequestTracker
インターフェイスを使用してアプリケーションに手動で要求トラッキングコードを追加します。
サポート対象のネットワークライブラリ
以下のライブラリは、Android ネットワーク要求の大部分をカバーしています。ただし、モバイルアプリケーションでは、カスタム HTTP ライブラリが使用される場合があります。
HttpURLConnection
HttpsURLConnection
HttpClient
クラスOkHttp
OkHttp3
ch.boye.httpclientandroidlib
サーバ側の処理との相関を許可するようにヘッダーを設定するには、ServerCorrelationHeaders
クラスを使用します。
リクエストトラッキングの追加
要求追跡を手動で追加するには、HttpRequestTracker
オブジェクトを使用し、要求の開始時と終了時にエージェントに通知して、エージェントに応答のフィールドを報告します。
要求のトラッキング
HTTP 要求の追跡を開始するには、次のインターフェイスのインスタンスを使用します。
このインターフェイスを使用する前に、Instrumentation.
start
メソッドを使用してエージェントを初期化する必要があります。
public interface HttpRequestTracker {
public Exception getException();
public HttpRequestTracker withException(Exception e);
public String getError();
public HttpRequestTracker withError(String error);
public int getResponseCode();
public HttpRequestTracker withResponseCode(int responseCode);
public Map<String, List<String>> getResponseHeaderFields();
public HttpRequestTracker withResponseHeaderFields(Map<String, List<String>> responseHeaderFields);
/
*
*
* Stops tracking an HTTP request.
*
* Immediately after receiving a response or an error, set the appropriate fields and call this method to
* report the outcome of the HTTP request. You should not continue to use this object after calling this
* method -- if you need to track another request, obtain a new instance.
*/
public void reportDone();
}
例:
次のようなリクエストスニペットがあるとします。
public byte[] sendRequest(URL url) throws HttpException {
try {
// implementation omitted
return responseBody;
} catch (UnderlyingException e) {
throw new HttpException(e);
}
}
トラッカーを追加すると、次のようになります。
public byte[] sendRequest(URL url) throws HttpException {
HttpRequestTracker tracker = Instrumentation.beginHttpRequest(url);
try {
// implementation omitted
tracker.withResponseCode(theResponseCode)
.withResponseHeaderFields(theResponseHeaderFields)
.reportDone();
return responseBody;
} catch (UnderlyingException e) {
tracker.withException(e)
.reportDone();
throw new HttpException(e);
}
}
サーバー側の相関を有効にする
要求とサーバ側の処理の相関を有効にするには、サーバ側のエージェントが検出できる発信要求に特定のヘッダーを追加します。
これは、標準 HTTP ライブラリに対して自動的に実行されます。
public class ServerCorreleationHeaders {
public static Map<String, List<String>> generate();
}
次の作業が必要です。
- バックエンドにリクエストを送信する前に、
generate
メソッドを呼び出し、生成されたヘッダーを設定します。 withResponseHeaderFields
フィールドのデータを使用して、応答ヘッダーを報告します。
要求/応答のコンテンツ長をオーバーライドする
通常は、HttpRequestTracker.withRequestHeaderFields()
と HttpRequestTracker.withResponseHeaderFields()
を使用してヘッダーを渡すことで、ネットワーク要求と応答のコンテンツ長を取得できます。
何らかの理由でこれがカスタム HTTP トラッキングに対して機能しない場合(たとえば、ネットワークライブラリが送信されるまでこれらのフィールドにデータを入力しない場合)、HttpRequestTracker.withRequestContentLength(Long length)
および HttpRequestTracker.withResponseContentLength(Long length)
を使用して要求と応答のコンテンツの長さを報告できます。
たとえば、コンテンツのバイト配列を持つ要求を追跡するとします。次に示すように、バイト配列のサイズを渡すことで、要求のコンテンツ長を報告できます。
byte[] requestContent;
HttpRequestTracker tracker;
tracker.withRequestContentLength(requestContent.size());
エージェント設定のカスタマイズ
エージェント自体の動作をカスタマイズするには、AgentConfiguration
オブジェクトを Instrumentation.start
メソッドに渡します。AgentConfiguration
オブジェクトを使用すると、次の操作を実行できます。
- オンプレミス EUM サーバをポイントする
- ロギングを有効にする
- アプリケーション名をカスタム設定する。これは、基本的に異なるパッケージ名を持つ同じアプリケーションバイナリを異なる地理的領域に展開する場合に便利です。これにより、すべてのデータが同じ名前で処理されるようになります。
- ネットワーク要求に使用されていないアプリケーション内部の HTTP 要求を無視する
- カスタム HTTP ライブラリを使用してビーコンを送信するようにエージェントを設定する
構文は次のようになります。
Instrumentation.start(AgentConfiguration.builder()
.withAppKey("<EUM_APP_KEY>")
.withContext(getApplicationContext())
.withCollectorURL(collectorURL
*) // The URL of the EUM Server(on-prem)
.withCompileTimeInstrumentationCheck(true) // Set to false if you are using features of the SDK only, like custom HTTP support, but not to instrument your app.
.withLoggingEnabled(true)//set default INFO logging. Tagged "AppDynamics".
.withApplicationName(applicationName)//set a custom app name
.withExcludedUrlPatterns(excludedUrlPatterns) // Set excluded url regex patterns for http tracking
.withCollectorChannelFactory(collectorChannelFactory()) // The custom HTTP implementation to use
.build());
* EUM サーバーのデフォルト URL は https://mobile.eum-appdynamics.com:443 です。EUM サーバーの URL のリストについては、「外部アクセスロケーション」を参照してください。
詳しくは、最新の Java ドキュメントを参照してください。
カスタム HTTP ライブラリを使用するようにエージェントを設定する
Android エージェントは、ビーコンを配信するために HTTP を使用します。この目的で、エージェントがカスタム HTTP ライブラリを使用する構成を行うには、次の手順を実行します。
次の抽象クラスを拡張するクラスを実装します。
public abstract class CollectorChannel { private URL url; private int connectTimeout; private int readTimeout; private Map<String, List<String>> requestProperties = new HashMap<String, List<String>>(); private String requestMethod; public void setURL(URL url) { this.url = url; } public URL getURL() { return url; } public void setConnectTimeout(int connectTimeout) { this.connectTimeout = connectTimeout; } public int getConnectTimeout() { return connectTimeout; } public void setReadTimeout(int readTimeout) { this.readTimeout = readTimeout; } public int getReadTimeout() { return readTimeout; } public void addRequestProperty(String property, String value) { if (!requestProperties.containsKey(property)) { requestProperties.put(property, new ArrayList<String>()); } requestProperties.get(property).add(value); } public Map<String, List<String>> getRequestProperties() { return Collections.unmodifiableMap(requestProperties); } public void setRequestMethod(String requestMethod) { this.requestMethod = requestMethod; } public String getRequestMethod() { return requestMethod; } public abstract OutputStream getOutputStream() throws IOException; public abstract InputStream getInputStream() throws IOException; public abstract int getResponseCode() throws IOException; public abstract Map<String,List<String>> getHeaderFields() throws IOException; }
CODEこのインターフェイスは、少しだけ
HttpURLConnection
に基づいています。CollectorChannelFactory
インターフェイスのバージョンを実装します。これは次のようになります。public interface CollectorChannelFactory { /** * Returns a new instance of CollectorChannel. * * If you want to supply a custom CollectorChannel, implement this interface, and return * an instance of your concrete implementation of CollectorChannel from this method. */ public CollectorChannel newCollectorChannel(); }
JAVAnewCollectorChannel
の実装は、CollectorChannel
の実装の新しいインスタンスを返す必要があります。CollectorChannelFactory
をAgentConfiguration
オブジェクトに渡します。
ユーザーインタラクションの把握
Android エージェントを有効にすると、特定のユーザーインタラクションを追跡できます。ユーザインタラクションがキャプチャされると、UI イベントごとにセッションをソートし、セッション ウォーターフォールのタイムラインで UI イベントを表示することができます。
ユーザが次のいずれかまたはすべてを実行するときにキャプチャできます。
- ボタンのクリック
- テキストフィールドの選択
- リスト項目のクリック
セキュリティおよびプライバシー上の懸念点
インタラクション キャプチャ モードは、セキュリティとプライバシー上の理由でデフォルトでは無効になっています。これは、ユーザインタラクションに機密情報が含まれている可能性があるためです。さらに、UI インタラクションとスクリーンショットのキャプチャの両方を有効にすると、このような潜在的なセキュリティとプライバシー上の問題が複合化する場合があります。
ユーザ インタラクション キャプチャ モードの有効化
ユーザインタラクションのキャプチャモードを有効にするには、AgentConfiguration
オブジェクトからメソッド withInteractionCaptureMode()
にキャプチャモードを渡します。次のインストゥルメンテーション コードの例では、サポート対象のすべてのタイプのユーザインタラクションをキャプチャするように Android エージェントを設定します。
Instrumentation.start(AgentConfiguration.builder()
.withAppKey("<EUM_APP_KEY>")
.withContext(getApplicationContext())
.withInteractionCaptureMode(InteractionCaptureMode.All)
.build());
また、1 つのタイプのユーザインタラクションのみをキャプチャするように Android エージェントを設定することもできます。
Instrumentation.start(AgentConfiguration.builder()
.withAppKey("<EUM_APP_KEY>")
.withContext(getApplicationContext())
.withInteractionCaptureMode(InteractionCaptureMode.ButtonPressed)
.build());
スクリーンショットの設定および作成
モバイルスクリーンショットは、Android エージェントでデフォルトで有効になっています。スクリーンショットを自動的に表示するようにコントローラ UI を設定するか、または次に示すように Android SDK を使用して手動でスクリーンショットを取得することができます。
Instrumentation.takeScreenshot();
たとえば、UI 要素をロードして顧客に表示される方法を表示した後に、スクリーンショットを取得することができます。
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_spinner_with_toast);
spinner = (Spinner) findViewById(R.id.spnOptions);
btnSpinnerVal = (Button) findViewById(R.id.btnSpinnerValue);
loadSpinner();
Instrumentation.takeScreenshot();
}
スクリーンショットの無効化
コントローラ UI からまたは Android SDK を使用すると、スクリーンショットを無効にすることができます。Android SDK を使用してスクリーンショットを無効にするには、次に示すように AgentConfiguration
クラスからメソッド withScreenshotsEnabled(false)
を使用します。
Instrumentation.start(AgentConfiguration.builder()
.withAppKey("<EUM_APP_KEY>")
.withContext(getApplicationContext())
.withScreenshotsEnabled(false)
.build());
}
スクリーンショットのブロック/ブロック解除
Android SDK を使用すると、コードブロックの実行中にスクリーンショットが実行されないようにブロックすることもできます。これにより、スクリーンショットのブロックを解除するまで、スクリーンショットの作成が一時的にブロックされます。これにより、ユーザがログインやアカウント画面などで個人データを入力する状況でのスクリーンショットの作成を停止できます。
Instrumentation.blockScreenshots()
と Instrumentation.unblockScreenshots()
のメソッドを使用して、スクリーンショットをブロックおよびブロック解除します。スクリーンショットが AgentConfiguration.Builder.withScreenshotsEnabled(true)
またはコントローラの UI を使用して無効になっている場合、これらのメソッドは効果がありません。スクリーンショットがブロックされているかどうかを確認するために Instrumentation.screenshotsBlocked()
を呼び出すことができます。
次の例は、ユーザ情報を表示するときに API を使用してスクリーンショットをブロックおよびブロック解除する方法を示しています。
public class UserAccountActivity extends Activity {
...
public void displayCustomerAccount() {
// Check to see if screenshots are blocked
if (! Instrumentation.screenshotsBlocked()) {
// If screenshots aren't blocked, block them before showing customer details
Instrumentation.blockScreenshots();
}
// Code to display customer details
displayAccount(this.user);
// After you're done, unblock screenshots
Instrumentation.unblockScreenshots();
}
...
}
ネットワークリクエストの URL の変換
アプリケーションがネットワークリクエストを行う場合、機密情報が含まれている URL を EUM サーバーに報告したくない場合があります。その場合は、ネットワークリクエスト URL を報告する前に変換するか、すべて無視します。
インポートを行うには以下を実行します。
- 特定の URL を変更または無視するネットワーク リクエスト コールバックを実装します。
- 初期化コードにネットワーク リクエスト コールバックを登録します。
ネットワーク要求のコールバックの実装
特定の URL を変更または無視するコールバックは、次のインターフェイスの実装です。メソッド onNetworkRequest
は同期されているため、関数からすばやく戻ることをお勧めします。
public interface com.appdynamics.eumagent.runtime.NetworkRequestCallback {
boolean onNetworkRequest(HttpRequestTracker httpRequestTracker);
}
URL の変換
通常 、onNetworkRequest
メソッドは次の手順に従って URL を変換する必要があります。
- 正規表現やパターンマッチングなどの手法を使用して、特定の URL を識別します。
HttpRequestTracker
オブジェクトのurl
プロパティを変更します。url
プロパティに有効な URL を割り当てます。(HttpRequestTracker
オブジェクトのその他のプロパティの変更は無視されます。)true
を返します。
すべてのネットワークリクエストの URL を変換することもできるので、最初の手順はオプションです。
private static class myNetworkRequestCallback implements com.appdynamics.eumagent.runtime.NetworkRequestCallback {
@Override
public boolean onNetworkRequest(HttpRequestTracker httpRequestTracker) {
URL urlMask = new URL("http://networkrequest-mask.com");
httpRequestTracker.withURL(urlMask);
return true;
}
}
ただし、一般的には次の例に示すように、機密情報が含まれている URL を特定して変換する必要があります。
private static class myNetworkRequestCallback implements com.appdynamics.eumagent.runtime.NetworkRequestCallback {
@Override
public boolean onNetworkRequest(HttpRequestTracker httpRequestTracker) {
String urlString = httpRequestTracker.getURL().toString();
try {
URL url = new URL("http://customer-account.com");
if (urlString.contains("accountInfo")) {
// Change the URL for calls to Facebook
httpRequestTracker.withURL(url);
return true;
}
} catch (MalformedURLException e) {
return false;
}
return true;
}
}
URL の無視
onNetworkRequest
メソッドが false を返した場合、ビーコンはドロップされます。ビーコンを無視する一般的なプロセスは次のとおりです。
正規表現やパターンマッチングなどの手法を使用して、特定の URL を識別します。
false
を返します。
理論的には、onNetworkRequest
の次の実装によってすべてのネットワーク要求を無視することができます。
private static class myNetworkRequestCallback implements com.appdynamics.eumagent.runtime.NetworkRequestCallback {
@Override
public boolean onNetworkRequest(HttpRequestTracker httpRequestTracker) {
return false;
}
}
一般的には、この例で暗示されているように、モニターして false
を返さないネットワーク要求を特定し、ネットワーク要求を無視します。
private static class myNetworkRequestCallback implements com.appdynamics.eumagent.runtime.NetworkRequestCallback {
@Override
public boolean onNetworkRequest(HttpRequestTracker httpRequestTracker) {
String urlString = httpRequestTracker.getURL().toString();
try {
URL url = new URL("http://socialnetworksite.com");
if (urlString.contains("avatar")) {
// Ignore calls for avatars
return false;
}
} catch (MalformedURLException e) {
return false;
}
return true;
}
}
ネットワーク要求のコールバックの登録
コールバックを実装した後、次に示すように初期化コードに登録します。Android エージェントがネットワーク要求ビーコンを作成する準備ができたら、最初に HttpRequestTracker
オブジェクトを使用してコールバックを呼び出します。
Instrumentation.start(AgentConfiguration.builder()
.withContext(getApplicationContext())
.withAppKey("<EUM_APP_KEY>")
.withNetworkRequestCallback(new myNetworkRequestCallback())
.build());
ロギングの有効化とロギングレベルの設定
ロギングを有効にし、ロギングレベルを設定するには、AgentConfiguration
クラスのメソッド withLoggingLevel
を使用します。ロギングは、次のいずれかのレベルに設定できます。
LOGGING_LEVEL_NONE
LOGGING_LEVEL_INFO
LOGGING_LEVEL_VERBOSE
冗長ロギングはトラブルシューティングにのみ使用し、実稼働では無効にしてください。
Example:
AgentConfiguration config = AgentConfiguration.builder()
config.withAppKey(appKey)
config.withContext(context)
.withLoggingLevel(Instrumentation.LOGGING_LEVEL_VERBOSE)
.build();
Instrumentation.start(config);
Android SDK のドキュメント
SDK API の完全なマニュアルについては、次に示す最新の Java ドキュメントまたは以前のバージョンを参照してください。