50

次のいずれかをインターセプトできるようにするAndroidiOSの処理メカニズムを定義する方法はありますか?

myapp:///events/3/
- or -
http://myapp.com/events/3/

プロトコルまたはホストのいずれかを「リッスン」し、対応するActivity/ViewControllerを開きます。

これらを可能な限りシステム全体にできるようにしたいと思います。これはiOSでもっと問題になると思いますが、理想的には、これら2つのスキームのいずれかをハイパーリンクとして任意のアプリからクリックできると思います。Gmail、Safariなど。

4

3 に答える 3

78

EDIT 5/2014、これはよくある質問のように思われるので、回答に詳細を追加しました:

アンドロイド:

Android の場合は、カスタム URI がクリックされたときにマイ アクティビティを起動するインテント フィルター を参照してください。

インテント フィルターを使用します。

<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="myapp" /> 
</intent-filter>

これは、起動するアクティビティに添付されます。例えば:

<activity android:name="com.MyCompany.MyApp.MainActivity" android:label="@string/app_name">
  <intent-filter>
      <action android:name="android.intent.action.MAIN" />
      <category android:name="android.intent.category.LAUNCHER" />
  </intent-filter>
  <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="myapp" android:host="com.MyCompany.MyApp" />
  </intent-filter>
</activity>

次に、アクティビティで、実行されていない場合、アクティビティはインテントで渡された URI で起動されます。

Intent intent = getIntent();
Uri openUri = intent.getData();

すでに実行されている場合は、アクティビティで onNewIntent() が呼び出され、インテント内の URI が再び使用されます。

最後に、代わりにネイティブ アプリ内でホストされている UIWebView のカスタム プロトコルを処理する場合は、次を使用できます。

myWebView.setWebViewClient(new WebViewClient()
{
 public Boolean shouldOverrideUrlLoading(WebView view, String url)
 {
  // inspect the url for your protocol
 }
});

iOS:

iOS については、iOS 4 では動作するが iOS 3.2 では動作しない (UIApplicationDelegate の handleOpenURL を介した) URL を使用したアプリの起動を参照してください。

次のような Info.plist キーを使用して URL スキームを定義します。

<key>CFBundleURLTypes</key>
    <array>
        <dict>
            <key>CFBundleURLName</key>
            <string>com.yourcompany.myapp</string>
        </dict>
        <dict>
            <key>CFBundleURLSchemes</key>
            <array>
                <string>myapp</string>
            </array>
        </dict>
    </array>

次に、アプリのデリゲートで呼び出されるハンドラー関数を定義します

- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation
{
 // parse and validate the URL
}

ネイティブ アプリ内でホストされている UIWebViewsでカスタム プロトコルを処理する場合は、UIWebViewDelegate メソッドを使用できます。

- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType
{
 NSURL *urlPath = [request URL];
 if (navigationType == UIWebViewNavigationTypeLinkClicked)
 {
    // inspect the [URL scheme], validate
    if ([[urlPath scheme] hasPrefix:@"myapp"]) 
    {
      ...
    }
  }
}

}

WKWebView ( iOS8 +) の場合、代わりに WKNavigationDelegate と次のメソッドを使用できます。

- (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler
{
 NSURL *urlPath = navigationAction.request.URL;  
 if (navigationAction.navigationType == WKNavigationTypeLinkActivated)
 {
   // inspect the [URL scheme], validate
   if ([[urlPath scheme] hasPrefix:@"myapp"])
   {
    // ... handle the request
    decisionHandler(WKNavigationActionPolicyCancel);
    return;
   }
 }

 //Pass back to the decision handler
 decisionHandler(WKNavigationActionPolicyAllow);
}
于 2012-07-10T20:17:29.673 に答える
24

更新:これは非常に古い質問であり、iOS と Android の両方で状況が大きく変わりました。以下に元の回答を残しますが、新しいプロジェクトに取り組んでいるか、古いプロジェクトを更新している人は、代わりに両方のプラットフォームでサポートされているディープリンクの使用を検討する必要があります.

iOS では、ディープ リンクはユニバーサル リンクと呼ばれます。Web サイトの一部を指す URL にアプリを関連付ける JSON ファイルを Web サイトに作成する必要があります。次に、NSUserActivityオブジェクトを受け入れるようにアプリを更新し、指定された URL に対応するコンテンツを表示するようにアプリを設定します。また、アプリが処理できる URL をリストする権利をアプリに追加する必要があります。使用中、オペレーティング システムは、アプリが処理する URL の 1 つを開こうとすると、サイトから関連付けファイルをダウンロードし、アプリを起動します。

Android でのアプリ リンクの設定も同様に機能します。まず、Web サイトとアプリの間の関連付けを設定します。次に、アプリが処理できる URL を開こうとする試みをアプリがインターセプトできるようにするインテント フィルターを追加します。

詳細は明らかに異なりますが、アプローチは両方のプラットフォームでほぼ同じです。どのアプリがそのコンテンツにアクセスしようとしても、Web サイトのコンテンツの表示にアプリを挿入することができます。


元の答え:

iOS の場合、はい、次の 2 つのことができます。

  1. 特定のスキームで URL を処理できることをアプリに宣伝させます。

  2. 任意のスキームを処理するプロトコル ハンドラをインストールします。

最初のオプションは非常に簡単で、カスタム URL スキームの実装で説明されています。アプリが特定のスキームを処理できることをシステムに知らせるには:

  • アプリの Info.plist を CFBundleURLTypes エントリで更新します

  • -application:didFinishLaunchingWithOptions: アプリのデリゲートに実装します。

2 番目の可能性は、独自のプロトコル ハンドラを作成することです。これはアプリ内でのみ機能しますが、上記の手法と組み合わせて使用​​できます。上記の方法を使用して、特定の URL に対してアプリを起動するシステムを取得し、アプリ内でカスタム URL プロトコル ハンドラーを使用して、iOS の URL 読み込みシステムの機能を活用します。

  • の独自のサブクラスを作成しますNSURLProtocol

  • オーバーライド+canInitWithRequest:-- 通常は URL スキームを確認し、処理したいスキームと一致する場合はそれを受け入れますが、リクエストの他の側面も確認できます。

  • サブクラスを登録します。[MyURLProtocol registerClass];

  • と をオーバーライド-startLoading-stopLoadingて、リクエストの読み込みをそれぞれ開始および停止します。

詳細については、上記のリンクにある NSURLProtocol ドキュメントをお読みください。ここでの難易度は、実装しようとしているものに大きく依存します。他のアプリが簡単なリクエストを作成できるように、iOS アプリがカスタム URL ハンドラーを実装するのは一般的です。独自の HTTP または FTP ハンドラーの実装は、もう少し複雑です。

価値があるのは、これがiOSでPhoneGapがどのように機能するかです. PhoneGap には PGURLProtocol と呼ばれる NSURLProtocol サブクラスが含まれており、アプリが読み込もうとする URL のスキームを調べ、それが認識できるスキームの 1 つである場合に引き継ぎます。PhoneGap のオープンソースのいとこはCordovaです。調べてみると参考になるかもしれません。

于 2012-07-10T20:27:24.090 に答える
1

あなたの質問の2番目のオプションについて:

http://myapp.com/events/3/

iOS 9 で導入された Universal Links と呼ばれる新しい技術があり、https://

https://developer.apple.com/library/content/documentation/General/Conceptual/AppSearch/UniversalLinks.html

于 2016-10-20T17:46:42.173 に答える