เปิดแอปพลิเคชัน Android ที่กำหนดเองจากเบราว์เซอร์ Android


คำตอบ:


616

ใช้<intent-filter>กับ<data>องค์ประกอบ ตัวอย่างเช่นหากต้องการจัดการลิงก์ทั้งหมดไปยัง twitter.com คุณต้องใส่สิ่งนี้ไว้<activity>ในAndroidManifest.xml:

<intent-filter>
    <data android:scheme="http" android:host="twitter.com"/>
    <action android:name="android.intent.action.VIEW" />
</intent-filter>

จากนั้นเมื่อผู้ใช้คลิกที่ลิงค์ไปยัง Twitter ในเบราว์เซอร์พวกเขาจะถูกถามว่าแอปพลิเคชันใดที่จะใช้เพื่อให้การดำเนินการเสร็จสิ้น: เบราว์เซอร์หรือแอปพลิเคชันของคุณ

แน่นอนถ้าคุณต้องการรวมการทำงานระหว่างเว็บไซต์และแอพของคุณไว้แน่นคุณสามารถกำหนดโครงร่างของคุณเอง:

<intent-filter>
    <data android:scheme="my.special.scheme" />
    <action android:name="android.intent.action.VIEW" />
</intent-filter>

จากนั้นในเว็บแอปของคุณคุณสามารถใส่ลิงค์เช่น:

<a href="my.special.scheme://other/parameters/here">

และเมื่อผู้ใช้คลิกแอปของคุณจะเปิดตัวโดยอัตโนมัติ (เพราะอาจเป็นแอพเดียวที่สามารถจัดการmy.special.scheme://ประเภทของ uris ได้) ข้อเสียเพียงอย่างเดียวคือถ้าผู้ใช้ไม่ได้ติดตั้งแอพพวกเขาจะได้รับข้อผิดพลาดที่น่ารังเกียจ และฉันไม่แน่ใจว่าจะมีวิธีการตรวจสอบใด ๆ


แก้ไข:เพื่อตอบคำถามของคุณคุณสามารถใช้getIntent().getData()คืนUriวัตถุได้ จากนั้นคุณสามารถใช้Uri.*วิธีการแยกข้อมูลที่คุณต้องการ ตัวอย่างเช่นสมมติว่าผู้ใช้คลิกที่ลิงก์ไปที่http://twitter.com/status/1234:

Uri data = getIntent().getData();
String scheme = data.getScheme(); // "http"
String host = data.getHost(); // "twitter.com"
List<String> params = data.getPathSegments();
String first = params.get(0); // "status"
String second = params.get(1); // "1234"

คุณสามารถทำสิ่งต่าง ๆ ข้างต้นได้ทุกที่ในตัวคุณActivityแต่คุณอาจต้องการทำสิ่งต่อไปonCreate()นี้ นอกจากนี้คุณยังสามารถใช้เพื่อให้ได้จำนวนของกลุ่มเส้นทางที่อยู่ในนั้นparams.size() Uriมองหา javadoc หรือเว็บไซต์ผู้พัฒนา android สำหรับUriวิธีการอื่นที่คุณสามารถใช้เพื่อแยกส่วนเฉพาะ


6
ขอบคุณสำหรับคำตอบของคุณในทันที แต่โปรดบอกวิธีการเข้าถึงพารามิเตอร์หลังจาก "my.special.scheme: //"
Parimal Modi

4
ฉันได้แก้ไขคำตอบของฉันเพื่อรวมคำแนะนำเกี่ยวกับวิธีดึงข้อมูลจาก Uri โปรดทำเครื่องหมายคำตอบนี้ว่ายอมรับ (เท่านั้น) หากคุณพิจารณาโดยคลิกที่เครื่องหมายถูกถัดจากคำตอบ
เฟลิกซ์

9
จะเกิดอะไรขึ้นหากแอปพลิเคชัน android เป้าหมายไม่ได้ติดตั้ง วิธีจัดการกับสิ่งนี้
Nemo

13
ทุกคนที่ชอบก็ไม่สามารถที่จะได้รับงานโครงการนี้ต้องการที่จะเพิ่มandroid:exported="true"ให้กับพวกเขาActivityในที่ประจักษ์ ตรวจสอบคำตอบนี้stackoverflow.com/a/13044911/1276636
Sufian

4
ไม่แน่ใจว่าสิ่งนี้ทำงานได้อย่างไรสำหรับทั้งโลก ไม่สามารถใช้งานกับ Chrome ได้และจะเปิดลิงก์ในเบราว์เซอร์เสมอจนกว่าคุณจะวางองค์ประกอบ "android: pathPrefix" คำตอบยังไม่มีค่าหมวดหมู่ตามที่กล่าวไว้ในเอกสารประกอบ หากยังไม่ได้ผลสำหรับใครบางคนให้อ้างอิงสิ่งนี้โปรด: stackoverflow.com/a/21727055/2695276 PS: ดิ้นรนหลายวัน
Rajat Sharma

70

คำตอบทั้งหมดข้างต้นไม่ได้ผลสำหรับฉันCHROMEเมื่อวันที่ 28 มกราคม 2014

แอปของฉันเปิดใช้งานได้อย่างถูกต้องจากhttp://example.com/someresource/ลิงก์จากแอปเช่นแฮงเอาท์ Gmail และอื่น ๆ แต่ไม่ใช่จากภายในเบราว์เซอร์โครม

เพื่อแก้ปัญหานี้เพื่อที่จะเปิดใช้งานอย่างถูกต้องจากโครเมี่ยมคุณต้องตั้งตัวกรองความตั้งใจเช่นนี้

<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:host="example.com"
        android:pathPrefix="/someresource/"
        android:scheme="http" />
    <data
        android:host="www.example.com"
        android:pathPrefix="/someresource/"
        android:scheme="http" />
</intent-filter>

บันทึกpathPrefixองค์ประกอบ

แอปของคุณจะปรากฏในเครื่องมือเลือกกิจกรรมเมื่อใดก็ตามที่ผู้ใช้ร้องขอhttp://example.com/someresource/รูปแบบจากเบราว์เซอร์ chrome โดยคลิกลิงก์จากผลการค้นหาของ google หรือเว็บไซต์อื่น ๆ


สิ่งนี้ช่วยฉันได้มาก ขอบคุณมาก! กรุณาโพสต์คำตอบของคุณที่นี่เพื่อที่ฉันจะให้รางวัลแก่คุณ! stackoverflow.com/questions/21663001/…
Vlad Schnakovszki

นี่คือภาษาอะไร?
Dims

สวัสดีฉันรู้ว่ามันเก่าเกินไป ฉันหลงในสถานการณ์เดียวกัน ฉันได้ระบุ pathPrefix แบบแผนและโฮสต์ แต่มันไม่ทำงาน ฉันลองกับแบบแผนเท่านั้นจากนั้นก็ใช้งานได้ แต่เมื่อฉันเพิ่มโฮสต์มันก็หยุดทำงาน ความคิดใด ๆ ที่สามารถเป็นปัญหาได้?
seema

ใช้เวลาหลายวันกว่าจะได้คำตอบนี้ ไม่แน่ใจว่ามันทำงานได้อย่างไรกับคนทั้งโลกโดยไม่ใช้องค์ประกอบ pathPrefix ไม่เคยทำงานให้ฉันกับ chrome แม้จะทำทุกอย่างตามเอกสาร ขอบคุณมาก.
Rajat Sharma

66

โปรดดูความคิดเห็นของฉันที่นี่: สร้างลิงก์ในเบราว์เซอร์ Android เพื่อเริ่มแอพของฉันหรือไม่

เราไม่สนับสนุนให้ผู้คนใช้แผนการของตนเองอย่างเด็ดขาดเว้นแต่พวกเขาจะกำหนดโครงร่างอินเทอร์เน็ตใหม่ทั่วโลก


10
Hackbod เป็นหนึ่งในวิศวกรของ Google ที่อยู่เบื้องหลังแพลตฟอร์ม Android อาจเป็นความคิดที่ดีที่จะทำตามคำแนะนำนี้ ในความเป็นจริงดูเหมือนว่าการสนับสนุนแบบกำหนดเองเช่นนี้ยากจนใน Honeycomb
nmr

23
ฉันไม่สามารถรับผิดชอบต่อข้อ จำกัด ที่นักพัฒนาซอฟต์แวร์ใช้กับ iOS ได้ ;)
hackbod

12
รับผิดชอบ? ไม่ แต่คุณสามารถนำมาพิจารณาได้ตั้งแต่ไม่ว่าคุณจะชอบหรือไม่ข้อ จำกัด เหล่านั้นถูกกำหนดโดยนักพัฒนาซอฟต์แวร์ของคุณหลายคน
ByteMe

6
hackbod กำลังตอบคำถามสำหรับ Android โดยเฉพาะ ไม่มีการกล่าวถึง iOS ดังนั้นจึงไม่จำเป็นต้องคำนึงถึง
nilskp

4
@hackbod จะตั้งชื่อแบบแผน (เช่น href = "com.ourdomain.myapp // what") เป็นวิธีปฏิบัติที่ดีสมมติว่าลิงก์แบบนั้นสามารถพบได้ในเว็บไซต์อื่นหรือไม่
Julien Bérubé

48

ในกรณีของฉันฉันต้องตั้งสองประเภทสำหรับ<intent-filter>และจากนั้นมันทำงาน:

<intent-filter>
<data android:scheme="my.special.scheme" />
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT"/>
<category android:name="android.intent.category.BROWSABLE"/>
</intent-filter>

2
เหมือนกันที่นี่จำเป็นต้องเพิ่มหมวดหมู่เพิ่มเติม
KPK

ใครสามารถอธิบายกระบวนการที่แท้จริงของการทำสิ่งนี้ได้? ลิงก์ใด ๆ ที่จะนำไปใช้อย่างถูกต้องข้อกำหนดเบื้องต้นจะมีประโยชน์ ขอบคุณ
Ankit Garg

ทดสอบกับการตั้งค่า dev ที่จริงฉันให้ชื่อโดเมนผิด ความผิดฉันเอง.
Ankit Garg

คำตอบที่ได้รับคะแนนสูงสุดไม่ได้ผลสำหรับฉัน แต่สิ่งนี้ทำได้ ขอบคุณ.
EL45

25

ตัวอย่างเช่นคุณมีสิ่งต่อไปนี้:

ลิงก์สำหรับเปิดแอปของคุณ: http://example.com

ชื่อแพ็คเกจของแอปของคุณ: com.example.mypackage

จากนั้นคุณต้องทำสิ่งต่อไปนี้:

1) เพิ่มตัวกรองเจตนาในกิจกรรมของคุณ (สามารถเป็นกิจกรรมใด ๆ ที่คุณต้องการสำหรับข้อมูลเพิ่มเติมตรวจสอบเอกสารประกอบ )

        <activity
        android:name=".MainActivity">

        <intent-filter android:label="@string/filter_title_view_app_from_web">
            <action android:name="android.intent.action.VIEW" />
            <category android:name="android.intent.category.DEFAULT" />
            <category android:name="android.intent.category.BROWSABLE" />
            <!-- Accepts URIs that begin with "http://example.com" -->

            <data
                android:host="example.com"
                android:scheme="http" />
        </intent-filter>

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

    </activity> 

2) สร้างไฟล์ HTML เพื่อทดสอบลิงก์หรือใช้วิธีนี้

<a href="intent://example.com#Intent;scheme=http;package=com.example.mypackage;end">Open your Activity directly (just open your Activity, without a choosing dialog). </a>

<a href="http://example.com">Open this link with browser or your programm (by choosing dialog).</a>

3) ใช้ Mobile Chrome เพื่อทดสอบ

4) นั่นแหล่ะ

และไม่จำเป็นต้องเผยแพร่แอปในตลาดเพื่อทดสอบการเชื่อมโยงลึก =)

นอกจากนี้สำหรับข้อมูลเพิ่มเติมโปรดดูเอกสารและมีประโยชน์ในการนำเสนอ


ฉันต้องสร้างไฟล์ html และอัปโหลดเพื่อให้มันทำงานได้ ฉันสงสัยว่าทำไมคนที่สองโดยเฉพาะไม่ทำงานโดยตรงจากเบราว์เซอร์ (โครม)
Makalele

18

ควรมีการ<category android:name="android.intent.category.BROWSABLE"/>เพิ่มลงในตัวกรองเจตนาเพื่อให้กิจกรรมได้รับการยอมรับอย่างถูกต้องจากลิงก์


4
สำหรับการอ้างอิงการเพิ่ม CATEGORY_BROWSABLE หมายความว่า "เบราว์เซอร์สามารถเรียกใช้กิจกรรมเป้าหมายได้อย่างปลอดภัยเพื่อแสดงข้อมูลที่อ้างอิงโดยลิงก์ - ตัวอย่างเช่นรูปภาพหรือข้อความอีเมล"
greg7gkb

นี่เป็นหมวดหมู่ที่มีอยู่หรือคุณกำลังเสนอหมวดหมู่ใหม่
Anish

มันมีอยู่ เห็นได้ชัดว่าคุณควรมีโฮสต์เว็บไซต์แยกต่างหากในแท็กตัวกรองเจตนาที่แตกต่างกันหรือทำให้เกิดปัญหา
NoBugs

2
ไม่เพียงแค่ BROWSABLE แต่ยังรวมถึง android.intent.category.DEFAULT - ดังนั้นจึงสามารถเปิดลิงก์ได้เมื่อเริ่มต้นในแอปอื่นเช่นอีเมล (ไม่ใช่แค่เบราว์เซอร์)
AlikElzin-kilaka

8

ลิงค์ต่อไปนี้ให้ข้อมูลเกี่ยวกับการเปิดใช้แอพ (หากติดตั้ง) โดยตรงจากเบราว์เซอร์ มิฉะนั้นจะเปิดแอพใน play store โดยตรงเพื่อให้ผู้ใช้สามารถดาวน์โหลดได้อย่างราบรื่น

https://developer.chrome.com/multidevice/android/intents


7

โปรดทราบว่าไอคอนของคุณจะหายไปจากตัวเรียกใช้ Android เมื่อคุณใช้คุณสมบัตินี้กว่าที่คุณจะต้องแยกตัวกรองความตั้งใจ

    <activity
        android:name=".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="your-own-uri" />
        </intent-filter>
    </activity>


5

คำตอบของเฟลิกซ์ที่ท่าเรือXamarin

ในของคุณMainActivityเพิ่ม ( docs: Android.App.IntentFilterAttribute Class ):

....
[IntentFilter(new[] { 
    Intent.ActionView }, 
    Categories = new[] { Intent.CategoryDefault, Intent.CategoryBrowsable }, 
    DataScheme = "my.special.scheme")
]
public class MainActivity : Activity
{
    ....

Xamarin จะเพิ่มสิ่งต่อไปนี้ในตัวAndroidManifest.xmlคุณ:

<activity
    android:label="Something"
    android:screenOrientation="portrait"
    android:theme="@style/MyTheme"
    android:name="blah.MainActivity">
    <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="my.special.scheme" />
    </intent-filter>
</activity>

และเพื่อรับ params ( ฉันทดสอบใน OnCreate of MainActivity ):

var data = Intent.Data;
if (data != null)
{
    var scheme = data.Scheme;
    var host = data.Host;
    var args = data.PathSegments;

    if (args.Count > 0)
    {
        var first = args[0];
        var second = args[1];
        ...
    }
}

เท่าที่ฉันรู้ข้างต้นสามารถเพิ่มในกิจกรรมใด ๆ ไม่เพียง แต่กิจกรรมหลัก

หมายเหตุ:

  1. เมื่อผู้ใช้คลิกที่ลิงค์ระบบปฏิบัติการ Android จะเปิดใช้งานแอปของคุณใหม่(ฆ่าตัวอย่างถ้ามีและเปิดใช้งานใหม่)หมายความว่าOnCreateเหตุการณ์ของแอปMainLauncher Activityจะถูกไล่ออกอีกครั้ง
  2. ด้วยลิงก์นี้: ค่าของโค้ดสุดท้าย<a href="my.special.scheme://host/arg1/arg2">ข้างต้นจะเป็น:
scheme: my.special.scheme
host: host
args: ["arg1", "arg2"]
first: arg1
second: arg2

อัปเดต:หาก Android สร้างอินสแตนซ์ใหม่ของแอปของคุณคุณควรเพิ่มandroid:launchMode="singleTask"ด้วย


3

วิธีการของเฟลิกซ์ในการจัดการลิงก์ที่ลึกเป็นวิธีการทั่วไปในการจัดการลิงก์ที่ลึก ฉันขอแนะนำให้ตรวจสอบห้องสมุดนี้เพื่อจัดการการกำหนดเส้นทางและการแยกวิเคราะห์ลิงก์ที่ลึกของคุณ:

https://github.com/airbnb/DeepLinkDispatch

คุณสามารถใช้คำอธิบายประกอบเพื่อลงทะเบียนกิจกรรมของคุณสำหรับ URI ลิงก์ที่ลึกและมันจะแยกพารามิเตอร์สำหรับคุณโดยไม่ต้องทำตามปกติในการรับกลุ่มเส้นทางจับคู่และอื่น ๆ คุณสามารถใส่คำอธิบายประกอบและกิจกรรมเช่นนี้ :

@DeepLink("somePath/{someParameter1}/{someParameter2}")
public class MainActivity extends Activity {
   ...
}

0

เฮ้ฉันได้ทางออกแล้ว ฉันไม่ได้ตั้งค่าหมวดหมู่เป็น "ค่าเริ่มต้น" นอกจากนี้ฉันกำลังใช้กิจกรรมหลักสำหรับข้อมูลเจตนา ตอนนี้ฉันกำลังใช้กิจกรรมอื่นสำหรับข้อมูลเจตนา ขอบคุณสำหรับความช่วยเหลือ :)


ฟังดูไม่น่า (แม้ว่าฉันจะรู้ว่านี่เป็นคำถามเก่าและบางทีสิ่งต่าง ๆ ได้เปลี่ยนไป) จากdeveloper.android.com/guide/components/intents-filters.html#ifs "สำหรับความตั้งใจที่จะผ่านการทดสอบหมวดหมู่ทุกหมวดหมู่ในวัตถุแสดงเจตนาจะต้องตรงกับหมวดหมู่ในตัวกรองตัวกรองสามารถแสดงรายการหมวดหมู่เพิ่มเติมได้ แต่ไม่สามารถละเว้นสิ่งที่อยู่ในเจตนาได้ "
Noach Magedman

0

คุณต้องเพิ่มชื่อปลอม - ชื่อโฮสต์ในแอป CALLBACK_URL ': //' ไม่สมเหตุสมผลเท่า URL และไม่สามารถแยกวิเคราะห์ได้


0

example.php:

<?php
if(!isset($_GET['app_link'])){  ?>   
    <iframe src="example.php?app_link=YourApp://blabla" style="display:none;" scrolling="no" frameborder="0"></iframe>
    <iframe src="example.php?full_link=http://play.google.com/xyz" style="display:none;" scrolling="no" frameborder="0"></iframe>
    <?php 
}
else { ?>
    <script type="text/javascript">
    self.window.location        = '<?php echo $_GET['app_link'];?>';
    window.parent.location.href = '<?php echo $_GET['full_link'];?>';
    </script>
<?php 
}

1
สิ่งนี้จะสร้าง iframe ที่มองไม่เห็นสองตัว: ลิงก์ลึกและลิงก์ปกติ หากติดตั้งแอพแล้วลิงก์ Deep iframe จะเปิดใช้งาน มิฉะนั้นลิงค์ปกติจะปรากฏขึ้น ด้วยการทำงานพิเศษบางอย่างการเชื่อมโยงแบบ Deep Deferred สามารถนำไปใช้งานได้ซึ่งการเชื่อมโยงแบบลึกจะถูกเรียกใช้หลังจากติดตั้งแอพแล้ว
Dominic Cerisano

0

@JRuns ดูคำตอบในที่นี่ แนวคิดคือการสร้าง html ด้วยแบบกำหนดเองของคุณและอัปโหลดที่อื่น จากนั้นหากคุณคลิกลิงก์ที่กำหนดเองในไฟล์ html ของคุณคุณจะถูกนำไปยังแอปของคุณ ฉันใช้นี้บทความสำหรับหุ่นยนต์ แต่อย่าลืมตั้งค่าName = "MyApp.Mobile.Droid.MainActivity"แอตทริบิวต์ชื่อเต็มให้กับกิจกรรมเป้าหมายของคุณ


0

ตั้งแต่ 15/06/2019

สิ่งที่ฉันทำคือรวมถึงความเป็นไปได้ทั้งสี่ในการเปิด URL

เช่นด้วยhttp/ httpsและ 2 ด้วยwwwคำนำหน้าและ 2 โดยไม่ต้องwww

และโดยการใช้แอพของฉันจะเริ่มต้นอัตโนมัติตอนนี้โดยไม่ต้องขอให้ฉันเลือกเบราว์เซอร์และตัวเลือกอื่น ๆ

<intent-filter android:autoVerify="true">
    <action android:name="android.intent.action.VIEW" />
    <category android:name="android.intent.category.DEFAULT" />
    <category android:name="android.intent.category.BROWSABLE" />

    <data android:scheme="https" android:host="example.in" />
    <data android:scheme="https" android:host="www.example.in" />
    <data android:scheme="http" android:host="example.in" />
    <data android:scheme="http" android:host="www.example.in" />

</intent-filter>
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.