Friday, September 11, 2015

Android Notification (căn bản về thông báo trong Android)

Notification là dạng thông báo xuất hiện ở phần trên cùng của màn hình, dạng thông báo này hiện giời được hỗ trợ trên cả 3 nền tảng phổ biến hiện này: Android, iOS và WindowPhone.



Android cung cấp thư viện NotificationCompat.Builder, Notification để tạo các thông báo này.

  1. NotificationCompat.Builder.build(): để tạo một thông báo

  2. Phương thức notify() của Notification: để cập nhật thông báo

  3. setSmalIcon: chỉ định icon của thông báo

  4. setContentTitle: Tiêu đề thông báo

  5. setContentText: Nội dung thông báo



Ví dụ tạo một thông báo:
[sourcecode language="java"]
Notification.Builder mBuilder = new Notification.Builder(this);
mBuilder.setContentTitle("Tin nhắn mới");
mBuilder.setContentText("Có điểm thực hành môn Android.");
mBuilder.setTicker("Thông báo!"); mBuilder.setSmallIcon(R.drawable.ic_launcher);
[/sourcecode]

Cập nhật thông báo
[sourcecode language="java"]
mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
/* cập nhật thông báo */
mNotificationManager.notify(notificationID, mBuilder.build());
[/sourcecode]

Thông thường các ứng dụng cấu hình khi người dùng chạm lên thông báo thì hệ thống sẽ mở lại ứng dụng đã phát sinh thông báo. Để Android có thể mở lại một ứng dụng đã thông báo (có thể là bất kỳ ứng dụng nào) hợp lệ thì chúng ta cần phải thông qua đối tượng hỗ trợ là PendingIntent

Ví dụ sau đây thực hiện theo mô tả bên trên.

[sourcecode language="java"]
/* Tạo đối tượng chỉ đến activity sẽ mở khi chọn thông báo */
Intent resultIntent = new Intent(this, NotificationView.class);
TaskStackBuilder stackBuilder = TaskStackBuilder.create(this);
stackBuilder.addParentStack(NotificationView.class);
// kèm dữ liệu theo activity để xử lý
resultIntent.putExtra("events",new String[] { "Có điểm thực hành môn Android" });
resultIntent.putExtra("id",notificationID);
/* Đăng ký activity được gọi khi chọn thông báo */
stackBuilder.addNextIntent(resultIntent);
PendingIntent resultPendingIntent = stackBuilder.getPendingIntent(0,
PendingIntent.FLAG_UPDATE_CURRENT);
mBuilder.setContentIntent(resultPendingIntent);
[/sourcecode]

Sau khi mở ứng dụng (NotificationView) đã phát sinh thông báo qua hỗ trợ của PendingIntent chúng ta có thể xóa thông báo báo với phương thức cancel từ NotificartioManager

Ví dụ như sau:
[sourcecode language="java"]
NotificationManager mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
mNotificationManager.cancel(i.getIntExtra("id", 0));
[/sourcecode]

Notification có 2 dạng cơ bản là dạng đơn và dạng danh sách.
Ví dụ:
Snap 2015-09-10 at 16.57.29
Mã nguồn ở
đây

Thursday, September 10, 2015

Direct access to SQL Server From Android

Sử dụng thư viện JTDS --> http://sourceforge.net/projects/jtds/  để truy cập SQL Server từ Android

[embed]https://youtu.be/8cp8ykUNmL4[/embed]

Download thư viện từ đây

Kết nối với SQL Server như sau:
[sourcecode language="java"]
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);
Class.forName("net.sourceforge.jtds.jdbc.Driver").newInstance();
conn = DriverManager
.getConnection(""
+ "jdbc:jtds:sqlserver://172.16.160.81/northwind;instance=SQL2008;"
+ "user=sa;password=sa;");
[/sourcecode]

net.sourceforge.jtds.jdbc.Driver là dạng Drive truy cập SQL Server.

Thêm dữ liệu

[sourcecode language="java"]
comm = conn.prepareStatement("insert into Employees("
+ "firstname, lastname) values(?,?)");
comm.setString(1, etFirst.getText().toString());
comm.setString(2, etLast.getText().toString());
comm.executeUpdate();
[/sourcecode]

Đọc dữ liệu

[sourcecode language="java"]
comm = conn.createStatement();
ResultSet rs = comm.executeQuery("Select EmployeeID, Firstname From Employees");
String msg = "";
while (rs.next()) {
msg += "\nID: " + rs.getInt("EmployeeID") + " Name: "
+ rs.getString("Firstname");
[/sourcecode]

Giao diện

[sourcecode language="html"]
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/LinearLayout1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context="${relativePackage}.${activityClass}" >

<EditText
android:id="@+id/etFirstName"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="4dp"
android:background="#eeeeee"
android:hint="Firstname"
android:textColor="#000000"
android:textSize="24dp" >

<requestFocus />
</EditText>

<EditText
android:id="@+id/etLastName"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#eeeeee"
android:hint="Lastname"
android:padding="4dp"
android:textColor="#000000"
android:textSize="24dp" />

<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="4dp" >

<Button
android:id="@+id/btnConnect"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="Connect" />

<Button
android:id="@+id/btnAdd"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="Add new" />
</LinearLayout>

<TextView
android:id="@+id/tvDs"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#ffffff"
android:padding="8dp"
android:text=""
android:textAppearance="?android:attr/textAppearanceMedium" />
</LinearLayout>
[/sourcecode]

Mã nguồn tham khảo https://drive.google.com/file/d/0B2F9IAasWwaNYVZSc2tiZDNlNTA/view?usp=sharing

Wednesday, September 9, 2015

kiểm tra tính tương thích của ứng Android trên các thiết bị chạy chip intel

http://testdroid.com/news/free-android-app-game-and-web-testing-on-intel-devices

một bài hướng dẫn kiểm tra tương thích rất chi tiết

Tuesday, September 8, 2015

https://www.aspsms.com một dịch vụ gởi tin nhắn SMS

Tìm mãi mới thấy cái dịch vụ này
https://www.aspsms.com

Http/Https Client cho Android

Thư viện giao tiếp qua http và https cho Android
https://github.com/loopj/android-async-http/wiki

Friday, September 4, 2015

Sử dụng ValueChangeEvent tren Java Server Face

Một ví dụ sử dụng sự kiện ValueChangeEvent trên Face cho các bạn học viên mới tìm hiểu JSF
face_ValueChangeEvent1
Chọn loại sản phẩm -> danh sách sản phẩm sẽ được lọc lại:
face_ValueChangeEvent2

1. Tạo website sử dụng framework Face 2x (1x cũng được)
2. Định nghĩa 2 ManageBean (Products và Categories) và 2 JavaBean (Product và Category)
3. Thiết kế giao diện trang index.xhtml

Trong ví dụng này tôi sử dụng Netbean để demo
Tạo ManageBean (Products và Categories)
- File -> New File -> Other -> Java Server Face -> JSF ManageBean
Products
[sourcecode language="java"]
package codes;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.Collection;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.RequestScoped;
import javax.faces.event.ValueChangeEvent;
/**
*
* @author ntdan
*/
@ManagedBean
@RequestScoped
public class Products {

/**
* Creates a new instance of Products
*/
public Products() {
}

private Collection list;
private int id;
private int cid;

public int getCid() {
return cid;
}

public void setCid(int cid) {
this.cid = cid;
}
private String name;
private String price;

public int getId() {
return id;
}

public void setId(int id) {
this.id = id;
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public String getPrice() {
return price;
}

public void setPrice(String price) {
this.price = price;
}

public Collection getList() {
return list;
}

public void select_cid_change(ValueChangeEvent event)
{
try {
Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver");
Connection conn = DriverManager.getConnection("jdbc:sqlserver://172.16.160.81\\sql2008;"
+ "database=northwind;","sa","sa");

PreparedStatement comm = conn.prepareStatement("Select categoryid, productid, productname, unitprice"
+ " from products where categoryID=?");
comm.setInt(1, Integer.parseInt(event.getNewValue().toString()));
ResultSet rs = comm.executeQuery();

list = new ArrayList<Product>();
Product pro;

while(rs.next())
{
pro = new Product();
pro.setId(rs.getInt("productid"));
pro.setcId(rs.getInt("categoryid"));
pro.setName(rs.getString("productname"));
pro.setPrice(rs.getString("unitprice"));

list.add(pro);
}
} catch (Exception e) {
list = null;
}
}
}
[/sourcecode]

Categories
[sourcecode language="java"]
package codes;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.Collection;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.RequestScoped;
/**
*
* @author ntdan
*/
@ManagedBean
@RequestScoped
public class Categories {
public Categories() {
}

private int id;
private String name;

public int getId() {
return id;
}

public void setId(int id) {
this.id = id;
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}
private Collection list;

public Collection getList() {
try {
Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver");
Connection conn = DriverManager.getConnection("jdbc:sqlserver://172.16.160.81\\sql2008;"
+ "database=northwind;", "sa", "sa");

PreparedStatement comm = conn.prepareStatement("Select categoryid, categoryname"
+ " from categories");

ResultSet rs = comm.executeQuery();

list = new ArrayList<Category>();
Category ca;

while (rs.next()) {
ca = new Category();
ca.setId(rs.getInt("categoryid"));
ca.setName(rs.getString("categoryname"));
list.add(ca);
}
} catch (Exception e) {
list = null;
}
return list;
}
}
[/sourcecode]

Tạo 2 javabean như sau
- File -> New File -> Java Class
Product
[sourcecode language="java"]
package codes;
public class Product {
public Product() {
}

private int id;
private int cId;
private String name;
private String price;

public int getId() {
return id;
}

public void setId(int id) {
this.id = id;
}

public int getcId() {
return cId;
}

public void setcId(int cId) {
this.cId = cId;
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public String getPrice() {
return price;
}

public void setPrice(String price) {
this.price = price;
}
}
[/sourcecode]

Category
[sourcecode language="java"]
package codes;
public class Category {
public Category() {
}

private int id;
private String name;

public int getId() {
return id;
}

public void setId(int id) {
this.id = id;
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}
}
[/sourcecode]

Thiết kế giao diện xhtml
[sourcecode language="html"]
<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://xmlns.jcp.org/jsf/html"
xmlns:f="http://xmlns.jcp.org/jsf/core">
<h:head>
<title>Value Change Event</title>
<link type="text/css" rel="stylesheet" href="//codeproject.cachefly.net/App_Themes/CodeProject/Css/Main.min.css?dt=2.8.150901.1"></link>
</h:head>
<h:body>

<f:view>
<h:form>
Categories:<br/>
<h:selectOneMenu onchange="submit();"
value="#{products.cid}"
valueChangeListener="#{products.select_cid_change}">
<f:selectItems value="#{categories.list}" var="sate"
itemLabel="#{sate.name}"
itemValue="#{sate.id}"/>
</h:selectOneMenu>

<h:dataTable border="1" id="t" width="100%"
value="#{products.list}" var="product">
<h:column>
<f:facet name="header">
ID
</f:facet>
<h:outputText value="#{product.id}"/>
</h:column>

<h:column>
<f:facet name="header">
Name
</f:facet>
<h:outputText value="#{product.name}"/>
</h:column>

<h:column>
<f:facet name="header">
Price
</f:facet>
<h:outputText value="#{product.price}"/>
</h:column>
<h:column>
<f:facet name="header">
Operation
</f:facet>
<h:commandLink value="Delete" action="index"/>
</h:column>
</h:dataTable>
</h:form>
</f:view>

</h:body>
</html>
[/sourcecode]
f:selectItems: sẽ render các phần tử (thẻ option của HTML) cho hộp chọn (thẻ select của HTML) với nội dung giữa thẻ option là tên nhóm sản phẩm (itemLabel="#{sate.name}") và thuộc tính value của option sẽ được điền mã nhóm (itemValue="#{sate.id}").

Mỗi khi chọn một phần tử trong hộp chọn sự kiện onchange sẽ phát sinh (HTML), chúng ta có thể đón nhận sự kiện này dưới ManageBean qua thuộc tính valueChangeListener="#{products.select_cid_change}" của selectOneMenu để xử lý sự kiên và cập nhật lại danh sách sản phẩm.

Mã nguồn tham khảo --> ở đây

Translate