Sách

Thứ Hai, 24 tháng 6, 2019

Đào tạo android

1. Tài liệu tự học:

- Kênh youtube tham khảo:
+ https://www.youtube.com/user/khoazend/playlists
- Lộ trình tự học tham khảo:
+ https://khoapham.vn/khoa-hoc-lap-trinh-android.html
+ http://itplus-academy.edu.vn/Khoa-hoc-lap-trinh-ung-dung-di-dong-Android.html
+ https://techmaster.vn/khoa-hoc/25513/lap-trinhandroid

2. Công việc:
- Xây dựng màn hình tab EDM của app Keeng. Yêu cầu:
+ Hiển thị đầy đủ dữ liệu lên màn hình (giao diện giống hệt tab EDM app Keeng hiện tại)
+ Click vào mỗi item đều có phản hồi
+ Có cache dữ liệu khi mở app lên mà không có mạng
+ Tự động load lại dữ liệu khi từ trạng thái mất mạng -> có mạng
+ Chơi được video và audio.

API lấy dữ liệu: /ws/edm/getHomeEdmV1
Method: GET
Header:
+ version: version name của ứng dụng
+ session_token: t:s:425f539317e5d9c79216ccc1c37954b2d81d9ab5
+ country_code: VN
+ device_id: imei của máy
+ client_type: 1
+ revision: version code của ứng dụng
+ language_code: vi
+ local_code: 84
Param:
+ platform: keeng

API log hành vi click: /ws/social/user/log
Method: POST
Header:
+ version: version name của ứng dụng
+ session_token: t:s:425f539317e5d9c79216ccc1c37954b2d81d9ab5
+ country_code: VN
+ device_id: imei của máy
+ client_type: 1
+ revision: version code của ứng dụng
+ language_code: vi
+ local_code: 84
Param:
+ item_type: item_type của object trong api getHomeEdmV1 trả về
+ is_feed: 1
+ item_id: id của object trong api getHomeEdmV1 trả về
+ action_type: 1

3. Kết quả cần thu được:
- Có hiểu biết xây dựng ứng dụng từ việc tạo project
- Có kiến thức cơ bản về kiến trúc ứng dụng
- Nắm vững các kiến thức về các vòng đời: activity, fragment. Các giao tiếp giữa activity với activity, fragment với fragment, activity với fragment.
- Có kiến thức cơ bản về service, broadcast.
- Biết sử dụng thư viện để load ảnh, cache ảnh
- Biết sử dụng SQLite thiết kế database cho ứng dụng
- Biết sử dụng cache
- Biết sử dựng thư viện để gọi API kết nối với server
- Biết sử dụng thư viện để chơi nhạc, video

Thứ Tư, 6 tháng 3, 2019

[Android] Lấy danh sách tất cả ứng dụng trong thiết bị

public static List<AppInfo> getInstalledPackages(Context context) {
//todo get all applications has installed on device.
PackageManager packageManager = context.getPackageManager();
List<AppInfo> list = new ArrayList<>();
List<PackageInfo> packs = packageManager.getInstalledPackages(0);

for (PackageInfo packageInfo : packs) {
try {
AppInfo item = new AppInfo();
ApplicationInfo applicationInfo = packageInfo.applicationInfo;
item.setName(applicationInfo.loadLabel(packageManager));
item.setPackageName(packageInfo.packageName);
item.setVersionName(packageInfo.versionName);
item.setVersionCode(packageInfo.versionCode);
item.setDescription(applicationInfo.loadDescription(packageManager));
item.setIcon(applicationInfo.loadIcon(packageManager));
//item.setLogo(applicationInfo.loadLogo(packageManager));
//item.setBanner(applicationInfo.loadBanner(packageManager));
item.setSystem(((applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0));

//todo get all requested permissions of application
PackageInfo packageInfoPermissions =
packageManager.getPackageInfo(packageInfo.packageName, PackageManager.GET_PERMISSIONS);
if (packageInfoPermissions != null) {
String[] requestedPermissions = packageInfoPermissions.requestedPermissions;
if (requestedPermissions != null) {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < requestedPermissions.length; i++) {
sb.append((i + 1));
sb.append(". ");
sb.append(requestedPermissions[i]);
sb.append("\n");
}
item.setPermission(sb.toString());
}
}
list.add(item);
} catch (OutOfMemoryError | Exception e) {
e.printStackTrace();
}
}
if (list.size() > 0) {
Comparator comparator = new Comparator<AppInfo>() {
@Override
public int compare(final AppInfo leftObject, final AppInfo rightObject) {
return leftObject.getName().compareToIgnoreCase(rightObject.getName());
}
};
Collections.sort(list, comparator);
}
Log.i(TAG, "getInstalledPackages: " + list);
return list;
}

public class AppInfo implements Serializable {
String packageName;
String versionName;
int versionCode;
String name;
String description;
Drawable logo;
Drawable icon;
Drawable banner;
boolean isSystem;
String permission;

public AppInfo() {
}

public String getPackageName() {
return packageName;
}

public void setPackageName(final String packageName) {
this.packageName = packageName;
}

public String getVersionName() {
return versionName;
}

public void setVersionName(final String versionName) {
this.versionName = versionName;
}

public int getVersionCode() {
return versionCode;
}

public void setVersionCode(final int versionCode) {
this.versionCode = versionCode;
}

public String getName() {
if (name == null)
name = "";
return name;
}

public void setName(final CharSequence name) {
if (name != null)
this.name = name.toString();
else
this.name = "";
}

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

public String getDescription() {
return description;
}

public void setDescription(final CharSequence description) {
if (description != null)
this.description = description.toString();
else
this.description = "";
}

public void setDescription(final String description) {
this.description = description;
}

public Drawable getLogo() {
return logo;
}

public void setLogo(final Drawable logo) {
this.logo = logo;
}

public Drawable getIcon() {
return icon;
}

public void setIcon(final Drawable icon) {
this.icon = icon;
}

public Drawable getBanner() {
return banner;
}

public void setBanner(final Drawable banner) {
this.banner = banner;
}

public boolean isSystem() {
return isSystem;
}

public void setSystem(final boolean system) {
isSystem = system;
}

public String getPermission() {
return permission;
}

public void setPermission(String permission) {
this.permission = permission;
}

@Override
public String toString() {
return "\n{" +
"packageName='" + packageName + '\'' +
", versionName='" + versionName + '\'' +
", versionCode=" + versionCode +
", name='" + name + '\'' +
", description='" + description + '\'' +
", isSystem=" + isSystem +
'}';
}
}

Thứ Hai, 4 tháng 3, 2019

[ffmpeg Tutorial] Convert Video Thành Webm Với Ffmpeg

Câu lệnh convert video thành WEBM

Định dạng WEBM sử dụng chuẩn codec vp8 của Google. Và để convert video thành WEBM với FFmpeg, bạn có thể sử dụng thư viện libvpx để encode video và thư viện libvorbis để encode audio.
Câu lệnh cơ bản:
ffmpeg -i input.mp4 -f webm -c:v libvpx -b:v 1M -c:a libvorbis output.webm -hide_banner
Trong đó:
  • -i là cờ dùng để xác định input, sau đó là tên file (input.mp4)
  • -f dùng để xác định format của file output, sau đó là tên định dạng (webm).
  • -c:v dùng để xác định codec sử dụng cho video, sau đó là tên thư viện sử dụng libvpx
  • -b:v dùng để xác định bitrate cho video đầu ra. Sau đó là số bitrate 1M. Chú ý: ở đây mình sử dụng số liệu chính xác là 1M. Trong khi với MP4, mình chỉ có thể xác định maxrate.
  • -c:a dùng để xác định codec sử dụng cho audio, sau đó là tên thư viện sử dụng libvorbis
  • output.webm là tên file output.
  • -hide_banner dùng để ẩn những thông tin liên quan đến FFmpeg (phiên bản, các thư viện sử dụng,…)
Kết quả:
Convert video thành WEBM
Convert video thành WEBM
Ngoài ra, bạn cũng có thể thêm các tham số để điều chỉnh về độ phân giải (-vf scale=1280:729) hoặc tốc độ framerate (-r 20),… để được kết quả như mong đợi.

So sánh WEBM với MP4

  • WEBM sử dụng thư viện libvpx để encode video theo chuẩn vp8 và thư viện libvorbis để encode audio. Còn MP4 sử dụng thư viện libx264 để encode video theo chuẩn H264 và thư viện aac để encode audio.
  • Convert video thành WEBM thường lâu hơn rất nhiều so với convert video thành MP4.
  • WEBM nén tốt hơn, cho video chất lượng tốt hơn với dung lượng nhỏ hơn MP4.
  • WEBM phù hợp với việc sử dụng video trên nền web. Tuy nhiên, không phải trình duyệt nào cũng hỗ trợ như MP4.

Lời kết

Trên đây là câu lệnh cơ bản để convert video thành WEBM với FFmpeg. Nếu có gì thắc mắc, vui lòng để lại câu hỏi trong phần bình luận nhé. Mình sẽ cố gắng giải đáp nếu có thể.
Xin chào và hẹn gặp lại!