Wednesday, November 22, 2017

Điều chỉnh giao diện ứng dụng cho iphone X

Iphone X mới ra có dải đen trên đầu màn hình.

Nếu cứ để bình thường thì phần trên ứng dụng sẽ bị che mất, có thể ảnh hưởng đến tương tác của người dùng. Ta sẽ lùi phần đầu xuống một khoảng để tránh khoảng đen đi. Để làm điều này ta cần biết chiều cao dải đen là bao nhiêu. Đây là thông số kỹ thuật của nó.

Vậy dải đen có chiều cao là 30pt, ta cũng biết kích thước màn hình của iphone X là 375x812 nên ta có thể đặt một biến tên là xle và dùng lệnh if như sau.
let c = UIScreen.mainScreen().bounds.size.height
Hoặc
let c = view.frame.size.height
        if c==812{
            xle = 30
        }
Sau đó khi set vị trí y của view như label chẳng hạn, ta dùng.
label = UILabel(frame: CGRect(x: 0, y: 15+xle, width: 320, height: 40))
Khi đó lúc chạy trên iphone X thì label sẽ tự dịch xuống một khoảng 30pt.
Vì thiết bị có chiều cao lớn hơn 800 ngoài iphone X chỉ còn các ipad màn hình lớn nên ta cũng có thể đặt trong lệnh if là c>800, lúc đó khoảng 30pt không là gì so với màn hình lớn nên không ảnh hưởng tới giao diện tổng thể.

Dùng Popover để hiển thị màn hình mới

Đôi khi ta muốn màn hình mới bật ra có dạng nổi giống như một Alert, chỉ cần thêm kiểu chuyển màn hình cho ViewController mới là Popover như sau.
let vc = second()
       
        vc.modalPresentationStyle = .Popover
        var popover = vc.popoverPresentationController   
        if let popover = vc.popoverPresentationController {      
            popover.sourceView = self.view           
            popover.sourceRect = CGRectMake(self.view.center.x,self.view.center.y+180,0,0)           
            vc.preferredContentSize = CGSizeMake(300,360)           
            popover.delegate = self
        }
       
        self.presentViewController(vc, animated: true, completion: nil)

Khi đó màn hình bật ra sẽ nổi ở giữa màn hình hiện tại, rộng 300, cao 360.


Ta sẽ phải điều chỉnh vị trí các view cho phù hợp với chiều rộng mới.

Lấy text từ trang web

Để đọc mạng lấy text từ trang web không phải thuần txt, ta dùng class sau.
class RequestTask extends AsyncTask<String, String, String>{
     @Override   
     protected String doInBackground(String... url) {
         
     HttpClient client = new DefaultHttpClient();
     HttpGet httpget = new HttpGet(url[0]);

     try {
     HttpResponse getResponse = client.execute(httpget);
     final int statusCode = getResponse.getStatusLine().getStatusCode();

     if(statusCode != HttpStatus.SC_OK) {
     Log.w("MyApp", "Download Error: " + statusCode + "| for URL: " + url);
                      return null;
                  }
     String line = "";
     StringBuilder total = new StringBuilder();
     HttpEntity getResponseEntity = getResponse.getEntity();
     BufferedReader reader = new BufferedReader(new InputStreamReader(getResponseEntity.getContent())); 

     while((line = reader.readLine()) != null) {
            total.append(line);
           }
  line = total.toString();
           return line;
          } catch (Exception e) {
             Log.w("MyApp", "Download Exception : " + e.toString());
          }
          return null;
     }
     @Override
     protected void onPostExecute(String result) {
             
     t.setText(result);
     }
     }
Gọi class bên dưới dòng setContentView, cho vào trong một progressBar để chờ.
mProgressDialog = new ProgressDialog(this);
           mProgressDialog.setMessage("Loading, please wait...");
            mProgressDialog.show();
        new Thread(new Runnable(){
            public void run(){
           
               new RequestTask().execute("http://llkqe.blogspot.com/2016/06/blog-post.html");
                if(mProgressDialog.isShowing())
                {
                   mProgressDialog.dismiss();
                }
            }
        }).start();
    }

Lúc này văn bản đọc ra trông như sau.

Để lấy được chuỗi cần dùng, ta xử lý chặt chuỗi và lấy String sau một String đặc biệt ta thêm vào trước chuỗi, ở đây là chữ “Đây”.
Khai báo mảng để add String cần lấy vào.
ArrayList<String> docmang = new ArrayList<String>();
Sau đó trong hàm @Override
          protected void onPostExecute(String result) {
Thay các dòng sau vào.
String l=result.toString();
             
String a[] = l.split(" ");
for (int i = 0; i < a.length; i++) { 
if(a[i].equals("Đây")){
docmang.add(a[i+7]);                   
  }
}
String r="";
for (int i = 0; i < docmang.size(); i++) {
r=r+docmang.get(i)+"\n";
}
t.setText(r+"");
Kết quả chạy ra sẽ như sau.

Để tránh bị crash khi không có mạng, cần kiểm tra kết nối mạng, để nếu không có mạng thì hiện Toast để người dùng biết.
Khi mới học lập trình, tôi thấy đọc ra toàn ký tự như giun dế nên nghĩ mình làm sai ở đâu đó nhưng không phải, cần xử lý thêm mới được.
Trong các sách dạy lập trình người ta dùng trang web thuần txt để làm ví dụ nên nếu không biết bạn chạy trang khác sẽ không ra giống như sách. Thực tế là phải xử lý thêm như trên, sách người ta không dạy cái ăn ngay được!
Cách này dùng để khi ta muốn làm ứng dụng cập nhật kết quả bóng đá thì post kết quả lên blog nào đó, mỗi khi người dùng mở app, ứng dụng sẽ tự vào đọc lấy kết quả ta đã post rồi xử lý cho vào chương trình.

Monday, November 13, 2017

Lưu dữ liệu với SharedPreferences

Để lưu dữ liệu trong Android ngoài cách ghi thành file txt ta cũng có thể dùng SharedPreferences.
int mode = Activity.MODE_PRIVATE;
final String MYPREFS = "mySave";
SharedPreferences save = getSharedPreferences(MYPREFS, mode);
SharedPreferences.Editor editor = save.edit();
editor.putBoolean("isTrue", true);
editor.putFloat("lastFloat", 1f);
editor.putInt("number", 2);
editor.putString("text", "Chu ghi vao");
editor.commit();

Khi lấy dữ liệu đã ghi thì dùng
final String MYPREFS = "mySave";
int mode = Activity.MODE_PRIVATE;
SharedPreferences myShare = getSharedPreferences(MYPREFS,mode);
           
boolean isTrue = myShare.getBoolean("isTrue", false);
float lastFloat = myShare.getFloat("lastFloat", 0f);
int number = myShare.getInt("number", 1);

String luu = myShare.getString("text","");
Hoặc ta có thể làm ngắn gọn hơn như sau.

final SharedPreferences.Editor edit = prefs.edit();
 edit.putInt("vi", vimoix);
 
edit.commit();  
Khi lấy thì dùng.

SharedPreferences prefs;
prefs=PreferenceManager.getDefaultSharedPreferences(this);
int so = prefs.getInt("vi", 0);
 

Để bàn phím không che TextField

Khi thiết kế giao diện, nếu TextField của bạn ở vị trí quá thấp thì khi người dùng ấn vào bàn phím hiện ra sẽ che mất TextField.
Để làm cho TextField tự cuộn lên được ta để giao diện trong một ScrollView Sc, sau dó thêm các hàm sau vào trên ngoặc đóng cuối cùng.
func keyboardShow(n:NSNotification) {
       
        let d = n.userInfo!
        var r = (d[UIKeyboardFrameEndUserInfoKey] as! NSValue).CGRectValue()
        r = self.sc.convertRect(r, fromView:nil)
        self.sc.contentInset.bottom = r.size.height+50
        self.sc.scrollIndicatorInsets.bottom = r.size.height
    }
   
    func keyboardHide(sender: NSNotification!)
    {
        sc.setContentOffset(CGPointMake(0, 0), animated: false)
    }
Sau đó bên dưới dòng super.viewDidLoad() thêm các dòng sau.
NSNotificationCenter.defaultCenter().addObserver(
            self, selector: #selector(keyboardShow),
            name: UIKeyboardWillShowNotification, object: nil)
        NSNotificationCenter.defaultCenter().addObserver(
            self, selector: #selector(ViewController.keyboardHide(_:)),
            name: UIKeyboardWillHideNotification, object: nil)

Bây giờ khi bạn chạm vào TextField nó sẽ tự cuộn lên không bị che nữa.

Thursday, October 5, 2017

Một số chú ý để tránh ứng dụng bị suspend, reject

Có một số lỗi mà khi submit app lên Play Store, bạn không để ý dễ bị mắc phải. Dấu suspend đỏ sẽ đóng vào ứng dụng trong danh sách. Sau hai hoặc ba lỗi tài khoản sẽ bị xóa, rất khó mua lại.
Việc đặt tên gói ứng dụng trùng với cái đã có trên Store chắc chắn bị reject, ứng dụng mặc định hay có tên gói mở đầu là com.example, để nguyên chữ example sẽ bị từ chối ngay từ lúc upload app. Nên tạo cho mình các tiền tố com.abcde thật đặc biệt để nó không thể trùng được.
Nếu không tự vẽ được icon, bạn đi tìm trên mạng thấy có cái rất đẹp, nhưng nó lại có bản quyền, đó là lỗi suspend phổ biến.
Hãy dùng công cụ search có chọn lọc, lấy các kết quả dùng được mọi nơi hoặc vào các trang cung cấp icon miễn phí như Clker.com để tìm.
Phần mô tả cũng hay bị bắt lỗi mô tả không chính xác, bị qui vào tội lừa đảo.
Bạn làm ứng dụng kiểm tra nói dối nói thật, hoặc bắt ma dò quỷ, mô tả y như thật rằng ứng dụng làm được việc đó sẽ rất dễ bị suspend. Cần phải nói rõ đó chỉ là giả, nhưng nói rõ vậy ứng dụng sẽ có ít lượt tải !
Nếu bạn đi copy đoạn mô tả của một ứng dụng tương tự, mà đoạn đó có gì không chính xác cho ứng dụng của bạn, cũng dễ suspend, đừng thắc mắc sao cái kia không bị !
Ứng dụng có thể bị từ chối nếu quảng cáo đính kèm vi phạm, ví dụ quảng cáo cho game bài bạc nhưng bạn lại chọn phạm vi người dùng là Everyone chẳng hạn.
Ứng dụng decode, tức là bạn không làm mà đi lấy của người khác về đổi tên package đi rồi up lên rất dễ bị từ chối, thậm chí xóa tài khoản chỉ sau một lỗi.
Nếu đi mượn ý tưởng, nhớ là phải tự code. Có hàng trăm ứng dụng 2048, không ai dám bảo chỉ mình mới nghĩ ra ý tưởng đó.
Ai cũng làm cái xe máy, nhưng tôi làm theo kiểu của tôi. Anh không thể khẳng định chỉ có mình mới có ý tưởng về cái xe máy. Vì thế mà 2048 có hàng trăm cái, Flappy Bird cũng vậy, Google không cần biết bạn copy ý tưởng hay tự nghĩ ra nhưng nó biết bạn tự code hay không.
Tài khoản nào tự code sẽ được tôn trọng hơn.
Việc lên store Apple khó hơn Play Store rất nhiều, Apple yêu cầu cao với các lập trình viên, ứng dụng có thể bị từ chối vì lý do là đơn giản. Một ứng dụng có thể bị reject nhiều lần bởi người duyệt, điều đó không ảnh hưởng tới tài khoản.
Apple không suspend, không xóa tài khoản, nhưng bạn cần đóng phí 99$ một năm.
Nếu có dùng camera, lấy vị trí location phải có thông báo tới người dùng.
Trả lời các câu hỏi khi chuẩn bị submit phải chính xác, nếu có quảng cáo mà nói không chắc chắn bị reject, không mà nói có thường được bỏ qua !
Nếu bạn dùng tài nguyên của bên thứ ba, như nghe, tải nhạc thì cần chứng minh bạn có bản quyền hoặc đó là những thứ miễn phí.


Submit ứng dụng lên Play Store

Sau khi đăng nhập vào tài khoản, màn hình Developer Console bật ra.

 Nhấn + Create application. Trong hộp thoại mới vừa được hiện ra, phần Language,  ứng dụng quốc tế để là English, nội địa là Vietnamese.

Điền tên ứng dụng vào. Ấn Create.
Ấn vào  Manage Releases, Manage Production.

Chọn Create release giao diện sẽ không khác nhiều so với ảnh dưới đây.

Nháy vào Upload Apk để up file apk lên.

Nếu không bị lỗi gì, bạn điền tiếp các thông tin ở bên dưới trang, bao gồm RELEASE NAME – nên chính xác với version name là tên phiên bản bạn đặt.
Sau khi đã điền bạn có thể nhấn Save và Review để lưu lại các thông tin cũng như kiểm tra lại các thông tin đã điền.
Tiếp đến phần Store Listing và điền đầy đủ thông tin vào các mục được yêu cầu (có dấu *).

Điền tên ứng dụng, mô tả ngắn, mô tả dài. Trong phần mô tả dài nên lặp lại từ khóa quan trọng 3 lần. Ví dụ ứng dụng về thời tiết thì từ weather lặp lại 3 lần.
Ảnh screenshot từ 2-8 cái, chụp các màn hình ứng dụng lúc đang hoạt động.
Nếu ứng dụng có yêu cầu các quyền “nguy hiểm” – dangerous permissions, gồm truy cập danh bạ, truy cập tin nhắn, truy cập bộ nhớ… thì bạn cần nêu ngắn gọn lí do ứng dụng cần phải được cấp các quyền đó ở phần này.
Phần Hi res icon chính là biểu tượng ứng dụng của bạn. Biểu tượng này phải tuyệt đối chính xác với biểu tượng trong ứng dụng của bạn. Kích thước: 512*512.
Feature graphic là một cái ảnh giới thiệu theo dạng đồ họa cho đẹp, khi người dùng xem ứng dụng trên điện thoại, ảnh này hiện lên trên đầu. Kích thước là 1024 dài * 500 cao. Có thể tạo nó bằng các phần mềm picture resize miễn phí trên mạng.
Ở phần Categorisation, phần App type, nếu là ứng dụng thì bạn chọn là Applications còn nếu là game thì bạn chọn Games. Bạn nên chọn Category mà mình muốn, cũng như điền các thông tin khác. Trong phần Privacy policy, bạn đánh dấu vào ô “Not submitting a privacy policy URL at current time”. Sau đó cuộn lên trên cùng và chọn Save draft.
Sau khi đã Save draft thành công, bạn sẽ chuyển xuống phần Content rating.
Cuộn xuống tìm biểu tượng cái cờ lê rồi nháy vào đó, điền địa chỉ email, sau đó ấn tiếp rồi tích vào các lựa chọn. Nếu ứng dụng của bạn có nội dung liên quan ma túy, bạo lực, man rợ, rùng rợn, sex thì chọn Yes, không chọn No. Calculate rating. Sau khi đã thực hiện xong, nhấn Save draft để lưu lại.
Tiếp theo là phần định giá cho ứng dụng, Pricing and distribution: nếu như bạn chọn Miễn phí, thì sau này sẽ không thể chuyển thành Có tính phí được.

Các ứng dụng Miễn phí có quyền cung cấp các gói hàng trong ứng dụng có phí (tức in-app billing, in-app payment).
Distribution chọn Select all country.

Nếu ứng dụng có quảng cáo thì chọn là có. Cuộn lên ấn Save draft.

Sau khi đã xong các phần trên, ta quay lại phần Manage Releases. Kiểm tra tất cả các mục cần thiết bên trái đều được đánh dấu tic màu xanh thì ấn Start roll out, chữ Publish app hiện lên đậm ấn vào đó là xong.