2015年12月15日 星期二

Android Address 取得地址

以座標來取得住址位置
http://developer.android.com/reference/android/location/Address.html

1./res/layout/activity_main.xml 放個TextView


    



2.MainAcitvity.java
package com.terryyamg.addressestest;

import android.app.Activity;
import android.location.Address;
import android.location.Geocoder;
import android.os.Bundle;
import android.widget.TextView;

import java.io.IOException;
import java.util.List;

public class MainActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        TextView tvAddress = (TextView) findViewById(R.id.tvAddress);

        Geocoder geocoder = new Geocoder(this);
        List<Address> addresses = null;
        double lat = 22.6721740;
        double lon = 120.3100350;
        try {
            addresses = geocoder.getFromLocation(lat, lon, 1); //放入座標
        } catch (IOException e) {
            e.printStackTrace();
        }
        if (addresses != null && addresses.size() > 0) {
            Address address = addresses.get(0);
            String addressText = String.format("%s-%s%s%s%s",
                    address.getCountryName(), //國家
                    address.getAdminArea(), //城市
                    address.getLocality(), //區
                    address.getThoroughfare(), //路
                    address.getSubThoroughfare() //巷號
            );

            tvAddress.setText(addressText);
        }

    }

}


檔案下載:
https://github.com/terryyamg/AddressesTest
參考連結:
http://developer.android.com/reference/android/location/Address.html
http://wptrafficanalyzer.in/blog/android-reverse-geocoding-at-touched-location-in-google-map-android-api-v2/

2015年12月9日 星期三

Android MVP 設計模式 Spinner練習

練習MVP設計模式,以Spinner為例
將檔案切成Model View Presenter


1.在Layout放置一個Spinner元件
2.View - MainActivity.java
package com.terryyamg.mvptest;

import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Spinner;
import android.widget.Toast;

//View
public class MainActivity extends Activity implements MainActivityView {

    private Spinner spinner;
    private ArrayAdapter<String> listAdapter;

    private MainActivityPresenter presenter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        spinner = (Spinner) findViewById(R.id.spinner);

        presenter = new MainActivityPresenterImpl(this);
        presenter.guide(); //導向
    }

    //Override MainActivityView 設定Adapter
    @Override
    public void setAdapter(String[] data) {
        listAdapter = new ArrayAdapter<>(this,
                android.R.layout.simple_spinner_item, data);
        listAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
    }

    //Override MainActivityView 設定Spinner動作
    @Override
    public void setSpinner(final String[] data) {
        spinner.setAdapter(listAdapter);
        spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
            @Override
            public void onItemSelected(AdapterView<?> arg0, View arg1,
                                       int pos1, long arg3) {
                Toast.makeText(MainActivity.this, data[pos1], Toast.LENGTH_SHORT).show();
            }

            @Override
            public void onNothingSelected(AdapterView<?> arg0) {

            }
        });
    }
}

3.View - MainActivityView.java
package com.terryyamg.mvptest;

public interface MainActivityView {

    void setAdapter(String[] data);

    void setSpinner(String[] data);

}

4.Presenter - MainActivityPresenter.java
package com.terryyamg.mvptest;

public interface MainActivityPresenter {

    void guide();

}

5.Presenter - MainActivityPresenterImpl.java
package com.terryyamg.mvptest;

//Presenter
public class MainActivityPresenterImpl implements MainActivityPresenter {

    private MainActivityView mView;
    private MainActivityModel mModel;

    public MainActivityPresenterImpl(MainActivityView mView) {
        this.mView = mView;
        this.mModel = new MainActivityModelImpl();
    }


    @Override
    public void guide() {
        mModel.setData(mView); //導向Model
    }
}

6.Model - MainActivityModel.java
package com.terryyamg.mvptest;

public interface MainActivityModel {

    void setData(MainActivityView view);

}

7.Model - MainActivityModelImpl.java
package com.terryyamg.mvptest;

//Model
public class MainActivityModelImpl implements MainActivityModel {

    @Override
    public void setData(MainActivityView view) {
        String[] data = {"A", "B", "C", "D", "E"};

        //放入資訊
        view.setAdapter(data);
        view.setSpinner(data);
    }
}

完成後就可以得到一個與一般的spinner相同的效果

檔案下載:
 https://github.com/terryyamg/MVPTest
參考連結:
 https://github.com/antoniolg/androidmvp

2015年11月23日 星期一

Android Badger Icon 提示 通知 數字

icon上的數字提示通知,Android沒有內建的,所以使用第三方套件ShortcutBadger

使用IDE: Android Studio
1.建立新方案後,在build.gradle(Module:app)檔案裡的dependencies位置裡面加上 compile 'me.leolin:ShortcutBadger:1.1.3@aar' 下載該套件
dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    testCompile 'junit:junit:4.12'
    compile 'com.android.support:appcompat-v7:23.1.1'
    compile 'me.leolin:ShortcutBadger:1.1.3@aar'
}
2.AndroidManifest.xml


    

        
            
                

                
            
        

    


3.res/layout/activity_main.xml


    

    

    




4.MainActivity.java
package com.terryyamg.shortcutbadgertext;

import android.app.Activity;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;

import me.leolin.shortcutbadger.ShortcutBadger;

public class MainActivity extends Activity {

    private int badgeCount;
    private EditText numInput;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        numInput = (EditText) findViewById(R.id.numInput);

        Button button = (Button) findViewById(R.id.btnSetBadge);
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                badgeCount = 0;
                try {
                    badgeCount = Integer.parseInt(numInput.getText().toString());
                } catch (NumberFormatException e) {
                    Toast.makeText(MainActivity.this, "錯誤:", Toast.LENGTH_SHORT).show();
                }

                ShortcutBadger.with(MainActivity.this).count(badgeCount); //次數

                Toast.makeText(MainActivity.this, "通知次數=" + badgeCount, Toast.LENGTH_SHORT).show();
            }
        });


        //find the home launcher Package
        Intent intent = new Intent(Intent.ACTION_MAIN);
        intent.addCategory(Intent.CATEGORY_HOME);
        ResolveInfo resolveInfo = getPackageManager().resolveActivity(intent, PackageManager.MATCH_DEFAULT_ONLY);
        String currentHomePackage = resolveInfo.activityInfo.packageName;

        TextView textViewHomePackage = (TextView) findViewById(R.id.textViewHomePackage);
        textViewHomePackage.setText("手機型號:" + currentHomePackage);
    }

    @Override
    protected void onStart() {
        super.onStart();
        ShortcutBadger.with(this).remove(); //歸0
        Toast.makeText(this, "已讀", Toast.LENGTH_SHORT).show();
    }
}


檔案下載:
https://github.com/terryyamg/ShortcutBadgerText
參考連結:
https://github.com/leolin310148/ShortcutBadger

2015年10月13日 星期二

Android app intent other app 從一個App啟動另一個App特定頁面,附帶傳值

1.在App1加入程式碼
Intent intent = new Intent(Intent.ACTION_MAIN);
intent.setComponent(new ComponentName("com.xxxx.xxxx","com.xxxx.xxxx.SpecialMainActivity")); //包裹名稱,要開啟的頁面
intent.putExtra("value", "test"); //要傳送的值
startActivity(intent);
2.在App2的AndroidManifest.xml加入

        
            
            
                
            
            
        
3.在App2加入接收程式碼
Intent intent = getIntent();
if (intent.hasExtra("value")) {
 String value= intent.getStringExtra("value");
 Log.i("value", value+"");
}else{
 Log.i("value", "null");
}
參考連結:
http://stackoverflow.com/questions/3872063/launch-an-application-from-another-application-on-android

2015年8月20日 星期四

Android Web Url Activity 網頁連結啟動app

點選網頁超連結來啟動app
1.AndroidManifest.xml


    

    
        
            
                

                
            
            
                

                
                

                
            
        
    


2.activity_main.xml


    
    


3.MainActivity.java
package tw.android;

import java.util.List;

import android.app.Activity;
import android.net.Uri;
import android.os.Bundle;
import android.widget.TextView;

public class MainActivity extends Activity {
 private TextView textView1;

 /** Called when the activity is first created. */
 @Override
 public void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.activity_main);

  textView1 = (TextView) findViewById(R.id.textView1);

  Uri data = getIntent().getData();
  if (data != null) {
   String scheme = data.getScheme(); // "uccu"
   // String host = data.getHost();
   List<String> params = data.getPathSegments();
   String first = params.get(0); // word1
   String second = params.get(1); // word2

   textView1.setText(scheme + ":///" + first + "/" + second);
  }else{
   textView1.setText("請從網頁來");
  }
 }
}
4.web.html
<!DOCTYPE html>
<html>
<head>
<title>Page Title</title>
</head>
<body>

<a href="uccu:///word1/word2/">啟動吧!!APP!!!</a>

</body>
</html> 


參考來源:
http://stackoverflow.com/questions/2958701/launch-custom-android-application-from-android-browser

2015年8月5日 星期三

iOS Swift Multiple PickerView Spinner 多重 關聯 連動 滾輪

2017.06.18 update Android的下拉選項為Spinner
相對應的iOS的為滾輪PickerView

1.首先在Main.storyboard拖拉一個Picker View元件
並點選右方Show the Connections inspector
dataSourcedelegate拉致上方圖片上三個小圖的最左邊小圖關聯
2.將storyboard元件拉至ViewController

3.ViewController繼承UIPickerViewDelegate, UIPickerViewDataSource

4.ViewController.swift

//
//  ThreePickerViewController.swift
//  MultiplePickerViewTest
//
//  Created by Terry Yang on 2017/6/18.
//  Copyright © 2017年 terryyamg. All rights reserved.
//

import UIKit

class ThreePickerViewController: UIViewController, UIPickerViewDelegate, UIPickerViewDataSource {
    
    @IBOutlet weak var picker3: UIPickerView!
    
    //第一輪
    var list1  = ["亞洲","歐洲"]
    //第二輪
    var list21 = ["日本","台灣"]
    var list22 = ["英國","德國","義大利"]
    //第三輪
    var list211 = ["東京","沖繩","北海道"]
    var list212 = ["台北","台中","台南","高雄","台東"]
    var list221 = ["倫敦"]
    var list222 = ["柏林"]
    var list223 = ["羅馬"]
    
    //init
    var island : String = "亞洲"
    var country : String = "日本"
    var city : String = ""
    
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
        picker3.delegate = self
        picker3.dataSource = self
    }
    
    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }
    
    //幾個滾輪
    func numberOfComponents(in pickerView: UIPickerView) -> Int {
        return 3
    }
    
    //確認各個滾輪有幾筆
    func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
        //component - 第幾個滾輪
        switch(component){
        case 0:
            return list1.count
        case 1:
            return island == "亞洲" ? list21.count : list22.count
        case 2:
            switch country {
            case "日本":
                return list211.count
            case "台灣":
                return list212.count
            case "英國":
                return list221.count
            case "德國":
                return list222.count
            case "義大利":
                return list223.count
            default:
                return 0
            }
        default:
            return 0
        }
    }
    
    //放入內容
    func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
        switch(component){
        case 0:
            return list1[row]
        case 1:
            //true: 回傳第二輪的亞洲內容 false: 回傳第二輪的歐洲內容
            return island == "亞洲" ? list21[row] : list22[row]
        case 2:
            switch country {
            case "日本":
                return list211[row]
            case "台灣":
                return list212[row]
            case "英國":
                return list221[row]
            case "德國":
                return list222[row]
            case "義大利":
                return list223[row]
            default:
                return nil
            }
        default:
            return nil
        }
    }
    
    //回傳選擇的字串
    func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
        switch component {
        case 0:
            island = list1[row]
            updateCountry(0)
            updateCity(0)
            print("洲: \(island)")
            //選擇第一個滾輪後-重新載入
            pickerView.reloadAllComponents()
            //第二個與第三個滾輪回到第一個項目
            pickerView.selectRow(0, inComponent: 1, animated: true)
            pickerView.selectRow(0, inComponent: 2, animated: true)
        case 1:
            updateCountry(row)
            updateCity(0)
            print("國: \(country)")
            //選擇第二個滾輪後-重新載入
            pickerView.reloadAllComponents()
            //第三個滾輪回到第一個項目
            pickerView.selectRow(0, inComponent: 2, animated: true)

        case 2:
            updateCity(row)
            print("城: \(city)")
        default:
            print("無")
        }
        
    }
    
    func updateCountry(_ row: Int){
        if island == "亞洲" {
            country = list21[row]
        } else {
            country = list22[row]
        }
    }
    
    func updateCity(_ row: Int){
        switch country {
        case "日本":
            city = list211[row]
        case "台灣":
            city = list212[row]
        case "英國":
            city = list221[row]
        case "德國":
            city = list222[row]
        case "義大利":
            city = list223[row]
        default:
            print("無")
        }
        
    }
    
}


檔案下載:
 https://github.com/terryyamg/MultiplePickerViewTest
參考來源:
http://stackoverflow.com/questions/30832489/reload-component-in-ui-picker-view-swift
https://stackoverflow.com/questions/11191062/how-to-reset-uipickerview-to-index0-iphone

2015年8月2日 星期日

iOS Swift 筆記 暫存 SharedPreferences StandardUserDefaults

Android的筆記暫存功能為SharedPreferences
iOS相同的功能為NSUserDefaults.standardUserDefaults()
        //儲存在記事本
        let preferencesSave = NSUserDefaults.standardUserDefaults()
        
        preferencesSave.setValue("張三豐", forKey: "name") //儲存字串
        preferencesSave.setBool(true, forKey: "boy") //儲存布林值
        preferencesSave.setDouble(178.5, forKey: "height") //儲存Double
        preferencesSave.setInteger(99, forKey: "year") //儲存int
        //儲存
        let didSave = preferencesSave.synchronize()


        //讀取記事本
        let preferencesRead = NSUserDefaults.standardUserDefaults()
        
        if preferencesRead.objectForKey("name") == nil {
                //  Doesn't exist
                NSLog("NO name", "...")       
        } else {
                let name = preferencesRead.stringForKey("name") //讀取字串
                let boy = preferencesRead.boolForKey("boy") //讀取布林值
                let height = preferencesRead.doubleForKey("height") //讀取Double
                let year = preferencesRead.integerForKey("year") //讀取int
                NSLog("name:\(name!)", "")
        }

參考連結:
http://stackoverflow.com/questions/19206762/equivalent-to-shared-preferences-in-ios