2012年6月27日 星期三

[Linux] 檔案目錄權限

一、使用者
1). Owner
2). Group
3). Other



二、權限分三種
1). Read:4
2). Write:2
3). eXecute:1



三、特殊權限
1). Setuid:4
 (檔案) 設置使文件在執行階段具有文件所有者的權限
2). Setgid:2
 (目錄) 目錄被設置該位後, 任何用戶在此目錄下創建的文件都具有和該目錄所屬的組相同的組
3). sTicky:1
 (檔案) 即使具有write的權限,僅有檔案使用者及root權限者才可以刪除檔案

● 設置方式:加在原本三位權限的最前方
ex: chmod 1777 /tmp




※ note:
$ ll /bin/su
drwxrwxrwt 19 root  root  4096 2012-06-27 11:17 ./
$ ll /usr/bin/sudo
-rwsr-xr-x 2 root root 168800 2011-05-30 14:06 /usr/bin/sudo*
$ ll /tmp/ drwxrwxrwt 19 root  root  4096 2012-06-27 17:39 ./





※ ref:
http://www.lslnet.com/linux/f/docs1/i55/big5368810.htm

2012年6月22日 星期五

[Android] [JAVA] 按鈕監聽


作法
1). 單項標準作法
2). 多項使用switch作法

//=============================================================

1). 單項標準作法

public class DeviceInfo2 extends Activity {
 /** Called when the activity is first created. */
 @Override
 public void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.main);
  // 找到元件資源
  Button button_info1 = (Button) findViewById(R.id.main_submit_info1);
  // 設定按鍵觸發的method
  button_info1.setOnClickListener(listDeviceInfo);
 }

 private Button.OnClickListener listDeviceInfo = new Button.OnClickListener() {
  @Override
  public void onClick(View v) {
   // 宣告intent,並指定要啟動的class
   Intent intent = new Intent(DeviceInfo2.this, mService.class);
   // 以startservice方式啟動intent
   startService(intent);
  }
 };
}



//=============================================================

2). 多項使用switch作法

public class DeviceInfo2 extends Activity implements OnClickListener{
 /** Called when the activity is first created. */
 @Override
 public void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.main);
  // 找到元件資源
  Button button_info1 = (Button) findViewById(R.id.main_submit_info1);
  button_info1.setOnClickListener(this); 
 }
 @Override
 public void onClick(View v) {
  switch (v.getId()){
  case R.id.main_submit_info1:
   // 宣告intent,並指定要啟動的class
   Intent intent = new Intent(DeviceInfo2.this, mService.class);
   // 以startservice方式啟動intent
   startService(intent);
   break;
  }
 }




2012年6月20日 星期三

[Example] [Android] [JAVA] JNI & NDK應用_BMI

JNI & NDK應用_BMI
JNI會將使用者輸入的身高體重傳到C
真正計算是由C來實作
C會將算完的答案回傳到JAVA
JAVA再將其顯示在UI上

流程方法
藉由java撰寫native method,JNI即可在Java中呼叫C寫的程式
C的程式藉由NDK包成.so檔,就可以被JNI呼叫

程式流程
1). (java) 撰寫native method,不需實做

2). 將寫好的.java檔,編成.class檔,再轉成.h檔

3). (C) 撰寫C程式碼,實做.h中的function標頭

4). 撰寫NDK需要的Android.mk

5). 利用NDK將C程式碼轉成.so檔

6). (java) 利用JNI呼叫C的程式















//=============================================================
[Main.java]
package com.jni;

import java.text.DecimalFormat;

import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.view.View;
import android.view.View.OnClickListener;
import android.os.Bundle;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;

public class Main extends Activity {
 double height, weight;

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

  Button button = (Button) findViewById(R.id.button_submit);
  button.setOnClickListener(calbmi);

 }

 private OnClickListener calbmi = new OnClickListener() {

  @Override
  public void onClick(View v) {
   DecimalFormat nf = new DecimalFormat("0.00");
   EditText fieldheight = (EditText) findViewById(R.id.edit_height);
   EditText fieldweight = (EditText) findViewById(R.id.edit_weight);
   
   try {
    height = Double.parseDouble(fieldheight.getText().toString());
    weight = Double.parseDouble(fieldweight.getText().toString());
   } catch (NumberFormatException e) {
    // Toast.makeText(v.getContext(),
    // "Please submit height and weight.", Toast.LENGTH_LONG)
    // .show();
    openOptionsDialog();
   }

   if (height == 0 || weight == 0) {
    openOptionsDialog();
   } 
   else {
    TextView bmi = (TextView) findViewById(R.id.text_result);
    double bmi_value = new Bmi().calbmi(height, weight);
    bmi.setText("Your BMI is " + nf.format(bmi_value));
   }
  }
 };

 private void openOptionsDialog() {
  AlertDialog.Builder dialog = new AlertDialog.Builder(Main.this);
  dialog.setTitle(R.string.dialog_title);
  dialog.setMessage(R.string.dialog_msg);
  dialog.setPositiveButton(R.string.dialog_btn,
    new DialogInterface.OnClickListener() {
     public void onClick(DialogInterface dialoginterface, int i) {
     }
    });
  dialog.show();
 }


}


[Bmi.java]
package com.jni;

public class Bmi {
 public native String stringFromJNI();
 public native double calbmi(double height, double weight);
 static{
  System.loadLibrary("cal_bmi_c");
 }
}




參考資料:
[Android] [JAVA] JNI & NDK

2012年6月19日 星期二

[Android] [JAVA] JNI & NDK


Java Native Interface(JNI)
JNI 是用來讓Java跟別種語言溝通的函式庫
Android中是讓Java及C之間溝通
分為Java Call C及C Call Java

Android Native Development Tools(NDK)
將C code包成.so檔,供Java利用

流程方法
藉由java撰寫native method,JNI即可在Java中呼叫C寫的程式
C的程式藉由NDK包成.so檔,就可以被JNI呼叫

//=============================================================

程式流程
1). (java) 撰寫native method,不需實做

2). 將寫好的.java檔,編成.class檔,再轉成.h檔

3). (C) 撰寫C程式碼,實做.h中的function標頭

3). 利用NDK將C程式碼轉成.so檔

4). (java) 利用JNI呼叫C的程式

//=============================================================

步驟
1). (java) 撰寫native method,不需實做
native method前要加native
要load的.so檔是libcal_bmi_c.so,扣除掉前面的lib及後面的.so

method是calbmi,回傳是double的型態
從Java傳入使用者輸入的height, weight

[Bmi.java]
package com.jni;

public class Bmi {
 public native double calbmi(double height, double weight);
 static{
  //要load的.so檔。去掉開頭的lib,及結尾的.so
  System.loadLibrary("cal_bmi_c");
 }
}

2). 將寫好的.java檔,編成.class檔,再轉成.h檔
Eclipse會自動編成.class檔
進入project的資料夾,新開jni資料夾
將編好的.h檔放在jni資料夾中
$ cd [project資料夾]

$ mkdir jni

$ cd jni

$ javah -jni -classpath [放置class的資料夾] [package].[class]

ex: javah -jni -classpath /home/qn_lo/develop/android/workspace/BmiJni/bin/classes com.jni.Bmi


3). (C) 撰寫C程式碼,實做.h中的function標頭在jni資料夾新增C程式碼檔案
將.h檔的JNIEXPORT複製到C並實作
[com_jni_Bmi.h]
/* DO NOT EDIT THIS FILE - it is machine generated */
#include 
/* Header for class com_jni_Bmi */

#ifndef _Included_com_jni_Bmi
#define _Included_com_jni_Bmi
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     com_jni_Bmi
 * Method:    calbmi
 * Signature: (DD)D
 */
JNIEXPORT jdouble JNICALL Java_com_jni_Bmi_calbmi
  (JNIEnv *, jobject, jdouble, jdouble);

#ifdef __cplusplus
}
#endif
#endif


[com_jni_Bmi.c]
#include 
#include 
JNIEXPORT jdouble JNICALL Java_com_jni_Bmi_calbmi
  (JNIEnv *env, jobject obj, jdouble cheight, jdouble cweight)
{
 double height,weight,bmi;
 height=cheight/100;
 weight=cweight;
 bmi=weight/(height*height);
    return bmi;
}


4). 撰寫NDK需要的Android.mk在jni資料夾中新增Android.mk
LOCAL_MODULE是編成的.so檔名
LOCAL_SRC_FILES是要編的C程式碼檔名
LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

LOCAL_MODULE    := cal_bmi_c
LOCAL_SRC_FILES := com_jni_Bmi.c

include $(BUILD_SHARED_LIBRARY)


5). 利用NDK將C程式碼轉成.so檔
 a). 先到Android NDK下載NDK
 b). 在project資料夾下新建libs的資料夾
  如果有需要,可在Eclipse中在Project按右鍵reflesh
 c). 在Eclipse的Project點右鍵[properties]
  在[Builders]中new一個編譯器,選擇program
  輸入Builder的Name,在Main標籤中,輸入Location及Working Directory


















  在Refresh標籤中,將Refresh resource upon completion勾選
  並選擇Specific resource的路徑為project的libs











  在Build Options標籤中
  勾選Specify working set of relevant resource
  並選擇Specify Resource路徑為Project的jni











 d). 按下Build All的按鈕將C編成.so檔











6). (java) 利用JNI呼叫C的程式在java要呼叫,[放JNI的class]().[native method]
new Bmi().calbmi(height, weight)



參考資料:
http://ironurbane.iteye.com/blog/425513
http://kitty.2y.idv.tw/~enijmax/linux/CLib_Jni.html

[blog] Blogger加SyntaxHighlighter顯示程式碼

SyntaxHighlighter

一套可在blogger中置入整齊的程式碼的工具,僅用網頁的Java即可呈現
支援多種語言及多種風格樣板


















//=============================================================

1). 至官網下載壓縮包,並將script資料夾上傳到網頁空間
或者也可以使用官網提供的Host Version
以下範例使用官網提供的Host Version

2). 到blogger後台,修改html中,找到<b:skin>標籤,將以下程式碼貼在此標籤前



3). 找到標籤,將程式碼貼在此標籤前


4). 要使用時,在文章中用此標籤將程式碼夾起來
..程式碼..


※ brush有很多種,細節請見官網的blush列表
※ 有額外的設定檔可加在標籤內,細節請見官網的configuration
ex:
...

2012年6月8日 星期五

[Android] [JAVA] bindService

bindService可將Activity與Service連接
當連線成功後,會自動呼叫執行這個connection內的onServiceConnected(ComponentName className, IBinder service) function,在這function會接收到由service內的onBinde()所丟出來的Ibinder物件,利用這IBinder物件取得Service物件,就可以直接操作Service內各個public 的method

[Activity]
1). 宣告MyService的變數,用此讀取MyService的資料

2). 宣告ServiceConnection的變數,並撰寫onServiceConnected及onServiceDisconnected的method

3). 使用bindService方法連結Activity及Service

[Service]
1). 宣告MyBinder的變數

2). 定義MyBinder的類別來取得MyService的物件實例

3). 使用onBind的方法綁定Service,返回一個ibinder的對象進行操作

4). 撰寫剩下的onRebind、onUnbind

//=============================================================
[Main.xml]
package com.servicetest2;

import android.app.Activity;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.IBinder;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.Toast;

public class Main extends Activity implements OnClickListener {
 private Intent intent;
 private MyService myService;
 private boolean flag;
 private ServiceConnection serviceconnection = new ServiceConnection() {

  @Override
  public void onServiceConnected(ComponentName name, IBinder service) {
   Toast.makeText(Main.this, "Bind Service", Toast.LENGTH_SHORT).show();
   myService = ((MyService.MyBinder) service).getService();
   flag = true;
   Log.d("Main","Bind");
  }

  @Override
  public void onServiceDisconnected(ComponentName name) {
   Toast.makeText(Main.this, "Bind Service Failed", Toast.LENGTH_SHORT).show();
   myService = null;
  }

 };

 public void onClick(View view) {
  switch (view.getId()) {
  case R.id.btnStartService:
   startService(intent);
   break;
  case R.id.btnStopService:
   stopService(intent);
   break;
  case R.id.btnBindService:
   bindService(intent, serviceconnection, Context.BIND_AUTO_CREATE);
   break;
  case R.id.btnUnbindService:
   // 當有bind,才會unbind
   if (flag == true) {
    unbindService(serviceconnection);
    flag = false;
    Log.d("switch","if");
   }
   Log.d("switch","break");
   break;
  }
 }

 @Override
 public void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.main);
  flag = false;

  // 取得資源
  Button btnStartService = (Button) findViewById(R.id.btnStartService);
  Button btnBindService = (Button) findViewById(R.id.btnBindService);
  Button btnUnbindService = (Button) findViewById(R.id.btnUnbindService);
  Button btnStopService = (Button) findViewById(R.id.btnStopService);

  // 設置按下按鈕的物件實例
  btnStartService.setOnClickListener(this);
  btnBindService.setOnClickListener(this);
  btnUnbindService.setOnClickListener(this);
  btnStopService.setOnClickListener(this);

  intent = new Intent(this, MyService.class);

 }
}


//-------------------------------------------------------------------------------------------------------------
[MyService.xml]
package com.servicetest2;

import android.app.Service;
import android.content.Intent;
import android.os.Binder;
import android.os.IBinder;
import android.util.Log;

public class MyService extends Service{

 public MyBinder myBinder=new MyBinder();
 
 @Override
 public IBinder onBind(Intent intent) {
  Log.d("MyService","onBind");
  return myBinder;
 }
 
 @Override
 public void onRebind(Intent intent){
  Log.d("MyService","onRebind");
  super.onRebind(intent);
 }
 
 @Override
 public boolean onUnbind(Intent intent){
  Log.d("MyService","onUnbind");
  return super.onUnbind(intent);
 }
 
 @Override
 public void onCreate(){
  Log.d("MyService","onCreate");
  super.onCreate();  
 }
 
 @Override
 public void onDestroy(){
  Log.d("MyService","onDestory");
  super.onDestroy();  
 }

 @Override
 public void onStart(Intent intent, int startId){
  Log.d("MyService","onStart");
  super.onStart(intent, startId);  
 }
 
 public class MyBinder extends Binder{
  MyService getService(){
   return MyService.this;
   
  }
  
 }

}