Android – Giao tiếp với ứng dụng khác – Phần 1

Rate this post

Như đã biết thông thường một ứng dụng Android sẽ có nhiều Activity, mỗi Activity chịu trách nhiệm vẽ màn hình giao diện người dùng và xử lý các sự kiện diễn ra trên giao diện đó, chẳng hạn như vẽ bản đồ, chụp ảnh…v.v Để có thể chuyển đổi qua lại giữa các Activity thì chúng ta dùng lớp Intent (tiếng Anh có nghĩa là dự định, tức là dự định làm một cái gì đó), Intent không những cho phép chúng ta gọi tới các Activity trong cùng một ứng dụng mà còn cho phép gọi tới những Activity ở các ứng dụng khác nữa.

Mở một ứng dụng khác

Chúng ta đã từng sử dụng lớp Intent để di chuyển qua lại giữa các Activity, làm như thế là chúng ta đã gọi Intent một cách tường minh, tức là khai báo rõ ràng tên lớp Activity sẽ được mở bởi Intent. Còn đôi khi chúng ta muốn mở một ứng dụng khác thì lúc đó chúng ta sử dụng Intent “ngầm”.

Mở Intent ngầm

Các đối tượng Intent ngầm sẽ không nhận tên của một lớp Activity nào cả, mà thay vào đó là một hành động nào nó, chẳng hạn như mở ứng dụng bản đồ, mở trình duyệt, mở ứng dụng gửi mail… và các đối tượng Intent này cũng có thể gửi dữ liệu đến các hành động đó nữa, ví dụ như mở bản đồ tại thành phố Nội, mở trình duyệt tại địa chỉ phocode.com…v.v Thường thì dữ liệu gửi đi sẽ được lưu trong lớp android.net.Uri.

Ví dụ 1:

package com.phocode;

import android.content.Intent;
import android.net.Uri;
import android.app.Activity;
import android.os.Bundle;

public class MainActivity extends Activity{

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        Uri number =  Uri.parse("tel:00841218749385");
        Intent callIntent = new Intent(Intent.ACTION_DIAL, number);
        startActivity(callIntent);
    }
}

Đoạn code trên sẽ mở màn hình gọi điện với số điện thoại được chỉ định trong đối tượng Uri.

Capture

Ví dụ 2:

package com.phocode;

import android.content.Intent;
import android.net.Uri;
import android.app.Activity;
import android.os.Bundle;

public class MainActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        Uri webpage = Uri.parse("https://phocode.com");
        Intent webIntent = new Intent(Intent.ACTION_VIEW, webpage);
        startActivity(webIntent);
    }
}

Đoạn code trên sẽ mở trình duyệt web mặc định tới website có địa chỉ được chỉ định trong đối tượng Uri.

Capture

Tham số khởi tạo đối tượng Intent ở đây không phải là tên một lớp Activity nào, mà là một hằng số chỉ định một hành động nào đó, ví dụ như Intent.ACTION_VIEW là mở trình duyệt web, Intent.ACTION_DIAL là mở trình gọi điện… tham số thứ 2 là một đối tượng Uri mang theo dữ liệu cho hành động đó. Danh sách các đối tượng hành động cùng với kiểu dữ liệu Uri có thể xem ở đây.

Một số đối tượng hành động có thể nhận thêm nhiều dữ liệu chứ không chỉ có một, dữ liệu đó không bắt buộc nhưng có thể truyền đi, lúc đó chúng ta truyền vào bằng phương thức putExtra() như thường, ví dụ:

package com.phocode;

import android.content.Intent;
import android.net.Uri;
import android.app.Activity;
import android.os.Bundle;

public class MainActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        Intent emailIntent = new Intent(Intent.ACTION_SEND);
        emailIntent.setType("text/plain");
        emailIntent.putExtra(Intent.EXTRA_EMAIL, "admin@example.com");
        emailIntent.putExtra(Intent.EXTRA_SUBJECT, "Hello");
        emailIntent.putExtra(Intent.EXTRA_TEXT, "Nice to meet you");
        startActivity(emailIntent);
    }
}

Đoạn code trên sẽ mở ứng dụng gửi tin nhắn.

Nếu hệ điều hành thấy có nhiều hơn một ứng dụng có thể mở được đối tượng Intent này thì hệ điều hành sẽ mở một hộp thoại chứa danh sách các ứng dụng đó cho người dùng chọn, còn nếu chỉ có một ứng dụng có thể mở được thì hệ điều hành sẽ chạy ứng dụng đó luôn.

Capture

Kiểm tra Intent có thể mở được hay không

Hệ điều hành Android đảm bảo rằng luôn luôn sẽ có ứng dụng được cài sẵn có thể mở được dữ liệu được gửi đi bởi đối tượng Intent ngầm. Tuy nhiên chúng ta nên kiểm tra trước thì sẽ tốt hơn bởi vì nếu không có ứng dụng nào có thể mở được đối tượng Intent của chúng ta thì chương trình của bạn sẽ bị crash (tức là bị tắt mà không rõ lý do).

Để biết được đối tượng Intent mà chúng ta định gọi có thể mở được bởi ứng dụng nào đó hay không thì chúng ta dùng phương thức queryIntentActivities() của lớp android.content.pm.PackageManager và truyền vào đối tượng Intent và chế độ kiểm tra. Ví dụ:

package com.phocode;

import android.content.Intent;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.app.Activity;
import android.os.Bundle;
import android.widget.Toast;

import java.util.List;

public class MainActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        Uri webpage = Uri.parse("https://phocode.com");
        Intent webIntent = new Intent(Intent.ACTION_VIEW, webpage);

        PackageManager packageManager = getPackageManager();
        List activities = packageManager.queryIntentActivities(webIntent, PackageManager.MATCH_DEFAULT_ONLY);
        boolean isIntentSafe = activities.size() > 0;

        Toast.makeText(getApplicationContext(), (isIntentSafe ? "Intent is safe" : "Intent is not safe"), Toast.LENGTH_LONG).show();
    }
}

Chúng ta có thể lấy đối tượng PackageManager từ phương thức getPackageManager() của lớp Activity.

List activities = packageManager.queryIntentActivities(webIntent, PackageManager.MATCH_DEFAULT_ONLY);
boolean isIntentSafe = activities.size() > 0;

Phương thức queryIntentActivities() sẽ trả về một đối tượng List chứa danh sách các lớp Activity có thể mở được đối tượng Intent của chúng ta. Ở đây chúng ta chỉ cần xem nếu danh sách này khác rỗng thì tức là đối tượng Intent của chúng ta có thể mở được

Mở hộp thoại chọn ứng dụng

Ở ví dụ gửi tin nhắn ở trên chúng ta thấy có 2 ứng dụng có thể mở đối tượng Intent của chúng ta nên hệ điều hành sẽ hiển thị một hộp thoại cho phép người dùng lựa chọn ứng dụng để mở, ngoài ra ở dưới hộp thoại còn có 2 nút là Just OnceAlways, nút Just Once có nghĩa là ngay tại thời điểm đó chỉ chọn ứng dụng đó để sử dụng, còn các lần sau thì hệ điều hành sẽ mở lại hộp thoại để người dùng chọn ứng dụng khác, còn nút Always tức là từ nay về sau hệ điều hành sẽ sử dụng ứng dụng đó luôn chứ không bắt người dùng phải chọn lại nữa.

Tuy nhiên nếu muốn chúng ta có thể yêu cầu hệ điều hành mỗi lần chạy sẽ phải mở hộp thoại chọn ứng dụng chứ không sử dụng ứng dụng được gắn mác Always. 

Để làm việc này chúng ta tạo một đối tượng Intent và gọi phương thức createChooser() rồi truyền vào phương thức này đối tượng Intent mà chúng ta muốn sử dụng. Ví dụ:

package com.phocode;

import android.content.Intent;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.app.Activity;
import android.os.Bundle;
import android.widget.Toast;

import java.util.List;

public class MainActivity extends Activity{

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        Intent emailIntent = new Intent(Intent.ACTION_SEND);
        emailIntent.setType("text/plain");
        emailIntent.putExtra(Intent.EXTRA_EMAIL, "admin@example.com");
        emailIntent.putExtra(Intent.EXTRA_SUBJECT, "Hello");
        emailIntent.putExtra(Intent.EXTRA_TEXT, "Nice to meet you");
        startActivity(emailIntent);

        String title = "Choose app to open";
        Intent chooser = Intent.createChooser(emailIntent, title);

        if(emailIntent.resolveActivity(getPackageManager()) != null)
            startActivity(chooser);
    }
}

Phương thức createChooser() sẽ nhận đối tượng Intent mà chúng ta muốn mở và một chuỗi hiển thị tiêu đề cho hộp thoại.

if(emailIntent.resolveActivity(getPackageManager()) != null)
    startActivity(chooser);

Đoạn code trên chỉ là kiểm tra xem đối tương Intent của chúng ta có ứng dụng nào có thể mở được hay không thôi, nếu có thì mới cho hiển thị hộp thoại chọn ứng dụng.

Capture

Hộp thoại chọn ứng dụng theo cách này sẽ không có 2 nút Just OnceAlways.

0 0 votes
Article Rating
Subscribe
Thông báo cho tôi qua email khi
guest

This site uses Akismet to reduce spam. Learn how your comment data is processed.

0 Comments
Inline Feedbacks
View all comments