您好,您可能指的是Android OS。
成都創(chuàng)新互聯(lián)專注于企業(yè)網(wǎng)絡(luò)營銷推廣、網(wǎng)站重做改版、格爾木網(wǎng)站定制設(shè)計、自適應(yīng)品牌網(wǎng)站建設(shè)、H5技術(shù)、商城網(wǎng)站定制開發(fā)、集團公司官網(wǎng)建設(shè)、成都外貿(mào)網(wǎng)站建設(shè)公司、高端網(wǎng)站制作、響應(yīng)式網(wǎng)頁設(shè)計等建站業(yè)務(wù),價格優(yōu)惠性價比高,為格爾木等各大城市提供網(wǎng)站開發(fā)制作服務(wù)。
Android OS其實就是安卓操作系統(tǒng)的名字。Android是一種基于Linux的自由及開放源代碼的操作系統(tǒng),主要使用于移動設(shè)備,如智能手機和平板電腦,由Google公司和開放手機聯(lián)盟領(lǐng)導(dǎo)及開發(fā)。尚未有統(tǒng)一中文名稱,中國大陸地區(qū)較多人使用“安卓”或“安致”。Android操作系統(tǒng)最初由Andy Rubin開發(fā),主要支持手機。2005年8月由Google收購注資。2007年11月,Google與84家硬件制造商、軟件開發(fā)商及電信營運商組建開放手機聯(lián)盟共同研發(fā)改良Android系統(tǒng)。隨后Google以Apache開源許可證的授權(quán)方式,發(fā)布了Android的源代碼。第一部Android智能手機發(fā)布于2008年10月。Android逐漸擴展到平板電腦及其他領(lǐng)域上,如電視、數(shù)碼相機、游戲機等。2011年第一季度,Android在全球的市場份額首次超過塞班系統(tǒng),躍居全球第一。 2013年的第四季度,Android平臺手機的全球市場份額已經(jīng)達到78.1%。2013年09月24日谷歌開發(fā)的操作系統(tǒng)Android在迎來了5歲生日,全世界采用這款系統(tǒng)的設(shè)備數(shù)量已經(jīng)達到10億臺。
如果您確定您問的是Android SO的話,下面給出解釋。
Android SO是Android編程中用到的so類型的文件,是一個c++的函數(shù)庫,在android的JNI中,是先將相應(yīng)的C語言打包成so庫導(dǎo)入到lib文件夾中調(diào)用的。
參考:百度百科。
初涉android的藍牙操作,按照固定MAC地址連接獲取Device時,程序始終是異常終止,查了好多天代碼都沒查出原因。今天改了一下API版本,突然就成功連接了??偨Y(jié)之后發(fā)現(xiàn)果然是個坑爹之極的錯誤。
為了這種錯誤拼命查原因浪費大把時間是非常不值得的,但是問題不解決更是揪心??上野俣攘四敲炊啵紱]有給出確切原因。今天特此mark,希望后來者遇到這個問題的時候能輕松解決。
下面是我的連接過程,中間崩潰原因及解決辦法。
1:用AT指令獲得藍牙串口的MAC地址,地址是簡寫的,按照常理猜測可得標準格式。
2:開一個String adress= "************" //MAC地址, String MY_UUID= "************"http://UUID根據(jù)通信而定,網(wǎng)上都有。
3:取得本地Adapter用getDefaultAdapter(); 遠程的則用getRemoteDevice(adress); 之后便可用UUID開socket進行通信。
如果中途各種在getRemoteDevice處崩潰,大家可以查看一下當(dāng)前的API版本,如果是2.1或以下版本的話,便能確定是API版本問題,只要換成2.2或者以上就都可以正常運行了~ ? 這么坑爹的錯誤的確很為難初學(xué)者。 ?唉·········· ?為這種小trick浪費很多時間真是難過。
(另外有個重要地方,別忘了給manifest里面加以下兩個藍牙操作權(quán)限哦~)
uses-permission?android:name="android.permission.BLUETOOTH"/uses-permission
uses-permission?android:name="android.permission.BLUETOOTH_ADMIN"/uses-permission
下面附上Android藍牙操作中用固定MAC地址傳輸信息的模板,通用搜索模式日后再補刪模板:
private?BluetoothAdapter?mBluetoothAdapter?=?null;
private?BluetoothSocket?btSocket?=?null;
private?OutputStream?outStream?=?null;
private?InputStream?inStream?=?null;
private?static?final?UUID?MY_UUID?=?UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");??//這條是藍牙串口通用的UUID,不要更改
private?static?String?address?=?"00:12:02:22:06:61";?//?==要連接的藍牙設(shè)備MAC地址
/*獲得通信線路過程*/
/*1:獲取本地BlueToothAdapter*/
mBluetoothAdapter?=?BluetoothAdapter.getDefaultAdapter();
if(mBluetoothAdapter?==?null)
{
Toast.makeText(this,?"Bluetooth?is?not?available.",?Toast.LENGTH_LONG).show();
finish();
return;
}
if(!mBluetoothAdapter.isEnabled())
{
Toast.makeText(this,?"Please?enable?your?Bluetooth?and?re-run?this?program.",?Toast.LENGTH_LONG).show();
finish();
return;
}
/*2:獲取遠程BlueToothDevice*/
BluetoothDevice?device?=?mBluetoothAdapter.getRemoteDevice(address);
if(mBluetoothAdapter?==?null)
{
Toast.makeText(this,?"Can't?get?remote?device.",?Toast.LENGTH_LONG).show();
finish();
return;
}
/*3:獲得Socket*/
try?{
btSocket?=?device.createRfcommSocketToServiceRecord(MY_UUID);
}?catch?(IOException?e)?{
Log.e(TAG,?"ON?RESUME:?Socket?creation?failed.",?e);
}
/*4:取消discovered節(jié)省資源*/
mBluetoothAdapter.cancelDiscovery();
/*5:連接*/
try?{
btSocket.connect();
Log.e(TAG,?"ON?RESUME:?BT?connection?established,?data?transfer?link?open.");
}?catch?(IOException?e)?{
try?{
btSocket.close();
}?catch?(IOException?e2)?{
Log?.e(TAG,"ON?RESUME:?Unable?to?close?socket?during?connection?failure",?e2);
}
}
/*此時可以通信了,放在任意函數(shù)中*/
/*??try?{
outStream?=?btSocket.getOutputStream();
inStream?=?btSocket.getInputStream();?//可在TextView里顯示
}?catch?(IOException?e)?{
Log.e(TAG,?"ON?RESUME:?Output?stream?creation?failed.",?e);
}
String?message?=?"1";
byte[]?msgBuffer?=?message.getBytes();
try?{
outStream.write(msgBuffer);
}?catch?(IOException?e)?{
Log.e(TAG,?"ON?RESUME:?Exception?during?write.",?e);
}
*/
通用搜索模式代碼模板:
簡潔簡潔方式1 demo
作用: 用VerticalSeekBar控制一個 LED屏幕的亮暗。
直接上碼咯~
package?com.example.seed2;
import?android.app.Activity;
import?android.app.AlertDialog;
import?android.app.Dialog;
import?android.os.Bundle;
import?java.io.IOException;
import?java.io.InputStream;
import?java.io.OutputStream;
import?java.util.UUID;
import?android.bluetooth.BluetoothAdapter;
import?android.bluetooth.BluetoothDevice;
import?android.bluetooth.BluetoothSocket;
import?android.content.DialogInterface;
import?android.util.Log;
import?android.view.KeyEvent;
import?android.widget.Toast;
public?class?MetalSeed?extends?Activity?{
private?static?final?String?TAG?=?"BluetoothTest";
private?BluetoothAdapter?mBluetoothAdapter?=?null;
private?BluetoothSocket?btSocket?=?null;
private?OutputStream?outStream?=?null;
private?InputStream?inStream?=?null;
private?VerticalSeekBar?vskb?=?null;
private?static?final?UUID?MY_UUID?=?UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");??//這條是藍牙串口通用的UUID,不要更改
private?static?String?address?=?"00:12:02:22:06:61";?//?==要連接的藍牙設(shè)備MAC地址
/**?Called?when?the?activity?is?first?created.?*/
@Override
public?void?onCreate(Bundle?savedInstanceState)?{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
this.vskb?=?(VerticalSeekBar)super.findViewById(R.id.mskb);
this.vskb.setOnSeekBarChangeListener(new?OnSeekBarChangeListenerX());
mBluetoothAdapter?=?BluetoothAdapter.getDefaultAdapter();
if(mBluetoothAdapter?==?null)
{
Toast.makeText(this,?"Bluetooth?is?not?available.",?Toast.LENGTH_LONG).show();
finish();
return;
}
if(!mBluetoothAdapter.isEnabled())
{
Toast.makeText(this,?"Please?enable?your?Bluetooth?and?re-run?this?program.",?Toast.LENGTH_LONG).show();
finish();
return;
}
}
private?class?OnSeekBarChangeListenerX?implements?VerticalSeekBar.OnSeekBarChangeListener?{
public?void?onProgressChanged(VerticalSeekBar?seekBar,?int?progress,?boolean?fromUser)?{
//Main.this.clue.setText(seekBar.getProgress());
/*??String?message;
byte?[]?msgBuffer;
try?{
outStream?=?btSocket.getOutputStream();
}?catch?(IOException?e)?{
Log.e(TAG,"ON?RESUME?:?Output?Stream?creation?failed.",?e);
}
message?=Integer.toString(?seekBar.getProgress()?);
msgBuffer?=?message.getBytes();
try{
outStream.write(msgBuffer);
}?catch?(IOException?e)?{
Log.e?(TAG,?"ON?RESUME?:?Exception?during?write.",?e);
}???????*/
}
public?void?onStartTrackingTouch(VerticalSeekBar?seekBar)?{
String?message;
byte?[]?msgBuffer;
try?{
outStream?=?btSocket.getOutputStream();
}?catch?(IOException?e)?{
Log.e(TAG,"ON?RESUME?:?Output?Stream?creation?failed.",?e);
}
message?=Integer.toString(?seekBar.getProgress()?);
msgBuffer?=?message.getBytes();
try{
outStream.write(msgBuffer);
}?catch?(IOException?e)?{
Log.e?(TAG,?"ON?RESUME?:?Exception?during?write.",?e);
}
}
public?void?onStopTrackingTouch(VerticalSeekBar?seekBar)?{
String?message;
byte?[]?msgBuffer;
try?{
outStream?=?btSocket.getOutputStream();
}?catch?(IOException?e)?{
Log.e(TAG,"ON?RESUME?:?Output?Stream?creation?failed.",?e);
}
message?=Integer.toString(?seekBar.getProgress()?);
msgBuffer?=?message.getBytes();
try{
outStream.write(msgBuffer);
}?catch?(IOException?e)?{
Log.e?(TAG,?"ON?RESUME?:?Exception?during?write.",?e);
}
}
}
@Override
public?void?onStart()
{
super.onStart();
}
@Override
public?void?onResume()
{
super.onResume();
BluetoothDevice?device?=?mBluetoothAdapter.getRemoteDevice(address);
try?{
btSocket?=?device.createRfcommSocketToServiceRecord(MY_UUID);
}?catch?(IOException?e)?{
Log.e(TAG,?"ON?RESUME:?Socket?creation?failed.",?e);
}
mBluetoothAdapter.cancelDiscovery();
try?{
btSocket.connect();
Log.e(TAG,?"ON?RESUME:?BT?connection?established,?data?transfer?link?open.");
}?catch?(IOException?e)?{
try?{
btSocket.close();
}?catch?(IOException?e2)?{
Log?.e(TAG,"ON?RESUME:?Unable?to?close?socket?during?connection?failure",?e2);
}
}
//?Create?a?data?stream?so?we?can?talk?to?server.
/*??try?{
outStream?=?btSocket.getOutputStream();
inStream?=?btSocket.getInputStream();
}?catch?(IOException?e)?{
Log.e(TAG,?"ON?RESUME:?Output?stream?creation?failed.",?e);
}
String?message?=?"read";
byte[]?msgBuffer?=?message.getBytes();
try?{
outStream.write(msgBuffer);
}?catch?(IOException?e)?{
Log.e(TAG,?"ON?RESUME:?Exception?during?write.",?e);
}
int?ret??=?-1;
while(?ret?!=?-1)
{
try?{
ret?=?inStream.read();
}?catch?(IOException?e)
{
e.printStackTrace();
}
}
*/
}
@Override
so文件是unix的動態(tài)連接庫,是二進制文件,作用相當(dāng)于windows下的.dll文件。
補充:
在Android中調(diào)用動態(tài)庫文件(*.so)都是通過jni的方式。
Android中加載so文件的提供的API:
void System.load(String pathName);
說明:pathName:文件名+文件路徑;
1,在項目根目錄下建立文件夾libs/armeabi文件夾
2,將so庫放入libs/armeabi文件夾注意事項:
1,如果采用靜態(tài)注冊的方式請注意C文件中嚴格按照命名規(guī)則Java_packageName_className_method()的方式命名
2,在Android項目中建立同上述命名規(guī)則中packageName中相同的包名,在此包名下建立同上述命名規(guī)則中className相同的類名
3,在className聲明native方法
4,程序中加載so庫System.loadLibrary(data/data/xxx.xxx.xxx/lib/xx.so)或者System.loadLibrary(xx),例如:System.loadLibrary(data/data/com.dtBank.app.service/lib/libjnixcld.so);
將SO文件直接放到libs/armeabi下,然后代碼中System.loadLibrary("xxx");再publicnativestaticintxxx_xxx_xxx();接下來就可以直接調(diào)用xxx_xxx_xxx()方法;
2.第二種方案,創(chuàng)建自己的SO文件,在自己的SO文件里調(diào)用第三方SO,再在程序中調(diào)用自己的SO,這種比較復(fù)雜,需要建java類文件,生成.h文件,編寫C源文件include之前生成的.h文件并實現(xiàn)相應(yīng)方法,最后用androidNDK開發(fā)包中的ndk-build腳本生成對應(yīng)的.so共享庫;求解:
網(wǎng)上說的第二種方案,是自己引用so庫,最后聲稱JAR
------解決方案--------------------------------------------------------
首先要看這個SO是不是JNI規(guī)范的SO,比如有沒有返回JNI不直接支持的類型。也就是說這個SO是不是可以直接當(dāng)作JNI來調(diào)用。如果答案是否定的,你只能選第二個方案。
如果答案是肯定的,還要看你是不是希望這個SO的庫直接暴露給JAVA層,如果答案是否定的,你只能選第二個方案,比如你本身也是一個庫的提供者。
一般如果你只有SO,就說明這個是別人提供給你的,你可以要求對方給你提供配套的JAVA調(diào)用文件。
1、這個要看這個SO是不是符合JNI調(diào)用的規(guī)范。還要看你自己的意愿。
2、因為第二種方法最靈活,各種情況都可以實現(xiàn)。3、可以------解決方案--------------------------------------------------------
看能不能直接從JAVA調(diào)用的最簡單的方法就是看SO里的函數(shù)名是不是Java_XXX_XXX_XXX格式的
是就可以,你可以自己寫一個配套的JAVA文件,注意一下SO函數(shù)名和JAVA函數(shù)名的轉(zhuǎn)換規(guī)則,或者向SO提供方索要;
不是的話就選第二種方案吧。
By;黎約天罰BEY
;?????01
安卓手機打開.so文件需要下載Native Libs Monitor這個app,這個應(yīng)用可以幫助我們理解手機上安裝的APK用到了哪些.so文件,以及.so文件來源于哪些函數(shù)庫或者框架。我們也可以自己對app反編譯來獲取這些信息。
so文件是手機的一些運行庫文件,在系統(tǒng)lib的文件夾下,置換移植其他系統(tǒng)的程序也需要修改更換相關(guān)so文件;沒有它系統(tǒng)軟件不能運行,哪部分損壞就影響相對功能,電話接打,通訊錄,相機等等都是要依賴so文件使用的。so文件需要資深安卓大師更改,一般都是現(xiàn)成的搬運移植,打開它沒有什么意義。安卓手機想要查看.so文件就需要下載Native Libs Monitor。
so是shared object的縮寫,見名思義就是共享的對象,機器可以直接運行的二進制代碼。大到操作系統(tǒng),小到一個專用軟件,都離不開so。so主要存在于Unix和Linux系統(tǒng)中。so是與平臺相關(guān)的二進制機器碼,Android應(yīng)用支持的cpu架構(gòu)取決于APK中位于lib或jniLib目錄中的.so文件。
由于Android基于Linux Kernl的,也繼承了Linux中所有so相關(guān)的設(shè)計。
除了系統(tǒng)方面的原因,Android開發(fā)者還要知道以下幾點:
so機制讓開發(fā)者最大化利用已有的C和C++代碼,達到重用的效果,利用軟件世界積累了幾十年的優(yōu)秀代碼。
so是二進制,沒有解釋編譯的開消,用so實現(xiàn)的功能比純java實現(xiàn)的功能要快。
so內(nèi)存分配不受Dalivik/ART的單個應(yīng)用限制,減少OOM。