首先說AndroidManifest.xml文件
AndroidManifest.xml除了能聲明程序中的Activities, ContentProviders,Services, 和Intent Receivers,還能指定permissions和instrumentation(安全控制和測試)
下面截取部分進行說明:
<?xml version="1.0"encoding="utf-8"?>
//定義android命名空間,使得Android中各種標準屬性能在文件中使用
<manifest xmlns:android=http://schemas.android.com/apk/res/android
//指定本應用內java主程序包的包名,它也是一個應用進程的默認名稱
package="com.blue_light">
<uses-permission android:name="android.permission.BLUETOOTH"/>
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>
<application
//當allowBackup標誌爲true時,用戶即可通過adb backup和adb restore來進行對應用數據的備份和恢復,這可能會帶來一定的安全風險
android:allowBackup="true"
android:icon="@mipmap/applogo"
android:label="@string/app_name"
//聲明你的application是否願意支持從右到左(RTL就是right-to-left)的佈局。
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity
android:name=".WelcomeActivity"
android:label="@string/app_name"
//landscape:限制界面爲橫屏,旋轉屏幕也不會改變當前狀態。
//portrait:限制界面爲豎屏,旋轉屏幕也不會改變當前狀態。
android:screenOrientation="portrait"
android:theme="@style/AppTheme.NoActionBar">
<intent-filter>
//指定程序的入口
<action android:name="android.intent.action.MAIN"/>
//指定加載該應用時運行該Activity
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
<activity
android:name=".MainActivity"
android:theme="@style/AppTheme.NoActionBar"
// android:windowSoftInputMode="adjustPan"當前窗口的內容將自動移動以便當前焦點從不被鍵盤覆蓋和用戶能總是看到輸入內容的部分
// android:windowSoftInputMode="stateVisible|adjustResize" 屏幕整體上移
android:windowSoftInputMode="adjustPan"/>
<service
android:name="com.csr.btsmart.BtSmartService"
android:enabled="true"
//該屬性用來標示,其它應用的組件是否可以喚醒service或者和這個service進行交互:如果爲false,只有同一個應用的組件或者有着同樣user ID的應用可以啓動這個service或者綁定這個service。
android:exported="false"></service>
</application>
</manifest>
下面就來分析每一個用到的源程序文件:
首先是WelcomeActivity,如果是首次進入,等待2秒後跳轉到MainActivity
//讀取SharedPreFerences中需要的數據,使用SharedPreFerences來記錄程序啓動的使用次數
//取得相應的值,如果沒有該值,說明還未寫入,用true作爲默認值
SharedPreferences preferences = getSharedPreferences(SHARED_PREFERENCES, MODE_PRIVATE);
isFirstInit = preferences.getBoolean(FIRST_INIT_FLAG, true);
try{
Thread.sleep(2000);
intent = newIntent(WelcomeActivity.this,MainActivity.class);
} catch(InterruptedException e) {
Log.e(DEBUG_TAG,"First initfailed to start MainActivity.\n"+
e.getMessage());
e.printStackTrace();
return;
}
WelcomeActivity.this.startActivity(intent);
WelcomeActivity.this.finish();
SharedPreferences preferences = getSharedPreferences(WelcomeActivity.SHARED_PREFERENCES, MODE_PRIVATE); SharedPreferences.Editor editor = preferences.edit(); editor.putBoolean(WelcomeActivity.FIRST_INIT_FLAG, false); /* 提交修改 */ editor.commit();
初始化安裝時,往往需要創建一些文件夾
public staticFile path1;
//在SD卡上創建一個文件夾
public static void createSDCardDir(inttype){
if(Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState())){
// 創建一個文件夾對象,賦值爲外部存儲器的目錄
File sdcardDir =Environment.getExternalStorageDirectory();
//得到一個路徑,內容是sdcard的文件夾路徑和名字
if(type==1){
path=sdcardDir.getPath()+"/Blue_Light/單開";
}
else if(type==2){
path=sdcardDir.getPath()+"/Blue_Light/雙開";
}
else if(type==3){
path=sdcardDir.getPath()+"/Blue_Light/三開";
}
path1 =new
File(path);
if (!path1.exists()) {
//若不存在,創建目錄,可以在應用啓動的時候創建
path1.mkdirs();
Log.i(TAG,"創建文件成功");
}
}
else{
Log.i(TAG,"文件已存在");
}
}
創建數據庫操作對象
Android中創建數據庫有兩種方法:
1.手動創建或者打開數據庫
SQLiteDatabase database =openOrCreateDatabase("myDevice.db3", MODE_PRIVATE, null); 調用openOrCreateDatabase()方法,如果有該數據庫,就打開,沒有就創建一個。
2.使用SQLiteOpenHelper, 然後我們再在Activity中這樣使用:
//創建MyDatabaseHelper對象,創建數據庫myDevice.db3指定數據庫版本爲1,此處使用相對路徑即可,
//數據庫文件自動會保存在程序的數據文件夾的databases目錄下。
db =
new DatabaseHelper(this,"myDevice.db3", null,1);
SQLiteOpenHelper是一個抽象的數據庫操作類,首先執行的是OnCreate,這裏我們可以執行創建表等動作,但該方法並沒有真正創建數據庫,創建數據庫是在以下的情況:
SQLiteDatabasedatabase = helper.getWritableDatabase();調用getWritableDatabase()或者getReadableDatabase()時,就會真正創建數據庫。創建或打開數據庫後,我們就可以建表
數據庫中創建四張表並插入一條默認場景數據:
//創建設備表SQL語句
private static final StringCREATE_DEVICE_TABLE_SQL
="create table device(_id integerprimary "
+ "key autoincrement , name,device_scene_name,device_group_name,address,mode);";
//創建設備表SQL語句
private static final String CREATE_BASEDEVICE_TABLE_SQL="create tablebasedevice(_id
integer primary " + "key autoincrement , address , name,mode ,scene_name);";
//創建場景表SQL語句
private static final StringCREATE_SCENE_TABLE_SQL
="create table scene(_id integerprimary "
+ "key autoincrement ,scene_name,scene_state);";
//創建分組表
private static final StringCREATE_GROUP_TABLE_SQL
="create table groups(_id integerprimary "
+ "key autoincrement ,group_scene_name,group_name);";
private static final String INSERT_SCENE_SQL=
"insert into scene values(null ,'AndroidHome','Yes');";
獲取某一場景下所有設備:
/**獲取某一場景下所有的設備
*/
public List<BaseDeviceItem>getAllDevice_Scene(String scene_name)
{
List<BaseDeviceItem> devices= new
ArrayList<BaseDeviceItem>();
//獲取遊標
Cursor cursor = this.getReadableDatabase().rawQuery("select * frombasedevice where scene_name=?",
new String[]{scene_name});
//使用遊標遍歷所有數據
while (cursor.moveToNext()){
//使用遊標獲取基本信息參數,生成基本設備對象
BaseDeviceItem device=new BaseDeviceItem(cursor.getString(1),cursor.getString(2),cursor.getString(3),cursor.getString(4));
devices.add(device);
}
return devices;
}
基本設備表中添加設備:
/**
*基本表中添加設備
*/
public void addBaseDevice(String address,String name,String
mode,String scenename)
{
SQLiteDatabase db = this.getWritableDatabase();
db.execSQL("insert into basedevicevalues(null,?,?,?,? )",
new Object[]{address,name,mode,scenename});
db.close();
}
修改基本表信息:
/**
* 修改基本表設備名稱
*/
public void updateNameBaseDevice(final String oldname,String
newname,String scene)
{
SQLiteDatabase db = this.getWritableDatabase();
db.execSQL("update basedevice "+
"set name =? where name = ? andscene_name=? ",
new Object[]{newname,oldname,scene});
db.close();
}
刪除設備表中設備:
/**刪除設備表中設備
*/
public void delDevice_Device(String sceneName,String groupName,String
devicename)
{
SQLiteDatabase db = this.getWritableDatabase();
db.execSQL("DELETE FROM device WHEREdevice_scene_name = ? and device_group_name= ? and name=?", newString[] {sceneName,groupName,devicename
});
db.close();
}
刪除一個場景時要記得刪除所有數據庫表中包含該場景信息的條目。
另外添加一段Android中數據流的使用:
InputStream im = getResources().openRawResource(R.raw.smart_switchv0_3_update_1_20160325);
//加一個判斷條件,改變寫入到不同類型文件夾的文件,即改變im和path2的路徑名
path2 =new
File(OtaFileWriteManager.path1+
"/Smart_SwitchV0.3_update_1_20160325.img");
if(!path2.exists())
OtaFileWriteManager.inputstreamtofile(im,path2);
public static voidinputstreamtofile(InputStream ins,File
file) {
try {
OutputStream os = new FileOutputStream(file);
int bytesRead = 0;
byte[] buffer = new byte[1024];
while ((bytesRead = ins.read(buffer,0,
1024))!= -1) {
os.write(buffer,0,
bytesRead);
}
os.close();
ins.close();
} catch(Exception e) {
e.printStackTrace();
}
}