– Ở bài tập 24 và bài tập 25 Tôi đã hướng dẫn rất kỹ về cách sử dụng Intent (các intent này còn gọi làExplicit Intent).

– Trong bài tập 26 Tôi sẽ hướng dẫn bạn cách sử dụng Implicit Intent (bạn cứ hiểu nôm na là những Intent được xây dựng sẵn, được cung cấp sẵn trong hệ điều hành Android). Tạm thời bạn cứ hiểu như vậy đi, nếu như Tôi sai thì Tôi sẽ sửa lại sau, vì có thể có nhiều cách hiểu khác hay hơn Tôi nhiều.

– Tôi đặt vấn đề như sau:

+ Một ngày đẹp trời khủng khiếp nào đó chẳng hạn 3h giờ ngày 13 tháng 3 năm 2013, “Dế” đáng ghét của bạn bị rớt xuống nền nhà cái bạch bạch bạch…. bị mẻ, méo mấy miếng và hư luôn chương trình gọi điện thoại và nhắn tin SMS (bị hư 2 chức năng này, nhưng mà “Dế Mẻ” đó vẫn hoạt động). Không ai thèm sửa Dế cho bạn, xui cái bạn đang học Android lớp của Tôi, Tôi yêu cầu bạn phải tự lập trình ra chức năng Gọi điện thoại và nhắn tin SMS cho Dế đó (dĩ nhiên thiết bị của bạn sử dụng Android OS). Vậy bạn phải làm rồi, vì không làm sẽ bị 0 điểm.

+ Vậy dùng những kỹ thuật nào để có thể viết được chức năng nghe gọi+ nhắn tin SMS thay thế cho chương trình có sẵn của Android?

+ Tôi sẽ hướng dẫn các bạn vào buổi sau, bạn hãy chú ý theo dõi. Trong thời gian chờ đợi thì Tôi khuyên các bạn phải làm đi làm lại bài tập 24 và bài tập 25.

– Tôi giới hạn bài tập này như sau: Bài tập này đơn thuần chỉ là cho phép nhập tên và số điện thoại vào bộ nhớ (không phải danh bạ điện thoại) sau đó hiển thị danh sách này vào ListView, ListView sẽ cung cấp ContextMenu có 2 mục: “Gọi điện thoại” và “Nhắn tin”. Qua phần Content Provider và Telephony API các bạn sẽ được học kỹ hơn về cách lấy danh bạ từ điện thoại ra, cách đọc tin nhắn trong inbox ra, cách tương tác với danh bạ và tin nhắn… Nên bài tập này các bạn xem nó như là “Chơi chơi” vui thôi.

– Mấu chốt của bài này là các bạn phải tự biết cách tạo một cuộc gọi, cách gửi tin nhắn trong Android như thế nào, mấy phần “râu ria” khác các bạn đừng bận tâm.

– Để có thể gọi điện thoại và nhắn tin thì các bạn phải khai báo trong Manifest các permission sau:

<uses-permission android:name=”android.permission.CALL_PHONE” />
<uses-permission android:name=”android.permission.SEND_SMS” />

– Bạn xem giao diện của chương trình:

26_sms_0– Nhấn “Save Contact” để lưu thông tin vào ListView như hình.

– Xử lý context menu cho ListView:

26_sms_1– Chức năng “Call to …” để gọi, màn hình gọi sẽ hiện ra như bên dưới:

26_sms_2– Chức năng “Send Sms to …“, cho ra màn hình gửi tin nhắn như bên dưới:

26_sms_3– Nhấn “Send Message” để gửi. Ở đây Tôi muốn nói các bạn rằng có 2 hành vi gửi tin nhắn.

1) gửi tin nhắn mà không biết kết quả thành công hay không (dễ dàng, những mà không nên. Trường hợp này thường xuyển sảy ra. Tôi lấy cụ thể trường hợp của Tôi, nhà Tôi ở trên Núi sóng thường yếu và không liên lạc được, nếu viết theo cách này thì Bạn sẽ không biết là gửi cho Tôi thành công hay không.)

Ví dụ: Viết như bên dưới thì có thể gửi được tin nhắn ở trường hợp bình thường, không kiểm tra kết quả trả về (Còn kiểm tra kết quả trả về bạn xem trong coding đầy đủ).

final SmsManager sms SmsManager.getDefault();

sms.sendTextMessage(  “0987773061″, null, “Hello teo teo!”, null, null);

2) gửi tin nhắn có kiểm tra kết quả thành công (ta nên dùng cách này, nhưng mà khó vì các bạn chưa học IntentFilter, nhưng Tôi vẫn đưa vào, có gì các bạn tìm hiểu sau)

– Bây giờ bạn xem cấu tạo chương trình:

26_sms_4– Giao diện chính activity_main.xml:

26_sms_5

– Xem source XML activity_main.xml:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
 android:id="@+id/LinearLayout1"
 android:layout_width="match_parent"
 android:layout_height="match_parent"
 android:orientation="vertical"
 tools:context=".MainActivity" >
<TableLayout
 android:layout_width="match_parent"
 android:layout_height="wrap_content"
 android:stretchColumns="*" >
<TableRow
 android:id="@+id/tableRow1"
 android:layout_width="wrap_content"
 android:layout_height="wrap_content" >
<TextView
 android:id="@+id/textView1"
 android:layout_width="wrap_content"
 android:layout_height="wrap_content"
 android:layout_span="2"
 android:background="#008000"
 android:gravity="center"
 android:text="&quot;Chơi Chơi&quot; Phone Utility"
 android:textColor="#FFFFFF"
 android:textSize="15sp" />
 </TableRow>
<TableRow
 android:id="@+id/tableRow2"
 android:layout_width="wrap_content"
 android:layout_height="wrap_content" >
<TextView
 android:id="@+id/textView2"
 android:layout_width="wrap_content"
 android:layout_height="wrap_content"
 android:text="Name:" />
<EditText
 android:id="@+id/editName"
 android:layout_width="wrap_content"
 android:layout_height="wrap_content"
 android:ems="10" >
<requestFocus />
 </EditText>
 </TableRow>
<TableRow
 android:id="@+id/tableRow3"
 android:layout_width="wrap_content"
 android:layout_height="wrap_content" >
<TextView
 android:id="@+id/textView3"
 android:layout_width="wrap_content"
 android:layout_height="wrap_content"
 android:text="Phone:" />
<EditText
 android:id="@+id/editPhone"
 android:layout_width="wrap_content"
 android:layout_height="wrap_content"
 android:ems="10"
 android:inputType="phone" />
 </TableRow>
<TableRow
 android:id="@+id/tableRow4"
 android:layout_width="wrap_content"
 android:layout_height="wrap_content" >
<Button
 android:id="@+id/btnSaveContact"
 android:layout_width="wrap_content"
 android:layout_height="wrap_content"
 android:layout_column="1"
 android:text="Save Contact" />
 </TableRow>
 </TableLayout>
<TextView
 android:id="@+id/textView4"
 android:layout_width="match_parent"
 android:layout_height="wrap_content"
 android:background="#008000" />
<ListView
 android:id="@+id/lvContact"
 android:layout_width="match_parent"
 android:layout_height="wrap_content" >
 </ListView>
</LinearLayout>

– Các XML resource khác các bạn tự xem trong project.

– Class MyContact:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
package tranduythanh.com;
import java.io.Serializable;
public class MyContact implements Serializable{
 /**
 *
 */
 private static final long serialVersionUID = 1L;
 private String name;
 private String phone;
 public String getName() {
 return name;
 }
 public void setName(String name) {
 this.name = name;
 }
 public String getPhone() {
 return phone;
 }
 public void setPhone(String phone) {
 this.phone = phone;
 }
 public MyContact(String name, String phone) {
 super();
 this.name = name;
 this.phone = phone;
 }
 public MyContact() {
 super();
 }
 @Override
 public String toString() {
 return this.name+"["+this.phone+"]";
 }
}

– Class xử lý MainActivity:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
package tranduythanh.com;
import java.util.ArrayList;
import android.net.Uri;
import android.os.Bundle;
import android.app.Activity;
import android.content.Intent;
import android.view.ContextMenu;
import android.view.MenuItem;
import android.view.View;
import android.view.ContextMenu.ContextMenuInfo;
import android.view.View.OnClickListener;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemLongClickListener;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ListView;
public class MainActivity extends Activity {
EditText editName,editPhone;
 Button btnSave;
 ListView lvContact;
 //Danh sách contact để đưa vào ListView
 ArrayList<MyContact>arrContact=new ArrayList<MyContact>();
 ArrayAdapter<MyContact>adapter=null;
 MyContact selectedContact=null;
 @Override
 protected void onCreate(Bundle savedInstanceState) {
 super.onCreate(savedInstanceState);
 setContentView(R.layout.activity_main);
 doGetFormWidgets();
 doAddEvents();
 }
 public void doGetFormWidgets()
 {
 btnSave=(Button) findViewById(R.id.btnSaveContact);
 editName=(EditText) findViewById(R.id.editName);
 editPhone=(EditText) findViewById(R.id.editPhone);
 lvContact=(ListView) findViewById(R.id.lvContact);
 //tạo đối tượng adapter
 adapter=new ArrayAdapter<MyContact>
 (this, android.R.layout.simple_list_item_1,arrContact);
 //gán Adapter vào cho ListView
 lvContact.setAdapter(adapter);
 //thiết lập contextmenu cho ListView
 registerForContextMenu(lvContact);
 }
 public void doAddEvents()
 {
 btnSave.setOnClickListener(new OnClickListener() {
@Override
 public void onClick(View arg0) {
 // TODO Auto-generated method stub
 doSaveContact();
 }
 });
 //lấy contact được chọn trước đó trong ListView
 //Vì khi mở context menu sẽ làm mất focus nên ta phải lưu lại trước
 //khi mở context menu
 lvContact.setOnItemLongClickListener(new OnItemLongClickListener() {
@Override
 public boolean onItemLongClick(AdapterView<?> arg0, View arg1,
 int arg2, long arg3) {
 //lưu vết contact được chọn trong ListView
 selectedContact=arrContact.get(arg2);
 return false;
 }
 });
 }
 /**
 * mỗi lần nhấn Save contact thì gọi hàm này
 * để cập nhạt contact vào List view
 * bạn lưu ý là ta chỉ làm trong bộ nhớ
 * không phải lưu vào Danh Bạ (phần này học sau)
 */
 public void doSaveContact()
 {
 MyContact ct=new MyContact();
 ct.setName(editName.getText()+"");
 ct.setPhone(editPhone.getText()+"");
 arrContact.add(ct);
 adapter.notifyDataSetChanged();
 }
 @Override
 public void onCreateContextMenu(ContextMenu menu, View v,
 ContextMenuInfo menuInfo) {
 // TODO Auto-generated method stub
 super.onCreateContextMenu(menu, v, menuInfo);
 //gắn context menu vào
 getMenuInflater().inflate(R.menu.phonecontextmenu, menu);
 menu.setHeaderTitle("Call- Sms");
 menu.getItem(0).setTitle("Call to "+selectedContact.getPhone());
 menu.getItem(1).setTitle("Send sms to "+selectedContact.getPhone());
 }
 @Override
 public boolean onContextItemSelected(MenuItem item) {
 //kiểm tra xem Menu Item nào được chọn
 switch(item.getItemId())
 {
 case R.id.mnuCall:
 doMakeCall();
 break;
 case R.id.mnuSms:
 doMakeSms();
 break;
 case R.id.mnuRemove:
 arrContact.remove(selectedContact);
 adapter.notifyDataSetChanged();
 break;
 }
 return super.onContextItemSelected(item);
 }
 /**
 * Thực hiện gọi điện thoại
 */
 public void doMakeCall()
 {
 Uri uri=Uri.parse("tel:"+selectedContact.getPhone());
 Intent i=new Intent(Intent.ACTION_CALL, uri);
 startActivity(i);
 }
 /**
 * thực hiện mở giao diện gửi tin nhắn
 * Truyền thông tin contact đang chọn qua
 * activity mới
 */
 public void doMakeSms()
 {
 Intent i=new Intent(this, MySMSActivity.class);
 Bundle b=new Bundle();
 b.putSerializable("CONTACT", selectedContact);
 i.putExtra("DATA", b);
 startActivity(i);
 }
}

-Bạn xem dòng lệnh 96 – thiết lập tiêu đề cho context menu

– Dòng lệnh  97,98  để sửa lại title cho các menuitem ứng với mỗi contact.

– Dòng lệnh 121 có hàm doMakeCall để gọi điện thoại cho số nào đó. Bạn nhìn vào nội dung bên trong để xem quy tắc tạo lệnh gọi.

– Class xử lý gửi tin nhắn MySMSActivity:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
package tranduythanh.com;
import android.os.Bundle;
import android.app.Activity;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.telephony.SmsManager;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;
public class MySMSActivity extends Activity {
Button btnSendSMS;
 EditText editContent;
 TextView txtSendTo;
 @Override
 protected void onCreate(Bundle savedInstanceState) {
 super.onCreate(savedInstanceState);
 setContentView(R.layout.activity_my_sms);
 btnSendSMS =(Button) findViewById(R.id.btnSendSms);
 editContent =(EditText) findViewById(R.id.editSMS);
 txtSendTo=(TextView) findViewById(R.id.txtSendTo);
 //Lấy thông tin từ Intent
 Intent i =getIntent();
 Bundle b=i.getBundleExtra("DATA");
 final MyContact c=(MyContact) b.getSerializable("CONTACT");
 btnSendSMS.setOnClickListener(new OnClickListener() {
@Override
 public void onClick(View v) {
 // TODO Auto-generated method stub
 sendSms(c);
 }
 });
 txtSendTo.setText("Send to : "+c.getPhone());
 }
 /**
 * hàm dùng để gửi tin nhắn có kiểm tra kết quả trả về
 * Tôi chưa giải thích ở đây được vì nó liên quan rất nhiều
 * kiến thức, khi nào tới Broadcast Receiver, telephony Tôi sẽ
 * giải thích lại
 * @param c
 */
 public void sendSms(MyContact c)
 {
 //lấy mặc định SmsManager
 final SmsManager sms = SmsManager.getDefault();
 Intent msgSent = new Intent("ACTION_MSG_SENT");
 //Khai báo pendingintent để kiểm tra kết quả
 final PendingIntent pendingMsgSent =
 PendingIntent.getBroadcast(this, 0, msgSent, 0);
 registerReceiver(new BroadcastReceiver() {
 public void onReceive(Context context, Intent intent) {
 int result = getResultCode();
 String msg="Send OK";
 if (result != Activity.RESULT_OK) {
 msg="Send failed";
 }
 Toast.makeText(MySMSActivity.this, msg,
 Toast.LENGTH_LONG).show();
 }
 }, new IntentFilter("ACTION_MSG_SENT"));
 //Gọi hàm gửi tin nhắn đi
 sms.sendTextMessage(c.getPhone(), null, editContent.getText()+"",
 pendingMsgSent, null);
 finish();
 }
}

– Dòng lệnh 51 có hàm sendSms để gửi tin nhắn đi. hàm này Tôi viết có kiểm tra kết quả gửi thành công hay không. Tôi không giải thích nhiều vì nó liên quan tới quá nhiều kiến thức. Tạm thời bạn cố gắng hiểu từng dòng lệnh Tôi giải thích ở bên trong là ok rồi.

– Bạn có thể tải coding mẫu đầy đủ ở đây:http://www.mediafire.com/?ilpeqrycsbdswzg

– Bài này là tiền đề để làm các ứng dụng khác liên quan tới Telephony.

– Đến đây coi như bạn đã tạm ổn vê Intent. Bài tập kế tiếp Tôi sẽ hướng dẫn các bạn làm về Đa ngôn ngữ trong Android, đã nói tới Mobile thì thường nó phải hỗ trợ đa ngôn ngữ (cả thế giới đều sài, với những ngôn ngữ khác nhau).

– Chúc các bạn thành công.

Nguồn: http://duythanhcse.wordpress.com/category/l%E1%BA%ADp-trinh-android/