總網頁瀏覽量

2012年10月9日 星期二

Android 測試Android ProximityAlertReciever類別

測試Android ProximityAlertReciever類別
設定好監聽事件後,再更新座標,並接收警告或通知



Source code:

package com.example.addproximityalert;

import android.location.Criteria;
import android.location.Location;
import android.location.LocationManager;
import android.location.LocationProvider;
import android.os.Bundle;
import android.app.Activity;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;

public class MainActivity extends Activity {
    private static final String PROXIMITY_ALERT_ACTION_NAME = "com.test"; 
    private static final String TEST_MOCK_PROVIDER_NAME = "test_provider";
    private Button btnOut, btnIn;
    private TextView longitude_txt, latitude_txt;
    private LocationManager mLocationManager;
    private ProximityAlertReciever par;
    
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        findViews();
        String locService = Context.LOCATION_SERVICE;   
        mLocationManager = (LocationManager) getSystemService(locService); 
        par = new ProximityAlertReciever();
        LocationProvider lp = mLocationManager.getProvider(TEST_MOCK_PROVIDER_NAME);
        if (lp != null) {
            mLocationManager.removeTestProvider(TEST_MOCK_PROVIDER_NAME);
        }
        addTestProvider(TEST_MOCK_PROVIDER_NAME);
        set();

    }
    public void findViews(){
        longitude_txt = (TextView)findViewById(R.id.longitude);
        latitude_txt = (TextView)findViewById(R.id.latitude);
        
        btnOut = (Button) findViewById(R.id.btn1); 
        btnOut.setOnClickListener(new OnClickListener() {  
            public void onClick(View arg0) {  
               updateLocation(30, 30);   
            }  
        });
        
        btnIn = (Button) findViewById(R.id.btn2); 
        btnIn.setOnClickListener(new OnClickListener() {  
            public void onClick(View arg0) {  
               updateLocation(0, 0);   
            }  
        });
    }
    

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.activity_main, menu);
        return true;
    }
    
    private void updateLocation(final double latitude, final double longitude){
        updateLocation(TEST_MOCK_PROVIDER_NAME, latitude, longitude);
    }
    
    private void updateLocation(final String providerName, final double latitude, final double longitude) {
        Location location = new Location(providerName);
        location.setLatitude(latitude);
        location.setLongitude(longitude);
        location.setTime(java.lang.System.currentTimeMillis());
        mLocationManager.setTestProviderLocation(providerName, location);
    }
    
    private void set(){
        double lat = 0;  
        double lng = 0;   
        float radius = 1000;    
        long expiration = -1;  
        Intent intent = new Intent(PROXIMITY_ALERT_ACTION_NAME);

        PendingIntent pi = PendingIntent.getBroadcast(this, -1, intent, PendingIntent.FLAG_ONE_SHOT);  
        mLocationManager.addProximityAlert(lat, lng, radius, expiration, pi);  
        IntentFilter filter = new IntentFilter(PROXIMITY_ALERT_ACTION_NAME);
        registerReceiver(new ProximityAlertReciever(), filter);
    }
    
    private void addTestProvider(final String providerName) {
        mLocationManager.addTestProvider(providerName, true, false, true, false, false, false, false, Criteria.POWER_MEDIUM, Criteria.ACCURACY_FINE);
        mLocationManager.setTestProviderEnabled(providerName, true);
    }
    
    
    class ProximityAlertReciever extends BroadcastReceiver {    
        @Override  
        public void onReceive(Context context, Intent intent) {    
            String key = LocationManager.KEY_PROXIMITY_ENTERING;  
            boolean isEnter = intent.getBooleanExtra(key, false);  
            if(isEnter){
                Toast.makeText(context, "以進入區域", Toast.LENGTH_LONG).show();  
            }
           
        }  
    } 
}

Java 搜尋文字檔關鍵字並輸出

搜尋同一目錄內文字檔關鍵字後,並輸出整理到一個文字檔
可編譯為jar檔,重複使用

Source code:

import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.regex.Matcher;


public class FindKeyWord {
    public static void main(String args[]) throws IOException{
        ReadClass mReadClass = new ReadClass();
        mReadClass.readData();
    }
}

class ReadClass{
    int count = 0;

    public void readData(){
        //String dirPath = "C:\\Users\\Test\\Desktop\\";
        String dirPathTemp = System.getProperty("user.dir");
        String dirPath = Matcher.quoteReplacement(dirPathTemp);
        CharSequence findWord = "keyword";
        File dir = new File(dirPath);
        StringBuilder sb = new StringBuilder();
        
        if(dir.exists() && dir.isDirectory()){
            String[] names = dir.list();
            for(String name: names){
                FileReader fr;
                try {
                    fr = new FileReader(dirPath + "\\"  + name);
                    BufferedReader bf = new BufferedReader(fr);
                    String data = null;
                    try {
                        while((data = bf.readLine()) != null){
                            if(data.contains(findWord)){
                                String regString = "=";
                                String[] StringArray = data.split(regString);
                                output(StringArray[1], dirPath);
                            }
                        }
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                    try {
                        bf.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    } 
                } catch (FileNotFoundException e) {
                    e.printStackTrace();
                }               
            }
        }else{
            String info = "路徑錯誤: " +  dirPath + "請重新輸入";
        }
    }
    public void output(String str, String dirPath) throws IOException{
        String filePath = dirPath + "\\" + "data.txt"; 
        FileWriter mFileWriter = new FileWriter(filePath, true);
        String item = null;
        if((count/10) < 1){
            item = "  " + Integer.toString(count);
        }else if((count/10) < 10){
            item = " " + Integer.toString(count);
        }else{
            item = Integer.toString(count);
        }
        String mString = new String(item + ", keyword = " + str + "\r\n");
        mFileWriter.write(mString);
        mFileWriter.flush();
        mFileWriter.close();
        count++;
    }
}

2012年9月9日 星期日

Make file


Make file

基本說明
#include <stdio.h>
int main(void)
{
        printf("Hello World\n");
}
gcc hello.c  =>  產生a.out   輸入./a.out即可執行
gcc –c hello.c  =>  產生 hello.o 目的檔
gcc –o hello hello.o  =>  產生 hello 可執行檔  輸入./hello即可執行

-O:最佳化參數,-Wall:會產生詳細的編譯過程

gcc sin.c -lm -L/lib -L/usr/lib
-l :是『加入某個函式庫(library)』的意思,
 m :則是 libm.so 這個函式庫,其中, lib 與副檔名(.a .so)不需要寫
-L 後面接的路徑是剛剛上面那個函式庫的搜尋目錄
Linux 預設是將函式庫放置在 /lib /usr/lib 當中
-I/path 後面接的路徑( Path )就是設定要去搜尋相關的 include 檔案的目錄


製作Makefile
標的(target): 目標檔1 目標檔2
<tab>   gcc -o 欲建立的執行檔 目標檔1 目標檔2

main: main.o haha.o sin_value.o cos_value.o
           gcc -o main main.o haha.o sin_value.o cos_value.o -lm
clean:
           rm -f main main.o haha.o sin_value.o cos_value.o

LIBS = -lm
OBJS = main.o haha.o sin_value.o cos_value.o
CFLAGS=-Wall
main: ${OBJS}
        gcc -o main ${OBJS} ${LIBS}
clean:
        rm -f main ${OBJS}

$@:代表目前的標的(target)
gcc -o main ${OBJS} ${LIBS} 可改為gcc -o $@ ${OBJS} ${LIBS}


MakeFile

#Filename MakeFile
#this file is used for show how to use makefile
$(info start workoing)
hello: hello.c
    echo “nothing”

hello.bin: hello.c
    @echo “now make hello.bin”
    gcc hello.c –o hello.bin

.PHONY: he
    @echo “now make he”
    gcc hello.c –o hello.bin

$是函數呼叫符號, info是一個函數名稱,作用是輸出一段資訊,類似的資訊輸出還有warningerror兩個函數,不過error函數執行後會終止執行並退出
.PHONY關鍵字用於宣告一個目標,被.PHONY宣告的目標將總是執行其指定的命令,而如果不宣告的話,則僅當目標後面的條件變動後才執行
命令前面的@符號的作用是,不顯示被執行的命令,因為預設情況下,Make解譯器在執行命令時會列印出執行的命令
對於hello.bin目標,是當hello.c檔案被修改後,將會執行gcc命令重新對該c檔案編譯,並輸出hello.bin檔案

執行腳本,執行以下命令
$make  –f  Makefile  hello

-f參數用於指定要執行的指令檔案名稱,如果不指定檔案名稱,則解譯器會自動從目前的目錄下尋找名稱為Makefile的指令檔案






2012年9月4日 星期二

JAVA常遇到疑問

3-2.6 == 0.4  =>為false
因為java使用基底型別進行浮點數計算時, 會不準確
3-2.6 為0.3999999999999

使用BigDecimal進行浮點數運算來解決

BigDecimal x = new BigDecimal("3");
BigDecimal x = new BigDecimal("2.6");
BigDecimal z = z.subtract(y);
double value = z.doubleValue();
System.out.println(value == 0.4);

                                                                                                                     

9/2 = 4
9/2.0 = 4.5
整數與浮點數的運算會轉為浮點數型態再進行運算

                                                                                                                     

使用Label與break

public static void main(String[] args){
    label:
        for(int i= 1; i <= 7; i++){
           System.out.print("TEST");
           if(i =  3)
                break label;
       }
}

當i = 3時, 就會跳出label, 使用雙重迴圈也是一樣的情形


java
clone()方法複製物件
當已經存在一個A物件,現在需要一個與A物件完全相同的B物件,並對B物件的屬性值進行修改,但是A物件原有的屬性值不能改變

使用Object類別中的clone()方法,可以用來完成物件的淺複製,即被複製的物件各個屬性都是基本型態,而不是參考型態的屬性(Example)






















JNI 記錄

Java call C

Step 1: Write the Java Code
建立HelloWorld.java
//HelloWorld.java
public class HelloWorld
{
    public native void showHelloWorld();
    static {
        System.loadLibrary("hello");//呼叫libhello.so
    }
                public static void main(String[] args){
                                new HelloWorld().showHelloWorld();
                }
}

Step 2: Compile the Java Code
執行javac HelloWorld.java //編譯

Step 3: Create the .h File (
這是自動產生出的不要去編輯)
javah -jni HelloWorld //自動產生對應C標頭檔,內容中粗體為C的函式宣告:
-d選項可以指定輸出路徑
-jni 表示產生jni標頭檔案

//hello.h
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class HelloWorld */

#ifndef _Included_HelloWorld
#define _Included_HelloWorld
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     HelloWorld
 * Method:    showHelloWorld
 * Signature: ()V
 */
JNIEXPORT void JNICALL Java_HelloWorld_showHelloWorld
  (JNIEnv *, jobject);

#ifdef __cplusplus
}
#endif
#endif

Step 4: Write the Native Method Implementation
建立jni.c

//hello.c
#include <jni.h>
#include "HelloWorld.h"
#include <stdio.h>

JNIEXPORT void JNICALL
Java_HelloWorld_showHelloworld(JNIEnv *env, jobject obj)
{
                printf("Hello world!\n");
                return;
}


Step 5: Create a Shared Library
執行
gcc -fPIC -shared -Ijni.h 目錄> -Ijni_md.h目錄> jni.c -o libjni.so




C call Java
C訪問java不能透過函數指標 只能透過通用的參數介面
需要把想要訪問的類別名 函數名稱 參數傳遞給java引擎

訪問Java中函數的流程:

1. 取得Java對象的類別
cls = env -> GetObjectClass(jobject)

2. 取得Java函數的id
jmethodId mid = env -> GetMethodId(cls, "method_name", "([Ljava/lang/String;)V");

第二個參數為Java中的函數名稱
第三個參數為Java函數的參數和返回值

Java提供javap工具 可以查看Java函數的輸入 返回參數
javap -s com/android/HelloWorld

-s的含義是簽名(Signature) 因為Java允許函數重載 所以不同的參數 返回值代表著不同的函數

3. 找到函數後 就可以使用該函數
env -> CallXXXMethod(jobject, mid, ret);

訪問Java中變數的流程:

1. cls = env -> GetObjectClass(jobject)

取得變數的id
2. jfieldId fid = env -> GetFiledId(cls, "filed_name", "I");

field_nameJava變數的名稱
第三個參數為變數的類型

3. 取得變數值
value = env -> GetXXXField(env, jobject, fid)





JNIEnv 表示Java環境, jobject 指向呼叫的物件
java: int, long, byte, boolean, char, short, float, double, object
c中表示類型前面加一個j來表示

jclass取得:   
jclass FindClass(const char*, clsName);
jclass GetObjectClass(jobject obj);
jclass GetSuperClass(jclass obj);

jclass cls_string = env -> FindClass("java/lang/String") 取得string類型方式

取得方法名:
GetFieldID/GetMethodID
GetStaticFieldID/GetStaticMethodID

Java類型
native類型
boolean
Z
byte
B
char
C
double
D
float
F
int
I
long
L
Object
‘L’+’package’+’;’
short
S

object ---> Ljava/lang/Sting;
Array ---> [Ljava/lang/object;