Local blog for Japanese speaking developers

Google I/O アプリにおけるカンファレンスのデータの同期と GCM

2014年9月12日金曜日


カンファレンス データの効率的なダウンロード

Google I/O ともなると、カンファレンス データはかなり巨大です。セッション、部屋、講演者、地図の位置情報、ソーシャル ハッシュタグ、ビデオ ライブラリの項目など、すべての情報が入っています。すべてのデータを繰り返しダウンロードするのはバッテリー使用料や通信容量の観点から見て無駄です。そこで我々は、どうすればダウンロードしたり処理したりするデータの量を最小化できるか検討しました。

検討の結果、データをいくつかの JSON ファイルに分割し、それらをメインの JSON ファイル(「マニフェスト ファイル」)から参照するようにしました。マニフェスト ファイルの URL が唯一アプリの中に埋め込まれている URL です(Config.java の MANIFEST_URL 定数)。JSON ファイルを置いておくための場所として、今回の I/O アプリでは Google Cloud Storage を利用しましたが、HTTP でアクセスできる同様のホスティング サービスであれば同じように利用できます。

同期プロセスの最初の部分でマニフェスト ファイルを見に行きます。前回ダウンロードしたときから変更があるかチェックし、ある場合のみ処理します。このロジックを実装しているのは RemoteConferenceDataFetcher クラスの fetchConfenceDataIfNewer メソッドです。

public class RemoteConferenceDataFetcher {
    // (...)
    public String[] fetchConferenceDataIfNewer(String refTimestamp) throws IOException {
        BasicHttpClient httpClient = new BasicHttpClient();
        httpClient.setRequestLogger(mQuietLogger);
        // (...)

        // データが refTimestamp より新しいときのみダウンロード
        if (!TextUtils.isEmpty(refTimestamp) && TimeUtils
            .isValidFormatForIfModifiedSinceHeader(refTimestamp)) {
                httpClient.addHeader("If-Modified-Since", refTimestamp);
            }
        }

        HttpResponse response = httpClient.get(mManifestUrl, null);
        int status = response.getStatus();
        if (status == HttpURLConnection.HTTP_OK) {
            // データに変更があったので処理する
        } else if (status == HttpURLConnection.HTTP_NOT_MODIFIED) {
            // サーバーのデータに変更はないので何もしない
            return null;
        } else {
            // (エラー処理)
        }
    }
    // (...)
}

HTTP リクエストに If-Modified-Since ヘッダーがついていることに注意してください。もしマニフェストに前回から変更がない場合、レスポンス コードとして HTTP_OK ではなく HTTP_NOT_MODIFIED が返ってくるので、後はダウンロードもパースも必要ありません。つまり、マニフェスト ファイルに変更がない限り同期プロセスは実に経済的です。HTTP リクエストが 1 回で、レスポンスもとても短いものです。

マニフェスト ファイルのフォーマットは単純明快です。カンファレンス データを含んだ JSON ファイルへの参照が並んでいます。

{
  "format": "iosched-json-v1",
  "data_files": [
    "past_io_videolibrary_v5.json",
    "experts_v11.json",
    "hashtags_v8.json",
    "blocks_v10.json",
    "map_v11.json",
    "keynote_v10.json",
    "partners_v2.json",
    "session_data_v2.681.json"
  ]
}

同期プロセスは次にデータ ファイルを順に処理していきます。この部分も経済的に実装してあります。すでにデータ ファイルのキャッシュがある場合は処理を省略してローカルのキャッシュを使います。この部分は processManifest メソッドで行っています。

JSON ファイルをそれぞれパースして情報をメモリに乗せ、最後にまとめて ContentProvider に書き込みます。

ContentProvideOperation の効率的な実行

カンファレンス データの同期は効率的でなければなりませんが、それはダウンロードするデータの容量だけでなく、データベースに対して実行する処理の量についても同様です。出来る限り経済的に行うために、この部分も最適化されています。データベース全体を新しいデータで上書きするのではなく、既存のローカル データを活かして変更のあるデータだけ更新するようにするのです。

これは 3 階層目の重要な最適化です。これを実現するためには、アプリがメモリ上の情報と ContentProvider 内の情報を比較して、更新の必要があるかどうか判別できなければなりません。メモリーとデータベースのフィールドを 1 つずつ見ていってもいいのですが、手間ですし、すべてのフィールドを見ていくのでパフォーマンスが劣ります。その代わりに、今回は各エンティティーに「インポート ハッシュコード」というフィールドを付け加えることにしました。インポート ハッシュコードはデータから生成される弱いハッシュです。例えば、講演者のデータに対するインポート ハッシュは以下のように求められます。

public class Speaker {
    public String id;
    public String publicPlusId;
    public String bio;
    public String name;
    public String company;
    public String plusoneUrl;
    public String thumbnailUrl;

    public String getImportHashcode() {
        StringBuilder sb = new StringBuilder();
        sb.append("id").append(id == null ? "" : id)
                .append("publicPlusId")
                .append(publicPlusId == null ? "" : publicPlusId)
                .append("bio")
                .append(bio == null ? "" : bio)
                .append("name")
                .append(name == null ? "" : name)
                .append("company")
                .append(company== null ? "" : company)
                .append("plusoneUrl")
                .append(plusoneUrl == null ? "" : plusoneUrl)
                .append("thumbnailUrl")
                .append(thumbnailUrl == null ? "" : thumbnailUrl);
        String result = sb.toString();
        return String.format(Locale.US, "%08x%08x", 
            result.hashCode(), result.length());
    }
}

データベースでエンティティーが更新されるたびにそのインポート ハッシュがデータベースのカラムに保存されます。後から更新されている可能性のあるバージョンがあるときは、そのインポート ハッシュを計算してデータベースに保存されているバージョンのインポート ハッシュと比較するだけでいいのです。値が異なる場合は、データベースのエンティティーを更新する ContentProviderOperation を実行します。値が同一の場合、そのエンティティーの更新は必要ないので飛ばします。この部分の処理は SpeakersHandler クラスの makeContentProviderOperations メソッドなどで見ることができます。

public class SpeakersHandler extends JSONHandler {
    private HashMap mSpeakers = new HashMap();
    // (...)
    @Override
    public void makeContentProviderOperations(ArrayList list) {
        // (...)
        int updatedSpeakers = 0;
        for (Speaker speaker : mSpeakers.values()) {
            String hashCode = speaker.getImportHashcode();
            speakersToKeep.add(speaker.id);

            if (!isIncrementalUpdate || !speakerHashcodes.containsKey(speaker.id) ||
                    !speakerHashcodes.get(speaker.id).equals(hashCode)) {
         // スピーカーが更新されているので、ContentProviderOperation を発行する
                ++updatedSpeakers;
                boolean isNew = !isIncrementalUpdate || 
                 !speakerHashcodes.containsKey(speaker.id);
                buildSpeaker(isNew, speaker, list);
            }
        }

 // 古いスピーカーを削除
        int deletedSpeakers = 0;
        if (isIncrementalUpdate) {
            for (String speakerId : speakerHashcodes.keySet()) {
                if (!speakersToKeep.contains(speakerId)) {
                    buildDeleteOperation(speakerId, list);
                    ++deletedSpeakers;
                }
            }
        }
    }

buildSpeaker() と buildDeleteOperation() というメソッド(ここでは中身を省略しています)はただ単に ContentProviderOperation を組み立てるだけです。ContentProvider にスピーカーの情報を挿入、更新、削除する ContentProviderOperation です。ここで注目していただきたいのは、ContentProviderOperation でスピーカー情報を更新するのはインポート ハッシュコードが変わったときだけだということです。また、以前は存在していたのに今はデータ上で参照されていないスピーカー情報はもう必要ないので、削除を行っています。

同期の信頼性を高める

I/O アプリの SyncAdapter はカンファレンス データの同期、ユーザーのスケジュールの同期、ユーザーからのフィードバックの同期など、いくつかのタスクを担っています。ネットワークの状態によっては、そういったタスクが途中で失敗することもあり得ます。それでも、あるタスクが失敗したからといって他のタスクを巻き添えにするのは好ましくありません。そのため、同期のプロセスはそれぞれ独立したタスクで構成されています。つまり、それぞれが try/catch ブロックで保護されています。これは SyncHelper クラスの performSync() メソッドでご覧いただけます。

// リモート同期を構成するタスク。
// 1 つづつ実行される(どれかが失敗しても他に影響を与えない)。
final int OP_REMOTE_SYNC = 0;
final int OP_USER_SCHEDULE_SYNC = 1;
final int OP_USER_FEEDBACK_SYNC = 2;

int[] opsToPerform = userDataOnly ?
        new int[] { OP_USER_SCHEDULE_SYNC } :
        new int[] { OP_REMOTE_SYNC, OP_USER_SCHEDULE_SYNC, OP_USER_FEEDBACK_SYNC};

for (int op : opsToPerform) {
    try {
        switch (op) {
            case OP_REMOTE_SYNC:
                dataChanged |= doRemoteSync();
                break;
            case OP_USER_SCHEDULE_SYNC:
                dataChanged |= doUserScheduleSync(account.name);
                break;
            case OP_USER_FEEDBACK_SYNC:
                doUserFeedbackSync();
                break;
        }
    } catch (AuthException ex) {
        // (... 認証エラーの後始末 ...)
    } catch (Throwable throwable) {
        // (... その他のエラーの後始末 ...)

        // 例外の発生をシステムに知らせる
        if (syncResult != null && syncResult.stats != null) {
            ++syncResult.stats.numIoExceptions;
        }
    }
}

同期プロセスの一部が失敗したときは syncResult.stats.numIoExceptions をインクリメントしてシステムに知らせます。こうしておけば、システムがあとで指数バックオフを利用しつつ同期を再試行します。

同期をいつ行うか。GCM の世界にようこそ。

カンファレンス データの更新を迅速に受け取ることができるかどうかは、ユーザーにとってとても重要です。特に Google I/O の最中(と、その前数日)はそうです。これを実現する方法として安易に思いつくのはアプリがサーバーをポーリングすることですが、当然のごとくそれでは通信帯域やバッテリーを多量に消費してしまいます。

より洗練された解決法として、我々は GCM (Google Cloud Messaging) を利用することにしました。サーバー側に新しいデータがあるときは、サーバーからすべての登録済みデバイスに GCM メッセージを送るのです。GCM メッセージを受け取ったデバイスは同期を開始して新しいカンファレンス データをダウンロードします。GCM メッセージを処理しているのは GCMIntentService クラスです。

public class GCMIntentService extends GCMBaseIntentService {

    private static final String TAG = makeLogTag("GCM");

    private static final Map MESSAGE_RECEIVERS;
    static {
        // 既知のメッセージと GCM メッセージの受信部
        Map  receivers = new HashMap();
        receivers.put("test", new TestCommand());
        receivers.put("announcement", new AnnouncementCommand());
        receivers.put("sync_schedule", new SyncCommand());
        receivers.put("sync_user", new SyncUserCommand());
        receivers.put("notification", new NotificationCommand());
        MESSAGE_RECEIVERS = Collections.unmodifiableMap(receivers);
    }

    // (...)

    @Override
    protected void onMessage(Context context, Intent intent) {
        String action = intent.getStringExtra("action");
        String extraData = intent.getStringExtra("extraData");
        LOGD(TAG, "Got GCM message, action=" + action + ", extraData=" + extraData);

        if (action == null) {
            LOGE(TAG, "Message received without command action");
            return;
        }

        action = action.toLowerCase();
        GCMCommand command = MESSAGE_RECEIVERS.get(action);
        if (command == null) {
            LOGE(TAG, "Unknown command received: " + action);
        } else {
            command.execute(this, action, extraData);
        }

    }
    // (...)
}

ここでは onMessage() メソッドが GCM メッセージの "action" フィールドに従ってメッセージを適切なハンドラーに引き渡しています。action フィールドが "sync_schedule" なら、メッセージは SyncCommand クラスのインスタンスに引き渡され、同期が開始します。ちなみに、SyncCommand クラスに対する GCM メッセージには jitter というパラメーターを指定することができます。同期は即座に行われるのではなく、jitter で指定された猶予期間までのランダムなタイミングで実行されます。これにより、全てのクライアントが一斉にリクエストを投げてサーバー側が大量のリクエストにさらされることを防いでいます。

ユーザー データの同期

I/O アプリではユーザーが興味のあるセッションを選択して自分個人のスケジュールを作ることができるようになっています。これは「私のスケジュール」画面で見ることができます。

このデータはユーザーが利用している複数の Android 端末間で同期され、さらに I/O のウェブサイトとも同期される必要があります。つまり、ユーザーの Google アカウントを使ってクラウド上にデータを保存する必要があります。今回は Google Drive AppData フォルダーを利用することにしました。

ユーザー データは SyncHelper クラスの doUserScheduleSync() メソッドで Google Drive に同期されます。ソース コードを見ていただくとわかりますが、このメソッドでは Google Drive HTTP API を使って Google Drive AppData フォルダーにアクセスし、ユーザーが登録したセッションのデータをクラウド上と端末内とですり合わせた上で、必要に応じてクラウド上のデータにローカルでの変更を反映しています。

つまり、ユーザーが Android 端末であるセッションを登録し、I/O のウェブサイト上で別のセッションを登録した場合、Android 端末と I/O ウェブサイトともに、両方のセッションが登録されている状態に同期されます。

これに加えて、ユーザーが I/O のウェブサイトでセッションを登録したり解除したりした場合にデータがすべての Android 端末に同期される必要があります。逆方向も同様です。このため、ユーザーがスケジュールに変更を行うたび、I/O ウェブサイトから GCM サーバーに通知を送ります。GCM サーバーはユーザーが利用しているすべてのデバイスに GCM メッセージを送信し、同期が開始されます。同じメカニズムが複数の端末の間でも働きます。つまり、あるデバイスでデータが更新されれば、他のすべてのデバイスに GCM メッセージが送信されるのです。

まとめ

データを新鮮に保つことは多くの Android アプリで肝心な機能です。ネットワーク通信やデータベースへの書き込みを最小限にとどめつつデータを最新に保ち、Google Cloud Storage や Google Drive や Google Cloud Messaging を活用して、複数のプラットフォーム、複数の端末間でデータの同期を取るなど、I/O アプリの開発での我々の取り組みについてご紹介しました。
Share on Twitter Share on Facebook
  

ラベル


  • .app 1
  • .dev 1
  • #11WeeksOfAndroid 13
  • #11WeeksOfAndroid Android TV 1
  • #Android11 3
  • #DevFest16 1
  • #DevFest17 1
  • #DevFest18 1
  • #DevFest19 1
  • #DevFest20 1
  • #DevFest21 1
  • #DevFest22 1
  • #DevFest23 1
  • #hack4jp 3
  • 11 weeks of Android 2
  • A MESSAGE FROM OUR CEO 1
  • A/B Testing 1
  • A4A 4
  • Accelerator 6
  • Accessibility 1
  • accuracy 1
  • Actions on Google 16
  • Activation Atlas 1
  • address validation API 1
  • Addy Osmani 1
  • ADK 2
  • AdMob 32
  • Ads 73
  • Ads API 143
  • ads query language 2
  • ads scripts 2
  • ads search 1
  • advanced markers 1
  • Advanced Protection Program 3
  • AdWords API 25
  • adwords scripts 2
  • aerial view api 1
  • Agency 1
  • AI 22
  • AI Agent Summit 1
  • AIY 3
  • AIY Vision Kit 2
  • ALPN 1
  • AMP 120
  • AMP Cache 9
  • AMP Camp 2
  • AMP CSS 1
  • AMP Extension 1
  • AMP Fest 1
  • AMP for Email 4
  • AMP Optimizer 1
  • AMP Packager 1
  • AMP Playground 1
  • AMP Plugin 1
  • AMP SSR 1
  • AMP Story 4
  • AMP Toolbox 1
  • amp-bind 1
  • amp.dev 1
  • AMPHTML Ads 1
  • Analytics 9
  • Andorid 13
  • Android 403
  • Android 10 1
  • Android 11 20
  • Android 11 Compatibility 1
  • Android 11 final release 1
  • Android 11 meetups 1
  • Android 9 1
  • android api 1
  • Android App Bundle 1
  • Android App Development 23
  • Android Architecture 1
  • Android Architecture Components 1
  • Android Auto 1
  • Android Design Support Library 1
  • Android Developer 14
  • Android Developer Story 4
  • Android Developers 13
  • Android Enterprise 6
  • Android for cars 2
  • Android Go 1
  • Android Jetpack 6
  • Android N 18
  • Android O 14
  • Android Open Source Project 1
  • Android P 7
  • Android Pay 1
  • android privacy 1
  • Android Q 13
  • Android Ready SE Alliance 1
  • android security 6
  • Android Security Year in Review 1
  • Android StrongBox 1
  • Android Studio 47
  • Android Studio 4.1 1
  • android study jam 1
  • Android Support Library 6
  • Android Things 15
  • Android Tools 2
  • Android TV 11
  • Android Vitals 4
  • Android Wear 29
  • android11 6
  • androidmarket 3
  • androidstudio 1
  • AndroidX 6
  • Angular 2
  • Angular 2 2
  • AngularJS 2
  • Announcements 2
  • Anthos 2
  • antmicro 1
  • AoG 1
  • aosp 1
  • API 28
  • APIExpert 45
  • apk 2
  • APM 1
  • app 3
  • App Action 1
  • App Bundle 2
  • app check 1
  • app engine 24
  • App Indexing 7
  • App Invites 6
  • App Maker 2
  • App modernization 1
  • AppCompat 2
  • Apps Flutter eBay 1
  • Apps Script 12
  • AppSheet 1
  • aprilfool 4
  • AR 3
  • Architecture Components 7
  • ARCore 3
  • ArtTech 1
  • asset-based extensions 2
  • assets 1
  • Associate Android Developer Certificate 1
  • Attribution Reporting 1
  • Audio 7
  • Auth Code 1
  • Authentication 9
  • AuthSub 2
  • Autofill 5
  • AutoML 1
  • Autotrack 2
  • award 1
  • Awareness API 1
  • basemap 1
  • basic-card 1
  • Beacons 6
  • bento 2
  • BERT 1
  • Best Practices 1
  • beta 4
  • Better Ads Standards 3
  • BigQuery 10
  • Billing 1
  • Biometrics 1
  • BLE 4
  • Blink 1
  • Blockly 1
  • blogger 1
  • BodyPix 1
  • bootcamp 1
  • Brillo 1
  • Brotli 2
  • Budou 1
  • budoux 1
  • Buildbetterapps 2
  • Business and Leadership 1
  • C++ 1
  • Calendar 3
  • call ads 1
  • campaign 2
  • campaignsharedset 1
  • Campus 1
  • Canvas 1
  • Cardboard 4
  • Career 1
  • Case Studies 1
  • Case Study 3
  • CCPA 1
  • CDS 2020 3
  • CDS Recap 2020 3
  • Certificate 8
  • changestatus 1
  • chrome 261
  • chrome 98 1
  • Chrome Apps 1
  • Chrome Custom Tab 4
  • Chrome Dev Summit 5
  • chrome extension 14
  • Chrome for Android 2
  • Chrome for iOS 3
  • Chrome OS 10
  • Chrome Root Program 1
  • Chrome Root Store 1
  • Chrome Tech Talk Night 4
  • chrome103 1
  • chrome104 1
  • chrome108 1
  • chrome90 1
  • Chromebook 5
  • Chromecast 7
  • chromewebstore 9
  • Chromium 20
  • CLI 1
  • ClientLogin 3
  • Closure Compiler 1
  • Cloud 29
  • Cloud AI Platform 2
  • Cloud Firestore 5
  • Cloud Functions 9
  • Cloud IoT Device SDK 1
  • cloud messaging 1
  • Cloud ML Summit 1
  • Cloud Next 19
  • Cloud OnAir 5
  • Cloud OnBoard 4
  • Cloud PubSub 1
  • Cloud Run 1
  • Cloud Storage 1
  • Cloud Study Jams 3
  • Cloud Summit 1
  • Cloud Test Lab 2
  • Cloudflare 1
  • CNN 1
  • Coalition for Better Ads 2
  • CocoaPods 1
  • code review 1
  • codejam 5
  • codelab 5
  • Codepen 1
  • Colaboratory 1
  • Common Criteria 1
  • Community 7
  • compatibility 1
  • Compose 1
  • compose camp 1
  • compute engine 3
  • consent 1
  • Contests 1
  • Context 1
  • controls 1
  • Conversation API 1
  • conversations 2
  • conversion 1
  • Cookie 10
  • Coral 3
  • core web vitals 1
  • COVID-19 2
  • Crash Reporting 2
  • Crashlytics 3
  • cryptography 1
  • Custom Element 1
  • Custom Model 1
  • CWV 2
  • dark theme 1
  • Dart 2
  • data retention 1
  • DataCenter 1
  • datacloudsummit 1
  • Daydream 4
  • deck.gl 2
  • Deep Learning 4
  • Delegation 1
  • Demo Party 1
  • Design Patterns 1
  • Design Sprint 3
  • DesignBytes 1
  • Designer 1
  • DevArt 3
  • DevBytes 6
  • Developer 15
  • Developer Console 4
  • Developer Library 1
  • Developer Preview 6
  • Developer Relations 3
  • Developer Review 1
  • Developer Student Club 1
  • DEVELOPERS 1
  • Developers Story 4
  • DevFest 12
  • DevFestX 3
  • DevOps 1
  • devtools 4
  • Dialogflow 1
  • Differential privacy 2
  • Digital Asset Links 1
  • Digital Goods API 1
  • directions api 1
  • DirectShare 1
  • Discover 1
  • distance matrix api 1
  • DNS-over-HTTPS 4
  • Domain 1
  • Doodle 1
  • DoubleClick 4
  • Doze モード 1
  • drive 2
  • DSA 1
  • DSC 1
  • DX 1
  • Dynamic Links 3
  • EarlGrey 1
  • Easter Egg 1
  • ECMAScript 2015 1
  • Eddystone 4
  • Edge 1
  • egypt 1
  • encoder 1
  • Encryption 1
  • English 2
  • environment api 1
  • Envoy 1
  • error 1
  • ES2015 1
  • ES2016 1
  • ES6 2
  • ES7 1
  • eta 1
  • Event 7
  • events 3
  • Explore 1
  • extensions 1
  • external 1
  • Featured 25
  • Feed 2
  • feed-based extensions 3
  • feeds 1
  • FIDO 7
  • filter 1
  • final release 1
  • Firebase 123
  • Firebase Admin SDK 6
  • Firebase Analytics 10
  • Firebase Auth 4
  • Firebase Cloud Messaging 10
  • Firebase Crashlytics 2
  • Firebase Database 5
  • firebase for games 1
  • Firebase Libraries 1
  • Firebase Notifications 1
  • Firebase Performance 3
  • Firebase Remote Config 6
  • firebase summit 1
  • Flash 1
  • FLEDGE 1
  • FLoC 2
  • Flutter 8
  • Flutter App Development 1
  • flutter3 1
  • font 3
  • fraud 1
  • G Suite 19
  • game 43
  • Game Developers Conference 2018 1
  • Game Developers Conference 2019 1
  • Game Development 1
  • gaming 1
  • gaql 8
  • Gboard 2
  • gc_datacloud 1
  • GCCN 1
  • GCP 17
  • GCPUG 1
  • GDC 1
  • GDD11JP 56
  • GDD2010JP 23
  • GDE 2
  • GDG 23
  • GDG Cloud 1
  • gdgoc 2
  • gdsc 5
  • Gemini 6
  • Gemma 2
  • generative AI 4
  • Geo 55
  • Get Inspired 1
  • Gingerbread 1
  • GLIDE 5
  • global foundries 1
  • Gmail 6
  • Gmail API 3
  • Go 1
  • Go Checksum Database 1
  • golang 5
  • goo.gl 1
  • Google 8
  • Google account 1
  • Google Analytics 4
  • Google API 2
  • Google Apps 14
  • Google Apps Script 4
  • Google Assistant 13
  • Google Assistant SDK 2
  • Google Binary Transparency 1
  • Google Cast 8
  • Google Chat 3
  • Google Cloud 50
  • Google Cloud Day 10
  • google cloud innovators 2
  • Google Cloud INSIDE Digital 2
  • Google Cloud INSIDE Games & Apps 9
  • Google Cloud INSIDE Media 1
  • Google Cloud INSIDE Retail 3
  • Google Cloud Messaging 11
  • google cloud next 4
  • google cloud next tokyo 12
  • Google Cloud Platform 16
  • Google Code-in 1
  • Google Dev Library 1
  • Google Developer Experts 2
  • google developer groups 1
  • google developer student clubs 1
  • Google Developers Academy 1
  • Google Developers live 5
  • Google Developers Summit 2
  • Google Drive 6
  • Google Earth 1
  • Google Fit 2
  • Google for Games 3
  • Google for Mobile 2
  • Google for Startups 8
  • Google for Work 1
  • Google I/O 27
  • Google I/O 2024 3
  • Google Identity Services 6
  • Google Impact Challenge 1
  • Google Maps 72
  • Google Maps Platform 92
  • Google Meet 1
  • Google ML Summit 2
  • Google Open Source Peer Bonus 1
  • Google Pay 6
  • Google Photo 1
  • Google Play 148
  • Google Play App Safety 1
  • Google Play Billing 1
  • Google Play Console 15
  • Google Play developer distribution agreement 1
  • Google Play Developer Policies 2
  • Google Play Game Services 10
  • Google Play Instant 1
  • Google Play Services 23
  • Google Play Store 1
  • Google Play アプリ署名 1
  • Google Plus 14
  • Google Search 8
  • Google Sheets API 3
  • Google Sign-In 17
  • Google Slides API 5
  • Google Summer of Code 1
  • Google Tag Manager 1
  • Google Tensor 1
  • Google Trust Services 3
  • Google マップ 4
  • google_ads_api_v6 1
  • Google+ 2
  • Googleapps 10
  • GoogleCloud 5
  • GoogleCloudDay 5
  • GoogleCloudInside 1
  • googlecloudlearn 1
  • googlecloudnext 2
  • GoogleGames 1
  • GoogleI/O 31
  • GoogleLabs 1
  • GooglePlay 3
  • GoogleTV 1
  • GPS 1
  • Gradle 1
  • Growth Academy 1
  • gRPC 2
  • GTUG 5
  • GWT 2
  • hack4jp 2
  • hackathon 7
  • handson 1
  • Hangouts Chat 3
  • hardware 2
  • Hosting 3
  • hotel 1
  • How-To Guide 1
  • HTML5 17
  • HTML5Rocks 1
  • HTTP/2 5
  • HTTPS 19
  • I/O Extended 8
  • ID Token 1
  • Identity 18
  • identity check 2
  • Identity Toolkit 1
  • IGF2010 4
  • IGF2020 2
  • Ignite 4
  • Imagen 2 1
  • IME 12
  • Indie Game 7
  • Indie Games Festival 7
  • Indie Games Festival 2018 2
  • Indie Games Festival 2019 12
  • Indie Games Festival 2020 7
  • Industry Trends 1
  • Inevitable ja Night 30
  • Influence 1
  • innovators hive 2
  • Insights 1
  • Instagram 1
  • Instant Apps 6
  • intern 2
  • Invites 1
  • IO19 3
  • iOS 22
  • IoT 7
  • IPv6 1
  • Issue Tracker 2
  • IWD 1
  • Japanese 6
  • Japanese Developer 1
  • Japanese Input 1
  • java 1
  • JavaScript 13
  • Jetpack 5
  • Jetpack Compose 6
  • Journeys 1
  • K-12 1
  • Kaggle 1
  • Key Transparency 1
  • Knowledge Graph 1
  • Kotlin 25
  • Kotlin Android Extensions 1
  • kotlin api 1
  • Kotlin Beginners 3
  • Kotlin Vocabulary 2
  • Kubernetes 4
  • l10n 8
  • latest 18
  • latest news 1
  • launch 1
  • LaunchPad 2
  • Learn 2
  • lifull 1
  • Lighthouse 1
  • LINE 1
  • Local AI 1
  • Location 1
  • Lollipop 10
  • Machine Learning 32
  • MAD Skills 2
  • MADSkills 2
  • Maker Faire Tokyo 1
  • maps compose 1
  • maps embed api 1
  • Maps JavaScript API 6
  • maps on air 1
  • maps sdk 2
  • maps transportation 1
  • Marshmallow 10
  • Material 1
  • Material Design 31
  • MDL 2
  • MDN 1
  • MediaPipe 1
  • Messaging 1
  • metrics 1
  • MIDI 2
  • migration 1
  • mikan 1
  • Mixed Contents 4
  • ML 3
  • ML Kit 12
  • mlops 1
  • Mobile 16
  • Mobile Bootcamp 4
  • mobile optimized maps 1
  • Mobile Sites certification 1
  • Mobile Vision 4
  • mod_pagespeed 1
  • Model Maker 1
  • monetization 2
  • monetize 3
  • Mozc 15
  • Music 1
  • NativeDriver 2
  • NativeScript 1
  • Navigation 1
  • NBU 1
  • ndk 3
  • Nearby 5
  • News 1
  • Next Extended 1
  • Next Tokyo 4
  • Nexus 2
  • Nexus S 1
  • NFC 1
  • NIST 1
  • Node.js 3
  • notifications 2
  • Noto CJK 1
  • Now in Android 13
  • NPAPI 2
  • NPN 1
  • oauth 17
  • officehour 1
  • One Tap 2
  • online security 2
  • open silicon 3
  • open source 10
  • OpenAI 1
  • opencensus 1
  • opencloudsummit 1
  • OpenGL 4
  • OpenID 3
  • OpenID Connect 4
  • OpenSocial 1
  • opensource 20
  • OpenTitan 2
  • Optimization 1
  • OSV 1
  • p-max 3
  • Page Experience 1
  • passkey 3
  • Password Manager 4
  • Payment 8
  • Payment Handler API 1
  • Payment Request API 2
  • PDF 1
  • PEM 33
  • people 2
  • People API 3
  • Performance 16
  • Performance budget 1
  • performance max 2
  • Performance Monitoring 1
  • performance report 1
  • permissions 1
  • personalization 1
  • PersonFinder 1
  • Phishing 2
  • phone 1
  • photorealistic 3d tiles 1
  • Physical Web 3
  • Pi 1
  • Pixel 5
  • Place Picker 1
  • placements 1
  • places api 1
  • places SDK 1
  • Platform Stability 1
  • Play Billing 2
  • Play Billing Library 2
  • Play Console 2
  • Player Analytics 4
  • Playtime 2017 1
  • Policy 8
  • policy compliance 2
  • policy violations 2
  • polylines 1
  • Polymer 7
  • pricing 1
  • privacy 15
  • Privacy Sandbox 22
  • Progressive Web Apps 14
  • project hosting 1
  • Promise 2
  • Promo code 1
  • Protocol Buffers 1
  • PRPL 1
  • publicdata 1
  • Push API 1
  • Push Notification 6
  • PWA 4
  • Python 3
  • query builder 8
  • query validator 1
  • QUIC 2
  • quick builder 1
  • quick start widget 1
  • QWIKLABS 3
  • RAIL 1
  • raspberry pi 1
  • React 1
  • React Native 2
  • reactive programming 1
  • Realtime Database 9
  • Recap Live Japan 2019 3
  • reCaptcha 1
  • Redux 1
  • release 7
  • Remote Config 4
  • Remote Display API 1
  • Reporting API 1
  • Requirements 1
  • Resonance Audio 1
  • resource type 1
  • Rewarded Video Ads 2
  • RKP 1
  • rmf 2
  • routes api 3
  • RSS 1
  • Run on OS Login 1
  • Runtime Permission 1
  • Rust 2
  • Safe Browsing 4
  • safety 1
  • Sample Code 2
  • Santa Tracker 1
  • SBOM 1
  • schedule 1
  • schema 2
  • schema.org 1
  • Scorecards 1
  • script 2
  • SDG 1
  • sdk 1
  • search central 1
  • secur 1
  • Secure Element 1
  • security 97
  • selfie 1
  • Service Worker 4
  • SHA-1 1
  • Sigstore 4
  • silicon 4
  • Site Isolation 1
  • sketchup 1
  • skywater 1
  • SLSA 1
  • smart displays 1
  • smart home 1
  • smart shopping campaign 1
  • SmartLock for Passwords 5
  • social 4
  • Social Good 1
  • Social Media 1
  • software development 1
  • solution challenge 2
  • Solve 1
  • SPDY 3
  • speak2tweet 1
  • speaker 1
  • Spectre 2
  • speedometer 1
  • Spreadsheet 3
  • ssc 1
  • ssd 1
  • SSR 1
  • stable release 1
  • startup 7
  • Storage 3
  • store sales direct 1
  • story 2
  • streetview 3
  • Study Jams 12
  • subscriptions 5
  • sunset 10
  • Swift 2
  • SwiftShader 1
  • Symantec 1
  • tag 1
  • tapple 1
  • Task 4
  • Team Drive 1
  • techtalk 13
  • TensorFlow 43
  • TensorFlow Federated 1
  • TensorFlow Lite 8
  • TensorFlow Object Detection API 1
  • TensorFlow Probability 2
  • TensorFlow.js 4
  • test 4
  • Test Lab 6
  • TF Certificate 2
  • TFX 1
  • The Fast and the Curious 13
  • Titan M2 1
  • Titan Security Key 1
  • TLS 4
  • Topics 1
  • ToS 1
  • trace 1
  • Transliteration 1
  • Transparency 1
  • Trust 1
  • Trusted Web Activity 1
  • Trusty OS 1
  • TrustZone 1
  • Twitter 1
  • UA-CH 1
  • Udacity 20
  • Unity 3
  • update 1
  • usecase 1
  • User Agent string 2
  • UX 5
  • v10 2
  • v10.1 1
  • v11 1
  • v13 1
  • v15 1
  • v19 1
  • v3 1
  • v4 1
  • v5 1
  • v6.1 1
  • v7 2
  • V8 5
  • v9 1
  • valuetrack 1
  • Verifiable Design 1
  • vertex ai 1
  • Vision AI 1
  • VP9 1
  • VR 11
  • Vulkan 2
  • wafer 1
  • Watch Face 2
  • wave 2
  • Wear OS 3
  • Weave 1
  • Web 38
  • Web Animations 1
  • Web Components 9
  • Web Manifest 2
  • Web Packaging 3
  • Web Stories 3
  • Web Story 3
  • Web Vitals 7
  • web.dev 1
  • WebAssembly 6
  • WebAuthn 1
  • WebGL 5
  • Webhook 1
  • WebM 1
  • WebMusic 5
  • WebRTC 1
  • WebView 1
  • Windows 1
  • Women in Gaming 1
  • Women Techmakers 1
  • Women Techmakers Scholars Program 1
  • WomenDeveloperAcademy 1
  • Wordpress 2
  • workmanager 1
  • WTM 8
  • Xcode 1
  • YouTube 18
  • YouTube API 1
  • youtube select 1
  • インタビュー 1
  • コードサンプル 1
  • サプライ チェーン 1
  • プライバシー 1
  • 機械学習 3
  • 言論の自由 1
  • 節電 3
  • 定期購入 1
  • 東日本大震災 9
  • 日本語入力 41


ブログ アーカイブ


  •     2026
    • 3月
    • 2月
  •     2025
    • 8月
    • 7月
    • 6月
    • 5月
    • 4月
    • 3月
    • 2月
    • 1月
  •     2024
    • 12月
    • 11月
    • 10月
    • 9月
    • 8月
    • 7月
    • 6月
    • 5月
    • 4月
    • 3月
    • 2月
    • 1月
  •     2023
    • 12月
    • 11月
    • 10月
    • 9月
    • 8月
    • 7月
    • 6月
    • 5月
    • 4月
    • 3月
    • 2月
    • 1月
  •     2022
    • 12月
    • 11月
    • 10月
    • 9月
    • 8月
    • 7月
    • 6月
    • 5月
    • 4月
    • 3月
    • 2月
    • 1月
  •     2021
    • 12月
    • 11月
    • 10月
    • 9月
    • 8月
    • 7月
    • 6月
    • 5月
    • 4月
    • 3月
    • 2月
    • 1月
  •     2020
    • 12月
    • 11月
    • 10月
    • 9月
    • 8月
    • 7月
    • 6月
    • 5月
    • 4月
    • 3月
    • 2月
    • 1月
  •     2019
    • 12月
    • 11月
    • 10月
    • 9月
    • 8月
    • 7月
    • 6月
    • 5月
    • 4月
    • 3月
    • 2月
    • 1月
  •     2018
    • 12月
    • 11月
    • 10月
    • 9月
    • 8月
    • 7月
    • 6月
    • 5月
    • 4月
    • 3月
    • 2月
    • 1月
  •     2017
    • 12月
    • 11月
    • 10月
    • 9月
    • 8月
    • 7月
    • 6月
    • 5月
    • 4月
    • 3月
    • 2月
    • 1月
  •     2016
    • 12月
    • 11月
    • 10月
    • 9月
    • 8月
    • 7月
    • 6月
    • 5月
    • 4月
    • 3月
    • 2月
    • 1月
  •     2015
    • 12月
    • 11月
    • 10月
    • 9月
    • 8月
    • 7月
    • 6月
    • 5月
    • 4月
    • 3月
    • 2月
  •     2014
    • 12月
    • 11月
    • 10月
    • 9月
    • 8月
    • 7月
    • 6月
    • 5月
    • 4月
    • 3月
    • 2月
    • 1月
  •     2013
    • 12月
    • 11月
    • 10月
    • 9月
    • 8月
    • 7月
    • 6月
    • 5月
    • 4月
    • 3月
    • 2月
    • 1月
  •     2012
    • 12月
    • 11月
    • 10月
    • 9月
    • 8月
    • 7月
    • 6月
    • 5月
    • 4月
    • 3月
    • 2月
    • 1月
  •     2011
    • 12月
    • 11月
    • 10月
    • 9月
    • 8月
    • 7月
    • 6月
    • 5月
    • 4月
    • 3月
    • 2月
    • 1月
  •     2010
    • 12月
    • 11月

Feed


"プロダクトに関するご意見はプロダクトフォーラムにお願いします"
  • Google
  • Privacy
  • Terms