2016年9月6日 星期二

Android spinner選單設定

private String[] getCarIDs(String tmp)
{
    String[] IDArray;
    try {
        //JSON資料解析
        JSONObject json_read=new JSONObject(tmp);
        JSONArray CarIDsJSON = json_read.getJSONArray("CarIDsJSON");
        IDArray =  new String[CarIDsJSON.length()];
        for (int i = 0; i < IDArray.length; i++) {
            IDArray[i] = CarIDsJSON.getString(i);
        }
    } catch (JSONException e) {
        e.printStackTrace();
        IDArray = new String[0];
    }

    return IDArray;
}


private Runnable  threadGetCarIDs = new Runnable() {
    @Override    public void run() {
        if(httpPostProcess.ReadJSON(httpPostProcess.POST_CarIDs, null)) //從後端抓JSON資料
        {
            if(!httpPostProcess.GetJSONData().equals("")) //有抓到資料
            {
                CarIDsJSONData = httpPostProcess.GetJSONData(); // 取得資料
                String[] carIDArry = getCarIDs(CarIDsJSONData);
                ArrayAdapter<String> IDs;
                IDs = new ArrayAdapter<String>(LoginActivity.this, android.R.layout.simple_spinner_item, carIDArry); //抓取選單內容
                sprCarIDs.setAdapter(IDs);  //設定選單
                //handler.sendEmptyMessage(MSG_GET_CAR_IDs);
            }
        }
    }
};

2016年9月2日 星期五

Android Class間用Content傳Handler

出處

在寫android遊戲或是工具軟體,常常會遇到 View之間 要怎麼切換?
Android.os底下 有一個class 叫 Handler 它能解決這個問題!

Handler能讓 兩個class之間相互傳遞訊息,來寫一段簡單的code可能會比較清楚
例如:

public class MainActivity extends Activity
{
ViewTest vt;
ViewTest2 vt2;
public void onCreate(Bundle savedInstanceState)
{
   super.onCreate(savedInstanceState);   
   vt =new ViewTest(this);
   vt2 =new ViewTest2(this);
   setContentView(vt);
}

Handler hander = new Handler()
{
@Override
public void handleMessage(Message msg)
{
     switch(msg.what)
      {
         case 1: setContentView(vt2);
                 break;
      }
   }
}
}


public class ViewTest extends View
{
  MainActivity context;
  Paint p;
public GameOverView(MainActivity context)
{
 super(context);
     this.context = context;
     p = new Paint();
}
  public void onDraw(Canvas c)
  {
    c.drawText("hello! View",10,10,);
  }

   @Override
public boolean onTouchEvent(MotionEvent e)
{
      if(e.getAction()= =MotionEvent.ACTION_DOWN)
      {
        context.hander.sendEmptyMessage(1);
      }
  return true;
}
}


public class ViewTest2 extends View
{
省略......
}

這段程式碼的意思是:
MainActivity 一開始設定的View 是 ViewTest ,然後,當使用者Touch螢幕
則讓ViewTest藉由MainActivity的Handler物件,發訊息給MainActivity,讓它切換ViewTest2
hander.sendEmptyMessage() 這邊是使用只有一個 int 參數的這個method,
隨意傳一個自訂的int數值,讓main class 去判斷,當傳入值數字正確,則main class做動作。

使用Handler 切換View的方法大致上是這樣!

但是有一點千萬要注意,如果是使用SurfaceView的話,則要注意 Thread狀態,Thread必須要讓它在dead 狀況下
然後,再去切換View,不然程式會出現錯誤。

2016年8月31日 星期三

Android 不同類別傳Activity

Still being relatively new to this I'm having issues in finding a view in a non-activity class MyLocation which I'm using in my activity class MainActivity. I'm using MyLocation to get longitude and latitude. I want to highlight a textview when either GPS or Network has been used. To do so I need to find the textviews in the non-activity class MyLocation.
Here is how I'm calling it in MainActivity:
public class MainActivity extends ActionBarActivity implements LocationListener {

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

            MyLocation myLocation = new MyLocation();
            myLocation.getLocation(this, locationResult);

}
And here what I tried in MyLocation to find the textviews:
public class MyLocation {

LocationManager lm;
LocationResult locationResult;
private Context context;
TextView tvnetwork, tvgps;
private int defaultTextColor;

LocationListener locationListenerNetwork = new LocationListener() {
    public void onLocationChanged(Location location) {

        locationResult.gotLocation(location);

        LayoutInflater inflater = (LayoutInflater) context
                .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        View v = inflater.inflate(R.layout.main, null);

        tvnetwork = (TextView) v.findViewById(R.id.tvnetwork);
        tvgps = (TextView) v.findViewById(R.id.tvgps);
        defaultTextColor = tvgps.getTextColors().getDefaultColor();

        tvnetwork.setTextColor(context.getResources().getColor(
                R.color.green));
        tvgps.setTextColor(defaultTextColor);

        lm.removeUpdates(this);
        lm.removeUpdates(locationListenerGps);
    }

    public void onProviderDisabled(String provider) {
    }

    public void onProviderEnabled(String provider) {
    }

    public void onStatusChanged(String provider, int status, Bundle extras) {
    }
};
But the views are not found. I already get a NPE @ .getSystemService(Context.LAYOUT_INFLATER_SERVICE);. What am I doing wrong?
shareimprove this question
  
Where you have defined your getLocation method ? – Spring Breaker Sep 12 '14 at 11:27 
  
very simple...when you are calling MyLocation class..just add context as parameter to it and thus you can get all the things from there on. – GvSharma Sep 12 '14 at 11:32

3 Answers


get a NPE @ .getSystemService(Context.LAYOUT_INFLATER_SERVICE);. What am I doing wrong?
Because context is null in MyLocation class. use MyLocation class constructor to pass MainActivity context in MyLocation to access system services as:
Activity activity;
public MyLocation(Context context,Activity activity){
this.context=context;
this.activity=activity;
}
and in MainActivity create MyLocation class object by passing MainActivity context as:
MyLocation myLocation = new MyLocation(MainActivity.this,this);
Now use context to access system services in MyLocation class
EDIT: Instead of inflating main layout again in onLocationChanged use Activity context to access view from Activity Layout as:
 public void onLocationChanged(Location location) {

       ....
        tvnetwork = (TextView) activity.findViewById(R.id.tvnetwork);
        tvgps = (TextView) activity.findViewById(R.id.tvgps);
        defaultTextColor = tvgps.getTextColors().getDefaultColor();

        tvnetwork.setTextColor(context.getResources().getColor(
                R.color.green));
        tvgps.setTextColor(defaultTextColor);

       ....
    }

Android 多個view寫法

void initOnClickListener() {

        int my_ids[] = {
                R.id.button01, R.id.button02, R.id.button03, ...
        };

        Button b = null;
        for( int i=0 ; i< ids.length ; ++i )
                if( ( b = (Button)findViewById( my_ids[i]) ) != null )
                        b.setOnClickListener(this);
}

public void onClick(View v) {
        switch( v.getId() ) {
                case R.id.button01:
                        break;
                case R.id.button02:
                        break;
                // ...
        }
}

2016年8月29日 星期一

C# 用Linq+匿名物件寫法 直接組JSON


用Linq+匿名物件寫法 直接組JSON
這招在Json.net的官方文件有範例(用JObject.FromObject的那個):http://james.newtonking.com/projects/json/help/html/CreatingLINQtoJSON.htm
但只有範例,沒寫為什麼Linq要那樣寫,誰看得懂阿XD
要用Linq直接組JSON
大概把握幾點:
Json Object:Json字串用大括號{}表示,Linq也是用大括號{}表示
Json Object的Name(Key、Property):Json字串在兩個雙引號””裡寫一個英文單字,Linq就直接寫英文單字即可
Json Array:Json字串用中括號[]表示,Linq就用from o in XXX select o,這種回傳IEnumerable的寫法(如果JSON字串是物件陣列的話就用from o in XXX select new {欄位1=YYY}這種形式)
Json Value:Linq就看Json字串填什麼值就跟著填什麼值

    protected void Page_Load(object sender, EventArgs e)
    {
        if (!IsPostBack)//Get Method
        {
            //準備資料
            List<string> registration_ids = new List<string>() { "4", "8", "15", "16", "23", "42" };

            //用Linq直接組
            var result = new
                            {
                                collapse_key = "score_update",
                                time_to_live = 108,
                                delay_while_idle = true,
                                data = new{
                                    score ="4x8",
                                    time = "15:16.2342"
                                },
                                registration_ids = from s in registration_ids
                                                            select s

                            };

            //序列化為JSON字串並輸出結果
            Response.Write(JsonConvert.SerializeObject(result));
        }
    }

2016年8月14日 星期日

Android map fragment 顯示按鈕

<fragment xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/map"
    android:name="com.google.android.gms.maps.SupportMapFragment"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.example.LocationChooser">


    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="right|top"
        android:text="Demo Button" 
        android:padding="10dp"
        android:layout_marginTop="20dp"
        android:paddingRight="10dp"/>

</fragment>

2016年7月27日 星期三

Android 畫面設定

// 關閉APP標題bar
this.requestWindowFeature(Window.FEATURE_NO_TITLE);

// 關閉最上面的狀態bar
this.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,WindowManager.LayoutParams.FLAG_FULLSCREEN);

//直行
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
//AndroidManifest.xml


//橫行
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE)
//AndroidManifest.xml

 

但切記,要再setContentView前就讀取此程式碼