新建一個(gè)android project 在創(chuàng)建畫面選擇Create project frome exceting
為廊坊等地區(qū)用戶提供了全套網(wǎng)頁(yè)設(shè)計(jì)制作服務(wù),及廊坊網(wǎng)站建設(shè)行業(yè)解決方案。主營(yíng)業(yè)務(wù)為成都網(wǎng)站建設(shè)、成都做網(wǎng)站、廊坊網(wǎng)站設(shè)計(jì),以傳統(tǒng)方式定制建設(shè)網(wǎng)站,并提供域名空間備案等一條龍服務(wù),秉承以專業(yè)、用心的態(tài)度為用戶提供真誠(chéng)的服務(wù)。我們深信只要達(dá)到每一位用戶的要求,就會(huì)得到認(rèn)可,從而選擇與我們長(zhǎng)期合作。這樣,我們也可以走得更遠(yuǎn)!
sourse 接著選擇android版本。然后location里面選擇你sdk文件夾下sample/androi-7/ApiDemos 這個(gè)文件夾 apidemos文件夾下面就是所有的例子程序。建立以后右鍵點(diǎn)擊選擇Run us菜單下面第一個(gè)選項(xiàng)運(yùn)行它。
就會(huì)自動(dòng)建立一個(gè)虛擬機(jī)跑起來這個(gè)例子程序了。
里面是各種組件的代碼...
希望你滿意我的答案
額,公司不允許發(fā)送帶附件的郵件,所以只能找個(gè)簡(jiǎn)單的貼代碼了。。。
這是activity的代碼:
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
TextView tv=new TextView(this);
String st="";
ContentResolver cr=getContentResolver();
Cursor cu=cr.query(ContactsContract.Contacts.CONTENT_URI,
null,null,null,null);
while(cu.moveToNext())
{
int name=cu.getColumnIndex(PhoneLookup.DISPLAY_NAME);
String contact=cu.getString(name);
int number=cu.getColumnIndex(PhoneLookup.NUMBER);
String num=cu.getString(number);
st+=(contact+":"+num+"\n");
}
cu.close();
tv.setText(st);
setContentView(tv);
}
還要在androidmanifest.xml中聲明permission:
manifest package="map.google" android:versionCode="1" android:versionName="1.0"
?
application android:icon="@drawable/icon" android:label="@string/app_name"
?
activity android:name=".helloGoogle" android:label="@string/app_name"
?
intent-filter
action android:name="android.intent.action.MAIN"/
category android:name="android.intent.category.LAUNCHER"/
/intent-filter
/activity
/application
uses-permission android:name="android.permission.READ_CONTACTS"/
/manifest
實(shí)現(xiàn)的功能很簡(jiǎn)單,從聯(lián)系人中讀出名字和號(hào)碼~~~
如compareTo這個(gè)api是一個(gè)比較大小的api
以下是商店離手機(jī)用戶距離的排序?qū)嵗?/p>
// 開始排序
private void Sorting(ArrayListInteger temp_km, ArrayListInteger temp_Adv_id ) {
// TODO Auto-generated method stub
for (int i = 0; i temp_km.size() - 1; i++) {
for (int j = 1; j temp_km.size() - i; j++) {
Integer a;
Integer b;
if ((temp_km.get(j - 1)).compareTo(temp_km.get(j)) 0) { // 比較兩個(gè)整數(shù)的大小
a = temp_km.get(j - 1);
b = temp_Adv_id.get(j - 1);
temp_km.set((j - 1), temp_km.get(j));
temp_Adv_id.set((j - 1), temp_Adv_id.get(j));
temp_km.set(j, a);//獲得重新排序后距離數(shù)組
temp_Adv_id.set(j, b);//商店在數(shù)組中的真實(shí)ID
}
}
}
希望對(duì)您有幫助。
內(nèi)存泄漏:
舉例:
請(qǐng)注意以下的例子是虛構(gòu)的
內(nèi)存抖動(dòng)
源自Android文檔中的 Memory churn 一詞,中文翻譯為內(nèi)存抖動(dòng)。
指快速頻繁的創(chuàng)建對(duì)象從而產(chǎn)生的性能問題。
引用Android文檔原文:
Java內(nèi)存泄漏的根本原因是 長(zhǎng)生命周期 的對(duì)象持有 短生命周期 對(duì)象的引用就很可能發(fā)生內(nèi)存泄漏。
盡管短生命周期對(duì)象已經(jīng)不再需要,但因?yàn)殚L(zhǎng)生命周期依舊持有它的引用,故不能被回收而導(dǎo)致內(nèi)存泄漏。
靜態(tài)集合類引起的內(nèi)存泄漏
如果僅僅釋放引用本身(tO = null), ArrayList 依然在引用該對(duì)象,GC無法回收。
監(jiān)聽器
在Java應(yīng)用中,通常會(huì)用到很多監(jiān)聽器,一般通過 addXXXXListener() 實(shí)現(xiàn)。但釋放對(duì)象時(shí)通常會(huì)忘記刪除監(jiān)聽器,從而增加內(nèi)存泄漏的風(fēng)險(xiǎn)。
各種連接
如數(shù)據(jù)庫(kù)連接、網(wǎng)絡(luò)連接(Socket)和I/O連接。忘記顯式調(diào)用 close() 方法引起的內(nèi)存泄漏。
內(nèi)部類和外部模塊的引用
內(nèi)部類的引用是很容易被遺忘的一種,一旦沒有釋放可能會(huì)導(dǎo)致一系列后續(xù)對(duì)象無法釋放。此外還要小心外部模塊不經(jīng)意的引用,內(nèi)部類是否提供相應(yīng)的操作去除外部引用。
單例模式
由于單例的靜態(tài)特性,使其生命周期與應(yīng)用的生命周期一樣長(zhǎng),一旦使用不恰當(dāng)極易造成內(nèi)存泄漏。如果單利持有外部引用,需要注意提供釋放方式,否則當(dāng)外部對(duì)象無法被正?;厥諘r(shí),會(huì)進(jìn)而導(dǎo)致內(nèi)存泄漏。
集合類泄漏
如集合的使用范圍超過邏輯代碼的范圍,需要格外注意刪除機(jī)制是否完善可靠。比如由靜態(tài)屬性 static 指向的集合。
單利泄漏
以下為簡(jiǎn)單邏輯代碼,只為舉例說明內(nèi)存泄漏問題,不保證單利模式的可靠性。
AppManager 創(chuàng)建時(shí)需要傳入一個(gè) Context ,這個(gè) Context 的生命周期長(zhǎng)短至關(guān)重要。
1. 如果傳入的是 Application 的 Context ,因?yàn)?Application 的生命周期等同于應(yīng)用的生命周期,所以沒有任何問題。
2. 如果傳入的是 Activity 的 Context ,則需要考慮這個(gè) Activity 是否在整個(gè)生命周期都不會(huì)被回收了,如果不是,則會(huì)造成內(nèi)存泄漏。
非靜態(tài)內(nèi)部類創(chuàng)建靜態(tài)實(shí)例造成的內(nèi)存泄漏
應(yīng)該將該內(nèi)部類單獨(dú)封裝為一個(gè)單例來使用。
匿名內(nèi)部類/異步線程
Runnable都使用了匿名內(nèi)部類,將持有MyActivity的引用。如果任務(wù)在Activity銷毀前未完成,將導(dǎo)致Activity的內(nèi)存無法被回收,從而造成內(nèi)存泄漏。
解決方法:將Runnable獨(dú)立出來或使用靜態(tài)內(nèi)部類,可以避免因持有外部對(duì)象導(dǎo)致的內(nèi)存泄漏。
Handler造成的內(nèi)存泄漏
Handler屬于TLS(Thread Local Storage)變量,生命周期與Activity是不一致的,容易導(dǎo)致持有的對(duì)象無法正確被釋放
當(dāng)Android應(yīng)用程序啟動(dòng)時(shí),該應(yīng)用程序的主線程會(huì)自動(dòng)創(chuàng)建一個(gè)Looper對(duì)象和與之關(guān)聯(lián)的MessageQueue。
當(dāng)主線程中實(shí)例化一個(gè)Handler對(duì)象后,它就會(huì)自動(dòng)與主線程Looper的MessageQueue關(guān)聯(lián)起來。所有發(fā)送到MessageQueue的Messag都會(huì)持有Handler的引用,所以Looper會(huì)據(jù)此回調(diào)Handle的handleMessage()方法來處理消息。只要MessageQueue中有未處理的Message,Looper就會(huì)不斷的從中取出并交給Handler處理。
另外,主線程的Looper對(duì)象會(huì)伴隨該應(yīng)用程序的整個(gè)生命周期。
在Java中,非靜態(tài)內(nèi)部類和匿名類內(nèi)部類都會(huì)潛在持有它們所屬的外部類的引用,但是靜態(tài)內(nèi)部類卻不會(huì)。
當(dāng)該 Activity 被 finish() 掉時(shí),延遲執(zhí)行任務(wù)的 Message 還會(huì)繼續(xù)存在于主線程中,它持有該 Activity 的 Handler 引用,所以此時(shí) finish() 掉的 Activity 就不會(huì)被回收了從而造成內(nèi)存泄漏(因 Handler 為非靜態(tài)內(nèi)部類,它會(huì)持有外部類的引用,在這里就是指 SampleActivity)。
避免不必要的靜態(tài)成員變量
對(duì)于BroadcastReceiver、ContentObserver、File、Cursor、Stream、Bitmap等資源的使用,應(yīng)在Activity銷毀前及時(shí)關(guān)閉或注銷。
不使用WebView對(duì)象時(shí),應(yīng)調(diào)用`destroy()`方法銷毀。
android:layout_width="fill_parent"android:layout_height="fill_parent"
xmlns:android="schemas.android/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_width="wrap_content"android:layout_height="wrap_content"
android:layout_height="wrap_content"android:text="播放音頻"
android:layout_height="wrap_content"android:text="停止播放"
android:layout_width="fill_parent"
android:layout_width="fill_parent"android:layout_height="250px"
android:layout_width="wrap_content"android:layout_height="wrap_content"
android:layout_height="wrap_content"android:id="@+id/Button03"
android:text="播放視頻"
android:layout_height="wrap_content"android:text="停止播放"android:id="@+id/Button04"
packagecom.testMedia;
importjava.io.IOException;
importjava.util.Timer;
importjava.util.TimerTask;
importandroid.app.Activity;
importandroid.media.AudioManager;
importandroid.media.MediaPlayer;
importandroid.os.Bundle;
importandroid.view.SurfaceHolder;
importandroid.view.SurfaceView;
importandroid.view.View;
importandroid.widget.Button;
importandroid.widget.SeekBar;
importandroid.widget.Toast;
publicclasstestMediaextendsActivity{
/**Calledwhentheactivityisfirstcreated.*/
privateSeekBarskb_audio=null;
privateButtonbtn_start_audio=null;
privateButtonbtn_stop_audio=null;
privateSeekBarskb_video=null;
privateButtonbtn_start_video=null;
privateButtonbtn_stop_video=null;
privateSurfaceViewsurfaceView;
1 ?首先做的是創(chuàng)建新的工程然后添加一下文件
我所說的添加的文件并不是和官方提供的例程源代碼開源的串口類android-serialport-api。完全一樣 我下的就是完全一樣的?
,這個(gè)官方的好像是新的或是舊的,就兩句代碼是不樣的
還有幾處就不一一點(diǎn)出了,總之差別不大,多一個(gè)Tag參數(shù),不過新手還是別管他。最好用我提供的代碼。第一次發(fā)不知道怎么附件代碼,一會(huì)再說把。
2 布局
接下來就是先寫個(gè)布局唄,這是我寫的 比我看到的Demo我有添加了一個(gè)清除接收數(shù)據(jù)的按鈕。
我想這種問題你們都不是事,/////////?。。。。。。。。。?!這幾個(gè)粉紅色的字是按鈕控件,我把背景設(shè)成透明了別誤會(huì)了。
3代碼
好了 然后就是關(guān)于這個(gè)頁(yè)面的Code了,
這是我的:
package android.serialport;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.text.BreakIterator;
import java.util.ServiceConfigurationError;
import android.os.Bundle;
import android.app.Activity;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.Window;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
public class MyserialActivity extendsActivity
{
EditText sendedit;
EditText receiveedit;
FileInputStream mInStream;
FileOutputStream mOutStream;
SerialPort classserialport;
ReadThread mReadThread;
private class ReadThread extends Thread
{
public void run()
{
super.run();
while(!isInterrupted())
{
int size;
}
}
}
void onDataReceive(final byte[] buffer,finalint size)
{
runOnUiThread(new Runnable()
{
@Override
publicvoid run()
{
// TODO Auto-generated method stub
if(mReadThread ?!= null)
{
receiveedit.append(newString(buffer,0,size));
}
}
});
}
@Override
protectedvoid onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
this.requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.activity_myserial);
sendedit= (EditText)findViewById(R.id.editText1);
receiveedit=(EditText)findViewById(R.id.editText2);
receiveedit.setFocusable(false);//進(jìn)制輸入
/*
* 打開串口
* */
finalButton openserial =(Button)findViewById(R.id.button1);
openserial.setOnClickListener(newView.OnClickListener()
{
@Override
publicvoid onClick(View arg0)
{
//TODO Auto-generated method stub
try
{
classserialport=new SerialPort(new File("/dev/ttyS2"),9600);
}catch(SecurityExceptione)
{
e.printStackTrace();
}
catch(IOExceptione)
{
e.printStackTrace();
}
mInStream=(FileInputStream) classserialport.getInputStream();
Toast.makeText(MyserialActivity.this,"串口打開成功",Toast.LENGTH_SHORT).show();
}
});
/*
* 發(fā)送數(shù)據(jù)
* */
finalButton sendButton =(Button)findViewById(R.id.button2);
sendButton.setOnClickListener(newView.OnClickListener()
{
@Override
publicvoid onClick(View arg0)
{
Stringindata;
indata=sendedit.getText().toString();
//TODO Auto-generated method stub
try
{
mOutStream=(FileOutputStream) classserialport.getOutputStream();
mOutStream.write(indata.getBytes());
mOutStream.write('\n');
}
catch(IOExceptione)
{
e.printStackTrace();
}
Toast.makeText(MyserialActivity.this,"數(shù)據(jù)發(fā)送成功",Toast.LENGTH_SHORT).show();
sendedit.setText("");
}
});
/*
* 接收數(shù)據(jù)
* */
finalButton receButton= (Button)findViewById(R.id.button3);
receButton.setOnClickListener(newView.OnClickListener()
{//inttag =0;
@Override
publicvoid onClick(View arg0)
{
// TODO Auto-generated method stub
intsize;
try
{
byte[]buffer = new byte[64];
if(mInStream== null) return;
size= mInStream.read(buffer);
if(size0)
{
receiveedit.setText("");
}
if(size0)
{
onDataReceive(buffer,size);
}
inttag =1;
receiveedit.setText(newString(buffer, 0, size));
}catch(IOExceptione)
{
e.printStackTrace();
return;
}
}
privateboolean isInterrupted()
{
// TODO Auto-generated methodstub
returnfalse;
}
});
/*
* 清楚接收區(qū)
* */
finalButton ClearButton = (Button)findViewById(R.id.clear);
ClearButton.setOnClickListener(newView.OnClickListener()
{
@Override
publicvoid onClick(View arg0)
{
//TODO Auto-generated method stub
receiveedit.setText("");
}
});
}
@Override
publicboolean onCreateOptionsMenu(Menu menu)
{
//Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.myserial,menu);
returntrue;
}
}
好吧 ?你做好了。
3需要加載的文件
下面我把所需要添加的代碼貼一貼
第一個(gè)是Serialport.java
/*
* Copyright 2009 Cedric Priscal
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package android.serialport;
import java.io.File;
import java.io.FileDescriptor;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import android.util.Log;
public class SerialPort {
private static final String TAG = "SerialPort";
/*
* Do not remove or rename the field mFd: it is used by native method close();
*/
private FileDescriptor mFd; ?//創(chuàng)建一個(gè)文件描述符對(duì)象 mFd
private FileInputStream mFileInputStream;
private FileOutputStream mFileOutputStream;
public SerialPort(File device, int baudrate) throws SecurityException, IOException {
/*
* 檢查訪問權(quán)限
* */
/* Check access permission */
if (!device.canRead() || !device.canWrite()) {//如果設(shè)備不可讀或者設(shè)備不可寫
try {
/* Missing read/write permission, trying to chmod the file *///沒有讀寫權(quán)限,就嘗試去掛載權(quán)限
Process su; //流程進(jìn)程 ?su
su = Runtime.getRuntime().exec("/system/bin/su");//通過執(zhí)行掛載到/system/bin/su 獲得執(zhí)行
String cmd = "chmod 777 " + device.getAbsolutePath() + "\n"
+ "exit\n";
/*String cmd = "chmod 777 /dev/s3c_serial0" + "\n"
+ "exit\n";*/
su.getOutputStream().write(cmd.getBytes());//進(jìn)程。獲得輸出流。寫(命令。獲得二進(jìn)制)
if ((su.waitFor() != 0) || !device.canRead()
|| !device.canWrite()) {//如果 進(jìn)程等待不是0 或者 設(shè)備不能讀寫就
throw new SecurityException();//拋出一個(gè)權(quán)限異常
}
} catch (Exception e) {
e.printStackTrace();
throw new SecurityException();
}
}
/*
*
* */
mFd = open(device.getAbsolutePath(), baudrate);
//device.getAbsolutePath()這是要掛載的路徑new File("/dev/ttyS2")
if (mFd == null) {
Log.e(TAG, "native open returns null");
throw new IOException();//輸入輸出異常
}
//將文件描述符 ? ? ? 做輸入輸出流的參數(shù) ? ? ?傳遞給創(chuàng)建的輸入輸出流
mFileInputStream = new FileInputStream(mFd);
mFileOutputStream = new FileOutputStream(mFd);
}
// Getters and setters
public InputStream getInputStream() {
return mFileInputStream;
}
public OutputStream getOutputStream() {
return mFileOutputStream;
}
// JNI
private native static FileDescriptor open(String path, int baudrate);
public native void close();
static {
System.loadLibrary("serial_port");
}
}
第二個(gè)是SerialPortFinder.java
/*
* Copyright 2009 Cedric Priscal
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package android.serialport;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.io.LineNumberReader;
import java.util.Iterator;
import java.util.Vector;
import android.util.Log;
public class SerialPortFinder {
/*
* 創(chuàng)建一個(gè)驅(qū)動(dòng)程序類
* */
public class Driver {
public Driver(String name, String root) {
mDriverName = name;//String 類型的
mDeviceRoot = root;
}
private String mDriverName;
private String mDeviceRoot;
VectorFile mDevices = null;
/*
* Vector 類在 java 中可以實(shí)現(xiàn)自動(dòng)增長(zhǎng)的對(duì)象數(shù)組
* 簡(jiǎn)單的使用方法如下:
vectorint test;//建立一個(gè)vector
test.push_back(1);
test.push_back(2);//把1和2壓入vector這樣test[0]就是1,test[1]就是2
* */
public VectorFile getDevices() {
if (mDevices == null) {
mDevices = new VectorFile();
File dev = new File("/dev");
File[] files = dev.listFiles();
int i;
for (i=0; ifiles.length; i++) {
if (files[i].getAbsolutePath().startsWith(mDeviceRoot)) {
Log.d(TAG, "Found new device: " + files[i]);
mDevices.add(files[i]);
}
}
}
return mDevices;
}
public String getName() {
return mDriverName;
}
}
/*
*
*
* */
private static final String TAG = "SerialPort";
private VectorDriver mDrivers = null;
VectorDriver getDrivers() throws IOException {
if (mDrivers == null) {
mDrivers = new VectorDriver();
LineNumberReader r = new LineNumberReader(new FileReader("/proc/tty/drivers"));
String l;
while((l = r.readLine()) != null) {
String[] w = l.split(" +");
if ((w.length == 5) (w[4].equals("serial"))) {
Log.d(TAG, "Found new driver: " + w[1]);
mDrivers.add(new Driver(w[0], w[1]));
}
}
r.close();
}
return mDrivers;
}
public String[] getAllDevices() {
VectorString devices = new VectorString();
// Parse each driver
IteratorDriver itdriv;
try {
itdriv = getDrivers().iterator();
while(itdriv.hasNext()) {
Driver driver = itdriv.next();
IteratorFile itdev = driver.getDevices().iterator();
while(itdev.hasNext()) {
String device = itdev.next().getName();
String value = String.format("%s (%s)", device, driver.getName());
devices.add(value);
}
}
} catch (IOException e) {
e.printStackTrace();
}
return devices.toArray(new String[devices.size()]);
}
public String[] getAllDevicesPath() {
VectorString devices = new VectorString();
// Parse each driver
IteratorDriver itdriv;
try {
itdriv = getDrivers().iterator();
while(itdriv.hasNext()) {
Driver driver = itdriv.next();
IteratorFile itdev = driver.getDevices().iterator();
while(itdev.hasNext()) {
String device = itdev.next().getAbsolutePath();
devices.add(device);
}
}
} catch (IOException e) {
e.printStackTrace();
}
return devices.toArray(new String[devices.size()]);
}
}
第三個(gè)是Android.mk
#
# Copyright 2009 Cedric Priscal
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
TARGET_PLATFORM := android-3
LOCAL_MODULE ? ?:= serial_port
LOCAL_SRC_FILES := SerialPort.c
LOCAL_LDLIBS ? ?:= -llog
include $(BUILD_SHARED_LIBRARY)
第四個(gè)是SerialPort.c
/*
* Copyright 2009 Cedric Priscal
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include termios.h
#include unistd.h
#include sys/types.h
#include sys/stat.h
#include fcntl.h
#include string.h
#include jni.h
#include "android/log.h"
static const char *TAG="serial_port";
#define LOGI(fmt, args...) __android_log_print(ANDROID_LOG_INFO, ?TAG, fmt, ##args)
#define LOGD(fmt, args...) __android_log_print(ANDROID_LOG_DEBUG, TAG, fmt, ##args)
#define LOGE(fmt, args...) __android_log_print(ANDROID_LOG_ERROR, TAG, fmt, ##args)
static speed_t getBaudrate(jint baudrate)
{
switch(baudrate) {
case 0: return B0;
case 50: return B50;
case 75: return B75;
case 110: return B110;
case 134: return B134;
case 150: return B150;
case 200: return B200;
case 300: return B300;
case 600: return B600;
case 1200: return B1200;
case 1800: return B1800;
case 2400: return B2400;
case 4800: return B4800;
case 9600: return B9600;
case 19200: return B19200;
case 38400: return B38400;
case 57600: return B57600;
case 115200: return B115200;
case 230400: return B230400;
case 460800: return B460800;
case 500000: return B500000;
case 576000: return B576000;
case 921600: return B921600;
case 1000000: return B1000000;
case 1152000: return B1152000;
case 1500000: return B1500000;
case 2000000: return B2000000;
case 2500000: return B2500000;
case 3000000: return B3000000;
case 3500000: return B3500000;
case 4000000: return B4000000;
default: return -1;
}
}
/*
* Class: ? ? cedric_serial_SerialPort
* Method: ? ?open
* Signature: (Ljava/lang/String;)V
*/
JNIEXPORT jobject JNICALL Java_android_serialport_SerialPort_open
(JNIEnv *env, jobject thiz, jstring path, jint baudrate)
{
int fd;
speed_t speed;
jobject mFileDescriptor;
/* Check arguments */
{
speed = getBaudrate(baudrate);
if (speed == -1) {
/* TODO: throw an exception */
LOGE("Invalid baudrate");
return NULL;
}
}
/* Opening device */
{
jboolean iscopy;
const char *path_utf = (*env)-GetStringUTFChars(env, path, iscopy);
LOGD("Opening serial port %s", path_utf);
fd = open(path_utf, O_RDWR | O_DIRECT | O_SYNC);
LOGD("open() fd = %d", fd);
(*env)-ReleaseStringUTFChars(env, path, path_utf);
if (fd == -1)
{
/* Throw an exception */
LOGE("Cannot open port");
/* TODO: throw an exception */
return NULL;
}
}
/* Configure device */
{
struct termios cfg;
LOGD("Configuring serial port");
if (tcgetattr(fd, cfg))
{
LOGE("tcgetattr() failed");
close(fd);
/* TODO: throw an exception */
return NULL;
}
cfmakeraw(cfg);
cfsetispeed(cfg, speed);
cfsetospeed(cfg, speed);
if (tcsetattr(fd, TCSANOW, cfg))
{
LOGE("tcsetattr() failed");
close(fd);
/* TODO: throw an exception */
return NULL;
}
}
/* Create a corresponding file descriptor */
{
jclass cFileDescriptor = (*env)-FindClass(env, "java/io/FileDescriptor");
jmethodID iFileDescriptor = (*env)-GetMethodID(env, cFileDescriptor, "init", "()V");
jfieldID descriptorID = (*env)-GetFieldID(env, cFileDescriptor, "descriptor", "I");
mFileDescriptor = (*env)-NewObject(env, cFileDescriptor, iFileDescriptor);
(*env)-SetIntField(env, mFileDescriptor, descriptorID, (jint)fd);
}
return mFileDescriptor;
}
/*
* Class: ? ? cedric_serial_SerialPort
* Method: ? ?close
* Signature: ()V
*/
JNIEXPORT void JNICALL Java_android_serialport_SerialPort_close
(JNIEnv *env, jobject thiz)
{
jclass SerialPortClass = (*env)-GetObjectClass(env, thiz);
jclass FileDescriptorClass = (*env)-FindClass(env, "java/io/FileDescriptor");
jfieldID mFdID = (*env)-GetFieldID(env, SerialPortClass, "mFd", "Ljava/io/FileDescriptor;");
jfieldID descriptorID = (*env)-GetFieldID(env, FileDescriptorClass, "descriptor", "I");
jobject mFd = (*env)-GetObjectField(env, thiz, mFdID);
jint descriptor = (*env)-GetIntField(env, mFd, descriptorID);
LOGD("close(fd = %d)", descriptor);
close(descriptor);
}