2012-06-13 30 views
30

Tôi muốn hiển thị trình chọn hoạt động hiển thị tất cả các ứng dụng có thể xem và/hoặc CHỈNH SỬA một số dữ liệu. Có cách nào dễ dàng để thực hiện việc này hay tôi phải triển khai hộp thoại chọn hoạt động của riêng mình? Hoặc có lẽ tôi chỉ có thể phân lớp Intent? Cảm ơn.Cách thực hiện ý định với nhiều hành động

+0

Mẫu mã thanh toán: https://gist.github.com/gelldur/9c199654c91b13478979 –

Trả lời

55

Tôi tìm thấy một giải pháp phần bằng cách sử dụng EXTRA_INITIAL_INTENTS:

Intent viewIntent = new Intent(Intent.ACTION_VIEW); 
Intent editIntent = new Intent(Intent.ACTION_EDIT); 
viewIntent.setDataAndType(uri, type); 
editIntent.setDataAndType(uri, type); 
Intent chooserIntent = Intent.createChooser(editIntent, "Open in..."); 
chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, new Intent[] { viewIntent }); 
startActivity(chooserIntent); 

tôi nói một phần bởi vì nếu một ứng dụng hỗ trợ cả ACTION_VIEW và ACTION_EDIT nó sẽ hiển thị hai lần trong danh sách, một trong số đó sẽ mở file để xem và cái kia để chỉnh sửa, và bạn sẽ không nhất thiết phải biết cái nào. Tôi nghĩ rằng một giải pháp hoàn chỉnh sẽ yêu cầu trình chọn ứng dụng tùy chỉnh, như Tim đề xuất.

EDIT (Hoàn thành giải pháp!):

Tôi tìm thấy một giải pháp mà không liên quan đến việc viết một tính năng chọn ứng dụng tùy chỉnh. Để phân biệt các ứng dụng ACTION_EDIT từ ứng dụng ACTION_VIEW, tôi đã tìm cách thêm chuỗi "(để chỉnh sửa)" vào nhãn cho một trong số chúng (trong trường hợp của tôi, ACTION_EDIT) bằng cách sử dụng dòng mã Tim được cung cấp. Ngoài ra, để đảm bảo chuỗi nối không xuất hiện để trở thành một phần của tên ứng dụng, tôi đã thay đổi màu sắc của nó để cyan:

PackageManager pm = kyoPrint.getPackageManager(); 
Intent viewIntent = new Intent(Intent.ACTION_VIEW); 
Intent editIntent = new Intent(Intent.ACTION_EDIT); 
viewIntent.setDataAndType(uri, type); 
editIntent.setDataAndType(uri, type); 
Intent openInChooser = Intent.createChooser(viewIntent, "Open in..."); 

// Append " (for editing)" to applicable apps, otherwise they will show up twice identically 
Spannable forEditing = new SpannableString(" (for editing)"); 
forEditing.setSpan(new ForegroundColorSpan(Color.CYAN), 0, forEditing.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); 
List<ResolveInfo> resInfo = pm.queryIntentActivities(editIntent, 0); 
Intent[] extraIntents = new Intent[resInfo.size()]; 
for (int i = 0; i < resInfo.size(); i++) { 
    // Extract the label, append it, and repackage it in a LabeledIntent 
    ResolveInfo ri = resInfo.get(i); 
    String packageName = ri.activityInfo.packageName; 
    Intent intent = new Intent(); 
    intent.setComponent(new ComponentName(packageName, ri.activityInfo.name)); 
    intent.setAction(Intent.ACTION_EDIT); 
    intent.setDataAndType(uri, type); 
    CharSequence label = TextUtils.concat(ri.loadLabel(pm), forEditing); 
    extraIntents[i] = new LabeledIntent(intent, packageName, label, ri.icon); 
} 

openInChooser.putExtra(Intent.EXTRA_INITIAL_INTENTS, extraIntents); 
startActivity(openInChooser); 

enter image description here

EDIT 2: BUG

Nếu không có hoạt động nào được tìm thấy theo ý định đầu tiên, KHÔNG có hoạt động nào sẽ được hiển thị, bao gồm bất kỳ hoạt động nào được tìm thấy theo ý định thứ hai. Tôi đã kết thúc việc viết nhạc cho riêng mình. Tôi chỉ điền một ExpandableListView với các tiêu đề cho từng loại mục đích với các hoạt động tương ứng của chúng với tư cách là trẻ em (được lưu trữ dưới dạng các LabeledIntents riêng lẻ).

+0

Câu trả lời hay!Tôi muốn làm một Chooser với Intents đến từ nhiều loại khác nhau và thậm chí là một hoạt động trong ứng dụng, và điều này cho phép tôi hợp nhất tất cả trong một Chooser duy nhất. – nobre

+0

Điều này thật tuyệt vời !! Tôi muốn khởi chạy càng nhiều trình duyệt càng tốt để xem tệp HTML cục bộ bằng cách sử dụng tất cả các ý định khác nhau mà tôi đã khám phá. Điều này hoạt động hoàn hảo, cảm ơn bạn. – daveD

+0

@Ken có thể tránh các mục trùng lặp trong trình chọn không? Tôi đang nói về các mục tồn tại từ một mục đích và cũng trong mục đích khác? Tôi đang cố gắng tạo ra một lựa chọn cho việc chia sẻ, và muốn đặt tin nhắn là viết tắt của tin nhắn SMS, nhưng tôi không thể tìm hiểu làm thế nào để làm điều đó. –

4

phụ thuộc vào dữ liệu của bạn. Nhưng nói chung bằng cách sử dụng với ACTION_VIEW và một số dữ liệu kèm theo, bạn có thể sử dụng IntentChoooser để điền danh sách các lựa chọn cho người dùng.

Intent intent = new Intent(Intent.ACTION_VIEW); 
intent.setType("text/plain"); 
intent.putExtra(Intent.EXTRA_TEXT, "some data"); 
startActivity(Intent.createChooser(intent, "Open with")); 

Đảm bảo đặt đúng loại để ứng dụng biết rằng bạn muốn mở thứ gì đó mà họ có thể xử lý.

EDIT: Tôi nghĩ bạn sẽ phải sử dụng truy vấn trình quản lý gói để kết hợp chúng thành một và thực hiện hoạt động/hộp thoại của bạn danh sách kết hợp.

Dưới đây là một ví dụ làm cho truy vấn:

List<ResolveInfo> resInfo = getPackageManager().queryIntentActivities(intent, 0); 

vì vậy nếu bạn thực hiện hai Intents của bạn và gọi đây là hai lần, đi qua trong mỗi ý bạn sẽ có thể kết hợp các danh sách kết quả để có được tập hợp đầy đủ lại khả năng. Sau đó, nó là để tạo ra một hoạt động hoặc hộp thoại để hiển thị chúng với.

+0

Tôi muốn hiển thị tất cả các ứng dụng hỗ trợ ACTION_VIEW ** hoặc ** ACTION_EDIT, không chỉ ACTION_VIEW – Ken

+0

Ahh, tôi hiểu. Bạn sẽ phải tự mình làm thêm một chút nữa. Xem chỉnh sửa của tôi. – FoamyGuy

Các vấn đề liên quan