diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index f32f5edd..99b60c14 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -6,6 +6,8 @@
+
+
diff --git a/app/src/main/java/com/navinfo/omqs/OMQSApplication.kt b/app/src/main/java/com/navinfo/omqs/OMQSApplication.kt
index 556829bb..eabe4308 100644
--- a/app/src/main/java/com/navinfo/omqs/OMQSApplication.kt
+++ b/app/src/main/java/com/navinfo/omqs/OMQSApplication.kt
@@ -2,8 +2,13 @@ package com.navinfo.omqs
import android.app.Application
import android.util.Log
+import com.navinfo.collect.library.data.dao.impl.MapLifeDataBase
+import com.navinfo.omqs.db.TraceDataBase
import com.navinfo.omqs.tools.FileManager
+import com.navinfo.omqs.ui.manager.TakePhotoManager
+import com.navinfo.omqs.util.NetUtils
import dagger.hilt.android.HiltAndroidApp
+import org.videolan.vlc.Util
import io.realm.Realm
import io.realm.RealmConfiguration
import kotlinx.coroutines.launch
@@ -16,10 +21,15 @@ class OMQSApplication : Application() {
override fun onCreate() {
super.onCreate()
FileManager.initRootDir(this)
+ Util.getInstance().init(applicationContext)
+ NetUtils.getInstance().init(this)
+ TakePhotoManager.getInstance().init(this, 1)
+ FileManager.initRootDir(this)
Realm.init(this)
val password = "encryp".encodeToByteArray().copyInto(ByteArray(64))
// 70617373776f72640000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
Log.d("OMQSApplication", "密码是: ${byteArrayToHexString(password)}")
+ // 1110000011000010111001101110011011101110110111101110010011001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
val config = RealmConfiguration.Builder()
.directory(File(Constant.DATA_PATH))
.name("OMQS.realm")
diff --git a/app/src/main/java/com/navinfo/omqs/db/RoomAppDatabase.kt b/app/src/main/java/com/navinfo/omqs/db/RoomAppDatabase.kt
index 260df186..be0365e2 100644
--- a/app/src/main/java/com/navinfo/omqs/db/RoomAppDatabase.kt
+++ b/app/src/main/java/com/navinfo/omqs/db/RoomAppDatabase.kt
@@ -2,6 +2,7 @@ package com.navinfo.omqs.db
import androidx.room.Database
import androidx.room.RoomDatabase
+import com.navinfo.collect.library.data.entity.NiLocation
import com.navinfo.omqs.bean.OfflineMapCityBean
import com.navinfo.omqs.bean.ScProblemTypeBean
import com.navinfo.omqs.bean.ScRootCauseAnalysisBean
diff --git a/app/src/main/java/com/navinfo/omqs/db/TraceDataBase.java b/app/src/main/java/com/navinfo/omqs/db/TraceDataBase.java
new file mode 100644
index 00000000..99d2ae2c
--- /dev/null
+++ b/app/src/main/java/com/navinfo/omqs/db/TraceDataBase.java
@@ -0,0 +1,181 @@
+package com.navinfo.omqs.db;
+
+import android.content.Context;
+import android.os.AsyncTask;
+import android.util.Log;
+import androidx.annotation.NonNull;
+import androidx.room.Database;
+import androidx.room.Room;
+import androidx.room.RoomDatabase;
+import androidx.sqlite.db.SupportSQLiteDatabase;
+import com.navinfo.collect.library.data.dao.impl.INiLocationDao;
+import com.navinfo.collect.library.data.entity.NiLocation;
+import com.tencent.wcdb.database.SQLiteCipherSpec;
+import com.tencent.wcdb.database.SQLiteDatabase;
+import com.tencent.wcdb.repair.BackupKit;
+import com.tencent.wcdb.repair.RecoverKit;
+import com.tencent.wcdb.room.db.WCDBDatabase;
+import com.tencent.wcdb.room.db.WCDBOpenHelperFactory;
+
+@Database(entities = { NiLocation.class},version = 1, exportSchema = false)
+public abstract class TraceDataBase extends RoomDatabase {
+ // marking the instance as volatile to ensure atomic access to the variable
+ /**
+ * 数据库单例对象
+ */
+ private static volatile TraceDataBase INSTANCE;
+
+ /**
+ * 地图坐标库类
+ */
+ public abstract INiLocationDao getNiLocationDao();
+
+ /**
+ * 数据库秘钥
+ */
+ private final static String DB_PASSWORD = "123456";
+
+ public static TraceDataBase getDatabase(final Context context, final String name) {
+ if (INSTANCE == null) {
+ synchronized (TraceDataBase.class) {
+ if (INSTANCE == null) {
+ // [WCDB] To use Room library with WCDB, pass a WCDBOpenHelper factory object
+ // to the database builder with .openHelperFactory(...). In the factory object,
+ // you can specify passphrase and cipher options to open or create encrypted
+ // database, as well as optimization options like asynchronous checkpoint.
+ SQLiteCipherSpec cipherSpec = new SQLiteCipherSpec()
+ .setPageSize(1024)
+ .setSQLCipherVersion(3);
+ WCDBOpenHelperFactory factory = new WCDBOpenHelperFactory()
+ .passphrase(DB_PASSWORD.getBytes()) // passphrase to the database, remove this line for plain-text
+ .cipherSpec(cipherSpec) // cipher to use, remove for default settings
+ .writeAheadLoggingEnabled(true) // enable WAL mode, remove if not needed
+ .asyncCheckpointEnabled(true); // enable asynchronous checkpoint, remove if not needed
+
+ INSTANCE = Room.databaseBuilder(context.getApplicationContext(),
+ TraceDataBase.class, name)
+
+ // [WCDB] Specify open helper to use WCDB database implementation instead
+ // of the Android framework.
+ .openHelperFactory(factory)
+
+ // Wipes and rebuilds instead of migrating if no Migration object.
+ // Migration is not part of this codelab.
+ .fallbackToDestructiveMigration()
+ .addCallback(sRoomDatabaseCallback)
+ .build();
+ }
+ }
+ }
+ return INSTANCE;
+ }
+
+ /**
+ * Override the onOpen method to populate the database.
+ * For this sample, we clear the database every time it is created or opened.
+ *
+ * If you want to populate the database only when the database is created for the 1st time,
+ * override RoomDatabase.Callback()#onCreate
+ */
+ private static Callback sRoomDatabaseCallback = new Callback() {
+
+ @Override
+ public void onOpen(@NonNull SupportSQLiteDatabase db) {
+ super.onOpen(db);
+ // If you want to keep the data through app restarts,
+ // comment out the following line.
+ new PopulateDbAsync(INSTANCE).execute();
+ }
+ };
+
+ /**
+ * Populate the database in the background.
+ * If you want to start with more words, just add them.
+ */
+ private static class PopulateDbAsync extends AsyncTask {
+
+ PopulateDbAsync(TraceDataBase db) {
+ }
+
+ @Override
+ protected Void doInBackground(final Void... params) {
+ // Start the app with a clean database every time.
+ // Not needed if you only populate on creation.
+ //mDao.deleteAll();
+ Log.e("qj", "doInBackground");
+ return null;
+ }
+ }
+
+ /**
+ * 数据恢复
+ */
+ protected boolean recoverData(){
+ if(INSTANCE!=null){
+ SQLiteDatabase sqlite = ((WCDBDatabase) INSTANCE.getOpenHelper().getWritableDatabase()).getInnerDatabase();
+ RecoverKit recover = new RecoverKit(
+ sqlite, // 要恢复到的目标 DB
+ sqlite.getPath() + "-backup", // 备份文件
+ DB_PASSWORD.getBytes() // 加密备份文件的密钥,非 DB 密钥
+ );
+ int result = recover.run(false); // fatal 参数传 false 表示遇到错误忽略并继续,
+ // 若传 true 遇到错误则中止并返回 FAILED
+ switch (result) {
+ case RecoverKit.RESULT_OK:
+ /* 成功 */
+ Log.e("qj","sRoomDatabaseCallback==RecoverKit成功");
+ return true;
+ case RecoverKit.RESULT_CANCELED: /* 取消操作 */
+ Log.e("qj","sRoomDatabaseCallback==RecoverKit取消操作");
+ break;
+ case RecoverKit.RESULT_FAILED: /* 失败 */
+ Log.e("qj","sRoomDatabaseCallback==RecoverKit失败");
+ break;
+
+ }
+
+ recover.release();
+ }
+
+ return false;
+ }
+
+ /**
+ * 备份数据
+ */
+ protected boolean backup() {
+ Log.e("qj", "sRoomDatabaseCallback===backup==start");
+ if (INSTANCE != null) {
+ //备份文件
+ SQLiteDatabase sqlite = ((WCDBDatabase) INSTANCE.getOpenHelper().getWritableDatabase()).getInnerDatabase();
+ BackupKit backup = new BackupKit(
+ sqlite, // 要备份的 DB
+ sqlite.getPath() + "-backup", // 备份文件
+ "123456".getBytes(), // 加密备份文件的密钥,非 DB 密钥
+ 0, null);
+ int result = backup.run();
+ switch (result) {
+ case BackupKit.RESULT_OK:
+ /* 成功 */
+ Log.e("qj", "sRoomDatabaseCallback==成功");
+ return true;
+ case BackupKit.RESULT_CANCELED:
+ /* 取消操作 */
+ Log.e("qj", "sRoomDatabaseCallback==取消操作");
+ break;
+ case BackupKit.RESULT_FAILED:
+ /* 失败 */
+ Log.e("qj", "sRoomDatabaseCallback==失败");
+ break;
+ }
+
+ backup.release();
+ }
+ Log.e("qj", "sRoomDatabaseCallback===backup==end");
+ return false;
+ }
+
+ protected void release() {
+ INSTANCE = null;
+ }
+}
diff --git a/app/src/main/java/com/navinfo/omqs/system/SystemConstant.java b/app/src/main/java/com/navinfo/omqs/system/SystemConstant.java
new file mode 100644
index 00000000..2683529b
--- /dev/null
+++ b/app/src/main/java/com/navinfo/omqs/system/SystemConstant.java
@@ -0,0 +1,42 @@
+package com.navinfo.omqs.system;
+
+import java.util.UUID;
+
+/**
+ * 系统变量对象
+ */
+public class SystemConstant {
+
+ public static String USER_ID = "1";
+
+ //选择相机默认或者外设
+ public static String SELECT_CAMERA_STATE = "select_camera_state";
+ //是否连接
+ public static String CAMERA_CONNECT_STATE = "camera_connect_state";
+ //是否可以点击
+ public static String CAMERA_CLICK_STATE = "camera_click_state";
+ //拍照模式
+ public static String TAKE_CAMERA_MODE = "take_camera_mode";
+
+ public static String TAKE_CAMERA_IP = "take_camera_ip";
+
+ public static String TAKE_CAMERA_MAC = "take_camera_mac";
+
+
+ //选择拍照或者录像
+ public static String SELECT_TAKEPHOTO_OR_RECORD = "select_takephoto_or_record";
+
+ /**
+ * 获取uuid
+ * @param isUpperCase
+ * true 大写 false 小写
+ */
+ public static String getUuid(boolean isUpperCase){
+ String uuid = UUID.randomUUID().toString().replaceAll("-", "");
+ if(isUpperCase)
+ uuid = uuid.toUpperCase();
+
+ return uuid;
+ }
+
+}
diff --git a/app/src/main/java/com/navinfo/omqs/system/SystemDateTime.java b/app/src/main/java/com/navinfo/omqs/system/SystemDateTime.java
new file mode 100644
index 00000000..cc0539f3
--- /dev/null
+++ b/app/src/main/java/com/navinfo/omqs/system/SystemDateTime.java
@@ -0,0 +1,799 @@
+package com.navinfo.omqs.system;
+
+import java.text.ParseException;
+import java.text.ParsePosition;
+import java.text.SimpleDateFormat;
+import java.util.Calendar;
+import java.util.Date;
+
+/**
+ * @ClassName: SystemDateTime.java
+ * @author qj
+ * @version V1.0
+ * @Date 2023年4月17日 下午1:56:02
+ * @Description: 时间工具类
+ */
+public class SystemDateTime {
+ // 时间字符串
+ private static String systemDate;
+ // 全部时间信息
+ private static String fullTime;
+ // 时间对象
+ static Date date = null;
+
+ /**
+ * 获取时间日期
+ * return
+ */
+ public static String getDate() {
+ date = new Date();
+ SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
+ systemDate = simpleDateFormat.format(date);
+ return systemDate;
+ }
+
+ /**
+ * 时间常量转日期
+ * @param time 时间常量
+ * return
+ */
+ public static String getDateFromTime(long time) {
+ date = new Date(time);
+ SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
+ systemDate = simpleDateFormat.format(date);
+ return systemDate;
+ }
+
+ /**
+ * 获取时分秒HH:mm:ss
+ * return
+ */
+ public static String getFullTime() {
+ date = new Date();
+ SimpleDateFormat simpleDateFormat = new SimpleDateFormat("HH:mm:ss");
+ fullTime = simpleDateFormat.format(date);
+ return fullTime;
+ }
+
+ /**
+ * 格式化时间常量为yyyyMMddHHmmss
+ * @param time 时间常量
+ * return
+ */
+ public static String getFullTimeFromTime(long time) {
+ date = new Date(time);
+ SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyyMMddHHmmss");
+ fullTime = simpleDateFormat.format(date);
+ return fullTime;
+ }
+
+ /**
+ * 获取时间信息 yyyy-MM-dd HH:mm:ss
+ * return
+ */
+ public static String getDataTime() {
+ date = new Date();
+ SimpleDateFormat simpleDateFormat = new SimpleDateFormat(
+ "yyyy-MM-dd HH:mm:ss");
+ fullTime = simpleDateFormat.format(date);
+ return fullTime;
+ }
+
+ /**
+ * 简要格式时间HH:mm
+ * return
+ */
+ public static String getShotDataTime() {
+ date = new Date();
+ SimpleDateFormat simpleDateFormat = new SimpleDateFormat(
+ "HH:mm");
+ fullTime = simpleDateFormat.format(date);
+ return fullTime;
+ }
+
+ /**
+ * 获取时间信息 yyyyMMddHHmmss
+ * return
+ */
+ public static String getTime() {
+ date = new Date();
+
+ SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyyMMddHHmmss");
+
+ fullTime = simpleDateFormat.format(date);
+
+ return fullTime;
+ }
+
+
+ /**
+ * 获取时间信息 yyyyMMddHH
+ * return
+ */
+ public static String getTimeyyyyMMddHH() {
+ date = new Date();
+
+ SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyyMMddHH");
+
+ fullTime = simpleDateFormat.format(date);
+
+ return fullTime;
+ }
+
+ /**
+ * 获取时间信息 yyyyMMddHHmmssSSS
+ * return
+ */
+ public static String getTimeSSS() {
+ Date date = new Date();
+
+ SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyyMMddHHmmssSSS");
+
+ fullTime = simpleDateFormat.format(date);
+
+ return fullTime;
+ }
+
+ /**
+ * 获取时间信息 yyyy-MM-dd HH:mm:ss:SSS
+ * return
+ */
+ public static String getTimeMill() {
+ date = new Date();
+
+ SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss:SSS");
+
+ fullTime = simpleDateFormat.format(date);
+
+ return fullTime;
+ }
+
+ /**
+ * 获取时间信息 yyyy-MM-dd HH:mm:ss
+ * return
+ */
+ public static Date getNowDateShort() {
+ Date currentTime = new Date();
+ SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+ String dateString = formatter.format(currentTime);
+ ParsePosition pos = new ParsePosition(8);
+ Date currentTime_2 = formatter.parse(dateString, pos);
+ return currentTime_2;
+ }
+
+ /**
+ * 将yyyyMMddHHmmss转yyyy-MM-dd HH:mm:ss
+ * @param date 时间字符串
+ * return
+ */
+ public static String dateToSimpleDate(String date) throws ParseException {
+ SimpleDateFormat format = new SimpleDateFormat("yyyyMMddHHmmss");
+ Date dDate = format.parse(date);
+ SimpleDateFormat format2 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+ String reTime = format2.format(dDate);
+ return reTime;
+ }
+
+ /**
+ * 将yyyyMMddHHmmss转yyyy年MM月dd日
+ * @param date 时间字符串
+ * return
+ */
+ public static String dateToChineseDate(String date) throws ParseException {
+ SimpleDateFormat format = new SimpleDateFormat("yyyyMMddHHmmss");
+ Date dDate = format.parse(date);
+ SimpleDateFormat format2 = new SimpleDateFormat("yyyy年MM月dd日");
+ String reTime = format2.format(dDate);
+ return reTime;
+ }
+
+ /**
+ * 将yyyy-MM-dd HH:mm:ss.SSS转换为yyyyMMddHHmmssSSS
+ * return
+ */
+ public static String TimePointSSSToTime(String date) throws ParseException{
+ SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
+ Date dDate = format.parse(date);
+ SimpleDateFormat format2 = new SimpleDateFormat("yyyyMMddHHmmssSSS");
+ String reTime = format2.format(dDate);
+ return reTime;
+ }
+
+ /**
+ * 将yyyy.MM.dd/HH时转yyyy-MM-dd HH:mm:ss
+ * @param date 时间字符串
+ * return
+ */
+ public static String dateToSimpleDate2(String date) throws ParseException {
+ SimpleDateFormat format = new SimpleDateFormat("yyyy.MM.dd/HH时");
+ Date dDate = format.parse(date);
+ SimpleDateFormat format2 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+ String reTime = format2.format(dDate);
+ return reTime;
+ }
+
+
+ /**
+ * 将yyyyMMddHHmmss转yyyy.MM.dd/HH时
+ * @param date 时间字符串
+ * return
+ */
+ public static String dateToDialogTime(String date) throws ParseException {
+ SimpleDateFormat format = new SimpleDateFormat("yyyyMMddHHmmss");
+ Date dDate = format.parse(date);
+ SimpleDateFormat format2 = new SimpleDateFormat("yyyy.MM.dd/HH时");
+ String reTime = format2.format(dDate);
+ return reTime;
+ }
+
+ /**
+ * 将yyyyMMddHHmmss转yyyy-MM-dd HH:mm:ss:SSS
+ * @param date 时间字符串
+ * return
+ */
+ public static String dateToSimpleDateSSS(String date) throws ParseException {
+ SimpleDateFormat format = new SimpleDateFormat("yyyyMMddHHmmss");
+ Date dDate = format.parse(date);
+ SimpleDateFormat format2 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss:SSS");
+ String reTime = format2.format(dDate);
+ return reTime;
+ }
+
+ /**
+ * 将yyyyMMddHHmmssSSS转yyyy-MM-dd HH:mm:ss:SSS
+ * @param date 时间字符串
+ * return
+ */
+ public static String iosDateToSimpleDateSSS(String date) throws ParseException {
+ SimpleDateFormat format = new SimpleDateFormat("yyyyMMddHHmmssSSS");
+ Date dDate = format.parse(date);
+ SimpleDateFormat format2 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss:SSS");
+ String reTime = format2.format(dDate);
+ return reTime;
+ }
+
+ /**
+ * 将yyyyMMddHHmmssSSS转yyyy-MM-dd HH:mm:ss
+ * @param date 时间字符串
+ * return
+ */
+ public static String iosDateToSimpleDate(String date) throws ParseException {
+ SimpleDateFormat format = new SimpleDateFormat("yyyyMMddHHmmssSSS");
+ Date dDate = format.parse(date);
+ SimpleDateFormat format2 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+ String reTime = format2.format(dDate);
+ return reTime;
+ }
+
+ /**
+ * 获取当前时间yyyy-MM-dd HH:mm:ss
+ * return
+ */
+ public static Date getNowDate() throws ParseException {
+ Date currentTime = new Date();
+ SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+ String dateString = formatter.format(currentTime);
+ ParsePosition pos = new ParsePosition(8);
+ Date currentTime_2 = formatter.parse(dateString);
+ return currentTime_2;
+ }
+
+ /**
+ * 将时间常量转字符串HHmmss.SSS
+ * @param l 时间常量
+ * return
+ */
+ public static String getTime(long l) {
+ if (l > 0) {
+ long utcL = l - 28800;
+ SimpleDateFormat sdf = new SimpleDateFormat("HHmmss.SSS");
+ return sdf.format(utcL);
+ }
+ return null;
+ }
+
+
+ /**
+ * 将时间常量转字符串yyyyMMddHHmmssSSS
+ * @param l 时间常量
+ * return
+ */
+ public static String getDateSimpleTime(long l) {
+ if (l > 0) {
+ SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmssSSS");
+ return sdf.format(l);
+ }
+ return null;
+ }
+
+ /**
+ * 将时间常量转字符串yyyy-MM-dd HH:mm:ss:SSS
+ * @param l 时间常量
+ * return
+ */
+ public static String getDateSimpleTimeSSS(long l) {
+ if (l > 0) {
+ SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss:SSS");
+ return sdf.format(l);
+ }
+ return null;
+ }
+
+ /**
+ * 格式化时间
+ *
+ * @param l
+ * @return yyyyMMddHH:mm:ss:SSS
+ */
+ public static String getDateTimeSSS(long l) {
+ if (l > 0) {
+ SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHH:mm:ss:SSS");
+ return sdf.format(l);
+ }
+ return null;
+ }
+
+
+ /**
+ * 将yyyyMMddHHmmss转long
+ *
+ * @param date
+ * @return
+ */
+ public static long getTimeInfo(String date) {
+ if (date == null || date.equals(""))
+ return 0;
+ try {
+ String time = dateToSimpleDate(date);
+ long timeL = getTime(time);
+ return timeL;
+ } catch (ParseException e) {
+ e.printStackTrace();
+ }
+ return 0;
+ }
+
+ /**
+ * 将yyyy-MM-dd HH:mm:ss时间转常量
+ *
+ * @param date
+ * @return
+ */
+ public static long getTime(String date) {
+ long changeDate = 0;
+ SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+ try {
+ Date currentDate = formatter.parse(date);
+ changeDate = currentDate.getTime();
+ if (changeDate != 0) {
+ return changeDate;
+ }
+ } catch (ParseException e) {
+ e.printStackTrace();
+ }
+ return 0;
+ }
+
+ /**
+ * 将yyyy-MM-dd HH:mm:ss时间转常量
+ *
+ * @param date
+ * @return
+ */
+ public static long getPicTime(String date) {
+ long changeDate = 0;
+ SimpleDateFormat formatter = new SimpleDateFormat("yyyy:MM:dd HH:mm:ss");
+ try {
+ Date currentDate = formatter.parse(date);
+ changeDate = currentDate.getTime();
+ if (changeDate != 0) {
+ return changeDate;
+ }
+ } catch (ParseException e) {
+ e.printStackTrace();
+ }
+ return 0;
+ }
+
+ /**
+ * 将yyyy-MM-dd HH:mm:ss.SSS时间转常量
+ *
+ * @param date
+ * @return
+ */
+ public static long getTimePointSSS(String date) {
+ long changeDate = 0;
+ SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
+ try {
+ Date currentDate = formatter.parse(date);
+ changeDate = currentDate.getTime();
+ if (changeDate != 0) {
+ return changeDate;
+ }
+ } catch (ParseException e) {
+ e.printStackTrace();
+ }
+ return 0;
+ }
+
+ /**
+ * 将yyyyMMddHHmmss时间转常量
+ *
+ * @param date
+ * @return
+ */
+ public static long getTimePoint(String date) {
+ long changeDate = 0;
+ SimpleDateFormat formatter = new SimpleDateFormat("yyyyMMddHHmmss");
+ try {
+ Date currentDate = formatter.parse(date);
+ changeDate = currentDate.getTime();
+ if (changeDate != 0) {
+ return changeDate;
+ }
+ } catch (ParseException e) {
+ e.printStackTrace();
+ }
+ return 0;
+ }
+
+ /**
+ * 将yyyy-MM-dd HH:mm:ss:SSS时间转常量
+ *
+ * @param date
+ * @return
+ */
+ public static long getTimeSSS(String date) {
+ long changeDate = 0;
+ SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss:SSS");
+ try {
+ Date currentDate = formatter.parse(date);
+ changeDate = currentDate.getTime();
+ if (changeDate != 0) {
+ return changeDate;
+ }
+ } catch (ParseException e) {
+ e.printStackTrace();
+ }
+ return 0;
+ }
+
+ /**
+ * 将yyyyMMddHHmmssSSS时间转常量
+ *
+ * @param date
+ * @return
+ */
+ public static long getTrackTimeSSS(String date) {
+ long changeDate = 0;
+ SimpleDateFormat formatter = new SimpleDateFormat("yyyyMMddHHmmssSSS");
+ try {
+ Date currentDate = formatter.parse(date);
+ changeDate = currentDate.getTime();
+ if (changeDate != 0) {
+ return changeDate;
+ }
+ } catch (ParseException e) {
+ e.printStackTrace();
+ }
+ return 0;
+ }
+
+ /**
+ * 对比两个时间格式是否超过3000m
+ *
+ * @param startDate
+ * 起始时间
+ *@param endDate
+ * 结束时间
+ * @return true 是 false 否
+ */
+ public static boolean isTimeOut(long startDate, long endDate)
+ throws ParseException {
+ long result = startDate - endDate;
+ if (result > 300000 || result < -300000) {
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * 对比两个时间格式是否超过3000m
+ *
+ * @param startDate
+ * 起始时间
+ *@param endDate
+ * 结束时间
+ *@param dTime
+ * 时间常量
+ * @return true 是 false 否
+ */
+ public static boolean isTimeOut(long startDate, long endDate, long dTime)
+ throws ParseException {
+ long result = startDate - endDate;
+ if (result > dTime || result < -dTime) {
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * 对比两个时间间隔多少天yyyy-MM-dd
+ *
+ * @param date1
+ * 起始时间
+ *@param date2
+ * 结束时间
+ * @return
+ *
+ */
+ public static int getDateSpan(String date1, String date2) {
+ SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
+ try {
+ Date start = formatter.parse(date1);
+ Date end = formatter.parse(date2);
+ long span = end.getTime() - start.getTime();
+ float day = span / ((float) 1000 * 3600 * 24);
+ return (int) day;
+ } catch (ParseException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ return 0;
+ }
+
+
+ /**
+ * 获取照片的时间
+ * return
+ */
+ public static String getYYYYMMDDDate() {
+ date = new Date();
+ SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyyMMdd");
+ systemDate = simpleDateFormat.format(date);
+ return systemDate;
+ }
+
+ /**
+ * 获取照片的时间 yyyy年MM月dd日
+ * return YYYYMMDDD
+ */
+ public static String getYYYYMMDDDateChinese() {
+ date = new Date();
+ SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy年MM月dd日");
+ systemDate = simpleDateFormat.format(date);
+ return systemDate;
+ }
+
+ /**
+ * yyyy年MM月dd日 转date
+ *
+ * @param dateString
+ * @return
+ */
+ public static Date stringYYYYMMDDHHToDate(String dateString) {
+ try {
+ SimpleDateFormat sim = new SimpleDateFormat("yyyy/MM/dd/HH时");
+ Date ticDate = sim.parse(dateString);
+ return ticDate;
+ } catch (Exception e) {
+
+ }
+ return null;
+ }
+
+ /**
+ * 当前时间前几天时间
+ * @param day
+ * 天数
+ * return
+ */
+ public static String getCurrentDateBefore(int day) {
+ date = new Date();
+ Calendar now = Calendar.getInstance();
+ now.setTime(date);
+ now.set(Calendar.DATE, now.get(Calendar.DATE) - day);
+ SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyyMMdd");
+ systemDate = simpleDateFormat.format(now.getTime());
+ return systemDate;
+ }
+
+ /**
+ * 当前时间前几天时间
+ * @param day
+ * 天数
+ * return
+ */
+ public static String getCurrentDateAfter(String time,int day) {
+ try{
+ SimpleDateFormat format = new SimpleDateFormat("yyyyMMddHH");
+ Date dDate = format.parse(time);
+ Calendar now = Calendar.getInstance();
+ now.setTime(dDate);
+ now.set(Calendar.DATE, now.get(Calendar.DATE) + day);
+ SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyyMMdd");
+ systemDate = simpleDateFormat.format(now.getTime());
+ }catch (Exception e){
+
+ }
+
+ return systemDate;
+ }
+
+ /**
+ * 获取时间
+ * @param time
+ * 时间
+ * return yyyy.MM.dd
+ */
+ public static String getDateYYMMDD(String time) {
+ try {
+ SimpleDateFormat format = new SimpleDateFormat("yyyyMMddHHmmss");
+ Date dDate = format.parse(time);
+ SimpleDateFormat format2 = new SimpleDateFormat("yyyy.MM.dd");
+ String reTime = format2.format(dDate);
+ return reTime;
+ } catch (ParseException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ return null;
+ }
+
+ /**
+ * 获取时间
+ * @param time
+ * 时间
+ * return yyyy.MM.dd
+ */
+ public static String getDateYYMMDDPoint(String time) throws Exception{
+
+ SimpleDateFormat format = new SimpleDateFormat("yyyyMMdd");
+ Date dDate = format.parse(time);
+
+ SimpleDateFormat format2 = new SimpleDateFormat("yyyy.MM.dd");
+ String reTime = format2.format(dDate);
+
+ return reTime;
+
+ }
+
+ /**
+ * 获取时间
+ * @param time yyyyMMddHHmmss
+ * return HH:mm:ss
+ */
+ public static String getDateHHMMSS(String time) {
+ try {
+ SimpleDateFormat format = new SimpleDateFormat("yyyyMMddHHmmss");
+ Date dDate = format.parse(time);
+ SimpleDateFormat format2 = new SimpleDateFormat("HH:mm:ss");
+ String reTime = format2.format(dDate);
+ return reTime;
+ } catch (ParseException e) {
+ e.printStackTrace();
+ }
+ return null;
+ }
+
+ /**
+ * 获取当前起始时间
+ * return yyyyMMddHHmmss
+ */
+ public static String getCurrentDataStartTimeStr() {
+
+ return getYYYYMMDDDate() + "000000";
+ }
+
+ /**
+ * 获取当天结束时间
+ * return yyyyMMddHHmmss
+ */
+ public static String getCurrentDataEndTimeStr() {
+
+ SimpleDateFormat format = null;
+ Date date = null;
+ Calendar myDate = Calendar.getInstance();
+ myDate.add(Calendar.DAY_OF_MONTH, 1);
+ date = myDate.getTime();
+ format = new SimpleDateFormat("yyyyMMdd000000");
+
+ return format.format(date);
+ }
+
+
+ public static int getDateSpanYYMMDDHHMMSS(String date1, String date2) {
+ SimpleDateFormat formatter = new SimpleDateFormat("yyyyMMddHHmmss");
+ try {
+ Date start = formatter.parse(date1);
+ Date end = formatter.parse(date2);
+ long span = end.getTime() - start.getTime();
+ float ss = Math.abs(span);
+ return (int) ss;
+ } catch (ParseException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ return 0;
+ }
+
+ public static int getDateSpanIOSYYMMDDHHMMSSSSS(String date1, String date2) {
+ SimpleDateFormat formatter = new SimpleDateFormat("yyyyMMddHHmmssSSS");
+ try {
+ Date start = formatter.parse(date1);
+ Date end = formatter.parse(date2);
+ long span = end.getTime() - start.getTime();
+ float ss = Math.abs(span);
+ return (int) ss;
+ } catch (ParseException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ return 0;
+ }
+
+ /**
+ * 获取时间
+ * return
+ */
+ public static String toDateYYMMDDHHSSMM(String time) {
+ try {
+ SimpleDateFormat format = new SimpleDateFormat("yyyyMMddHHmmss");
+ Date dDate = format.parse(time);
+ SimpleDateFormat format2 = new SimpleDateFormat("yyyy年MM月dd日HH时mm分ss秒");
+ String reTime = format2.format(dDate);
+ return reTime;
+ } catch (ParseException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ return null;
+ }
+
+ /**
+ * 字符串格式时间转成Date格式
+ *
+ * @param dateString
+ * @return
+ */
+ public static Date stringToDate(String dateString) {
+ try {
+ SimpleDateFormat sim = new SimpleDateFormat("yyyyMMddHHmmss");
+ Date ticDate = sim.parse(dateString);
+ return ticDate;
+ } catch (Exception e) {
+
+ }
+ return null;
+ }
+
+ /**
+ * 字符串格式时间转成Date格式
+ *
+ * @param dateString
+ * @return
+ */
+ public static Date stringFullTimeToDate(String dateString) {
+ try {
+ SimpleDateFormat sim = new SimpleDateFormat("yyyyMMddHHmmssSSS");
+ Date ticDate = sim.parse(dateString);
+ return ticDate;
+ } catch (Exception e) {
+
+ }
+ return null;
+ }
+
+ /**
+ * 判断两个日期相差天数
+ * 大的日期放后面
+ *
+ * @param date1
+ * @param date2
+ * @return
+ */
+ public static int differentDays(Date date1, Date date2) {
+ int days = (int) ((date2.getTime() - date1.getTime()) / (1000 * 3600 * 24));
+ return days;
+ }
+}
diff --git a/app/src/main/java/com/navinfo/omqs/ui/activity/PermissionsActivity.kt b/app/src/main/java/com/navinfo/omqs/ui/activity/PermissionsActivity.kt
index fa584a95..89b88868 100644
--- a/app/src/main/java/com/navinfo/omqs/ui/activity/PermissionsActivity.kt
+++ b/app/src/main/java/com/navinfo/omqs/ui/activity/PermissionsActivity.kt
@@ -29,10 +29,11 @@ open class PermissionsActivity : BaseActivity() {
//定位权限
permissionList.add(Permission.ACCESS_FINE_LOCATION)
permissionList.add(Permission.ACCESS_COARSE_LOCATION)
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
+ //android10
+ if (Build.VERSION.SDK_INT == Build.VERSION_CODES.Q) {
permissionList.add(Permission.ACCESS_BACKGROUND_LOCATION)
}
- XXPermissions.with(this)
+/* XXPermissions.with(this)
// 申请单个权限
.permission(permissionList)
// 设置权限请求拦截器(局部设置)
@@ -72,7 +73,7 @@ open class PermissionsActivity : BaseActivity() {
onPermissionsDenied()
}
}
- })
+ })*/
}
/**
diff --git a/app/src/main/java/com/navinfo/omqs/ui/activity/map/MainActivity.kt b/app/src/main/java/com/navinfo/omqs/ui/activity/map/MainActivity.kt
index b28d7c4f..afd789f6 100644
--- a/app/src/main/java/com/navinfo/omqs/ui/activity/map/MainActivity.kt
+++ b/app/src/main/java/com/navinfo/omqs/ui/activity/map/MainActivity.kt
@@ -1,19 +1,22 @@
package com.navinfo.omqs.ui.activity.map
import android.os.Bundle
-import android.provider.ContactsContract.Contacts
import android.util.Log
import androidx.activity.viewModels
import androidx.core.view.WindowCompat
import androidx.databinding.DataBindingUtil
+import com.blankj.utilcode.util.ToastUtils
import androidx.lifecycle.lifecycleScope
import androidx.lifecycle.viewModelScope
import androidx.navigation.findNavController
import com.navinfo.collect.library.map.NIMapController
+import com.navinfo.collect.library.map.handler.NiLocationListener
import com.navinfo.omqs.Constant
import com.navinfo.omqs.R
import com.navinfo.omqs.databinding.ActivityMainBinding
+import com.navinfo.omqs.db.TraceDataBase
import com.navinfo.omqs.http.offlinemapdownload.OfflineMapDownloadManager
+import com.navinfo.omqs.system.SystemConstant
import com.navinfo.omqs.ui.activity.BaseActivity
import dagger.hilt.android.AndroidEntryPoint
import javax.inject.Inject
@@ -61,6 +64,13 @@ class MainActivity : BaseActivity() {
//开启定位
mapController.locationLayerHandler.startLocation()
+ //启动轨迹存储
+ mapController.locationLayerHandler.setNiLocationListener(NiLocationListener {
+ binding!!.viewModel!!.addSaveTrace(it)
+ binding!!.viewModel!!.startSaveTraceThread(this)
+ })
+ //显示轨迹图层
+ mapController.layerManagerHandler.showNiLocationLayer(Constant.DATA_PATH+ SystemConstant.USER_ID+"/trace.sqlite")
}
override fun onPause() {
@@ -86,6 +96,13 @@ class MainActivity : BaseActivity() {
binding.mainActivityDrawer.open()
}
+ /**
+ * 打开相机预览
+ */
+ fun openCamera() {
+ binding!!.viewModel!!.onClickCameraButton(this)
+ }
+
/**
* 点击录音按钮
*/
diff --git a/app/src/main/java/com/navinfo/omqs/ui/activity/map/MainViewModel.kt b/app/src/main/java/com/navinfo/omqs/ui/activity/map/MainViewModel.kt
index c052a0f7..bc08d68e 100644
--- a/app/src/main/java/com/navinfo/omqs/ui/activity/map/MainViewModel.kt
+++ b/app/src/main/java/com/navinfo/omqs/ui/activity/map/MainViewModel.kt
@@ -1,12 +1,25 @@
package com.navinfo.omqs.ui.activity.map
+import android.content.Context
+import android.content.DialogInterface
import android.util.Log
import androidx.lifecycle.ViewModel
+import com.blankj.utilcode.util.ToastUtils
+import com.navinfo.collect.library.data.entity.NiLocation
import com.navinfo.collect.library.map.NIMapController
+import com.navinfo.collect.library.utils.GeometryTools
+import com.navinfo.collect.library.utils.GeometryToolsKt
+import com.navinfo.omqs.Constant
+import com.navinfo.omqs.R
+import com.navinfo.omqs.db.TraceDataBase
+import com.navinfo.omqs.system.SystemConstant
+import com.navinfo.omqs.ui.dialog.CommonDialog
+import com.navinfo.omqs.ui.manager.TakePhotoManager
import dagger.hilt.android.lifecycle.HiltViewModel
-import dagger.hilt.android.scopes.ActivityRetainedScoped
+import io.realm.RealmSet
+import org.videolan.libvlc.LibVlcUtil
+import java.util.*
import javax.inject.Inject
-import javax.inject.Singleton
/**
* 创建Activity全局viewmode
@@ -16,6 +29,9 @@ class MainViewModel @Inject constructor(
private val mapController: NIMapController,
) : ViewModel() {
+ private var mCameraDialog: CommonDialog? = null
+
+ private var niLocationList:MutableList = ArrayList()
/**
* 点击我的位置,回到我的位置
@@ -27,4 +43,81 @@ class MainViewModel @Inject constructor(
override fun onCleared() {
super.onCleared()
}
+
+ //点击相机按钮
+ fun onClickCameraButton(context: Context){
+
+ Log.e("qj", LibVlcUtil.hasCompatibleCPU(context).toString())
+
+ ToastUtils.showShort("点击了相机")
+
+ if (mCameraDialog == null) {
+ mCameraDialog = CommonDialog(context, context.resources.getDimension(R.dimen.head_img_width).toInt() * 3 + context.resources.getDimension(R.dimen.ten).toInt() + context.resources.getDimension(R.dimen.twenty_four).toInt(), context.resources.getDimension(R.dimen.head_img_width).toInt() + 10, 1)
+ mCameraDialog!!.setCancelable(true)
+ }
+ mCameraDialog!!.openCamear(mCameraDialog!!.getmShareUtil().continusTakePhotoState)
+ mCameraDialog!!.show()
+ mCameraDialog!!.setOnDismissListener(DialogInterface.OnDismissListener {
+ mCameraDialog!!.hideLoading()
+ mCameraDialog!!.stopVideo()
+ try {
+ if (!mCameraDialog!!.getmShareUtil().connectstate){
+ mCameraDialog!!.updateCameraResources(1, mCameraDialog!!.getmDeviceNum())
+ }
+ TakePhotoManager.getInstance().getCameraVedioClent(mCameraDialog!!.getmDeviceNum()).StopSearch()
+ } catch (e: Exception) {
+ }
+ })
+ mCameraDialog!!.setOnShowListener(DialogInterface.OnShowListener {
+ mCameraDialog!!.initmTakePhotoOrRecord(mCameraDialog!!.getmShareUtil().selectTakePhotoOrRecord)
+ if (!mCameraDialog!!.isShowVideo && mCameraDialog!!.getmShareUtil().connectstate && mCameraDialog!!.getmShareUtil().continusTakePhotoState) {
+ mCameraDialog!!.playVideo()
+ }
+ })
+ }
+
+ fun startSaveTraceThread(context: Context){
+ Thread(Runnable {
+ try {
+ while (true){
+
+ if(niLocationList!=null&&niLocationList.size>0){
+
+ var niLocation = niLocationList[0]
+ var doubleArray = doubleArrayOf()
+ doubleArray[0] = niLocation.longitude
+ doubleArray[1] = niLocation.latitude
+ val geometry = GeometryTools.createGeometry(doubleArray)
+ val tileX = RealmSet()
+ GeometryToolsKt.getTileXByGeometry(geometry.toString(), tileX)
+ val tileY = RealmSet()
+ GeometryToolsKt.getTileYByGeometry(geometry.toString(), tileY)
+
+ //遍历存储tile对应的x与y的值
+ tileX.forEach { x ->
+ tileY.forEach { y ->
+ niLocation.tilex = x
+ niLocation.tiley = y
+ }
+ }
+
+ TraceDataBase.getDatabase(context, Constant.DATA_PATH+ SystemConstant.USER_ID+"/trace.sqlite").niLocationDao.insert(niLocation)
+ niLocationList.removeAt(0)
+ Log.e("qj","saveTrace")
+ }
+ Thread.sleep(30)
+ }
+ } catch (e: InterruptedException) {
+ e.printStackTrace()
+ Log.e("qj","异常==${e.message}")
+ }
+ }).start()
+ }
+
+ //增加轨迹存储
+ fun addSaveTrace(niLocation: NiLocation){
+ if(niLocation!=null&&niLocationList!=null){
+ niLocationList.add(niLocation)
+ }
+ }
}
\ No newline at end of file
diff --git a/app/src/main/java/com/navinfo/omqs/ui/dialog/CommonDialog.java b/app/src/main/java/com/navinfo/omqs/ui/dialog/CommonDialog.java
new file mode 100644
index 00000000..43567e82
--- /dev/null
+++ b/app/src/main/java/com/navinfo/omqs/ui/dialog/CommonDialog.java
@@ -0,0 +1,1608 @@
+package com.navinfo.omqs.ui.dialog;
+
+import android.app.Dialog;
+import android.content.Context;
+import android.graphics.Bitmap;
+import android.graphics.PixelFormat;
+import android.graphics.drawable.AnimationDrawable;
+import android.graphics.drawable.Drawable;
+import android.media.AudioManager;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.Message;
+import android.text.TextUtils;
+import android.util.Log;
+import android.view.Display;
+import android.view.Gravity;
+import android.view.SurfaceHolder;
+import android.view.SurfaceView;
+import android.view.View;
+import android.view.WindowManager;
+import android.widget.CheckBox;
+import android.widget.CompoundButton;
+import android.widget.CompoundButton.OnCheckedChangeListener;
+import android.widget.ImageView;
+import android.widget.LinearLayout;
+import android.widget.TextView;
+import android.widget.Toast;
+
+import com.android.volley.VolleyError;
+import com.navinfo.collect.library.garminvirbxe.CameraGarminVirbXE;
+import com.navinfo.collect.library.garminvirbxe.CameraEventListener;
+import com.navinfo.collect.library.sensor.ISensor.enmSignalQuality;
+import com.navinfo.collect.library.sensor.ISensor.enmConnectionStatus;
+import com.navinfo.collect.library.sensor.ISensor.SensorWorkingMode;
+import com.navinfo.collect.library.garminvirbxe.SensorParams;
+import com.navinfo.collect.library.garminvirbxe.HostBean;
+import com.navinfo.omqs.Constant;
+import com.navinfo.omqs.R;
+import com.navinfo.omqs.system.SystemConstant;
+import com.navinfo.omqs.system.SystemDateTime;
+import com.navinfo.omqs.ui.activity.map.MainActivity;
+import com.navinfo.omqs.ui.manager.TakePhotoManager;
+import com.navinfo.omqs.ui.other.BaseToast;
+import com.navinfo.omqs.util.FileUtils;
+import com.navinfo.omqs.util.NetUtils;
+import com.navinfo.omqs.util.ShareUtil;
+
+import org.videolan.libvlc.EventHandler;
+import org.videolan.libvlc.IVideoPlayer;
+import org.videolan.libvlc.LibVLC;
+import org.videolan.vlc.Util;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.Date;
+
+/**
+ * 公共相机对话框
+ *
+ * @author chentao
+ */
+public class CommonDialog extends Dialog implements SurfaceHolder.Callback, IVideoPlayer {
+ /**
+ * 上下文环境
+ */
+ private Context context;
+ /**
+ * 拍照控制类
+ */
+ private TakePhotoManager takephotoManager;
+ /**
+ * 相机事件回调
+ */
+ private CameraEventListener listener;
+
+
+ /**
+ * 对话框取消按钮
+ */
+ private ImageView mCancelDialog;
+ /**
+ * 开始/结束拍照按钮
+ */
+ private CheckBox mStartOrEndTakePicture;
+ /**
+ * 一键连接按钮
+ */
+ private TextView mOneBtConnect;
+ /**
+ * GPS连接提示
+ */
+ private TextView mGpsTv;
+
+ /**
+ * 选择使用默认相机还是外接相机
+ */
+ private CheckBox mSelectCamera;
+ /**
+ * 选择录像还是拍照
+ */
+ private CheckBox mTakePhotoOrRecord;
+ /**
+ * 选择相机保持的状态
+ */
+ private boolean bl;
+ /**
+ * 连续拍照的状态
+ */
+ private boolean conbl;
+
+ /**
+ * 录像还是拍照bl
+ */
+ private boolean recordOrTaKebl;
+
+ //相机模式
+ private int mMode;
+
+ //true连接成功,false未连接成功
+ public boolean connectstate = false;
+
+ //true 可点击,false不可点击
+ private boolean click_state = true;
+
+ private boolean isShowVideo;
+ private SurfaceView mSurfaceView;//展示视频的surfaceView
+ private LinearLayout mSurfaceBgLayout;
+ private ImageView mImgView;
+ private LibVLC mMediaPlayer;
+ private SurfaceHolder mSurfaceHolder;
+ private View mLoadingView;
+ private int mVideoHeight;
+ private int mVideoWidth;
+ private int mVideoVisibleHeight;
+ private int mVideoVisibleWidth;
+ private int mSarNum;
+ private int mSarDen;
+ //存储状态信息
+ private ShareUtil mShareUtil;
+
+ private LoadingDialog videoLoadingProDlg = null;
+
+ private int mX, mY;
+ //相机对象
+ private HostBean mHostBean;
+
+ //设备号
+ private int mDeviceNum;
+
+ //是否点击取消
+ private boolean isCancel;
+
+ //开始校验时间
+ private long mStartCheckTime = 0;
+
+ //单拍模式照片名称
+ private String mSinglePhotoName;
+
+ //是否校验了时间
+ private boolean isCheckTime;
+
+ private static int COMMAND_CAMERA_SNAPPICTURE_SINGLE_COUNT = 0;
+
+ private static int COMMAND_CAMERA_MEDIAPLAY_ERROR_COUNT = 0;
+
+ private long mPreTime;
+ boolean isStartThread;
+ boolean isStartThread2;
+
+ public CommonDialog(Context context, int x, int y, int deviceNum) {
+ super(context, R.style.MyCustomDialog);
+ // TODO Auto-generated constructor stub
+ mX = x;
+ mY = y;
+ setmDeviceNum(deviceNum);
+ mShareUtil = new ShareUtil(context, deviceNum);
+ this.context = context;
+ }
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ // TODO Auto-generated method stub
+ super.onCreate(savedInstanceState);
+ this.setContentView(R.layout.connect_out_camera);
+
+ mSurfaceView = (SurfaceView) findViewById(R.id.video);
+
+ mImgView = (ImageView) findViewById(R.id.video_defalut);
+ try {
+ mMediaPlayer = Util.getInstance().getLibVlcInstance();
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+
+ mSurfaceHolder = mSurfaceView.getHolder();
+ mSurfaceHolder.setFormat(PixelFormat.RGBX_8888);
+ mSurfaceHolder.addCallback(this);
+
+ EventHandler em = EventHandler.getInstance();
+ em.addHandler(mVlcHandler);
+
+ this.setVolumeControlStream(AudioManager.STREAM_MUSIC);
+
+ mSurfaceView.setKeepScreenOn(true);
+
+ WindowManager.LayoutParams params = this.getWindow().getAttributes();
+ WindowManager wm = (WindowManager) context
+ .getSystemService(Context.WINDOW_SERVICE);
+ Display display = wm.getDefaultDisplay();
+ params.width = (int) (display.getWidth() * 0.3);
+ params.height = (int) (display.getHeight() * 0.8);
+ params.x = mX;
+ params.y = mY;
+ this.getWindow().setGravity(Gravity.LEFT | Gravity.TOP);
+ this.getWindow().setAttributes(params);
+
+ takephotoManager = TakePhotoManager.getInstance();
+
+ listener = new CameraEventListener() {
+
+ @Override
+ public void OnSignalQualityChanged(enmSignalQuality sq) {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ public void OnSensorEvent() {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ public void OnConnectionStatusChanged(enmConnectionStatus cs) {
+
+ }
+
+ @Override
+ public void OnConnectionStatusChanged(HostBean hostBean, enmConnectionStatus cs, int tag) {
+
+ if (tag != getmDeviceNum())
+ return;
+
+ ImageView iv = (ImageView) ((MainActivity) context).findViewById(getResId());
+
+ iv.setBackgroundDrawable(null);
+
+ if (cs == enmConnectionStatus.CONNECTTED) {
+
+ Log.e("AAA", "连接成功");
+
+ updateCameraResources(0, getmDeviceNum());
+
+ //当前是否开始录像或拍照
+ if (mStartOrEndTakePicture != null) {
+
+ conbl = mShareUtil.getContinusTakePhotoState();
+
+ if (mStartOrEndTakePicture.isChecked() != conbl){
+ mStartOrEndTakePicture.setChecked(conbl);
+ }
+
+ }
+
+ if (conbl && isShowing()) {
+ startGPSStatus();
+ }else{
+ //恢复按钮可用状态
+ if(mStartOrEndTakePicture!=null)
+ mStartOrEndTakePicture.setEnabled(true);
+ }
+
+
+ } else if (cs == enmConnectionStatus.DISCONNECTTED) {
+
+ connectionFailed("相机丢失连接,请检查网络是否畅通!");
+/* if (ShowMode.getInstance().getImageWorkMode().isStartWork()) {
+ BaseToast.makeText(getContext(), "相机拍摄中断,图像作业已结束!", BaseToast.LENGTH_SHORT).show();
+ ShowMode.getInstance().getImageWorkMode().endWork();
+ }*/
+ } else if (cs == enmConnectionStatus.CONNECTTING) {
+
+ Log.e("AAA", "连接中");
+ connectstate = false;
+ mShareUtil.setConnectstate(SystemConstant.USER_ID, connectstate);
+ mOneBtConnect.setText("连接中");
+ updateCameraResources(2, getmDeviceNum());
+
+ } else {
+ connectstate = false;
+ mShareUtil.setConnectstate(SystemConstant.USER_ID, connectstate);
+ click_state = true;
+
+ mOneBtConnect.setEnabled(click_state);
+ mOneBtConnect.setPressed(false);
+ mOneBtConnect.setText("一键连接");
+ mStartOrEndTakePicture.setEnabled(false);
+ mOneBtConnect.setBackgroundResource(R.drawable.btn_connect_bg_enabled);
+ updateCameraResources(1, getmDeviceNum());
+
+ Log.e("AAA", "未知返回");
+
+ stopVideo();
+ }
+
+ }
+
+ @Override
+ public void OnContinuousPhototTimeLapseRateResponse(HostBean hostBean, int tag) {
+ if (tag != getmDeviceNum())
+ return;
+ //再次启动命令
+ takephotoManager.StartRecording(mHostBean, getmDeviceNum());
+ }
+
+ @Override
+ public void OnContinuousPhototTimeLapseRateStartResponse(HostBean hostBean, int tag) {
+ if (tag != getmDeviceNum())
+ return;
+
+ Message msg = new Message();
+ msg.what = 0x55;
+ mHandler.sendMessage(msg);
+ }
+
+ @Override
+ public void OnContinuousPhototTimeLapseRateStopResponse(HostBean hostBean, int tag) {
+ if (tag != getmDeviceNum())
+ return;
+
+ //启动监控
+ if (connectstate && isShowing()) {
+ playVideo();
+ updateCameraResources(0, getmDeviceNum());
+ }
+ }
+
+ @Override //单拍模式
+ public void OnContinuousPhototSingle(HostBean hostBean, final String url, final String name, int tag) {
+
+ if (tag != getmDeviceNum())
+ return;
+
+ Log.i("OnGetGpsStatusResponse", "OnContinuousPhototSingle");
+
+
+ if (!TextUtils.isEmpty(url)) {
+
+ Message msg = new Message();
+ msg.what = HANDLER_BUFFER_START;
+ mHandler.sendMessage(msg);
+
+ new Thread(new Runnable() {
+ @Override
+ public void run() {
+
+
+ Message msg = new Message();
+
+ String picPath = Constant.DATA_PATH + "/" + SystemConstant.USER_ID + "/pic.jpg";
+
+ //创建目录
+ if(!new File(Constant.DATA_PATH + "/" + SystemConstant.USER_ID).exists()){
+ new File(Constant.DATA_PATH + "/" + SystemConstant.USER_ID).mkdirs();
+ }
+
+ //多次获取照片信息,解决概率事件无法获取有效照片问题
+ for (int i = 0; i < 5; i++) {
+ if (new File(picPath).exists()) {
+ new File(picPath).delete();
+ }
+
+ FileUtils.saveImageToDisk(url, picPath);
+
+ String time = FileUtils.getExifTime(picPath);
+
+ Log.e("AAA", "获取单张拍照时间" + time+"次数"+i);
+ if (!TextUtils.isEmpty(time)) {
+ long picTime = SystemDateTime.getPicTime(time);
+
+ long disTime = mStartCheckTime - picTime / 1000;
+
+ Log.i("qj", "OnGetMediaList" + disTime);
+
+ if (disTime < 30 && disTime > -30) {
+
+ mMode = mShareUtil.getTakeCameraMode();
+
+ //恢复模式
+ if (mMode == 0) {
+ if (takephotoManager.getCameraMode(getmDeviceNum()) != SensorWorkingMode.CAMERA_VEDIO_TIMELAPSE)
+ takephotoManager.setCameraMode(getmDeviceNum(), SensorWorkingMode.CAMERA_VEDIO_TIMELAPSE);
+ } else {
+ if (takephotoManager.getCameraMode(getmDeviceNum()) != SensorWorkingMode.CAMEAR_PHOTO_CONTINUOUS_PHOTO)
+ takephotoManager.setCameraMode(getmDeviceNum(), SensorWorkingMode.CAMEAR_PHOTO_CONTINUOUS_PHOTO);
+ }
+
+ try {
+ //延时1秒发送预览命令
+ Thread.sleep(1000);
+ } catch (Exception e) {
+
+ }
+ msg.what = 0x66;
+ mHandler.sendMessage(msg);
+ return;
+
+ }
+ }
+ }
+ msg.what = 0x77;
+ mHandler.sendMessage(msg);
+ }
+ }).start();
+
+ } else {
+ BaseToast.makeText(context, "校验时间信息失败,请注意核对时间信息!", Toast.LENGTH_SHORT).show();
+ mGpsTv.setVisibility(View.VISIBLE);
+ mGpsTv.setText("请在设置中确保PAD/时区与相机/时区保持一致。");
+ }
+ }
+
+ @Override
+ public void OnGetMediaList(HostBean hostBean, String json, int tag) {
+ if (tag != getmDeviceNum())
+ return;
+
+ }
+
+ @Override
+ public void requestError(HostBean hostBean, VolleyError e, CameraGarminVirbXE.enmCommandType commandType, int tag) {
+
+ if (tag != getmDeviceNum())
+ return;
+
+ //如果是单拍命令异常时重新再次进行获取
+ if(commandType!=null&&commandType== CameraGarminVirbXE.enmCommandType.COMMAND_CAMERA_SNAPPICTURE_SINGLE&&!isCheckTime&&mOneBtConnect!=null&&mOneBtConnect.getText().toString().contains("断开连接")){
+
+ COMMAND_CAMERA_SNAPPICTURE_SINGLE_COUNT ++;
+
+ //连续尝试多次进行获取,如果多次失败则提示
+ if(COMMAND_CAMERA_SNAPPICTURE_SINGLE_COUNT == 3){
+ Message msg = new Message();
+ msg.what = 0x77;
+ mHandler.sendMessage(msg);
+ COMMAND_CAMERA_SNAPPICTURE_SINGLE_COUNT = 0;
+ }else{
+ BaseToast.makeText(context,"重新获取时间信息。",Toast.LENGTH_SHORT).show();
+ showLoading();
+ //重新获取拍照时间
+ takephotoManager.setCameraMode(getmDeviceNum(), SensorWorkingMode.CAMERA_PHOTO_SINGLE);
+ //启动单拍模式开始校验时间
+ takephotoManager.SnapShot(getmHostBean(),getmDeviceNum());
+ //只要秒时间
+ mStartCheckTime = new Date().getTime() / 1000;
+ }
+ }
+
+ // BaseToast.makeText(context,"命令异常,请确认网络是否正常。",Toast.LENGTH_SHORT).show();
+
+ }
+
+ @Override
+ public void OnStopRecordResponse(HostBean hostBean, int tag) {
+ if (tag != getmDeviceNum())
+ return;
+
+ //启动监控
+ if (connectstate && isShowing()) {
+ playVideo();
+ updateCameraResources(0, getmDeviceNum());
+ }
+
+
+ }
+
+ @Override
+ public void OnStatusResponse(HostBean hostBean, int tag) {
+
+ if (tag != getmDeviceNum())
+ return;
+
+ updateCameraResources(0, getmDeviceNum());
+ connectstate = true;
+ mShareUtil.setConnectstate(SystemConstant.USER_ID, connectstate);
+ stopVideo();
+ mOneBtConnect.setPressed(true);
+ mOneBtConnect.setBackgroundResource(R.drawable.btn_red_disconnect_bg);
+ mOneBtConnect.setText("断开连接!");
+ //停止获取GPS状态
+ if (getmDeviceNum() == 1)
+ isStartThread = false;
+ else
+ isStartThread2 = false;
+ try {
+ Thread.sleep(200);
+ } catch (InterruptedException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ Log.i("chentao", "连接成功");
+ Log.e("AAA", "OnStatusResponse ok ");
+
+ }
+
+ @Override
+ public void OnStartRecordResponse(HostBean hostBean, int tag) {
+
+ if (tag != getmDeviceNum())
+ return;
+
+ Message msg = new Message();
+ msg.what = 0x55;
+ mHandler.sendMessage(msg);
+
+ }
+
+ @Override
+ public void OnSnapPictureResponse(HostBean hostBean, Bitmap bitmap, String picName, int tag) {
+
+ if (tag != getmDeviceNum())
+ return;
+
+ if (hostBean != null && mHostBean != null && hostBean.hardwareAddress.equals(mHostBean.hardwareAddress)) {
+
+ }
+ }
+
+ @Override
+ public void OnSearchResponse(int tag, ArrayList listIp) {
+
+ //判断标识
+ if (tag != getmDeviceNum())
+ return;
+
+ Log.e("AAA", "搜索到完成");
+
+ if (listIp.size() > 0) {
+ //已连接相机地址
+ String connectstateMac = ShareUtil.getConnectstateMac(context);
+ //存在连接设备
+ if (!TextUtils.isEmpty(connectstateMac)) {
+ boolean isConn = false;
+ b:
+ for (HostBean hostBean : listIp) {
+ if (!hostBean.hardwareAddress.equalsIgnoreCase(connectstateMac)) {
+ isConn = true;
+ connection(hostBean);
+ break b;
+ }
+ }
+ if (!isConn) {
+ connectionFailed("无可用设备");
+ }
+ } else {
+ connection(listIp.get(0));
+ }
+ } else {
+ connectionFailed("相机丢失连接,请检查网络是否畅通!");
+ }
+ }
+
+ @Override
+ public void OnConnectStatusChanged(HostBean hostBean, enmConnectionStatus connectStatus, int tag) {
+ if (hostBean != null && mHostBean != null && hostBean.hardwareAddress.equals(mHostBean.hardwareAddress)) {
+
+ }
+ }
+
+ @Override
+ public void OnGetDeviceInfo(HostBean hostBean, String devicesId, int tag) {
+ // TODO Auto-generated method stub
+ if (hostBean != null && mHostBean != null && hostBean.hardwareAddress.equals(mHostBean.hardwareAddress)) {
+ Log.e("AAA", "devicesId" + devicesId);
+ }
+ }
+
+ @Override
+ public void OnGetGpsStatusResponse(HostBean hostBean, boolean status, int tag) {
+
+ if (tag != getmDeviceNum())
+ return;
+
+ try {
+
+ if (mShareUtil.getContinusTakePhotoState() && !mStartOrEndTakePicture.isEnabled()) {
+
+ if (status) {
+
+ BaseToast.makeText(context, "成功获取相机GPS信号!正在校验时间信息。。。", Toast.LENGTH_SHORT).show();
+
+ //获取GPS信号停止获取线程
+ if (getmDeviceNum() == 1) {
+ isStartThread = false;
+ } else {
+ isStartThread2 = false;
+ }
+
+ //相机GPS信号差,请稍等片刻,或将相机移到开发地带。
+ if (!isCheckTime) {
+ mGpsTv.setText("正在校验时区正确性,请耐心等待!");
+ showLoading();
+ mGpsTv.setVisibility(View.VISIBLE);
+ //初始化
+ COMMAND_CAMERA_SNAPPICTURE_SINGLE_COUNT = 0;
+ takephotoManager.setCameraMode(getmDeviceNum(), SensorWorkingMode.CAMERA_PHOTO_SINGLE);
+ //启动单拍模式开始校验时间
+ takephotoManager.SnapShot(getmHostBean(),getmDeviceNum());
+ //只要秒时间
+ mStartCheckTime = new Date().getTime() / 1000;
+ }
+ Log.i("qj", "OnGetGpsStatusResponse启动时间校验");
+ } else {
+ mGpsTv.setText("相机GPS信号差,请稍等片刻,或将相机移到开发地带。");
+ mGpsTv.setVisibility(View.VISIBLE);
+ mStartOrEndTakePicture.setEnabled(status);
+ mShareUtil.setContinusTakePhotoState(SystemConstant.USER_ID, true);
+ }
+
+ }
+
+ } catch (Exception e) {
+ }
+ }
+ };
+
+ takephotoManager.setOnCameraEventChangeListener(listener);
+
+ bl = mShareUtil.getSelectCameraKind();
+
+ recordOrTaKebl = mShareUtil.getSelectTakePhotoOrRecord();
+
+ conbl = mShareUtil.getContinusTakePhotoState();
+
+ //初始化
+ init();
+
+ //添加监听器
+ addListeners();
+ }
+
+ //初始化
+ private void init() {
+
+ //拍照或录像
+ mTakePhotoOrRecord = (CheckBox) findViewById(R.id.takephoto_or_record);
+ mCancelDialog = (ImageView) findViewById(R.id.cancel_dialog);
+ mStartOrEndTakePicture = (CheckBox) findViewById(R.id.startorendtakepicture);
+ mOneBtConnect = (TextView) findViewById(R.id.one_bt_connect);
+ mGpsTv = (TextView) findViewById(R.id.gps_status_hint);
+ //是否为外设相机拍照
+ mSelectCamera = (CheckBox) findViewById(R.id.select_camera);
+
+ mMode = mShareUtil.getTakeCameraMode();
+
+ if (mMode == 0) {
+ recordOrTaKebl = true;
+ mTakePhotoOrRecord.setText("录像");
+ setmImgViewImageDrawable(0);
+ if (takephotoManager.getCameraMode(getmDeviceNum()) != SensorWorkingMode.CAMERA_VEDIO_TIMELAPSE)
+ takephotoManager.setCameraMode(getmDeviceNum(), SensorWorkingMode.CAMERA_VEDIO_TIMELAPSE);
+ } else {
+ recordOrTaKebl = false;
+ if (takephotoManager.getCameraMode(getmDeviceNum()) != SensorWorkingMode.CAMEAR_PHOTO_CONTINUOUS_PHOTO)
+ takephotoManager.setCameraMode(getmDeviceNum(), SensorWorkingMode.CAMEAR_PHOTO_CONTINUOUS_PHOTO);
+ mTakePhotoOrRecord.setText("拍照");
+ setmImgViewImageDrawable(1);
+ }
+
+ mSelectCamera.setChecked(bl);
+
+ mTakePhotoOrRecord.setChecked(recordOrTaKebl);
+
+ mOneBtConnect.setEnabled(click_state);
+
+ connectstate = mShareUtil.getConnectstate();
+
+ //当前为连接时启动已有的状态
+ if (connectstate) {
+ mOneBtConnect.setPressed(true);
+
+ mOneBtConnect.setBackgroundResource(R.drawable.btn_red_disconnect_bg);
+
+ mOneBtConnect.setText("断开连接!");
+
+ //启动或关闭拍照模式
+ mStartOrEndTakePicture.setChecked(conbl);
+
+ if (conbl) {
+
+ mStartOrEndTakePicture.setEnabled(false);
+ mHostBean = new HostBean();
+ mHostBean.hardwareAddress = mShareUtil.getTakeCameraMac();
+ mHostBean.ipAddress = mShareUtil.getTakeCameraIP();
+ takephotoManager.getCameraVedioClent(getmDeviceNum()).setmHostBean(mHostBean);
+
+ playVideo();
+
+ startGPSStatus();
+
+ } else {
+ mStartOrEndTakePicture.setEnabled(true);
+ }
+
+ }
+
+ }
+
+ /**
+ * 更新相机状态资源
+ */
+ public void updateCameraResources(int statusType, int indexClentCamera) {
+ int resId = R.id.main_activity_camera;
+
+ if (indexClentCamera == 2)
+ resId = R.id.main_activity_camera2;
+
+ Drawable drawable = context.getResources().getDrawable(R.mipmap.icon_page_video_a0);
+
+ ShareUtil shareUtil = new ShareUtil(context, indexClentCamera);
+ //0为录像模式
+ if (shareUtil.getTakeCameraMode() == 0) {
+ switch (statusType) {
+ case 0:
+ drawable = context.getResources().getDrawable(R.mipmap.icon_page_video_a0);
+ break;
+ case 1:
+ drawable = context.getResources().getDrawable(R.mipmap.icon_page_video_a1);
+ break;
+ case 2:
+ drawable = context.getResources().getDrawable(R.mipmap.icon_page_video_a2);
+ break;
+ case 3:
+ drawable = context.getResources().getDrawable(R.mipmap.icon_page_video_a3);
+ break;
+ }
+ } else {
+ switch (statusType) {
+ case 0:
+ drawable = context.getResources().getDrawable(R.mipmap.icon_page_take_photo_a0);
+ break;
+ case 1:
+ drawable = context.getResources().getDrawable(R.mipmap.icon_page_take_photo_a1);
+ break;
+ case 2:
+ drawable = context.getResources().getDrawable(R.mipmap.icon_page_take_photo_a2);
+ break;
+ case 3:
+ drawable = context.getResources().getDrawable(R.mipmap.icon_page_take_photo_a3);
+ break;
+ }
+ }
+
+
+ ImageView ivStatus = (ImageView) findViewById(resId);
+ if (ivStatus != null) {
+ try {
+ AnimationDrawable animation = (AnimationDrawable) ivStatus.getBackground();
+ if (animation.isRunning()) {
+ animation.stop();
+ ivStatus.setBackground(null);
+ }
+
+ } catch (Exception e) {
+
+ }
+ ivStatus.setImageDrawable(drawable);
+ }
+
+ }
+
+ public void updateCameraBackgroundResources(int drawable, int indexClentCamera) {
+ int resId = R.id.main_activity_camera;
+
+ if (indexClentCamera == 2)
+ resId = R.id.main_activity_camera2;
+
+ ImageView ivStatus = (ImageView) findViewById(resId);
+
+ if (ivStatus != null) {
+ String time = SystemDateTime.getDateSimpleTime(SystemDateTime.getTimeInfo(SystemDateTime.getTime()) - 0/*MainActivity.disGoogleTime*/);
+
+ ivStatus.setImageDrawable(null);
+
+ ivStatus.setBackgroundResource(drawable);
+
+ AnimationDrawable animation = (AnimationDrawable) ivStatus.getBackground();
+
+ animation.start();
+ }
+ }
+
+ //添加监听器
+ private void addListeners() {
+
+ //取消对话框按钮
+ mCancelDialog.setOnClickListener(new View.OnClickListener() {
+
+ @Override
+ public void onClick(View arg0) {
+ dismiss();
+
+ }
+ });
+ //打开/结束连拍
+ mStartOrEndTakePicture.setOnCheckedChangeListener(new OnCheckedChangeListener() {
+
+ @Override
+ public void onCheckedChanged(CompoundButton arg0, boolean arg1) {
+ if (connectstate) {
+
+ Log.i("chentao", "打开/结束连拍:" + arg1);
+ mShareUtil.setContinusTakePhotoState(SystemConstant.USER_ID, arg1);
+
+ if (!arg1) {
+
+ stopVideoOrPicture();
+
+ } else {
+
+ takephotoManager.StopContinuousTakePhoto(mHostBean, getmDeviceNum());
+
+ //重新運行
+ startGPSStatus();
+
+ }
+
+ } else {
+
+ mStartOrEndTakePicture.setChecked(true);
+
+ mShareUtil.setContinusTakePhotoState(SystemConstant.USER_ID, true);
+
+ BaseToast.makeText(context, "外接相机没有连接成功!不能进行连续拍照!", Toast.LENGTH_SHORT).show();
+ }
+
+ }
+ });
+ //一键连接按钮
+ mOneBtConnect.setOnClickListener(new View.OnClickListener() {
+
+ @Override
+ public void onClick(View arg0) {
+ if (connectstate) {
+
+ connectstate = false;
+
+ mShareUtil.setContinusTakePhotoState(SystemConstant.USER_ID, true);
+
+ mShareUtil.setConnectstate(SystemConstant.USER_ID, connectstate);
+
+ mStartOrEndTakePicture.setChecked(true);
+
+ //修改为禁用状态
+ mStartOrEndTakePicture.setEnabled(false);
+
+ //停止当前活动
+ takephotoManager.StopContinuousTakePhoto(mHostBean, getmDeviceNum());
+
+ mOneBtConnect.setBackgroundResource(R.drawable.btn_connect_bg_enabled);
+
+ mOneBtConnect.setText("一键连接!");
+
+ mOneBtConnect.setPressed(false);
+
+ mGpsTv.setVisibility(View.GONE);
+
+ mGpsTv.setText("相机GPS信号差,请稍等片刻,或将相机移到开发地带。");
+
+ updateCameraResources(1, getmDeviceNum());
+
+ stopVideo();
+
+ } else {
+ if (mOneBtConnect.getText().toString().equals("连接中")) {
+ mOneBtConnect.setText("一键连接!");
+ mStartOrEndTakePicture.setEnabled(false);
+ connectstate = false;
+ takephotoManager.StopSearchNet(mHostBean,getmDeviceNum());
+ mGpsTv.setVisibility(View.GONE);
+ mGpsTv.setText("相机GPS信号差,请稍等片刻,或将相机移到开发地带。");
+ updateCameraResources(1, getmDeviceNum());
+ } else {
+
+ if (NetUtils.getInstance().isExistWifi(false)) {
+ //搜索相机
+ takephotoManager.SearchNet(null, getmDeviceNum(), false);
+
+ mOneBtConnect.setText("连接中");
+
+ updateCameraResources(2, getmDeviceNum());
+
+ } else {
+ connectionFailed("相机丢失连接,请检查网络是否畅通!");
+ }
+
+ }
+
+ }
+
+ }
+ });
+ //选择相机
+ mSelectCamera.setOnCheckedChangeListener(new OnCheckedChangeListener() {
+
+
+ @Override
+ public void onCheckedChanged(CompoundButton arg0, boolean arg1) {
+ if (connectstate) {
+ Log.i("chentao", "选择相机:" + arg1);
+ mShareUtil.setSelectCameraKind(SystemConstant.USER_ID, arg1);
+ } else {
+ mSelectCamera.setChecked(false);
+ mShareUtil.setSelectCameraKind(SystemConstant.USER_ID, false);
+ BaseToast.makeText(context, "外接相机没有连接成功!只能使用系统相机,谢谢!", Toast.LENGTH_SHORT).show();
+ }
+ }
+ });
+ /**
+ * 选择拍照或者录像
+ */
+ mTakePhotoOrRecord.setOnCheckedChangeListener(new OnCheckedChangeListener() {
+
+ @Override
+ public void onCheckedChanged(CompoundButton arg0, final boolean isCheck) {
+
+ //if (mStartOrEndTakePicture.isChecked()) {
+ //点击取消重置按钮时不进行窗体提示
+ if (isCancel) {
+ isCancel = false;
+ return;
+ }
+
+ FirstDialog builder = new FirstDialog(context);
+ builder.setTitle("影响状态切换提示");
+
+ String status = null;
+
+ if (isCheck) {
+ status = "录像";
+ setmImgViewImageDrawable(0);
+ } else {
+ status = "连拍";
+ setmImgViewImageDrawable(1);
+ }
+
+ mTakePhotoOrRecord.setText(status);
+
+ builder.setMessage("切换影像状态为" + status);
+
+ builder.setPositiveButton("确认", new FirstDialog.OnClickListener() {
+
+ @Override
+ public void onClick(Dialog dialog, int arg1) {
+ dialog.dismiss();
+
+ //连接状态时先停止录像或者拍照状态
+ if (connectstate) {
+ //如果当前为工作状态,先停止
+ if (!mShareUtil.getContinusTakePhotoState()) {
+ stopVideoOrPicture();
+ }
+
+ //重置拍照按钮
+ mShareUtil.setContinusTakePhotoState(SystemConstant.USER_ID, true);
+ }
+
+ //设置另外一台相机状态
+ ShareUtil shareUtilOther = new ShareUtil(context, getmDeviceNum() == 1 ? 2 : 1);
+
+ //如果另外一个台处于连接并且开始录像或者拍照时需要停止运行
+ if (shareUtilOther.getConnectstate() && !shareUtilOther.getContinusTakePhotoState()) {
+ try {
+ CameraGarminVirbXE cameraGarminVirbXE = takephotoManager.getCameraVedioClent(getmDeviceNum());
+ cameraGarminVirbXE.StopRecording();
+
+ } catch (Exception e) {
+
+ }
+
+ }
+
+ shareUtilOther.setSelectTakePhotoOrRecord(SystemConstant.USER_ID, !isCheck);
+
+ shareUtilOther.setContinusTakePhotoState(SystemConstant.USER_ID, true);
+
+ mShareUtil.setSelectTakePhotoOrRecord(SystemConstant.USER_ID, isCheck);
+
+ if (isCheck) {
+
+ mTakePhotoOrRecord.setText("录像");
+ setmImgViewImageDrawable(0);
+
+ takephotoManager.setCameraMode(getmDeviceNum(), SensorWorkingMode.CAMERA_VEDIO_TIMELAPSE);
+
+ mShareUtil.setTakeCameraMode(SystemConstant.USER_ID, 0);
+
+ shareUtilOther.setTakeCameraMode(SystemConstant.USER_ID, 1);
+
+ } else {
+
+ mTakePhotoOrRecord.setText("拍照");
+ setmImgViewImageDrawable(1);
+
+ mShareUtil.setTakeCameraMode(SystemConstant.USER_ID, 1);
+
+ shareUtilOther.setTakeCameraMode(SystemConstant.USER_ID, 0);
+
+ takephotoManager.setCameraMode(getmDeviceNum(), SensorWorkingMode.CAMEAR_PHOTO_CONTINUOUS_PHOTO);
+
+ }
+ updateCameraStatusImg();
+ }
+
+ });
+ builder.setNegativeButton("取消", new FirstDialog.OnClickListener() {
+ @Override
+ public void onClick(Dialog dialog, int which) {
+ dialog.dismiss();
+ isCancel = true;
+ if (!isCheck) {
+ mTakePhotoOrRecord.setText("录像");
+ setmImgViewImageDrawable(0);
+ } else {
+ mTakePhotoOrRecord.setText("连拍");
+ setmImgViewImageDrawable(1);
+ }
+ updateCameraStatusImg();
+ mTakePhotoOrRecord.setChecked(!isCheck);
+ }
+ });
+
+ builder.show();
+
+
+ //}
+ /*else {
+
+ mTakePhotoOrRecord.setChecked(!isCheck);
+
+ BaseToast.makeText(context, "请先停止当前活动!", Toast.LENGTH_SHORT).show();
+ }*/
+
+ }
+
+ });
+ }
+
+ //更新资源图标
+ private void updateCameraStatusImg() {
+ if (mShareUtil.getConnectstate()) {
+ updateCameraResources(0, getmDeviceNum());
+ } else {
+ updateCameraResources(1, getmDeviceNum());
+ }
+ ShareUtil shareUtilOther = new ShareUtil(context, getmDeviceNum() == 1 ? 2 : 1);
+ if (shareUtilOther.getConnectstate()) {
+ updateCameraResources(0, getmDeviceNum() == 1 ? 2 : 1);
+ } else {
+ updateCameraResources(1, getmDeviceNum() == 1 ? 2 : 1);
+ }
+ }
+
+ /**
+ * @param :
+ * @return :
+ * @method : connectionFailed
+ * @Author : xiaoxiao
+ * @Describe : 外接相机连接失败的处理
+ * @Date : 2018/5/14
+ */
+ private void connectionFailed(String msg) {
+ Log.e("AAA", "连接失败");
+ BaseToast.makeText(context, TextUtils.isEmpty(msg) ? "相机丢失连接,请检查网络是否畅通!" : msg, Toast.LENGTH_SHORT).show();
+
+ connectstate = false;
+ mShareUtil.setConnectstate(SystemConstant.USER_ID, connectstate);
+ mOneBtConnect.setPressed(false);
+ mOneBtConnect.setBackgroundResource(R.drawable.btn_connect_bg_enabled);
+ mOneBtConnect.setText("一键连接");
+ //增加按钮状态控制
+ mStartOrEndTakePicture.setEnabled(false);
+ updateCameraResources(1, getmDeviceNum());
+
+ hideLoading();
+
+ //齐济,连接中断了需要停止当前的拍照流程
+ mStartOrEndTakePicture.setChecked(false);
+ }
+
+ /**
+ * @param :
+ * @return :
+ * @method : isShowVideo
+ * @Author : xiaoxiao
+ * @Describe : 获取当前是否显示视频
+ * @Date : 2018/5/14
+ */
+ public boolean isShowVideo() {
+ return isShowVideo;
+ }
+
+ /**
+ * @param :
+ * @return :
+ * @method : playVideo
+ * @Author : xiaoxiao
+ * @Describe : 播放视频
+ * @Date : 2018/5/14
+ */
+ public void playVideo() {
+ try {
+
+ if (isShowVideo)
+ return;
+
+ if (NetUtils.getInstance().isExistWifi(false)) {
+ showLoading();
+
+ final String ip = mShareUtil.getTakeCameraIP();
+
+ if (TextUtils.isEmpty(ip))
+ return;
+ final String httpIp = "rtsp://" + ip + "/livePreviewStream";
+ if (mMediaPlayer != null) {
+ new Thread(new Runnable() {
+ @Override
+ public void run() {
+ if(mMediaPlayer.isPlaying())
+ mMediaPlayer.stop();
+ int result = -1;
+ try {
+ result = mMediaPlayer.readMedia(httpIp);
+ } catch (Exception e) {
+ e.printStackTrace();
+ result = -1;
+ }
+ Message msg = new Message();
+ msg.what = 0x11;
+ msg.arg1 = result;
+ Log.e(CommonDialog.class.getName(), "result==" + result);
+ mHandler.sendMessage(msg);
+ }
+ }).start();
+ }
+ isShowVideo = true;
+ mSurfaceView.setVisibility(View.VISIBLE);
+ } else {
+ BaseToast.makeText(context, "网络异常,请检查网络是否畅通!", Toast.LENGTH_SHORT).show();
+ }
+
+ } catch (Exception e) {
+ BaseToast.makeText(context, "网络异常,请检查网络是否畅通!", Toast.LENGTH_SHORT).show();
+ e.printStackTrace();
+ }
+ }
+
+ /**
+ * @param :
+ * @return :
+ * @method : stopVideo
+ * @Author : xiaoxiao
+ * @Describe : 停止播放视频
+ * @Date : 2018/5/14
+ */
+ public void stopVideo() {
+ isShowVideo = false;
+ if (mMediaPlayer != null) {
+ if(mMediaPlayer.isPlaying())
+ mMediaPlayer.stop();
+ mSurfaceView.setKeepScreenOn(false);
+ mSurfaceView.setBackgroundColor(getContext().getResources().getColor(R.color.bg_gray2));
+ mSurfaceView.setVisibility(View.GONE);
+ // mSurfaceBgLayout.setBackgroundColor(getContext().getResources().getColor(R.color.bg_gray2));
+ }
+ if (mImgView != null)
+ mImgView.setVisibility(View.VISIBLE);
+
+ //启动录像
+ if (connectstate && !mShareUtil.getContinusTakePhotoState()) {
+
+ takephotoManager.StartRecording(mHostBean, getmDeviceNum());
+ }
+ }
+
+ /**
+ * @param : arg1-打开true,关闭false
+ * @return :
+ * @method : openCamear
+ * @Author : xiaoxiao
+ * @Describe : 打开或关闭相机
+ * @Date : 2018/5/14
+ */
+ public void openCamear(boolean arg1) {
+ if (mStartOrEndTakePicture != null)
+ mStartOrEndTakePicture.setChecked(arg1);
+
+ }
+
+
+ @Override
+ public void surfaceCreated(SurfaceHolder holder) {
+
+ }
+
+ @Override
+ public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
+ mSurfaceHolder = holder;
+ if (mMediaPlayer != null) {
+ mMediaPlayer.attachSurface(holder.getSurface(), this, width, height);
+ }
+ if (width > 0) {
+ mVideoHeight = height;
+ mVideoWidth = width;
+ }
+ }
+
+ @Override
+ public void surfaceDestroyed(SurfaceHolder holder) {
+ if (mMediaPlayer != null) {
+ mMediaPlayer.detachSurface();
+ }
+ }
+
+ @Override
+ public void setSurfaceSize(int width, int height, int visible_width, int visible_height, int sar_num, int sar_den) {
+ mVideoHeight = height;
+ mVideoWidth = width;
+ mVideoVisibleHeight = visible_height;
+ mVideoVisibleWidth = visible_width;
+ mSarNum = sar_num;
+ mSarDen = sar_den;
+ mHandler.removeMessages(HANDLER_SURFACE_SIZE);
+ mHandler.sendEmptyMessage(HANDLER_SURFACE_SIZE);
+ }
+
+ private static final int HANDLER_BUFFER_START = 1;
+ private static final int HANDLER_BUFFER_END = 2;
+ private static final int HANDLER_SURFACE_SIZE = 3;
+
+ private static final int SURFACE_BEST_FIT = 0;
+ private static final int SURFACE_FIT_HORIZONTAL = 1;
+ private static final int SURFACE_FIT_VERTICAL = 2;
+ private static final int SURFACE_FILL = 3;
+ private static final int SURFACE_16_9 = 4;
+ private static final int SURFACE_4_3 = 5;
+ private static final int SURFACE_ORIGINAL = 6;
+ private int mCurrentSize = SURFACE_BEST_FIT;
+
+ private Handler mVlcHandler = new Handler() {
+ @Override
+ public void handleMessage(Message msg) {
+ if (msg == null || msg.getData() == null)
+ return;
+ int key = msg.getData().getInt("event");
+ Log.e("AAA", "key=="+key);
+ switch (key) {
+ case EventHandler.MediaPlayerPositionChanged:
+ Log.e("AAA", "MediaPlayerPositionChanged");
+ break;
+ case EventHandler.MediaPlayerPlaying:
+ mHandler.removeMessages(HANDLER_BUFFER_END);
+ mHandler.sendEmptyMessage(HANDLER_BUFFER_END);
+ Log.e("AAA", "MediaPlayerPlaying");
+/* if(mShareUtil!=null&&mShareUtil.getConnectstate())
+ updateCameraResources(((MainActivity) context).getResources().getDrawable(R.drawable.icon_page_video_a0), getResId());*/
+ break;
+ case EventHandler.MediaPlayerEndReached:
+ Log.e("AAA", "MediaPlayerEndReached");
+ //播放完成
+ break;
+ case EventHandler.MediaPlayerStopped:
+ Log.e("AAA", "MediaPlayerStopped");
+ break;
+ case EventHandler.MediaPlayerEncounteredError:
+ Log.e("AAA", "MediaPlayerEncounteredError"+COMMAND_CAMERA_MEDIAPLAY_ERROR_COUNT);
+ COMMAND_CAMERA_MEDIAPLAY_ERROR_COUNT ++;
+ //预览失败
+ if(COMMAND_CAMERA_MEDIAPLAY_ERROR_COUNT==3){
+ Message msg1 = new Message();
+ msg1.what = 0x11;
+ msg1.arg1 = -1;
+ mHandler.sendMessage(msg1);
+ COMMAND_CAMERA_MEDIAPLAY_ERROR_COUNT = 0;
+ }else{
+ //重新尝试连接
+ isShowVideo = false;
+ //增加预览失败处理逻辑
+ playVideo();
+ }
+ break;
+ }
+
+ }
+ };
+
+ private Handler mHandler = new Handler() {
+ @Override
+ public void handleMessage(Message msg) {
+ switch (msg.what) {
+ case HANDLER_BUFFER_START:
+ showLoading();
+ break;
+ case HANDLER_BUFFER_END:
+ mSurfaceView.setBackgroundColor(getContext().getResources().getColor(com.navinfo.collect.library.R.color.transp));
+ mImgView.setVisibility(View.GONE);
+ //重置异常计数器
+ COMMAND_CAMERA_MEDIAPLAY_ERROR_COUNT = 0;
+ hideLoading();
+ break;
+ case HANDLER_SURFACE_SIZE:
+ changeSurfaceSize();
+ break;
+ case 0x55:
+ int drawable = R.drawable.pop_camera_img;
+ try {
+ if (TakePhotoManager.getInstance().getCameraVedioClent(getmDeviceNum()).GetMode() == SensorWorkingMode.CAMEAR_PHOTO_CONTINUOUS_PHOTO)
+ drawable = R.drawable.pop_camera_take_photo_img;
+ } catch (Exception e) {
+
+ }
+ updateCameraBackgroundResources(drawable, getmDeviceNum());
+ break;
+ case 0x11:
+ if (msg.arg1 >= 0) {
+ //Toast.makeText(getContext(),"预览成功",Toast.LENGTH_SHORT).show();
+ } else {
+ hideLoading();
+ Toast.makeText(getContext(), "预览失败", Toast.LENGTH_SHORT).show();
+ }
+ break;
+ case 0x66:
+ if(videoLoadingProDlg!=null&&videoLoadingProDlg.isShowing())
+ videoLoadingProDlg.setText("成功获取时间,正在加载预留画面");
+ //相机GPS信号差,请稍等片刻,或将相机移到开发地带。
+ mGpsTv.setText("相机GPS信号差,请稍等片刻,或将相机移到开发地带。");
+ mGpsTv.setVisibility(View.GONE);
+ isCheckTime = true;
+ //没有开始录像或者拍照时启动GPS获取,判断连接是否正常
+ if (getmDeviceNum() == 1) {
+ isStartThread = true;
+ } else {
+ isStartThread2 = true;
+ }
+ mStartOrEndTakePicture.setEnabled(true);
+ //开启预览模式
+ playVideo();
+ Log.e("checkTime", "校验成功");
+ break;
+ case 0x77:
+ hideLoading();
+ Log.e("checkTime", "校验失败");
+ mGpsTv.setVisibility(View.VISIBLE);
+ mGpsTv.setText("请在设置中确保PAD/时区与相机/时区保持一致或重新连接相机。");
+ BaseToast.makeText(context, "请在设置中确保PAD/时区与相机/时区保持一致。", Toast.LENGTH_SHORT).show();
+ break;
+
+ }
+ }
+ };
+
+ /**
+ * @param :
+ * @return :
+ * @method : showLoading
+ * @Author : xiaoxiao
+ * @Describe : 显示等待对话框
+ * @Date : 2018/5/14
+ */
+ private void showLoading() {
+ try {
+
+ if (videoLoadingProDlg == null)
+ videoLoadingProDlg = new LoadingDialog(getContext());
+
+
+ if (!videoLoadingProDlg.isShowing()) {
+ videoLoadingProDlg.setText("正在获取中...");
+ videoLoadingProDlg.setOnCancelListener(null);
+ videoLoadingProDlg.show();
+ }
+
+ } catch (Exception e) {
+
+ }
+ }
+
+ /**
+ * @param :
+ * @return :
+ * @method : hideLoading
+ * @Author : xiaoxiao
+ * @Describe : 隐藏等待对话框
+ * @Date : 2018/5/14
+ */
+ public void hideLoading() {
+ try {
+ if (videoLoadingProDlg != null) {
+ videoLoadingProDlg.dismiss();
+ videoLoadingProDlg = null;
+ }
+ } catch (Exception e) {
+
+ }
+ }
+
+ /**
+ * @param :
+ * @return :
+ * @method : startGPSStatus
+ * @Author : xiaoxiao
+ * @Describe :启动gps
+ * @Date : 2018/5/14
+ */
+ public void startGPSStatus() {
+
+ //重新校验时间
+ isCheckTime = false;
+
+ if (getmDeviceNum() == 1) {
+
+ if (!isStartThread) {
+ isStartThread = true;
+ mUIUpdateRecoverProgress.run();
+ }
+ } else if (getmDeviceNum() == 2) {
+
+ if (!isStartThread2) {
+ isStartThread2 = true;
+ //((MainActivity) context).mUIUpdateRecoverProgress.run();
+ }
+ }
+ }
+
+ public Runnable mUIUpdateRecoverProgress = new Runnable() {
+
+ @Override
+ public void run() {
+ //都获信号取后不在监听
+ if (!isStartThread)
+ return;
+
+ if (isStartThread && mShareUtil.getConnectstate() && NetUtils.getInstance().isExistWifi(false) && !TextUtils.isEmpty(mShareUtil.getTakeCameraIP()) && mShareUtil.getContinusTakePhotoState()) {
+
+ long subTime = System.currentTimeMillis() - mPreTime;
+
+ //修改为绝对值,防止时间错误
+ if (Math.abs(subTime) > 3000 && TakePhotoManager.getInstance() != null) {
+ mPreTime = System.currentTimeMillis();
+ TakePhotoManager.getInstance().getCameraVedioClent(1).setmTag(1);
+ TakePhotoManager.getInstance().getCameraVedioClent(1).GetGpsStatus();
+ }
+ }
+
+ mHandler.postDelayed(mUIUpdateRecoverProgress, 1000);
+
+ }
+ };
+
+ /**
+ * @param :
+ * @return :
+ * @method : changeSurfaceSize
+ * @Author : xiaoxiao
+ * @Describe : 改变视频屏幕显示尺寸
+ * @Date : 2018/5/14
+ */
+ private void changeSurfaceSize() {
+
+ WindowManager wm = (WindowManager) context
+ .getSystemService(Context.WINDOW_SERVICE);
+ Display display = wm.getDefaultDisplay();
+
+ int dw = display.getWidth();
+ int dh = display.getHeight();
+
+ // calculate aspect ratio
+ double ar = (double) mVideoWidth / (double) mVideoHeight;
+ // calculate display aspect ratio
+ double dar = (double) dw / (double) dh;
+
+ switch (mCurrentSize) {
+ case SURFACE_BEST_FIT:
+ if (dar < ar)
+ dh = (int) (dw / ar);
+ else
+ dw = (int) (dh * ar);
+ break;
+ case SURFACE_FIT_HORIZONTAL:
+ dh = (int) (dw / ar);
+ break;
+ case SURFACE_FIT_VERTICAL:
+ dw = (int) (dh * ar);
+ break;
+ case SURFACE_FILL:
+ break;
+ case SURFACE_16_9:
+ ar = 16.0 / 9.0;
+ if (dar < ar)
+ dh = (int) (dw / ar);
+ else
+ dw = (int) (dh * ar);
+ break;
+ case SURFACE_4_3:
+ ar = 4.0 / 3.0;
+ if (dar < ar)
+ dh = (int) (dw / ar);
+ else
+ dw = (int) (dh * ar);
+ break;
+ case SURFACE_ORIGINAL:
+ dh = mVideoHeight;
+ dw = mVideoWidth;
+ break;
+ }
+
+ mSurfaceHolder.setFixedSize(mVideoWidth, mVideoHeight);
+
+ Log.e("qj", mVideoWidth + "===");
+
+ mSurfaceView.invalidate();
+ }
+
+ public HostBean getmHostBean() {
+ return mHostBean;
+ }
+
+ //连接
+ private void connection(HostBean hostBean) {
+ if (hostBean != null) {
+ SensorParams params = new SensorParams();
+
+ params.put("ip", hostBean.ipAddress.toString());
+
+ Log.e("AAA", "ip" + hostBean.ipAddress);
+
+ mHostBean = hostBean;
+
+ mShareUtil.setTakeCameraIP(SystemConstant.USER_ID, hostBean.ipAddress.toString());
+
+ mShareUtil.setTakeCameraMac(SystemConstant.USER_ID, hostBean.hardwareAddress.toString());
+
+ takephotoManager.connect(getmDeviceNum(), hostBean, params);
+ }
+ }
+
+ private int getResId() {
+
+ if (getmDeviceNum() == 2)
+ return R.id.main_activity_camera2;
+
+ return R.id.main_activity_camera;
+ }
+
+ public ShareUtil getmShareUtil() {
+ return mShareUtil;
+ }
+
+ //停止录像或拍照
+ private void stopVideoOrPicture() {
+ updateCameraResources(0, getmDeviceNum());
+
+ if (isShowVideo()) {
+
+ stopVideo();
+
+ } else {
+
+ takephotoManager.StartRecording(mHostBean, getmDeviceNum());
+
+ isStartThread = true;
+
+ }
+ }
+
+ //获取编号
+ public int getmDeviceNum() {
+ return mDeviceNum;
+ }
+
+ //设置编号
+ public void setmDeviceNum(int mDeviceNum) {
+ this.mDeviceNum = mDeviceNum;
+ }
+
+ //启动或关闭拍照模式
+ public void initmTakePhotoOrRecord(boolean isCheck) {
+ if (mTakePhotoOrRecord != null && mTakePhotoOrRecord.isChecked() != isCheck) {
+ mTakePhotoOrRecord.setChecked(isCheck);
+ mTakePhotoOrRecord.setText(isCheck ? "录像" : "拍照");
+ isCancel = true;
+
+ if (!isCheck)
+ setmImgViewImageDrawable(1);
+ else
+ setmImgViewImageDrawable(0);
+ }
+ }
+
+ private void setmImgViewImageDrawable(int type) {
+ Drawable drawable = getContext().getResources().getDrawable(R.mipmap.icon_camera_img);
+ if (type == 1)
+ drawable = getContext().getResources().getDrawable(R.mipmap.icon_camera_take_photo_img);
+
+ if (mImgView != null)
+ mImgView.setImageDrawable(drawable);
+ }
+}
diff --git a/app/src/main/java/com/navinfo/omqs/ui/dialog/DataSource.java b/app/src/main/java/com/navinfo/omqs/ui/dialog/DataSource.java
new file mode 100644
index 00000000..d4b9e841
--- /dev/null
+++ b/app/src/main/java/com/navinfo/omqs/ui/dialog/DataSource.java
@@ -0,0 +1,11 @@
+package com.navinfo.omqs.ui.dialog;
+/**
+ * @ClassName: DataSource.java
+ * @author zcs
+ * @version V1.0
+ * @Date 2015年9月17日 下午1:20:08
+ * @Description: Dialog关闭时调用
+ */
+public abstract class DataSource {
+ public abstract void Data(String str,Object obg);
+}
diff --git a/app/src/main/java/com/navinfo/omqs/ui/dialog/FirstDialog.java b/app/src/main/java/com/navinfo/omqs/ui/dialog/FirstDialog.java
new file mode 100644
index 00000000..385f37be
--- /dev/null
+++ b/app/src/main/java/com/navinfo/omqs/ui/dialog/FirstDialog.java
@@ -0,0 +1,510 @@
+package com.navinfo.omqs.ui.dialog;
+
+import android.app.Dialog;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.os.Bundle;
+import android.text.TextUtils;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.LinearLayout;
+import android.widget.RelativeLayout;
+import android.widget.TextView;
+
+import com.navinfo.omqs.R;
+
+/**
+ * @author zcs
+ * @version V1.0
+ * @ClassName: FirstDialog.java
+ * @Date 2015年11月18日 下午5:25:27
+ * @Description: 弹出默认的dialog
+ */
+public class FirstDialog extends MyDialog {
+
+ private CharSequence mPositiveButtonText;
+ private OnClickListener mPositiveButtonListener;
+ private CharSequence mNegativeButtonText;
+ private OnClickListener mNegativeButtonListener;
+ private CharSequence mMiddleButtonText;
+ private OnClickListener mMiddleButtonListener;
+ private Object tag;
+
+ public FirstDialog(Context context) {
+
+ super(context);
+ ViewGroup.LayoutParams layoutParams = new ViewGroup.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT);
+ View rootView = LayoutInflater.from(context).inflate(R.layout.dialog_default, null);
+ setContentView(rootView/*, layoutParams*/);
+ }
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ }
+
+ @Override
+ public void request(Object obj) {
+
+ }
+
+
+
+ /**
+ * 设置标题文字
+ */
+ @Override
+ public void setTitle(CharSequence string) {
+ findViewById(R.id.ll_title).setVisibility(View.VISIBLE);
+ TextView tv = (TextView) findViewById(R.id.tv_title);
+ tv.setText(TextUtils.isEmpty(string) ? "" : string);
+ }
+
+ /**
+ * 设置标题颜色
+ */
+ public void setTitleColor(int color) {
+ ((TextView) findViewById(R.id.tv_title)).setTextColor(color);
+ }
+
+ /**
+ * 设置标题2文字
+ */
+ public void setTitle2(CharSequence string) {
+ findViewById(R.id.tv_title2).setVisibility(View.VISIBLE);
+ TextView tv = (TextView) findViewById(R.id.tv_title2);
+ tv.setText(TextUtils.isEmpty(string) ? "" : string);
+ }
+
+ public void setTitle2Color(int color) {
+ ((TextView) findViewById(R.id.tv_title2)).setTextColor(color);
+ }
+
+ /**
+ * 设置标题下分割线显隐
+ */
+ public void setTitleDividerVisible(int visible) {
+ findViewById(R.id.title_divider).setVisibility(visible);
+ }
+
+ /**
+ * 设置标题下分割线显隐
+ */
+ public void setTitleDividerVisible2(int visible) {
+ findViewById(R.id.title_divider2).setVisibility(visible);
+ }
+
+ public void setBottomDividerVisible(int visible) {
+ findViewById(R.id.v_divice).setVisibility(visible);
+
+ }
+
+ /**
+ * 确认按钮
+ *
+ * @param string
+ */
+ public void setConfirm(CharSequence string) {
+ mPositiveButtonText = string;
+ TextView btn = (TextView) findViewById(R.id.btn_fm_confirm);
+ showBottomView();
+ btn.setText(TextUtils.isEmpty(string) ? "确定" : string);
+ }
+
+ public void setConfirmEnable(boolean enable) {
+ TextView btn = (TextView) findViewById(R.id.btn_fm_confirm);
+ btn.setEnabled(enable);
+ }
+
+
+ public void setConfirmVisibility(int visibility) {
+ findViewById(R.id.btn_fm_confirm).setVisibility(visibility);
+ }
+
+ /**
+ * 确认按钮
+ *
+ * @param colors
+ */
+ public void setConfirmTxtColor(int colors) {
+ TextView btn = (TextView) findViewById(R.id.btn_fm_confirm);
+ btn.setTextColor(colors);
+ }
+
+ /**
+ * 确认按钮字体大小
+ *
+ * @param size
+ */
+ public void setConfirmSize(float size) {
+ TextView btn = (TextView) findViewById(R.id.btn_fm_confirm);
+ btn.setTextSize(size);
+ }
+
+ /**
+ * 取消按钮
+ *
+ * @param string
+ */
+ public void setCancel(CharSequence string) {
+ mNegativeButtonText = string;
+ TextView btn = (TextView) findViewById(R.id.btn_fm_cancel);
+ btn.setText(TextUtils.isEmpty(string) ? "取消" : string);
+ showBottomView();
+ btn.setVisibility(View.VISIBLE);
+ }
+
+ /**
+ * 取消按钮字体颜色
+ *
+ * @param color
+ */
+ public void setCancelTxtColor(int color) {
+ TextView btn = (TextView) findViewById(R.id.btn_fm_cancel);
+ btn.setTextColor(color);
+ }
+
+ /**
+ * 取消按钮是否可点
+ *
+ * @param bl
+ */
+ public void setCancelIsCanClick(Boolean bl) {
+ TextView btn = (TextView) findViewById(R.id.btn_fm_cancel);
+ btn.setEnabled(bl);
+ }
+
+ /**
+ * 取消按钮字体大小
+ *
+ * @param size
+ */
+ public void setCancelSize(float size) {
+ TextView btn = (TextView) findViewById(R.id.btn_fm_cancel);
+ btn.setTextSize(size);
+ }
+
+ /**
+ * 中间按钮
+ *
+ * @param string
+ */
+ public void setMiddle(CharSequence string) {
+ mNegativeButtonText = string;
+ TextView btn = (TextView) findViewById(R.id.btn_fm_middle);
+ btn.setText(TextUtils.isEmpty(string) ? "中间" : string);
+ showBottomView();
+ btn.setVisibility(View.VISIBLE);
+ }
+
+ /**
+ * 中间按钮字体颜色
+ *
+ * @param color
+ */
+ public void setMiddleTxtColor(int color) {
+ TextView btn = (TextView) findViewById(R.id.btn_fm_middle);
+ btn.setTextColor(color);
+ }
+
+ /**
+ * 中间按钮是否可点
+ *
+ * @param bl
+ */
+ public void setMiddleIsCanClick(Boolean bl) {
+ TextView btn = (TextView) findViewById(R.id.btn_fm_middle);
+ btn.setEnabled(bl);
+ }
+
+ /**
+ * 中间按钮字体大小
+ *
+ * @param size
+ */
+ public void setMiddleSize(float size) {
+ TextView btn = (TextView) findViewById(R.id.btn_fm_middle);
+ btn.setTextSize(size);
+ }
+
+ /**
+ * 设置中间提示信息
+ *
+ * @param string
+ */
+ public void setContentTxt(CharSequence string) {
+ TextView tv = (TextView) findViewById(R.id.tv_content);
+ tv.setText(TextUtils.isEmpty(string) ? "" : string);
+ }
+
+ /**
+ * 设置中间提示信息是否可长按复制
+ *
+ * @param isSelectable
+ */
+ public void setTextIsSelectable(boolean isSelectable) {
+ TextView tv = (TextView) findViewById(R.id.tv_content);
+ tv.setTextIsSelectable(isSelectable);
+ }
+
+ /**
+ * 设置点击事件
+ *
+ * @param click
+ */
+ public void setContentClickListener(View.OnClickListener click) {
+ findViewById(R.id.tv_content).setOnClickListener(click);
+ }
+
+
+ /**
+ * 设置中间显隐
+ *
+ * @param visable
+ */
+ public void setContentTxtVisable(int visable) {
+ TextView tv = (TextView) findViewById(R.id.tv_content);
+ tv.setVisibility(visable);
+ }
+
+ /**
+ * 设置中间提示信息
+ *
+ * @param string
+ */
+ public void setMessage(CharSequence string) {
+ setContentTxt(string);
+ }
+
+ /**
+ * 设置中间提示颜色
+ *
+ * @param color
+ */
+ public void setMessageColor(int color) {
+ TextView tv = (TextView) findViewById(R.id.tv_content);
+ tv.setTextColor(color);
+ }
+
+ /**
+ * 设置中间提示文字
+ *
+ * @param txtId
+ */
+ public void setMessage(int txtId) {
+ String txt = context.getResources().getString(txtId);
+ TextView tv = (TextView) findViewById(R.id.tv_content);
+ tv.setText(txt);
+ }
+
+ /**
+ * 设置中间显示的内容
+ */
+ public void setMiddleView(View view) {
+ RelativeLayout rl = (RelativeLayout) findViewById(R.id.rl_content_view);
+ rl.removeAllViews();
+ if (view != null)
+ rl.addView(view);
+ }
+
+ public void setMiddleViewMatch(View view) {
+ RelativeLayout rl = (RelativeLayout) findViewById(R.id.rl_content_view);
+ rl.removeAllViews();
+ if (view != null)
+ rl.addView(view, new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT));
+ }
+
+ public void removeMideView() {
+ RelativeLayout rl = (RelativeLayout) findViewById(R.id.rl_content_view);
+ rl.removeAllViews();
+ }
+
+ /**
+ * 设置中间显示的内容
+ */
+ public View setMiddleView(int id) {
+ RelativeLayout rl = (RelativeLayout) findViewById(R.id.rl_content_view);
+ rl.removeAllViews();
+ View inflate = View.inflate(getContext(), id, rl);
+ return rl.getChildAt(0);
+ }
+
+ /**
+ * 确定按钮 点击事件
+ *
+ * @param click
+ */
+ public Dialog setConfirmListener(OnClickListener click) {
+ return setPositiveButton(mPositiveButtonText, click);
+ }
+
+ /**
+ * 取消按钮 点击事件
+ *
+ * @param click
+ */
+ public Dialog setCancelListener(OnClickListener click) {
+ return setNegativeButton(mNegativeButtonText, click);
+ }
+
+ /**
+ * 取消按钮 点击事件
+ *
+ * @param click
+ */
+ public Dialog setMiddleListener(OnClickListener click) {
+ return setMiddleButton(mMiddleButtonText, click);
+ }
+
+ /**
+ * 中间按钮 是否可点
+ *
+ * @param bl
+ */
+ public void setMiddleButtonIsCanClick(Boolean bl) {
+ TextView btn_fm_confirm = (TextView) findViewById(R.id.btn_fm_middle);
+ btn_fm_confirm.setEnabled(bl);
+ }
+
+ public Dialog setMiddleButton(CharSequence text, OnClickListener listener) {
+ mMiddleButtonText = text;
+ mMiddleButtonListener = listener;
+ setMiddle(text);
+ findViewById(R.id.middle_view).setVisibility(View.VISIBLE);
+ TextView btn_fm_middle = (TextView) findViewById(R.id.btn_fm_middle);
+ btn_fm_middle.setVisibility(View.VISIBLE);
+ btn_fm_middle.setOnClickListener(new View.OnClickListener() {
+
+ @Override
+ public void onClick(View v) {
+ if (mMiddleButtonListener != null) {
+ mMiddleButtonListener.onClick(FirstDialog.this, 3);
+ } else {
+ dismiss();
+ }
+ }
+ });
+ return this;
+ }
+
+ public Dialog setMiddleButton(int txtId, final OnClickListener listener) {
+ String text = context.getResources().getString(txtId);
+ return setMiddleButton(text, listener);
+ }
+
+ /**
+ * 确认按钮 是否可点
+ *
+ * @param bl
+ */
+ public void setPositiveButtonIsCanClick(Boolean bl) {
+ TextView btn_fm_confirm = (TextView) findViewById(R.id.btn_fm_confirm);
+ btn_fm_confirm.setEnabled(bl);
+ }
+
+ public Dialog setPositiveButton(CharSequence text, OnClickListener listener) {
+ mPositiveButtonText = text;
+ mPositiveButtonListener = listener;
+ setConfirm(text);
+ findViewById(R.id.btn_fm_confirm).setOnClickListener(new View.OnClickListener() {
+
+ @Override
+ public void onClick(View v) {
+ if (mPositiveButtonListener != null) {
+ mPositiveButtonListener.onClick(FirstDialog.this, 2);
+ } else {
+ dismiss();
+ }
+ }
+ });
+ //如果设置了确定或取消按钮,则不允许点击其他区域隐藏对话框
+ this.setCancelable(false);
+ return this;
+ }
+
+ public Dialog setPositiveButton(int txtId, final OnClickListener listener) {
+ String text = context.getResources().getString(txtId);
+ return setPositiveButton(text, listener);
+ }
+
+ public Dialog setNegativeButton(CharSequence text, OnClickListener listener) {
+ mNegativeButtonText = text;
+ mNegativeButtonListener = listener;
+ setCancel(text);
+ findViewById(R.id.btn_fm_cancel).setOnClickListener(new View.OnClickListener() {
+
+ @Override
+ public void onClick(View v) {
+ if (mNegativeButtonListener != null) {
+ mNegativeButtonListener.onClick(FirstDialog.this, 1);
+ } else {
+ dismiss();
+ }
+ }
+ });
+ //如果设置了确定或取消按钮,则不允许点击其他区域隐藏对话框
+ this.setCancelable(false);
+ return this;
+ }
+
+ public Dialog setNegativeButton(int txtId, final OnClickListener listener) {
+ String text = context.getResources().getString(txtId);
+ return setNegativeButton(text, listener);
+ }
+
+ public interface OnClickListener {
+ /**
+ * This method will be invoked when a button in the dialog is clicked.
+ *
+ * @param dialog The dialog that received the click.
+ * @param which The button that was clicked (e.g.
+ * {@link DialogInterface#BUTTON1}) or the position
+ * of the item clicked.
+ */
+ /* TODO: Change to use BUTTON_POSITIVE after API council */
+ public void onClick(Dialog dialog, int which);
+ }
+
+ private void showBottomView() {
+ findViewById(R.id.v_divice).setVisibility(View.VISIBLE);
+ findViewById(R.id.ll_bottom_btn).setVisibility(View.VISIBLE);
+ //如果设置了确定或取消按钮,则不允许点击其他区域隐藏对话框
+ this.setCancelable(false);
+ }
+
+
+ public void setNegativeView(int View) {
+ findViewById(R.id.btn_fm_cancel).setVisibility(View);
+ findViewById(R.id.view_dialog).setVisibility(View);
+ }
+
+ public void setCancelVisibility(int isVisibility) {
+ findViewById(R.id.btn_fm_cancel).setVisibility(isVisibility);
+ }
+
+ public void setBottomLayoutVisibility(int isVisibility) {
+ findViewById(R.id.ll_bottom_layout).setVisibility(isVisibility);
+ }
+
+ public Object getTag() {
+ return tag;
+ }
+
+ public void setTag(Object tag) {
+ this.tag = tag;
+ }
+
+ public void setNegativeButtonEnable(boolean enable) {
+ findViewById(R.id.btn_fm_cancel).setEnabled(enable);
+ }
+
+ /**
+ * 设置北京资源
+ */
+ public void setBackgroundColor(int res) {
+ LinearLayout rl = (LinearLayout) findViewById(R.id.ll_dialog);
+ if(rl!=null)
+ rl.setBackgroundColor(res);
+ }
+}
diff --git a/app/src/main/java/com/navinfo/omqs/ui/dialog/IDialog.java b/app/src/main/java/com/navinfo/omqs/ui/dialog/IDialog.java
new file mode 100644
index 00000000..ac1f581b
--- /dev/null
+++ b/app/src/main/java/com/navinfo/omqs/ui/dialog/IDialog.java
@@ -0,0 +1,34 @@
+package com.navinfo.omqs.ui.dialog;
+/**
+ * @ClassName: Dialog.java
+ * @author zcs
+ * @version V1.0
+ * @param
+ * @Date 2023年4月14日 上午10:15:44
+ * @Description: 所有弹出框的父类
+ */
+public interface IDialog {
+
+ //void result(T t);
+ //public void result(T t);
+ //public void showData(T t);
+ /**
+ * 给弹出框赋值
+ * @param str
+ * @param obj
+ */
+ public void setData(String str,Object obj);
+
+ /**
+ * 给Diaolog传递的数据,显示时调用
+ * @param obj
+ */
+ public void request(Object obj);
+
+ /**
+ * 获得数据
+ * @return
+ */
+ public Object getData();
+
+}
diff --git a/app/src/main/java/com/navinfo/omqs/ui/dialog/LoadingDialog.java b/app/src/main/java/com/navinfo/omqs/ui/dialog/LoadingDialog.java
new file mode 100644
index 00000000..93affcb7
--- /dev/null
+++ b/app/src/main/java/com/navinfo/omqs/ui/dialog/LoadingDialog.java
@@ -0,0 +1,83 @@
+package com.navinfo.omqs.ui.dialog;
+
+import android.content.Context;
+import android.graphics.drawable.AnimationDrawable;
+import android.os.Bundle;
+import android.text.TextUtils;
+import android.view.View;
+import android.widget.TextView;
+import com.navinfo.omqs.R;
+
+/**
+ * @author zcs
+ * @version V1.0
+ * @ClassName: LoadingDialog.java
+ * @Date 2015年9月17日 下午1:34:39
+ * @Description: 弹出等待框
+ */
+public class LoadingDialog extends MyDialog {
+
+ private CharSequence text;
+
+ private View.OnClickListener textListener;
+
+ private TextView tv_msg;
+
+ public LoadingDialog(Context context) {
+
+ super(context);
+
+ // requestWindowFeature(Window.FEATURE_NO_TITLE);//不显示标题
+ }
+
+ @Override
+ public void request(Object obj) {
+
+ }
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+
+ View customFrame = View.inflate(context, R.layout.dialog_loading_custom_frame_layout, null);
+
+ ((AnimationDrawable) customFrame.findViewById(R.id.customFrameLoadImg).getBackground()).start();
+
+ tv_msg = (TextView) customFrame.findViewById(R.id.customFrameMsg);
+
+ tv_msg.setVisibility(TextUtils.isEmpty(text) ? View.GONE : View.VISIBLE);
+
+ tv_msg.setText(TextUtils.isEmpty(text) ? "" : text);
+
+ tv_msg.setOnClickListener(textListener);
+
+ setContentView(customFrame);
+ }
+
+ /**
+ * 设置等待提示文字
+ *
+ * @param text
+ */
+ public void setText(CharSequence text) {
+
+ this.text = text;
+ if (tv_msg!=null){
+ tv_msg.setVisibility(TextUtils.isEmpty(this.text) ? View.GONE : View.VISIBLE);
+ tv_msg.setText(TextUtils.isEmpty(this.text) ? "" : this.text);
+ }
+ }
+
+ /**
+ * 设置文本点击事件
+ *
+ * @param listener
+ */
+ public void setTextClickListener(View.OnClickListener listener){
+
+ this.textListener = listener;
+
+ if (tv_msg!=null){
+ tv_msg.setOnClickListener(listener);
+ }
+ }
+}
diff --git a/app/src/main/java/com/navinfo/omqs/ui/dialog/MyDialog.java b/app/src/main/java/com/navinfo/omqs/ui/dialog/MyDialog.java
new file mode 100644
index 00000000..b9413f22
--- /dev/null
+++ b/app/src/main/java/com/navinfo/omqs/ui/dialog/MyDialog.java
@@ -0,0 +1,92 @@
+package com.navinfo.omqs.ui.dialog;
+
+import android.app.Dialog;
+import android.content.Context;
+import android.graphics.Color;
+import android.graphics.drawable.ColorDrawable;
+import android.graphics.drawable.Drawable;
+import android.view.Window;
+
+/**
+ * @param
+ * @param
+ * @author qj
+ * @version V1.0
+ * @ClassName: MyDialog.java
+ * @Date 2023年4月14日 上午10:18:52
+ * @Description: 所有提示框的父类(在onCreate设置布局)
+ */
+public abstract class MyDialog extends Dialog implements IDialog {
+
+ protected Context context;
+
+ private Object obj;
+
+ private DataSource dataSource;
+
+ private String str;
+
+ public MyDialog(Context context) {
+ super(context);
+ this.context = context;
+ requestWindowFeature(Window.FEATURE_NO_TITLE);//不显示标题
+ getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
+ }
+
+ @Override
+ public void dismiss() {
+
+ if (dataSource != null) {
+
+ dataSource.Data(str, obj);
+
+ }
+
+ super.dismiss();
+ }
+
+ public void setWidthHeight(int width, int height) {
+ getWindow().setLayout(width, height);
+ }
+
+ @Override
+ public void show() {
+
+ request(obj);
+
+ super.show();
+ }
+
+ @Override
+ public void setData(String str, Object obj) {
+
+ this.str = str;
+
+ this.obj = obj;
+
+ }
+
+ @Override
+ public Object getData() {
+
+ return obj;
+
+ }
+
+ public void getResponse(DataSource dataSource) {
+
+ this.dataSource = dataSource;
+
+ }
+
+ /**
+ * 设置背景色
+ *
+ * @param drawable
+ */
+ public void setBackground(Drawable drawable) {
+
+ getWindow().setBackgroundDrawable(drawable);
+
+ }
+}
diff --git a/app/src/main/java/com/navinfo/omqs/ui/manager/TakePhotoManager.java b/app/src/main/java/com/navinfo/omqs/ui/manager/TakePhotoManager.java
new file mode 100644
index 00000000..dce99378
--- /dev/null
+++ b/app/src/main/java/com/navinfo/omqs/ui/manager/TakePhotoManager.java
@@ -0,0 +1,578 @@
+package com.navinfo.omqs.ui.manager;
+
+import android.content.Context;
+import android.graphics.Bitmap;
+import android.text.TextUtils;
+import android.util.Log;
+
+import com.android.volley.VolleyError;
+import com.navinfo.collect.library.garminvirbxe.CameraEventListener;
+import com.navinfo.collect.library.garminvirbxe.CameraGarminVirbXE;
+import com.navinfo.collect.library.garminvirbxe.HostBean;
+import com.navinfo.collect.library.garminvirbxe.SensorParams;
+import com.navinfo.collect.library.sensor.ISensor.enmConnectionStatus;
+import com.navinfo.collect.library.sensor.ISensor.enmSensorModel;
+import com.navinfo.collect.library.sensor.ISensor.SensorWorkingMode;
+import com.navinfo.collect.library.sensor.ISensor.enmSensorType;
+import com.navinfo.collect.library.sensor.ISensor.enmSignalQuality;
+import com.navinfo.collect.library.sensor.SensorManager;
+import com.navinfo.omqs.system.SystemConstant;
+import com.navinfo.omqs.util.ShareUtil;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+
+/**
+ * @author qj
+ * @version V1.0
+ * @Date 2023/4/14.
+ * @Description: (外设相机控制类)
+ */
+public class TakePhotoManager {
+
+ /**
+ * 拍照控制类集合
+ */
+ private List mSensorInstanceList;
+
+ /**
+ * 拍照过程回调监听
+ */
+ /**
+ * 拍照管理类
+ */
+ private static volatile TakePhotoManager mInstance;
+ //外设相机连接状态
+ private HashMap mConnectionStatusHashMap;
+ //上下文
+ private Context mCon;
+
+ /**
+ * 装拍照过程回调数组
+ */
+ private final List mOnCameraEventListeners = new ArrayList();
+
+ public static TakePhotoManager getInstance() {
+ if (mInstance == null) {
+ synchronized (TakePhotoManager.class) {
+ if (mInstance == null) {
+ mInstance = new TakePhotoManager();
+ }
+ }
+ }
+ return mInstance;
+ }
+
+ public void init(Context context, int cameraCount) {
+
+ mCon = context;
+
+ if (cameraCount == 0)
+ cameraCount = 1;
+
+ mSensorInstanceList = new ArrayList();
+
+ mConnectionStatusHashMap = new HashMap();
+
+ CameraEventListener cameraEevent = new CameraEventListener() {
+ @Override
+ public void OnSnapPictureResponse(HostBean hostBean, Bitmap bitmap, String picName, int tag) {
+ Log.i("info", "bitmap:" + bitmap);
+ if (mOnCameraEventListeners != null && mOnCameraEventListeners.size() > 0) {
+ for (CameraEventListener weakRef : mOnCameraEventListeners) {
+ if (weakRef != null) {
+ weakRef.OnSnapPictureResponse(hostBean, bitmap, picName, tag);
+ }
+ }
+ }
+ }
+
+ @Override
+ public void requestError(HostBean hostBean, com.android.volley.VolleyError e, CameraGarminVirbXE.enmCommandType commandType, int tag) {
+ if (mOnCameraEventListeners != null && mOnCameraEventListeners.size() > 0) {
+ for (CameraEventListener weakRef : mOnCameraEventListeners) {
+ if (weakRef != null) {
+ weakRef.requestError(hostBean, e, commandType, tag);
+ }
+ }
+ }
+ }
+
+ @Override
+ public void OnStartRecordResponse(HostBean hostBean, int tag) {
+ if (mOnCameraEventListeners != null && mOnCameraEventListeners.size() > 0) {
+ for (CameraEventListener weakRef : mOnCameraEventListeners) {
+ if (weakRef != null) {
+ weakRef.OnStartRecordResponse(hostBean, tag);
+ }
+ }
+ }
+ }
+
+ @Override
+ public void OnStopRecordResponse(HostBean hostBean, int tag) {
+ if (mOnCameraEventListeners != null && mOnCameraEventListeners.size() > 0) {
+ for (CameraEventListener weakRef : mOnCameraEventListeners) {
+ if (weakRef != null) {
+ weakRef.OnStopRecordResponse(hostBean, tag);
+ }
+ }
+ }
+ }
+
+ @Override
+ public void OnStatusResponse(HostBean hostBean, int tag) {
+ if (mOnCameraEventListeners != null && mOnCameraEventListeners.size() > 0) {
+ for (CameraEventListener weakRef : mOnCameraEventListeners) {
+ if (weakRef != null) {
+ weakRef.OnStatusResponse(hostBean, tag);
+ }
+ }
+ }
+ }
+
+ @Override
+ public void OnSearchResponse(int tag, ArrayList scanIpList) {
+ if (mOnCameraEventListeners != null && mOnCameraEventListeners.size() > 0) {
+ for (CameraEventListener weakRef : mOnCameraEventListeners) {
+ if (weakRef != null) {
+ weakRef.OnSearchResponse(tag, scanIpList);
+ }
+ }
+ }
+ }
+
+ @Override
+ public void OnConnectStatusChanged(HostBean hostBean, enmConnectionStatus connectStatus, int tag) {
+ if (mOnCameraEventListeners != null && mOnCameraEventListeners.size() > 0) {
+ for (CameraEventListener weakRef : mOnCameraEventListeners) {
+ if (weakRef != null) {
+ weakRef.OnConnectStatusChanged(hostBean, connectStatus, tag);
+ }
+ }
+ }
+ }
+
+ @Override
+ public void OnGetGpsStatusResponse(HostBean hostBean, boolean status, int tag) {
+ if (mOnCameraEventListeners != null && mOnCameraEventListeners.size() > 0) {
+ for (CameraEventListener weakRef : mOnCameraEventListeners) {
+ if (weakRef != null) {
+ weakRef.OnGetGpsStatusResponse(hostBean, status, tag);
+ }
+ }
+ }
+ }
+
+ @Override
+ public void OnConnectionStatusChanged(HostBean hostBean, enmConnectionStatus cs, int tag) {
+ if (mOnCameraEventListeners != null && mOnCameraEventListeners.size() > 0) {
+ for (CameraEventListener weakRef : mOnCameraEventListeners) {
+ if (weakRef != null) {
+ weakRef.OnConnectionStatusChanged(hostBean, cs, tag);
+ }
+ }
+ }
+ }
+
+ @Override
+ public void OnContinuousPhototTimeLapseRateResponse(HostBean hostBean, int tag) {
+ if (mOnCameraEventListeners != null && mOnCameraEventListeners.size() > 0) {
+ for (CameraEventListener weakRef : mOnCameraEventListeners) {
+ if (weakRef != null) {
+ weakRef.OnContinuousPhototTimeLapseRateResponse(hostBean, tag);
+ }
+ }
+ }
+ }
+
+ @Override
+ public void OnContinuousPhototTimeLapseRateStartResponse(HostBean hostBean, int tag) {
+ if (mOnCameraEventListeners != null && mOnCameraEventListeners.size() > 0) {
+ for (CameraEventListener weakRef : mOnCameraEventListeners) {
+ if (weakRef != null) {
+ weakRef.OnContinuousPhototTimeLapseRateStartResponse(hostBean, tag);
+ }
+ }
+ }
+ }
+
+ @Override
+ public void OnContinuousPhototTimeLapseRateStopResponse(HostBean hostBean, int tag) {
+ if (mOnCameraEventListeners != null && mOnCameraEventListeners.size() > 0) {
+ for (CameraEventListener weakRef : mOnCameraEventListeners) {
+ if (weakRef != null) {
+ weakRef.OnContinuousPhototTimeLapseRateStopResponse(hostBean, tag);
+ }
+ }
+ }
+ }
+
+ @Override
+ public void OnContinuousPhototSingle(HostBean hostBean, String url, String name, int tag) {
+ if (mOnCameraEventListeners != null && mOnCameraEventListeners.size() > 0) {
+ for (CameraEventListener weakRef : mOnCameraEventListeners) {
+ if (weakRef != null) {
+ weakRef.OnContinuousPhototSingle(hostBean, url, name, tag);
+ }
+ }
+ }
+ }
+
+ @Override
+ public void OnGetMediaList(HostBean hostBean, String json, int tag) {
+ if (mOnCameraEventListeners != null && mOnCameraEventListeners.size() > 0) {
+ for (CameraEventListener weakRef : mOnCameraEventListeners) {
+ if (weakRef != null) {
+ weakRef.OnGetMediaList(hostBean, json, tag);
+ }
+ }
+ }
+ }
+
+ @Override
+ public void OnSensorEvent() {
+ if (mOnCameraEventListeners != null && mOnCameraEventListeners.size() > 0) {
+ for (CameraEventListener weakRef : mOnCameraEventListeners) {
+ if (weakRef != null) {
+ weakRef.OnSensorEvent();
+ }
+ }
+ }
+ }
+
+ @Override
+ public void OnConnectionStatusChanged(enmConnectionStatus cs) {
+ if (mOnCameraEventListeners != null && mOnCameraEventListeners.size() > 0) {
+ for (CameraEventListener weakRef : mOnCameraEventListeners) {
+ if (weakRef != null) {
+ weakRef.OnConnectionStatusChanged(cs);
+ }
+ }
+ }
+ }
+
+ @Override
+ public void OnGetDeviceInfo(HostBean hostBean, String devicesId, int tag) {
+ if (mOnCameraEventListeners != null && mOnCameraEventListeners.size() > 0) {
+ for (CameraEventListener weakRef : mOnCameraEventListeners) {
+ if (weakRef != null) {
+ weakRef.OnGetDeviceInfo(hostBean, devicesId, tag);
+ }
+ }
+ }
+ }
+
+ @Override
+ public void OnSignalQualityChanged(enmSignalQuality sq) {
+ if (mOnCameraEventListeners != null && mOnCameraEventListeners.size() > 0) {
+ for (CameraEventListener weakRef : mOnCameraEventListeners) {
+ if (weakRef != null) {
+ weakRef.OnSignalQualityChanged(sq);
+ }
+ }
+ }
+ }
+ };
+
+ for (int i = 0; i < cameraCount; i++) {
+
+ CameraGarminVirbXE clent = (CameraGarminVirbXE) SensorManager.getInstance().CreateSensor(context, enmSensorType.SENSOR_CAMEAR, enmSensorModel.CAMERA_GARMIN_VIRB_XE);
+ clent.setmTag(i + 1);
+ clent.RegisterSensorEvent(cameraEevent);
+ mSensorInstanceList.add(clent);
+ }
+
+ }
+
+ //连接网络
+ public boolean connect(int indexClent, HostBean hostBean, SensorParams params) {
+ if (hostBean != null) {
+ CameraGarminVirbXE cameraGarminVirbXE = getCameraVedioClent(indexClent);
+ if (cameraGarminVirbXE != null) {
+ cameraGarminVirbXE.Connect(hostBean, params);
+ return true;
+ }
+ }
+ return false;
+ }
+
+ public enmConnectionStatus getConnectionStatus(HostBean hostBean) {
+
+ if (hostBean != null && mConnectionStatusHashMap != null && mConnectionStatusHashMap.containsKey(hostBean.hardwareAddress)) {
+ return mConnectionStatusHashMap.get(hostBean.hardwareAddress);
+ }
+
+
+ return enmConnectionStatus.DISCONNECTTED;
+ }
+
+ public enmConnectionStatus getConnectionStatus() {
+
+ if (mSensorInstanceList != null && mConnectionStatusHashMap != null) {
+ enmConnectionStatus mEnmConnectionStatus = enmConnectionStatus.DISCONNECTTED;
+ for (CameraGarminVirbXE cameraGarminVirbXE : mSensorInstanceList) {
+ mEnmConnectionStatus = cameraGarminVirbXE.GetConnectionStatus();
+ if (mEnmConnectionStatus == enmConnectionStatus.CONNECTTED)
+ return enmConnectionStatus.CONNECTTED;
+
+ }
+ }
+
+
+ return enmConnectionStatus.DISCONNECTTED;
+ }
+
+ //设置相机模式
+ public void setCameraMode(int indexClent, SensorWorkingMode mode) {
+ if (indexClent > 0 && mSensorInstanceList!=null && indexClent <= mSensorInstanceList.size()) {
+ getCameraVedioClent(indexClent).SetMode(mode);
+ }
+ }
+
+ //获取当前相机模式
+ public SensorWorkingMode getCameraMode(int indexClent) {
+ if (mSensorInstanceList != null && indexClent > 0 && indexClent <= mSensorInstanceList.size()) {
+ return getCameraVedioClent(indexClent).GetMode();
+ }
+
+ return null;
+ }
+
+ public String mediaList(int indexClent, String path) {
+ if (mSensorInstanceList != null && indexClent > 0 && indexClent <= mSensorInstanceList.size()) {
+ getCameraVedioClent(indexClent).mediaList(path);
+ }
+
+ return null;
+ }
+
+
+ //搜索网络
+ public void SearchNet(HostBean hostBean, int indexClent, boolean isReadCache) {
+ if (mSensorInstanceList != null && mSensorInstanceList.size() > 0 && indexClent > 0 && indexClent <= mSensorInstanceList.size()) {
+ mSensorInstanceList.get(indexClent - 1).Search(isReadCache);
+ return;
+ }
+ }
+
+ //连续拍照
+ public void StartRecording(HostBean hostBean, int indexCamera) {
+ if (mSensorInstanceList != null && indexCamera > 0 && indexCamera <= mSensorInstanceList.size()) {
+ getCameraVedioClent(indexCamera).StartRecording();
+ }
+ }
+
+
+ public void getGpsStatus() {
+ if (mSensorInstanceList != null && mSensorInstanceList.size() > 0) {
+ for (CameraGarminVirbXE cameraGarminVirbXE : mSensorInstanceList) {
+ cameraGarminVirbXE.GetGpsStatus();
+ }
+ }
+
+ }
+
+ //获取GPS状态
+ public void getGpsStatus(HostBean hostBean, int index) {
+ if (hostBean != null) {
+ CameraGarminVirbXE cameraGarminVirbXE = findCameraGarminVirbXE(hostBean, index);
+ if (cameraGarminVirbXE != null) {
+ cameraGarminVirbXE.GetGpsStatus();
+ }
+ }
+ }
+
+ public void startCameraVedio(HostBean hostBean, int indexClent) {
+ if (hostBean != null) {
+
+ StopContinuousTakePhoto(hostBean, indexClent);
+
+ setCameraMode(indexClent, SensorWorkingMode.CAMERA_VEDIO_TIMELAPSE);
+
+ ShareUtil.getCameraMode(mCon).setContinusTakePhotoState(SystemConstant.USER_ID, false);
+
+ StartRecording(hostBean, indexClent);
+
+ }
+
+ }
+
+ //抓拍
+ public void SnapShot(HostBean hostBean, int index) {
+ if (hostBean != null) {
+ CameraGarminVirbXE cameraGarminVirbXE = findCameraGarminVirbXE(hostBean, index);
+ if (cameraGarminVirbXE != null) {
+ cameraGarminVirbXE.snapPicture(SystemConstant.getUuid(true));
+ }
+ }
+ }
+
+ public Long getGoogleTime() {
+ if (mSensorInstanceList != null && mSensorInstanceList.size() > 0) {
+ for (CameraGarminVirbXE cameraGarminVirbXE : mSensorInstanceList) {
+ if (cameraGarminVirbXE.getGoogleGpsTime() > 0) {
+ return cameraGarminVirbXE.getGoogleGpsTime();
+ }
+ }
+ }
+
+ return 0l;
+ }
+
+ //停止时间线程,减少电量消耗
+ public void stopTimeThread() {
+ if (mSensorInstanceList != null && mSensorInstanceList.size() > 0) {
+ for (CameraGarminVirbXE cameraGarminVirbXE : mSensorInstanceList) {
+ cameraGarminVirbXE.stopTimeThread();
+ }
+ }
+ }
+
+ //设置拍照路径
+ public void setSavePath(HostBean hostBean, String path, int index) {
+ if (path == null || path.equals("")) {
+ return;
+
+ }
+ if (hostBean != null) {
+ CameraGarminVirbXE cameraGarminVirbXE = findCameraGarminVirbXE(hostBean, index);
+ if (cameraGarminVirbXE != null) {
+ File file = new File(path);
+ if (file.exists() && file.isDirectory()) {
+ cameraGarminVirbXE.SetCameraPictureSavaPath(path);
+ }
+ }
+ }
+ }
+
+ //停止搜索
+ public void StopSearchNet(HostBean hostBean, int indexClent) {
+ if (hostBean != null) {
+ CameraGarminVirbXE cameraGarminVirbXE = findCameraGarminVirbXE(hostBean, indexClent);
+ if (cameraGarminVirbXE != null) {
+ cameraGarminVirbXE.StopSearch();
+ }
+ }
+ }
+
+ //停止连拍
+ public void StopContinuousTakePhoto(HostBean hostBean, int indexCamera) {
+ if (mSensorInstanceList != null && indexCamera > 0 && indexCamera <= mSensorInstanceList.size()) {
+ getCameraVedioClent(indexCamera).StopRecording();
+ }
+
+ }
+
+ //停止所有相机
+ public void StopContinuousTakePhotoAll() {
+ if (mSensorInstanceList != null) {
+ for (CameraGarminVirbXE cameraGarminVirbXE : mSensorInstanceList) {
+ cameraGarminVirbXE.StopRecording();
+ }
+ }
+
+ }
+
+ //查找对应控制类
+ private CameraGarminVirbXE findCameraGarminVirbXE(HostBean hostBean, int index) {
+
+ if (mSensorInstanceList != null && mSensorInstanceList.size() > 0) {
+
+ for (CameraGarminVirbXE cameraGarminVirbXE : mSensorInstanceList) {
+ if (cameraGarminVirbXE.getmHostBean() != null && hostBean != null && !TextUtils.isEmpty(cameraGarminVirbXE.getmHostBean().hardwareAddress)
+ && !TextUtils.isEmpty(hostBean.hardwareAddress) && cameraGarminVirbXE.getmHostBean().hardwareAddress.equalsIgnoreCase(hostBean.hardwareAddress) && cameraGarminVirbXE.getmTag() == index) {
+ return cameraGarminVirbXE;
+ }
+ }
+
+ return mSensorInstanceList.get(0);
+ }
+
+ return null;
+ }
+
+
+ public void setOnCameraEventChangeListener(CameraEventListener listener) {
+ synchronized (mOnCameraEventListeners) {
+ if (mOnCameraEventListeners != null && mOnCameraEventListeners.size() > 0) {
+ for (CameraEventListener weakRef : mOnCameraEventListeners) {
+ if (weakRef != null
+ && weakRef == listener) {
+ return;
+ }
+ }
+ }
+ mOnCameraEventListeners.add(listener);
+ }
+ }
+
+ public void removeCameraEventListener(HostBean hostBean, CameraEventListener listener) {
+ synchronized (mOnCameraEventListeners) {
+ CameraEventListener weakRef;
+ if (mOnCameraEventListeners != null && mOnCameraEventListeners.size() > 0) {
+ for (int idx = 0; idx < mOnCameraEventListeners.size(); idx++) {
+ if ((weakRef = mOnCameraEventListeners.get(idx)) != null) {
+ if (weakRef == listener) {
+ mOnCameraEventListeners.remove(idx);
+ return;
+ }
+ } else {
+ mOnCameraEventListeners.remove(idx);
+ idx--;
+ }
+ }
+ }
+ }
+ }
+
+ public void removeCameraEventListenerAll(CameraEventListener listener) {
+ synchronized (mOnCameraEventListeners) {
+ CameraEventListener weakRef;
+ if (mOnCameraEventListeners != null && mOnCameraEventListeners.size() > 0) {
+ for (int idx = 0; idx < mOnCameraEventListeners.size(); idx++) {
+ if ((weakRef = mOnCameraEventListeners.get(idx)) != null) {
+ if (weakRef == listener) {
+ mOnCameraEventListeners.remove(idx);
+ return;
+ }
+ } else {
+ mOnCameraEventListeners.remove(idx);
+ idx--;
+ }
+ }
+ }
+ }
+ }
+
+ //根据拍照模式获取控制类
+ public CameraGarminVirbXE getCameraVedioClent(SensorWorkingMode mode) {
+
+ if (mode == null)
+ return null;
+
+ if (mSensorInstanceList != null && mSensorInstanceList.size() > 0) {
+ for (CameraGarminVirbXE cameraGarminVirbXE : mSensorInstanceList) {
+ if (cameraGarminVirbXE.GetMode() != null && cameraGarminVirbXE.GetMode() == mode) {
+ return cameraGarminVirbXE;
+ }
+ }
+ }
+
+ return null;
+ }
+
+ public CameraGarminVirbXE getCameraVedioClent(int indexClent) {
+
+ if (indexClent <= 0)
+ return null;
+
+ if (mSensorInstanceList != null && mSensorInstanceList.size() > 0 && indexClent <= mSensorInstanceList.size()) {
+ return mSensorInstanceList.get(indexClent - 1);
+ }
+
+ return null;
+ }
+}
diff --git a/app/src/main/java/com/navinfo/omqs/ui/other/BaseToast.java b/app/src/main/java/com/navinfo/omqs/ui/other/BaseToast.java
new file mode 100644
index 00000000..2914de36
--- /dev/null
+++ b/app/src/main/java/com/navinfo/omqs/ui/other/BaseToast.java
@@ -0,0 +1,77 @@
+package com.navinfo.omqs.ui.other;
+
+
+import android.app.Activity;
+import android.content.Context;
+import android.content.res.Resources;
+import android.util.DisplayMetrics;
+import android.view.Gravity;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.widget.TextView;
+import android.widget.Toast;
+import com.navinfo.omqs.R;
+
+/**
+ * 在屏幕中间出现toast提示
+ */
+public class BaseToast extends Toast{
+ final Context mContext;
+
+ private static int height;
+ static Toast result;
+ public BaseToast(Context context) {
+ super(context);
+ mContext = context;
+ DisplayMetrics dm = new DisplayMetrics();
+ // 获取屏幕信息
+ ((Activity) context).getWindowManager().getDefaultDisplay().getMetrics(dm);
+
+ height = dm.heightPixels;
+ }
+
+ /**
+ * 屏幕中间显示toast
+ * @param context
+ * @param text 显示内容
+ * @param duration 显示时长
+ * @return
+ */
+ public static Toast makeText(Context context, CharSequence text, int duration) {
+ try{
+ DisplayMetrics dm = new DisplayMetrics();
+ ((Activity) context).getWindowManager().getDefaultDisplay().getMetrics(dm);
+ height = dm.heightPixels;
+ result =result==null? new Toast(context):result;
+ LayoutInflater inflate = (LayoutInflater) context
+ .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
+ View v = inflate.inflate(R.layout.transient_notification, null);
+ TextView tv = (TextView) v.findViewById(android.R.id.message);
+ tv.setText(text);
+ result.setView(v);
+ if(duration filelist = new ArrayList();
+
+
+ /**
+ * 复制文件到sd卡
+ *
+ * @param context 上下文
+ * @param fileDir 文件目录
+ * @param filePath 文件路径
+ * @param files 文件集合
+ */
+ public static void copyFileToSdcard(Context context, String fileDir,
+ String filePath, Field[] files) {
+
+ for (Field r : files) {
+ try {
+ int id = context.getResources().getIdentifier(r.getName(),
+ "raw", context.getPackageName());
+ Log.i(TAG, new File(filePath).length() + "=====文件长度===="
+ + filePath);
+ if (!new File(fileDir).exists()) {
+ new File(fileDir).mkdirs();
+ }
+
+ // new File(path).delete();
+ if (new File(filePath).exists())
+ new File(filePath).delete();
+ new File(filePath).createNewFile();
+ BufferedOutputStream bufEcrivain = new BufferedOutputStream(
+ (new FileOutputStream(new File(filePath))));
+ BufferedInputStream VideoReader = new BufferedInputStream(
+ context.getResources().openRawResource(id));
+ byte[] buff = new byte[20 * 1024];
+ int len;
+ while ((len = VideoReader.read(buff)) > 0) {
+ bufEcrivain.write(buff, 0, len);
+ }
+ bufEcrivain.flush();
+ bufEcrivain.close();
+ VideoReader.close();
+
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ }
+
+ /**
+ * 复制单个文件
+ *
+ * @param oldPath String 原文件路径 如:c:/fqf.txt
+ * @param newPath String 复制后路径 如:f:/fqf.txt
+ * @return boolean
+ */
+ public static boolean copyFile(String oldPath, String newPath) {
+ try {
+ int bytesum = 0;
+ int byteread = 0;
+ File oldfile = new File(oldPath);
+ if (oldfile.exists()) { // 文件存在时
+ InputStream inStream = new FileInputStream(oldPath); // 读入原文件
+ FileOutputStream fs = new FileOutputStream(newPath);
+ byte[] buffer = new byte[1444];
+ while ((byteread = inStream.read(buffer)) != -1) {
+
+ bytesum += byteread; // 字节数 文件大小
+ System.out.println(bytesum);
+ fs.write(buffer, 0, byteread);
+
+ }
+ inStream.close();
+ return true;
+ }
+
+ } catch (Exception e) {
+
+ System.out.println("复制单个文件操作出错");
+ e.printStackTrace();
+
+ }
+ return false;
+
+ }
+
+
+ /**
+ * 实时轨迹信息写入文件
+ *
+ * @param info 信息
+ * @param isNewLine 是否换行写入
+ */
+ public static void writeRealTimeTrackToFile(String filePath, String info, boolean isNewLine) {
+
+
+ if (new File(filePath).exists() == false) {
+ new File(filePath).mkdirs();
+ }
+
+ File file = new File(filePath, "monitor_track.txt");
+
+ FileWriter filerWriter = null;
+
+ BufferedWriter bufWriter = null;
+
+ try {
+ if (!file.exists())
+ file.createNewFile();
+
+ //文件流
+ filerWriter = new FileWriter(file, true);//后面这个参数代表是不是要接上文件中原来的数据,不进行覆盖
+
+ //字符缓冲输出流
+ bufWriter = new BufferedWriter(filerWriter);
+
+ bufWriter.write(info);
+
+ if (isNewLine)
+ bufWriter.newLine();
+
+ } catch (IOException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }finally {
+ try{
+ if(bufWriter!=null)
+ bufWriter.close();
+
+ if(filerWriter!=null)
+ filerWriter.close();
+ }catch (Exception e){
+
+ }
+
+ }
+ }
+
+
+ /**
+ * 轨迹信息写入文件
+ *
+ * @param info 信息
+ * @param isNewLine 是否换行写入
+ */
+ public static void writeTrackToFile(String filePath, String info, boolean isNewLine) {
+ Date nowtime = new Date();
+
+ String needWriteFiel = logfile.format(nowtime);
+
+ if (TextUtils.isEmpty(filePath))
+ return;
+
+ if (new File(filePath).exists() == false) {
+ new File(filePath).mkdirs();
+ }
+ File file = new File(filePath, needWriteFiel + TrackFILEName);
+ FileWriter filerWriter = null;
+ BufferedWriter bufWriter = null;
+ try {
+ if (!file.exists())
+ file.createNewFile();
+
+ //文件流
+ filerWriter = new FileWriter(file, true);//后面这个参数代表是不是要接上文件中原来的数据,不进行覆盖
+
+ //字符缓冲输出流
+ bufWriter = new BufferedWriter(filerWriter);
+
+ bufWriter.write(info);
+
+ if (isNewLine)
+ bufWriter.newLine();
+
+ } catch (IOException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }finally {
+
+ try{
+ if(bufWriter!=null)
+ bufWriter.close();
+
+ if(filerWriter!=null)
+ filerWriter.close();
+ }catch (Exception e){
+
+ }
+
+ }
+ }
+
+ /**
+ * 实时轨迹偏差信息写入文件
+ *
+ * @param info 信息
+ * @param isNewLine 是否换行写入
+ */
+ public static void writeTrackLogToFile(String filePath, String info, boolean isNewLine) {
+
+
+ if (new File(filePath).exists() == false) {
+ new File(filePath).mkdirs();
+ }
+ File file = new File(filePath, "TrackLog.txt");
+ FileWriter filerWriter = null;
+ BufferedWriter bufWriter = null;
+ try {
+ if (!file.exists())
+ file.createNewFile();
+
+ //文件流
+ filerWriter = new FileWriter(file, true);//后面这个参数代表是不是要接上文件中原来的数据,不进行覆盖
+
+ //字符缓冲输出流
+ bufWriter = new BufferedWriter(filerWriter);
+
+ bufWriter.write(info);
+
+ if (isNewLine)
+ bufWriter.newLine();
+
+
+ } catch (IOException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }finally {
+ try{
+ if(bufWriter!=null)
+ bufWriter.close();
+
+ if(filerWriter!=null)
+ filerWriter.close();
+ }catch (Exception e){
+
+ }
+ }
+ }
+
+
+ /**
+ * 逐行写入
+ *
+ * @param info 信息
+ */
+ public static void writeLine(String filePath,String fileName, String info) {
+
+ if (TextUtils.isEmpty(filePath))
+ return;
+
+ if (new File(filePath).exists() == false) {
+ new File(filePath).mkdirs();
+ }
+ File file = new File(filePath + fileName);
+ FileWriter filerWriter = null;
+ BufferedWriter bufWriter = null;
+ try {
+ if (!file.exists())
+ file.createNewFile();
+
+ //文件流
+ filerWriter = new FileWriter(file, true);//后面这个参数代表是不是要接上文件中原来的数据,不进行覆盖
+
+ //字符缓冲输出流
+ bufWriter = new BufferedWriter(filerWriter);
+
+ bufWriter.write(info);
+
+ bufWriter.newLine();
+
+
+ } catch (IOException e) {
+ e.printStackTrace();
+ }finally {
+ try{
+ if(bufWriter!=null)
+ bufWriter.close();
+
+ if(filerWriter!=null)
+ filerWriter.close();
+ }catch (Exception e){
+
+ }
+ }
+ }
+
+ /**
+ * Adas轨迹信息写入文件
+ *
+ * @param info 信息
+ * @param isNewLine 是否换行写入
+ */
+ public static void writeAdasTrackToFile(String filePath, String info, boolean isNewLine) {
+
+ Date nowtime = new Date();
+
+ String needWriteFiel = logfile.format(nowtime);
+
+ if (TextUtils.isEmpty(filePath))
+ return;
+
+ if (new File(filePath).exists() == false) {
+ new File(filePath).mkdirs();
+ }
+
+ File file = new File(filePath, needWriteFiel + AdasTrackFILEName);
+ FileWriter filerWriter = null;
+ BufferedWriter bufWriter = null;
+ try {
+ if (!file.exists())
+ file.createNewFile();
+
+ //文件流
+ filerWriter = new FileWriter(file, true);//后面这个参数代表是不是要接上文件中原来的数据,不进行覆盖
+
+ //字符缓冲输出流
+ bufWriter = new BufferedWriter(filerWriter);
+
+ bufWriter.write(info);
+
+ if (isNewLine)
+ bufWriter.newLine();
+
+
+ } catch (IOException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }finally {
+ try{
+ if(bufWriter!=null)
+ bufWriter.close();
+
+ if(filerWriter!=null)
+ filerWriter.close();
+ }catch (Exception e){
+
+ }
+ }
+ }
+
+ /**
+ * 获取文件绝对路径
+ *
+ * @return list
+ * 文件绝对路径集合
+ */
+ public static List getFileList(String strPath, String[] suffix) {
+ File dir = new File(strPath);
+ File[] files = dir.listFiles(); // 该文件目录下文件全部放入数组
+
+ if (files != null) {
+ for (int i = 0; i < files.length; i++) {
+ String fileName = files[i].getName();
+ if (files[i].isDirectory()) { // 判断是文件还是文件夹
+ getFileList(files[i].getAbsolutePath(), suffix); // 获取文件绝对路径
+ } else {
+ if (suffix != null && suffix.length > 0) {
+ for (String str : suffix) {
+ if (fileName.endsWith(str)) { // 判断文件名是否以
+ String strFileName = files[i].getAbsolutePath();
+ System.out.println("---" + strFileName);
+ filelist.add(files[i]);
+ }
+ }
+ }
+ }
+ }
+
+ }
+ return filelist;
+ }
+
+ /**
+ * 清理缓存文件
+ */
+ public static void clearCacheFile() {
+ filelist.clear();
+ }
+
+ /**
+ * 获取文件目录大小
+ *
+ * @param file
+ */
+ public static double getDirSize(File file) {
+ //判断文件是否存在
+ if (file.exists()) {
+ //如果是目录则递归计算其内容的总大小
+ if (file.isDirectory()) {
+ File[] children = file.listFiles();
+ double size = 0;
+ for (File f : children)
+ size += getDirSize(f);
+ return size;
+ } else {//如果是文件则直接返回其大小,以“兆”为单位
+ double size = (double) file.length() / 1024 / 1024;
+ return size;
+ }
+ } else {
+ System.out.println("文件或者文件夹不存在,请检查路径是否正确!");
+ return 0.0;
+ }
+ }
+
+ public static byte[] readFileByBytes(String url) throws IOException {
+ File file = new File(url);
+ if (file.exists() && !file.mkdir()) {
+ long fileSize = file.length();
+ if (fileSize > Integer.MAX_VALUE) {
+// System.out.println("file too big...");
+ return null;
+ }
+
+ FileInputStream fi = new FileInputStream(file);
+ byte[] buffer = new byte[(int) fileSize];
+ int offset = 0;
+ int numRead = 0;
+ while (offset < buffer.length
+ && (numRead = fi.read(buffer, offset, buffer.length - offset)) >= 0) {
+ offset += numRead;
+ }
+ // 确保所有数据均被读取
+ if (offset != buffer.length) {
+ throw new IOException("Could not completely read file "
+ + file.getName());
+ }
+ fi.close();
+ return buffer;
+ }
+ return null;
+ }
+
+
+ //把从服务器获得图片的输入流InputStream写到本地磁盘
+ public static void saveImageToDisk(String url, String savePath) {
+
+ InputStream inputStream = getInputStream(url);
+ if(inputStream==null)
+ return;
+
+ byte[] data = new byte[1024];
+ int len = 0;
+ FileOutputStream fileOutputStream = null;
+ try {
+ fileOutputStream = new FileOutputStream(savePath);
+ while ((len = inputStream.read(data)) != -1) {
+ fileOutputStream.write(data, 0, len);
+
+ }
+ } catch (IOException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ } finally {
+
+ if (inputStream != null) {
+ try {
+ inputStream.close();
+ } catch (IOException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ }
+ if (fileOutputStream != null) {
+ try {
+ fileOutputStream.close();
+ } catch (IOException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ }
+
+ }
+
+ }
+
+ // 从服务器获得一个输入流(本例是指从服务器获得一个image输入流)
+ public static InputStream getInputStream(String urlPath) {
+ InputStream inputStream = null;
+ HttpURLConnection httpURLConnection = null;
+
+ try {
+ URL url = new URL(urlPath);
+ httpURLConnection = (HttpURLConnection) url.openConnection();
+ // 设置网络连接超时时间
+ httpURLConnection.setConnectTimeout(3000);
+ // 设置应用程序要从网络连接读取数据
+ httpURLConnection.setDoInput(true);
+
+ httpURLConnection.setRequestMethod("GET");
+ int responseCode = httpURLConnection.getResponseCode();
+ if (responseCode == 200) {
+ // 从服务器返回一个输入流
+ inputStream = httpURLConnection.getInputStream();
+
+ }
+
+ } catch (MalformedURLException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ } catch (IOException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+
+ return inputStream;
+
+ }
+
+ public static String getExifTime(String jpegFile) {
+ try {
+
+ ExifInterface exif = new ExifInterface(jpegFile);
+
+ String time = exif.getAttribute(ExifInterface.TAG_DATETIME);
+
+ return time;
+
+
+ } catch (IOException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+
+ return null;
+ }
+
+ /**
+ * 轨迹信息写入文件
+ *
+ * @param info 信息
+ * @param isNewLine 是否换行写入
+ */
+ public static void writeToFile(String filePath, String info, boolean isNewLine) {
+
+ if (TextUtils.isEmpty(filePath))
+ return;
+
+ File file = new File(filePath);
+ FileWriter filerWriter = null;
+ BufferedWriter bufWriter = null;
+ try {
+ if (!file.exists())
+ file.createNewFile();
+
+ //文件流
+ filerWriter = new FileWriter(file, true);//后面这个参数代表是不是要接上文件中原来的数据,不进行覆盖
+
+ //字符缓冲输出流
+ bufWriter = new BufferedWriter(filerWriter);
+
+ bufWriter.write(info);
+
+ if (isNewLine)
+ bufWriter.newLine();
+
+ } catch (IOException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }finally {
+ try{
+ if(bufWriter!=null)
+ bufWriter.close();
+
+ if(filerWriter!=null)
+ filerWriter.close();
+ }catch (Exception e){
+
+ }
+ }
+ }
+}
+
+
+
+
+
diff --git a/app/src/main/java/com/navinfo/omqs/util/NetUtils.java b/app/src/main/java/com/navinfo/omqs/util/NetUtils.java
new file mode 100644
index 00000000..a692c114
--- /dev/null
+++ b/app/src/main/java/com/navinfo/omqs/util/NetUtils.java
@@ -0,0 +1,78 @@
+package com.navinfo.omqs.util;
+
+import android.content.Context;
+import android.net.ConnectivityManager;
+import android.net.NetworkInfo;
+
+/**
+ * @ClassName: NetUtils.java
+ * @author qj
+ * @version V1.0
+ * @Date 2016年12月17日 下午1:56:02
+ * @Description: 网络类
+ */
+public class NetUtils {
+ //单例对象
+ private static volatile NetUtils mInstance;
+ //上下文
+ private Context mCon;
+
+ public static NetUtils getInstance() {
+
+ if (mInstance == null) {
+ synchronized (NetUtils.class) {
+ if (mInstance == null) {
+ mInstance = new NetUtils();
+ }
+ }
+ }
+ return mInstance;
+ }
+
+ /**
+ * 初始化
+ * @param context
+ * 上下文
+ */
+ public void init(Context context){
+
+ this.mCon = context;
+
+
+ }
+
+ /**
+ * 是否wifi
+ * @return true 是 false 否
+ */
+ public boolean isExistWifi(boolean isNeedMobile){
+
+ //获取系统服务
+ ConnectivityManager manager = (ConnectivityManager)mCon.getSystemService(Context.CONNECTIVITY_SERVICE);
+ try{
+ //获取状态
+ final NetworkInfo.State wifi = manager.getNetworkInfo(ConnectivityManager.TYPE_WIFI).getState();
+
+ if(wifi == NetworkInfo.State.CONNECTED||wifi==NetworkInfo.State.CONNECTING){
+ return true;
+ }
+ }catch (Exception e){
+ }
+
+
+ if(isNeedMobile){
+ try{
+ //获取状态
+ final NetworkInfo mobileNetwork = manager.getNetworkInfo(ConnectivityManager.TYPE_MOBILE);
+
+ if(mobileNetwork!=null&&mobileNetwork.getState()!=null&& (mobileNetwork.getState()== NetworkInfo.State.CONNECTED||mobileNetwork.getState()==NetworkInfo.State.CONNECTING)){
+ return true;
+ }
+ }catch (Exception e){
+ }
+
+ }
+
+ return false;
+ }
+}
diff --git a/app/src/main/java/com/navinfo/omqs/util/ShareUtil.java b/app/src/main/java/com/navinfo/omqs/util/ShareUtil.java
new file mode 100644
index 00000000..54e2511e
--- /dev/null
+++ b/app/src/main/java/com/navinfo/omqs/util/ShareUtil.java
@@ -0,0 +1,373 @@
+package com.navinfo.omqs.util;
+
+import android.content.Context;
+import android.content.SharedPreferences;
+import android.content.SharedPreferences.Editor;
+import com.navinfo.omqs.system.SystemConstant;
+
+/**
+ * @ClassName: ShareUtil.java
+ * @author qj
+ * @version V1.0
+ * @Date 2016年12月17日 下午1:56:02
+ * @Description: 相机数据存储
+ */
+public class ShareUtil {
+ //系统数据存储对象
+ private static SharedPreferences mSharePre=null;
+ //安卓编辑器
+ private static Editor editor;
+ //拍照状态标识
+ private final static String CONTINUS_TAKE_PHOTO_STATE = "continue_take_photo_state";
+ //外设相机按钮状态标识
+ private final static String SELECT_TAKE_PHOTO_OR_RECORD = "select_take_photo_or_record";
+ //外设相机种别标识
+ private final static String SELECT_CAMERA_KIND = "select_take_kind";
+ //外设相机连接标识
+ private final static String CAMERA_CONNECT_STATE = "camera_connect_state";
+ //外设相机工作模式
+ private final static String TAKE_CAMERA_MODE = "take_camera_mode";
+ //连接相机ip
+ private final static String TAKE_CAMERA_IP = "take_camera_ip";
+ //连接相机Mac
+ private final static String TAKE_CAMERA_MAC = "take_camera_mac";
+ //外设相机编号,应对多个相机连接使用,识别存储某一个设备连接状态等信息
+ private int mDeviceNum = 1;
+ //上下文
+ private Context mContext;
+
+ private ShareUtil() {
+ }
+
+ public ShareUtil(Context context, int deviceNum) {
+ mContext = context;
+ mDeviceNum = deviceNum;
+ }
+
+ /**
+ * method : getSelectCameraKind
+ * Author : qj
+ * Describe : 获取相机类型
+ * param : context 上下文
+ * return true 相机 false视频
+ * Date : 2018/4/23
+ */
+ public boolean getSelectCameraKind(){
+ if(mContext==null)
+ return false;
+
+ if(mSharePre==null){
+ mSharePre = mContext.getSharedPreferences(SystemConstant.SELECT_CAMERA_STATE, Context.MODE_PRIVATE);
+ }
+ return mSharePre.getBoolean(mDeviceNum+SystemConstant.USER_ID+SELECT_CAMERA_KIND, false);
+ }
+
+ /**
+ * method : setSelectCameraKind
+ * Author : qj
+ * Describe : 设置相机类型
+ * param : context 上下文
+ * param : userid用户id
+ * param : true 内置相机 false 外置相机
+ * Date : 2018/4/23
+ */
+ public void setSelectCameraKind(String userId,Boolean bll){
+ if(mContext==null)
+ return ;
+
+ if(mSharePre==null){
+ mSharePre = mContext.getSharedPreferences(SystemConstant.SELECT_CAMERA_STATE, Context.MODE_PRIVATE);
+ }
+
+ editor=mSharePre.edit();
+
+ editor.putBoolean(mDeviceNum+userId+SELECT_CAMERA_KIND,bll).commit();
+
+ }
+
+ /**
+ * method : getSelectTakePhotoOrRecord
+ * Author : qj
+ * Describe : 获取相机使用类型
+ * param : context 上下文
+ * param : true 相机拍照 false 录像视频
+ * Date : 2018/4/23
+ */
+ public boolean getSelectTakePhotoOrRecord(){
+ if(mContext==null)
+ return true;
+
+ if(mSharePre==null){
+ mSharePre = mContext.getSharedPreferences(SystemConstant.SELECT_TAKEPHOTO_OR_RECORD, Context.MODE_PRIVATE);
+ }
+
+ return mSharePre.getBoolean(mDeviceNum+SystemConstant.USER_ID+SELECT_TAKE_PHOTO_OR_RECORD, mDeviceNum==1?true:false);
+
+ }
+
+ /**
+ * method : setSelectTakePhotoOrRecord
+ * Author : qj
+ * Describe : 设置相机使用类型
+ * param : context 上下文
+ * param : userid 用户id
+ * param : true 相机拍照 false 录像视频
+ * Date : 2018/4/23
+ */
+ public void setSelectTakePhotoOrRecord(String userId,Boolean bll){
+ if(mContext==null)
+ return ;
+
+ if(mSharePre==null){
+ mSharePre = mContext.getSharedPreferences(SystemConstant.SELECT_TAKEPHOTO_OR_RECORD, Context.MODE_PRIVATE);
+ }
+ editor=mSharePre.edit();
+
+ editor.putBoolean(mDeviceNum+userId+SELECT_TAKE_PHOTO_OR_RECORD,bll).commit();
+
+ }
+
+ /**
+ * method : getContinusTakePhotoState
+ * Author : qj
+ * Describe : 获取相机工作状态
+ * param : context 上下文
+ * Date : 2018/4/23
+ */
+ public boolean getContinusTakePhotoState(){
+ if(mContext==null)
+ return true;
+
+ if(mSharePre==null){
+ mSharePre = mContext.getSharedPreferences(SystemConstant.SELECT_CAMERA_STATE, Context.MODE_PRIVATE);
+ }
+ return mSharePre.getBoolean(mDeviceNum+SystemConstant.USER_ID+CONTINUS_TAKE_PHOTO_STATE, true);
+
+ }
+
+ /**
+ * method : setContinusTakePhotoState
+ * Author : qj
+ * Describe : 设置相机工作状态
+ * param : context 上下文
+ * param : userid 用户id
+ * param : true 停止 false 否
+ * Date : 2018/4/23
+ */
+ public void setContinusTakePhotoState(String userId,Boolean bll){
+ if(mContext==null)
+ return ;
+
+ if(mSharePre==null){
+ mSharePre = mContext.getSharedPreferences(SystemConstant.SELECT_CAMERA_STATE, Context.MODE_PRIVATE);
+ }
+ editor=mSharePre.edit();
+
+ editor.putBoolean(mDeviceNum+userId+CONTINUS_TAKE_PHOTO_STATE,bll).commit();
+ }
+
+ /**
+ * method : getConnectstate
+ * Author : qj
+ * Describe : 获取相机连接状态
+ * param : context 上下文
+ * Date : 2018/4/23
+ */
+ public boolean getConnectstate(){
+ if(mContext==null)
+ return false;
+
+ if(mSharePre==null){
+ mSharePre = mContext.getSharedPreferences(SystemConstant.CAMERA_CONNECT_STATE, Context.MODE_PRIVATE);
+ }
+ return mSharePre.getBoolean(mDeviceNum+SystemConstant.USER_ID+CAMERA_CONNECT_STATE, false);
+ }
+
+ /**
+ * method : setConnectstate
+ * Author : qj
+ * Describe : 设置相机连接状态
+ * param : context 上下文
+ * param : userid 用户id
+ * param : true 连接 false 否
+ * Date : 2018/4/23
+ */
+ public void setConnectstate(String userId,Boolean bll){
+ if(mContext==null)
+ return ;
+
+ if(mSharePre==null){
+ mSharePre = mContext.getSharedPreferences(SystemConstant.CAMERA_CONNECT_STATE, Context.MODE_PRIVATE);
+ }
+ editor=mSharePre.edit();
+
+ editor.putBoolean(mDeviceNum+userId+CAMERA_CONNECT_STATE,bll).commit();
+ }
+
+ /**
+ * method : getTakeCameraMode
+ * Author : qj
+ * Describe : 获取相机模式
+ * param : context 上下文
+ * Date : 2018/4/23
+ */
+ public int getTakeCameraMode(){
+ if(mContext==null)
+ return 0;
+
+ if(mSharePre==null){
+ mSharePre = mContext.getSharedPreferences(SystemConstant.TAKE_CAMERA_MODE, Context.MODE_PRIVATE);
+ }
+
+ return mSharePre.getInt(mDeviceNum+SystemConstant.USER_ID+TAKE_CAMERA_MODE, mDeviceNum==1?0:1);
+
+ }
+
+ /**
+ * method : setTakeCameraMode
+ * Author : qj
+ * Describe : 设置相机模式
+ * param : context 上下文
+ * param : userid 用户id
+ * param : int 0 视频 1 拍照
+ * Date : 2018/4/23
+ */
+ public void setTakeCameraMode(String userId,int mode){
+ if(mContext==null)
+ return ;
+
+
+ if(mSharePre==null){
+ mSharePre = mContext.getSharedPreferences(SystemConstant.TAKE_CAMERA_MODE, Context.MODE_PRIVATE);
+ }
+ editor=mSharePre.edit();
+
+ editor.putInt(mDeviceNum+userId+TAKE_CAMERA_MODE,mode).commit();
+ }
+
+ /**
+ * method : getTakeCameraIP
+ * Author : qj
+ * Describe : 获取相机ip
+ * param : context 上下文
+ * Date : 2018/4/23
+ */
+ public String getTakeCameraIP(){
+ if(mContext==null)
+ return "";
+
+ if(mSharePre==null){
+ mSharePre = mContext.getSharedPreferences(SystemConstant.TAKE_CAMERA_IP, Context.MODE_PRIVATE);
+ }
+ String ip=mSharePre.getString(mDeviceNum+SystemConstant.USER_ID+TAKE_CAMERA_IP, "");
+ return ip;
+ }
+
+ /**
+ * method : setTakeCameraIP
+ * Author : qj
+ * Describe : 设置相机ip
+ * param : context 上下文
+ * param : userid 用户id
+ * param : ip 连接地址
+ * Date : 2018/4/23
+ */
+ public void setTakeCameraIP(String userId,String ip){
+ if(mContext==null)
+ return ;
+
+ if(mSharePre==null){
+ mSharePre = mContext.getSharedPreferences(SystemConstant.TAKE_CAMERA_IP, Context.MODE_PRIVATE);
+ }
+
+ editor=mSharePre.edit();
+
+ editor.putString(mDeviceNum+userId+TAKE_CAMERA_IP,ip).commit();
+ }
+
+ /**
+ * method : getTakeCameraMac
+ * Author : qj
+ * param : mac 硬件信息
+ * param : context 上下文
+ * Date : 2018/4/23
+ */
+ public String getTakeCameraMac(){
+ if(mContext==null)
+ return "";
+
+ if(mSharePre==null){
+ mSharePre = mContext.getSharedPreferences(SystemConstant.TAKE_CAMERA_MAC, Context.MODE_PRIVATE);
+ }
+ String mac=mSharePre.getString(mDeviceNum+SystemConstant.USER_ID+TAKE_CAMERA_MAC, "");
+ return mac;
+ }
+
+ /**
+ * method : setTakeCameraMac
+ * Author : qj
+ * Describe : 设置相机mac
+ * param : context 上下文
+ * param : userid 用户id
+ * param : mac 硬件信息
+ * Date : 2018/4/23
+ */
+ public void setTakeCameraMac(String userId,String mac){
+ if(mContext==null)
+ return ;
+
+ if(mSharePre==null){
+ mSharePre = mContext.getSharedPreferences(SystemConstant.TAKE_CAMERA_MAC, Context.MODE_PRIVATE);
+ }
+
+ editor=mSharePre.edit();
+
+ editor.putString(mDeviceNum+userId+TAKE_CAMERA_MAC,mac).commit();
+ }
+
+ /**
+ * method : getConnectstateMac
+ * Author : qj
+ * param : mac 硬件信息
+ * Date : 2018/4/23
+ */
+ public static String getConnectstateMac(Context context){
+ if(context==null)
+ return "";
+
+ ShareUtil shareUtil = new ShareUtil(context,1);
+
+ if(shareUtil.getConnectstate())
+ return shareUtil.getTakeCameraMac();
+
+ shareUtil = new ShareUtil(context,2);
+
+ if(shareUtil.getConnectstate())
+ return shareUtil.getTakeCameraMac();
+
+ return "";
+ }
+
+ /**
+ * method : getConnectstateMac
+ * Author : qj
+ * param : mac 硬件信息
+ * Date : 2018/4/23
+ */
+ public static ShareUtil getCameraMode(Context context){
+ if(context==null)
+ return null;
+
+ ShareUtil shareUtil = new ShareUtil(context,1);
+
+ if(shareUtil.getConnectstate()/*&&shareUtil.getTakeCameraMode()==0不需要判断相机类型*/)
+ return shareUtil;
+
+ shareUtil = new ShareUtil(context,2);
+
+ if(shareUtil.getConnectstate()/*&&shareUtil.getTakeCameraMode()==0不需要判断相机类型*/)
+ return shareUtil;
+
+ return null;
+ }
+}
diff --git a/app/src/main/res/color/btn_select_color.xml b/app/src/main/res/color/btn_select_color.xml
new file mode 100644
index 00000000..9c69fb58
--- /dev/null
+++ b/app/src/main/res/color/btn_select_color.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
diff --git a/app/src/main/res/color/common_dialog_cancel_text_selector.xml b/app/src/main/res/color/common_dialog_cancel_text_selector.xml
new file mode 100644
index 00000000..2b918209
--- /dev/null
+++ b/app/src/main/res/color/common_dialog_cancel_text_selector.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/app/src/main/res/color/common_dialog_confirm_text_selector.xml b/app/src/main/res/color/common_dialog_confirm_text_selector.xml
new file mode 100644
index 00000000..7d3143dd
--- /dev/null
+++ b/app/src/main/res/color/common_dialog_confirm_text_selector.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/app/src/main/res/color/common_dialog_middle_text_selector.xml b/app/src/main/res/color/common_dialog_middle_text_selector.xml
new file mode 100644
index 00000000..59fdfd14
--- /dev/null
+++ b/app/src/main/res/color/common_dialog_middle_text_selector.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/app/src/main/res/color/selector_default_text_color_white_enable_gray.xml b/app/src/main/res/color/selector_default_text_color_white_enable_gray.xml
new file mode 100644
index 00000000..18707d36
--- /dev/null
+++ b/app/src/main/res/color/selector_default_text_color_white_enable_gray.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/drawable/btn_bg_default.xml b/app/src/main/res/drawable/btn_bg_default.xml
new file mode 100644
index 00000000..bb1aa4b3
--- /dev/null
+++ b/app/src/main/res/drawable/btn_bg_default.xml
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/drawable/btn_connect_bg_enabled.xml b/app/src/main/res/drawable/btn_connect_bg_enabled.xml
new file mode 100644
index 00000000..edd37fc7
--- /dev/null
+++ b/app/src/main/res/drawable/btn_connect_bg_enabled.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
diff --git a/app/src/main/res/drawable/btn_red_disconnect_bg.xml b/app/src/main/res/drawable/btn_red_disconnect_bg.xml
new file mode 100644
index 00000000..46cc1931
--- /dev/null
+++ b/app/src/main/res/drawable/btn_red_disconnect_bg.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/drawable/chk_icon_camera_open_close_xml.xml b/app/src/main/res/drawable/chk_icon_camera_open_close_xml.xml
new file mode 100644
index 00000000..1119bd24
--- /dev/null
+++ b/app/src/main/res/drawable/chk_icon_camera_open_close_xml.xml
@@ -0,0 +1,9 @@
+
+
+ -
+
+ -
+
+ -
+
+
\ No newline at end of file
diff --git a/app/src/main/res/drawable/chk_icon_camera_record_or_takephoto_xml.xml b/app/src/main/res/drawable/chk_icon_camera_record_or_takephoto_xml.xml
new file mode 100644
index 00000000..7c7a5a79
--- /dev/null
+++ b/app/src/main/res/drawable/chk_icon_camera_record_or_takephoto_xml.xml
@@ -0,0 +1,9 @@
+
+
+ -
+
+ -
+
+ -
+
+
\ No newline at end of file
diff --git a/app/src/main/res/drawable/chk_icon_camera_start_stop_xml.xml b/app/src/main/res/drawable/chk_icon_camera_start_stop_xml.xml
new file mode 100644
index 00000000..ca55bb7e
--- /dev/null
+++ b/app/src/main/res/drawable/chk_icon_camera_start_stop_xml.xml
@@ -0,0 +1,11 @@
+
+
+ -
+
+ -
+
+ -
+
+ -
+
+
\ No newline at end of file
diff --git a/app/src/main/res/drawable/dialog_bg.xml b/app/src/main/res/drawable/dialog_bg.xml
new file mode 100644
index 00000000..c08ea5cd
--- /dev/null
+++ b/app/src/main/res/drawable/dialog_bg.xml
@@ -0,0 +1,14 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/drawable/dialog_bg_cancel.xml b/app/src/main/res/drawable/dialog_bg_cancel.xml
new file mode 100644
index 00000000..f46b1ed1
--- /dev/null
+++ b/app/src/main/res/drawable/dialog_bg_cancel.xml
@@ -0,0 +1,23 @@
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+
+ -
+
+
+
+
+
+
diff --git a/app/src/main/res/drawable/dialog_bg_ok.xml b/app/src/main/res/drawable/dialog_bg_ok.xml
new file mode 100644
index 00000000..5dee094d
--- /dev/null
+++ b/app/src/main/res/drawable/dialog_bg_ok.xml
@@ -0,0 +1,23 @@
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+
+ -
+
+
+
+
+
+
diff --git a/app/src/main/res/drawable/drawable_bg_blue_bg_4_radius.xml b/app/src/main/res/drawable/drawable_bg_blue_bg_4_radius.xml
new file mode 100644
index 00000000..cf3c0fea
--- /dev/null
+++ b/app/src/main/res/drawable/drawable_bg_blue_bg_4_radius.xml
@@ -0,0 +1,14 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/drawable/icon_btn_bg_gray_press.9.png b/app/src/main/res/drawable/icon_btn_bg_gray_press.9.png
new file mode 100644
index 00000000..f11d6107
Binary files /dev/null and b/app/src/main/res/drawable/icon_btn_bg_gray_press.9.png differ
diff --git a/app/src/main/res/drawable/icon_btn_bg_white_nor.9.png b/app/src/main/res/drawable/icon_btn_bg_white_nor.9.png
new file mode 100644
index 00000000..8f66eabd
Binary files /dev/null and b/app/src/main/res/drawable/icon_btn_bg_white_nor.9.png differ
diff --git a/app/src/main/res/drawable/icon_camera_close_xml.xml b/app/src/main/res/drawable/icon_camera_close_xml.xml
new file mode 100644
index 00000000..6bbcc538
--- /dev/null
+++ b/app/src/main/res/drawable/icon_camera_close_xml.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/drawable/loading_anim.xml b/app/src/main/res/drawable/loading_anim.xml
new file mode 100644
index 00000000..c80cc1ef
--- /dev/null
+++ b/app/src/main/res/drawable/loading_anim.xml
@@ -0,0 +1,42 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/drawable/pop_camera_img.xml b/app/src/main/res/drawable/pop_camera_img.xml
new file mode 100644
index 00000000..fb7e8b10
--- /dev/null
+++ b/app/src/main/res/drawable/pop_camera_img.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
diff --git a/app/src/main/res/drawable/pop_camera_take_photo_img.xml b/app/src/main/res/drawable/pop_camera_take_photo_img.xml
new file mode 100644
index 00000000..5acd8ef8
--- /dev/null
+++ b/app/src/main/res/drawable/pop_camera_take_photo_img.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
diff --git a/app/src/main/res/drawable/progress_bg.xml b/app/src/main/res/drawable/progress_bg.xml
index 244083fc..45d0d3d6 100644
--- a/app/src/main/res/drawable/progress_bg.xml
+++ b/app/src/main/res/drawable/progress_bg.xml
@@ -14,7 +14,7 @@
-
+
diff --git a/app/src/main/res/drawable/selector_bg_blue_gray_bg_4_radius.xml b/app/src/main/res/drawable/selector_bg_blue_gray_bg_4_radius.xml
new file mode 100644
index 00000000..63b99406
--- /dev/null
+++ b/app/src/main/res/drawable/selector_bg_blue_gray_bg_4_radius.xml
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
+
diff --git a/app/src/main/res/drawable/selector_default_text_color_white_enable_gray.xml b/app/src/main/res/drawable/selector_default_text_color_white_enable_gray.xml
new file mode 100644
index 00000000..18707d36
--- /dev/null
+++ b/app/src/main/res/drawable/selector_default_text_color_white_enable_gray.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/drawable/shade_btn_gray_bg_4_radius_hd.xml b/app/src/main/res/drawable/shade_btn_gray_bg_4_radius_hd.xml
new file mode 100644
index 00000000..0a579e50
--- /dev/null
+++ b/app/src/main/res/drawable/shade_btn_gray_bg_4_radius_hd.xml
@@ -0,0 +1,14 @@
+
+
+
+
+
+
diff --git a/app/src/main/res/drawable/transient_toast_bg.xml b/app/src/main/res/drawable/transient_toast_bg.xml
new file mode 100644
index 00000000..9f1f934f
--- /dev/null
+++ b/app/src/main/res/drawable/transient_toast_bg.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml
index f15ff59a..0ae01598 100644
--- a/app/src/main/res/layout/activity_main.xml
+++ b/app/src/main/res/layout/activity_main.xml
@@ -92,6 +92,29 @@
app:layout_constraintTop_toTopOf="parent"
app:navGraph="@navigation/right_fragment_nav_graph" />
+
+
+
+
diff --git a/app/src/main/res/layout/connect_out_camera.xml b/app/src/main/res/layout/connect_out_camera.xml
new file mode 100644
index 00000000..8c0f6134
--- /dev/null
+++ b/app/src/main/res/layout/connect_out_camera.xml
@@ -0,0 +1,161 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/dialog_default.xml b/app/src/main/res/layout/dialog_default.xml
new file mode 100644
index 00000000..eeaacc37
--- /dev/null
+++ b/app/src/main/res/layout/dialog_default.xml
@@ -0,0 +1,165 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/src/main/res/layout/dialog_loading_custom_frame_layout.xml b/app/src/main/res/layout/dialog_loading_custom_frame_layout.xml
new file mode 100644
index 00000000..9508e30c
--- /dev/null
+++ b/app/src/main/res/layout/dialog_loading_custom_frame_layout.xml
@@ -0,0 +1,26 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/fragment_offline_map.xml b/app/src/main/res/layout/fragment_offline_map.xml
index 798d5e1c..424a8307 100644
--- a/app/src/main/res/layout/fragment_offline_map.xml
+++ b/app/src/main/res/layout/fragment_offline_map.xml
@@ -11,7 +11,7 @@
android:id="@+id/offline_map_tab_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:background="@color/default_blue"
+ android:background="@color/blue"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent">
diff --git a/app/src/main/res/layout/personal_center_head.xml b/app/src/main/res/layout/personal_center_head.xml
index 30935119..7b3e03f6 100644
--- a/app/src/main/res/layout/personal_center_head.xml
+++ b/app/src/main/res/layout/personal_center_head.xml
@@ -3,7 +3,7 @@
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="@dimen/nav_header_height"
- android:background="@color/default_blue"
+ android:background="@color/blue"
android:gravity="bottom"
android:orientation="vertical"
android:paddingLeft="@dimen/activity_horizontal_margin"
diff --git a/app/src/main/res/layout/transient_notification.xml b/app/src/main/res/layout/transient_notification.xml
new file mode 100644
index 00000000..6c495d72
--- /dev/null
+++ b/app/src/main/res/layout/transient_notification.xml
@@ -0,0 +1,37 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/mipmap-hdpi/loading_01.png b/app/src/main/res/mipmap-hdpi/loading_01.png
new file mode 100644
index 00000000..1c190a99
Binary files /dev/null and b/app/src/main/res/mipmap-hdpi/loading_01.png differ
diff --git a/app/src/main/res/mipmap-hdpi/loading_02.png b/app/src/main/res/mipmap-hdpi/loading_02.png
new file mode 100644
index 00000000..bc930f2d
Binary files /dev/null and b/app/src/main/res/mipmap-hdpi/loading_02.png differ
diff --git a/app/src/main/res/mipmap-hdpi/loading_03.png b/app/src/main/res/mipmap-hdpi/loading_03.png
new file mode 100644
index 00000000..e461335e
Binary files /dev/null and b/app/src/main/res/mipmap-hdpi/loading_03.png differ
diff --git a/app/src/main/res/mipmap-hdpi/loading_04.png b/app/src/main/res/mipmap-hdpi/loading_04.png
new file mode 100644
index 00000000..071af1ed
Binary files /dev/null and b/app/src/main/res/mipmap-hdpi/loading_04.png differ
diff --git a/app/src/main/res/mipmap-hdpi/loading_05.png b/app/src/main/res/mipmap-hdpi/loading_05.png
new file mode 100644
index 00000000..43ba85ff
Binary files /dev/null and b/app/src/main/res/mipmap-hdpi/loading_05.png differ
diff --git a/app/src/main/res/mipmap-hdpi/loading_06.png b/app/src/main/res/mipmap-hdpi/loading_06.png
new file mode 100644
index 00000000..67c6faa1
Binary files /dev/null and b/app/src/main/res/mipmap-hdpi/loading_06.png differ
diff --git a/app/src/main/res/mipmap-hdpi/loading_07.png b/app/src/main/res/mipmap-hdpi/loading_07.png
new file mode 100644
index 00000000..797c5d8a
Binary files /dev/null and b/app/src/main/res/mipmap-hdpi/loading_07.png differ
diff --git a/app/src/main/res/mipmap-hdpi/loading_08.png b/app/src/main/res/mipmap-hdpi/loading_08.png
new file mode 100644
index 00000000..bbeecf25
Binary files /dev/null and b/app/src/main/res/mipmap-hdpi/loading_08.png differ
diff --git a/app/src/main/res/mipmap-hdpi/loading_09.png b/app/src/main/res/mipmap-hdpi/loading_09.png
new file mode 100644
index 00000000..397c08da
Binary files /dev/null and b/app/src/main/res/mipmap-hdpi/loading_09.png differ
diff --git a/app/src/main/res/mipmap-hdpi/loading_10.png b/app/src/main/res/mipmap-hdpi/loading_10.png
new file mode 100644
index 00000000..2c4c58b2
Binary files /dev/null and b/app/src/main/res/mipmap-hdpi/loading_10.png differ
diff --git a/app/src/main/res/mipmap-hdpi/loading_11.png b/app/src/main/res/mipmap-hdpi/loading_11.png
new file mode 100644
index 00000000..587c1df6
Binary files /dev/null and b/app/src/main/res/mipmap-hdpi/loading_11.png differ
diff --git a/app/src/main/res/mipmap-hdpi/loading_12.png b/app/src/main/res/mipmap-hdpi/loading_12.png
new file mode 100644
index 00000000..162ffd46
Binary files /dev/null and b/app/src/main/res/mipmap-hdpi/loading_12.png differ
diff --git a/app/src/main/res/mipmap-xhdpi/icon_camera_close_normal.png b/app/src/main/res/mipmap-xhdpi/icon_camera_close_normal.png
new file mode 100644
index 00000000..8290ed44
Binary files /dev/null and b/app/src/main/res/mipmap-xhdpi/icon_camera_close_normal.png differ
diff --git a/app/src/main/res/mipmap-xhdpi/icon_camera_close_press.png b/app/src/main/res/mipmap-xhdpi/icon_camera_close_press.png
new file mode 100644
index 00000000..59f00328
Binary files /dev/null and b/app/src/main/res/mipmap-xhdpi/icon_camera_close_press.png differ
diff --git a/app/src/main/res/mipmap-xhdpi/icon_camera_end.png b/app/src/main/res/mipmap-xhdpi/icon_camera_end.png
new file mode 100644
index 00000000..09e2ead9
Binary files /dev/null and b/app/src/main/res/mipmap-xhdpi/icon_camera_end.png differ
diff --git a/app/src/main/res/mipmap-xhdpi/icon_camera_img.png b/app/src/main/res/mipmap-xhdpi/icon_camera_img.png
new file mode 100644
index 00000000..f43569ec
Binary files /dev/null and b/app/src/main/res/mipmap-xhdpi/icon_camera_img.png differ
diff --git a/app/src/main/res/mipmap-xhdpi/icon_camera_off.png b/app/src/main/res/mipmap-xhdpi/icon_camera_off.png
new file mode 100644
index 00000000..c184fa69
Binary files /dev/null and b/app/src/main/res/mipmap-xhdpi/icon_camera_off.png differ
diff --git a/app/src/main/res/mipmap-xhdpi/icon_camera_on.png b/app/src/main/res/mipmap-xhdpi/icon_camera_on.png
new file mode 100644
index 00000000..77c08ef2
Binary files /dev/null and b/app/src/main/res/mipmap-xhdpi/icon_camera_on.png differ
diff --git a/app/src/main/res/mipmap-xhdpi/icon_camera_start.png b/app/src/main/res/mipmap-xhdpi/icon_camera_start.png
new file mode 100644
index 00000000..f3cb8821
Binary files /dev/null and b/app/src/main/res/mipmap-xhdpi/icon_camera_start.png differ
diff --git a/app/src/main/res/mipmap-xhdpi/icon_camera_start_disable.png b/app/src/main/res/mipmap-xhdpi/icon_camera_start_disable.png
new file mode 100644
index 00000000..e66018ef
Binary files /dev/null and b/app/src/main/res/mipmap-xhdpi/icon_camera_start_disable.png differ
diff --git a/app/src/main/res/mipmap-xhdpi/icon_camera_take_photo_img.png b/app/src/main/res/mipmap-xhdpi/icon_camera_take_photo_img.png
new file mode 100644
index 00000000..ec88d2af
Binary files /dev/null and b/app/src/main/res/mipmap-xhdpi/icon_camera_take_photo_img.png differ
diff --git a/app/src/main/res/mipmap-xhdpi/icon_camera_time.png b/app/src/main/res/mipmap-xhdpi/icon_camera_time.png
new file mode 100644
index 00000000..94777f50
Binary files /dev/null and b/app/src/main/res/mipmap-xhdpi/icon_camera_time.png differ
diff --git a/app/src/main/res/mipmap-xhdpi/icon_page_take_photo_a0.png b/app/src/main/res/mipmap-xhdpi/icon_page_take_photo_a0.png
new file mode 100644
index 00000000..8916ca0d
Binary files /dev/null and b/app/src/main/res/mipmap-xhdpi/icon_page_take_photo_a0.png differ
diff --git a/app/src/main/res/mipmap-xhdpi/icon_page_take_photo_a1.png b/app/src/main/res/mipmap-xhdpi/icon_page_take_photo_a1.png
new file mode 100644
index 00000000..b9b30d8a
Binary files /dev/null and b/app/src/main/res/mipmap-xhdpi/icon_page_take_photo_a1.png differ
diff --git a/app/src/main/res/mipmap-xhdpi/icon_page_take_photo_a2.png b/app/src/main/res/mipmap-xhdpi/icon_page_take_photo_a2.png
new file mode 100644
index 00000000..ca4a4e80
Binary files /dev/null and b/app/src/main/res/mipmap-xhdpi/icon_page_take_photo_a2.png differ
diff --git a/app/src/main/res/mipmap-xhdpi/icon_page_take_photo_a3.png b/app/src/main/res/mipmap-xhdpi/icon_page_take_photo_a3.png
new file mode 100644
index 00000000..d513a9d9
Binary files /dev/null and b/app/src/main/res/mipmap-xhdpi/icon_page_take_photo_a3.png differ
diff --git a/app/src/main/res/mipmap-xhdpi/icon_page_video_a0.png b/app/src/main/res/mipmap-xhdpi/icon_page_video_a0.png
new file mode 100644
index 00000000..975bafaa
Binary files /dev/null and b/app/src/main/res/mipmap-xhdpi/icon_page_video_a0.png differ
diff --git a/app/src/main/res/mipmap-xhdpi/icon_page_video_a1.png b/app/src/main/res/mipmap-xhdpi/icon_page_video_a1.png
new file mode 100644
index 00000000..221c49a7
Binary files /dev/null and b/app/src/main/res/mipmap-xhdpi/icon_page_video_a1.png differ
diff --git a/app/src/main/res/mipmap-xhdpi/icon_page_video_a2.png b/app/src/main/res/mipmap-xhdpi/icon_page_video_a2.png
new file mode 100644
index 00000000..17858f57
Binary files /dev/null and b/app/src/main/res/mipmap-xhdpi/icon_page_video_a2.png differ
diff --git a/app/src/main/res/mipmap-xhdpi/icon_page_video_a3.png b/app/src/main/res/mipmap-xhdpi/icon_page_video_a3.png
new file mode 100644
index 00000000..fdf21227
Binary files /dev/null and b/app/src/main/res/mipmap-xhdpi/icon_page_video_a3.png differ
diff --git a/app/src/main/res/mipmap-xhdpi/record_select.png b/app/src/main/res/mipmap-xhdpi/record_select.png
new file mode 100644
index 00000000..d265c7bb
Binary files /dev/null and b/app/src/main/res/mipmap-xhdpi/record_select.png differ
diff --git a/app/src/main/res/mipmap-xhdpi/takephoto_select.png b/app/src/main/res/mipmap-xhdpi/takephoto_select.png
new file mode 100644
index 00000000..f7d72ed0
Binary files /dev/null and b/app/src/main/res/mipmap-xhdpi/takephoto_select.png differ
diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml
index 3a08ff82..6e54318f 100644
--- a/app/src/main/res/values/colors.xml
+++ b/app/src/main/res/values/colors.xml
@@ -2,8 +2,21 @@
#FF000000
#FFFFFFFF
+ #FF0000
+ #00000000
+ #ff8d36
+ #1abbfe
+ #dadade
#999999
#FF3B30
#553C3F41
#108ee9
+ #ffffffff
+
+ #d1d1d1
+
+ #999999
+ #797979
+ #595959
+ #c1c1c1
\ No newline at end of file
diff --git a/app/src/main/res/values/dimens.xml b/app/src/main/res/values/dimens.xml
index 094d4c98..480ce172 100644
--- a/app/src/main/res/values/dimens.xml
+++ b/app/src/main/res/values/dimens.xml
@@ -9,4 +9,28 @@
15dp
13sp
10sp
+ 1dp
+ 2dp
+ 3dp
+ 4dp
+ 5dp
+ 6dp
+ 8dp
+ 9dp
+ 10dp
+ 12dp
+ 14dp
+ 15dp
+ 16dp
+ 18dp
+ 20dp
+ 22dp
+ 24dp
+
+ 25dp
+
+ 150dp
+
+ 75dp
+ 48dp
\ No newline at end of file
diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml
index ea96791b..4c69500a 100644
--- a/app/src/main/res/values/styles.xml
+++ b/app/src/main/res/values/styles.xml
@@ -6,7 +6,7 @@
- true
- true
- true
- - @color/default_blue
+ - @color/blue
- 6dp
- 14dp
- 14dp
@@ -54,4 +54,33 @@
- @color/btn_blue_white
- 15sp
+
+
+
+
+
+
+
+
+
+
diff --git a/app/src/main/res/xml/network_security_config.xml b/app/src/main/res/xml/network_security_config.xml
new file mode 100644
index 00000000..70cd516f
--- /dev/null
+++ b/app/src/main/res/xml/network_security_config.xml
@@ -0,0 +1,5 @@
+
+
+
+
\ No newline at end of file
diff --git a/collect-library/build.gradle b/collect-library/build.gradle
index 3cca075f..c125ed9d 100644
--- a/collect-library/build.gradle
+++ b/collect-library/build.gradle
@@ -76,7 +76,6 @@ dependencies {
androidTestImplementation 'androidx.test.ext:junit:1.1.5'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1'
// implementation 'com.yanzhenjie:kalle:0.1.7'
-
// VTM依赖
implementation "net.sf.kxml:kxml2:2.3.0"
implementation 'org.slf4j:slf4j-api:2.0.7'
diff --git a/collect-library/libs/Volley.jar b/collect-library/libs/Volley.jar
new file mode 100644
index 00000000..836877ff
Binary files /dev/null and b/collect-library/libs/Volley.jar differ
diff --git a/collect-library/libs/armeabi-v7a/libAsr2Code.so b/collect-library/libs/armeabi-v7a/libAsr2Code.so
new file mode 100644
index 00000000..fa01878c
Binary files /dev/null and b/collect-library/libs/armeabi-v7a/libAsr2Code.so differ
diff --git a/collect-library/libs/armeabi-v7a/libBugly.so b/collect-library/libs/armeabi-v7a/libBugly.so
new file mode 100644
index 00000000..2dc98ed3
Binary files /dev/null and b/collect-library/libs/armeabi-v7a/libBugly.so differ
diff --git a/collect-library/libs/armeabi-v7a/libDecode.so b/collect-library/libs/armeabi-v7a/libDecode.so
new file mode 100644
index 00000000..8efb1d5f
Binary files /dev/null and b/collect-library/libs/armeabi-v7a/libDecode.so differ
diff --git a/collect-library/libs/armeabi-v7a/libNuanceVocalizer.so b/collect-library/libs/armeabi-v7a/libNuanceVocalizer.so
new file mode 100644
index 00000000..2791e318
Binary files /dev/null and b/collect-library/libs/armeabi-v7a/libNuanceVocalizer.so differ
diff --git a/collect-library/libs/armeabi-v7a/libSetWakeupJni.so b/collect-library/libs/armeabi-v7a/libSetWakeupJni.so
new file mode 100644
index 00000000..93811097
Binary files /dev/null and b/collect-library/libs/armeabi-v7a/libSetWakeupJni.so differ
diff --git a/collect-library/libs/armeabi-v7a/libejTTS.so b/collect-library/libs/armeabi-v7a/libejTTS.so
new file mode 100644
index 00000000..9575bccc
Binary files /dev/null and b/collect-library/libs/armeabi-v7a/libejTTS.so differ
diff --git a/collect-library/libs/armeabi-v7a/libgnustl_shared.so b/collect-library/libs/armeabi-v7a/libgnustl_shared.so
new file mode 100644
index 00000000..96c22a25
Binary files /dev/null and b/collect-library/libs/armeabi-v7a/libgnustl_shared.so differ
diff --git a/collect-library/libs/armeabi-v7a/libiomx-gingerbread.so b/collect-library/libs/armeabi-v7a/libiomx-gingerbread.so
new file mode 100644
index 00000000..6665608d
Binary files /dev/null and b/collect-library/libs/armeabi-v7a/libiomx-gingerbread.so differ
diff --git a/collect-library/libs/armeabi-v7a/libiomx-hc.so b/collect-library/libs/armeabi-v7a/libiomx-hc.so
new file mode 100644
index 00000000..77f02566
Binary files /dev/null and b/collect-library/libs/armeabi-v7a/libiomx-hc.so differ
diff --git a/collect-library/libs/armeabi-v7a/libiomx-ics.so b/collect-library/libs/armeabi-v7a/libiomx-ics.so
new file mode 100644
index 00000000..8b534a94
Binary files /dev/null and b/collect-library/libs/armeabi-v7a/libiomx-ics.so differ
diff --git a/collect-library/libs/armeabi-v7a/libsimpleconfiglib.so b/collect-library/libs/armeabi-v7a/libsimpleconfiglib.so
new file mode 100644
index 00000000..ac2258c6
Binary files /dev/null and b/collect-library/libs/armeabi-v7a/libsimpleconfiglib.so differ
diff --git a/collect-library/libs/armeabi-v7a/libtiny_magic.so b/collect-library/libs/armeabi-v7a/libtiny_magic.so
new file mode 100644
index 00000000..d9e77292
Binary files /dev/null and b/collect-library/libs/armeabi-v7a/libtiny_magic.so differ
diff --git a/collect-library/libs/armeabi-v7a/libvlcjni.so b/collect-library/libs/armeabi-v7a/libvlcjni.so
new file mode 100644
index 00000000..37d9ae53
Binary files /dev/null and b/collect-library/libs/armeabi-v7a/libvlcjni.so differ
diff --git a/collect-library/libs/armeabi/libAsr2Code.so b/collect-library/libs/armeabi/libAsr2Code.so
new file mode 100644
index 00000000..fa01878c
Binary files /dev/null and b/collect-library/libs/armeabi/libAsr2Code.so differ
diff --git a/collect-library/libs/armeabi/libBugly.so b/collect-library/libs/armeabi/libBugly.so
new file mode 100644
index 00000000..2dc98ed3
Binary files /dev/null and b/collect-library/libs/armeabi/libBugly.so differ
diff --git a/collect-library/libs/armeabi/libDecode.so b/collect-library/libs/armeabi/libDecode.so
new file mode 100644
index 00000000..8efb1d5f
Binary files /dev/null and b/collect-library/libs/armeabi/libDecode.so differ
diff --git a/collect-library/libs/armeabi/libNuanceVocalizer.so b/collect-library/libs/armeabi/libNuanceVocalizer.so
new file mode 100644
index 00000000..2791e318
Binary files /dev/null and b/collect-library/libs/armeabi/libNuanceVocalizer.so differ
diff --git a/collect-library/libs/armeabi/libSetWakeupJni.so b/collect-library/libs/armeabi/libSetWakeupJni.so
new file mode 100644
index 00000000..93811097
Binary files /dev/null and b/collect-library/libs/armeabi/libSetWakeupJni.so differ
diff --git a/collect-library/libs/armeabi/libejTTS.so b/collect-library/libs/armeabi/libejTTS.so
new file mode 100644
index 00000000..9575bccc
Binary files /dev/null and b/collect-library/libs/armeabi/libejTTS.so differ
diff --git a/collect-library/libs/armeabi/libgnustl_shared.so b/collect-library/libs/armeabi/libgnustl_shared.so
new file mode 100644
index 00000000..5cf6d20f
Binary files /dev/null and b/collect-library/libs/armeabi/libgnustl_shared.so differ
diff --git a/collect-library/libs/armeabi/libiomx-gingerbread.so b/collect-library/libs/armeabi/libiomx-gingerbread.so
new file mode 100644
index 00000000..6665608d
Binary files /dev/null and b/collect-library/libs/armeabi/libiomx-gingerbread.so differ
diff --git a/collect-library/libs/armeabi/libiomx-hc.so b/collect-library/libs/armeabi/libiomx-hc.so
new file mode 100644
index 00000000..77f02566
Binary files /dev/null and b/collect-library/libs/armeabi/libiomx-hc.so differ
diff --git a/collect-library/libs/armeabi/libiomx-ics.so b/collect-library/libs/armeabi/libiomx-ics.so
new file mode 100644
index 00000000..8b534a94
Binary files /dev/null and b/collect-library/libs/armeabi/libiomx-ics.so differ
diff --git a/collect-library/libs/armeabi/libsimpleconfiglib.so b/collect-library/libs/armeabi/libsimpleconfiglib.so
new file mode 100644
index 00000000..71a782db
Binary files /dev/null and b/collect-library/libs/armeabi/libsimpleconfiglib.so differ
diff --git a/collect-library/libs/armeabi/libtiny_magic.so b/collect-library/libs/armeabi/libtiny_magic.so
new file mode 100644
index 00000000..d41e0a4c
Binary files /dev/null and b/collect-library/libs/armeabi/libtiny_magic.so differ
diff --git a/collect-library/libs/armeabi/libvlcjni.so b/collect-library/libs/armeabi/libvlcjni.so
new file mode 100644
index 00000000..37d9ae53
Binary files /dev/null and b/collect-library/libs/armeabi/libvlcjni.so differ
diff --git a/collect-library/libs/commons-lang3-3.3.2.jar b/collect-library/libs/commons-lang3-3.3.2.jar
new file mode 100644
index 00000000..bb069797
Binary files /dev/null and b/collect-library/libs/commons-lang3-3.3.2.jar differ
diff --git a/collect-library/libs/commons-net-3.3.jar b/collect-library/libs/commons-net-3.3.jar
new file mode 100644
index 00000000..f4f19a90
Binary files /dev/null and b/collect-library/libs/commons-net-3.3.jar differ
diff --git a/collect-library/src/main/AndroidManifest.xml b/collect-library/src/main/AndroidManifest.xml
index 5f8fe9fa..476a70ac 100644
--- a/collect-library/src/main/AndroidManifest.xml
+++ b/collect-library/src/main/AndroidManifest.xml
@@ -14,8 +14,7 @@
android:value="IxQi4mZGTlfv6Z9M2GRdqn4KKRbOATUU" />
+ android:networkSecurityConfig="@xml/network_security_config">
\ No newline at end of file
diff --git a/collect-library/src/main/java/com/navinfo/collect/library/data/NavinfoPbfData.java b/collect-library/src/main/java/com/navinfo/collect/library/data/NavinfoPbfData.java
index 6461d04c..31766754 100644
--- a/collect-library/src/main/java/com/navinfo/collect/library/data/NavinfoPbfData.java
+++ b/collect-library/src/main/java/com/navinfo/collect/library/data/NavinfoPbfData.java
@@ -4,7 +4,6 @@ import com.google.protobuf.Descriptors;
import com.google.protobuf.GeneratedMessageV3;
import com.navinfo.collect.library.data.entity.GeometryFeatureEntity;
import com.navinfo.onemap.det.sdkpbf.proto.crowdsource.Resultdata;
-
import org.locationtech.jts.geom.Coordinate;
import org.locationtech.jts.geom.CoordinateXYM;
import org.locationtech.jts.geom.CoordinateXYZM;
diff --git a/collect-library/src/main/java/com/navinfo/collect/library/garminvirbxe/CameraEventListener.java b/collect-library/src/main/java/com/navinfo/collect/library/garminvirbxe/CameraEventListener.java
new file mode 100644
index 00000000..bf59c5eb
--- /dev/null
+++ b/collect-library/src/main/java/com/navinfo/collect/library/garminvirbxe/CameraEventListener.java
@@ -0,0 +1,102 @@
+package com.navinfo.collect.library.garminvirbxe;
+
+import android.graphics.Bitmap;
+import com.android.volley.VolleyError;
+import java.util.ArrayList;
+import com.navinfo.collect.library.sensor.SensorEventListener;
+import com.navinfo.collect.library.sensor.ISensor.enmConnectionStatus;
+
+/**
+ * @author dongpuxiao
+ * @version V1.0
+ * @ClassName: CameraEventListener.java
+ * @Date 2017年8月22日 下午2:24:43
+ * @Description: 相机操作接口定义
+ */
+public interface CameraEventListener extends SensorEventListener{
+ /**
+ *拍照成功
+ *
+ * @return
+ */
+ public void OnSnapPictureResponse(HostBean hostBean, Bitmap bitmap, String picName, int tag);
+
+ /** 错误 */
+ public void requestError(HostBean hostBean, VolleyError e, CameraGarminVirbXE.enmCommandType commandType, int tag);
+
+ /**
+ * 开始自动拍照回调
+ */
+ public void OnStartRecordResponse(HostBean hostBean, int tag);
+
+ /**
+ * 停止自动拍照回调
+ */
+ public void OnStopRecordResponse(HostBean hostBean, int tag);
+
+ /**
+ * 停止自动拍照回调
+ */
+ public void OnStatusResponse(HostBean hostBean, int tag);
+
+ /**
+ * 局域网搜索相机完成回调
+ * @param tag
+ * @param scanIpList
+ */
+ public void OnSearchResponse(int tag,ArrayList scanIpList);
+
+ /**
+ * 状态发生改变时候回调
+ * @param connectStatus
+ */
+ public void OnConnectStatusChanged(HostBean hostBean, enmConnectionStatus connectStatus, int tag);
+
+
+ /**
+ * 返回是否有gps信息
+ * @param status
+ */
+ public void OnGetGpsStatusResponse(HostBean hostBean, boolean status, int tag);
+
+ /**
+ * 状态发生改变时候回调
+ * @param hostBean 相机
+ * @param cs
+ */
+ public void OnConnectionStatusChanged(HostBean hostBean, enmConnectionStatus cs, int tag);
+
+
+ /**
+ * 设置自动拍照为1s
+ */
+ public void OnContinuousPhototTimeLapseRateResponse(HostBean hostBean, int tag);
+
+ /**
+ * 启动自动拍照
+ */
+ public void OnContinuousPhototTimeLapseRateStartResponse(HostBean hostBean, int tag);
+
+ /**
+ * 启动自动拍照
+ */
+ public void OnContinuousPhototTimeLapseRateStopResponse(HostBean hostBean, int tag);
+
+ /**
+ * 单拍照
+ */
+ public void OnContinuousPhototSingle(HostBean hostBean, String url, String name, int tag);
+
+ /**
+ * 获取多媒体信息
+ *
+ */
+ public void OnGetMediaList(HostBean hostBean, String json, int tag);
+
+ /**
+ * 返回设备id
+ * @param devicesId
+ */
+ public void OnGetDeviceInfo(HostBean hostBean,String devicesId,int tag);
+}
+
diff --git a/collect-library/src/main/java/com/navinfo/collect/library/garminvirbxe/CameraGarminVirbXE.java b/collect-library/src/main/java/com/navinfo/collect/library/garminvirbxe/CameraGarminVirbXE.java
new file mode 100644
index 00000000..b1b5eda5
--- /dev/null
+++ b/collect-library/src/main/java/com/navinfo/collect/library/garminvirbxe/CameraGarminVirbXE.java
@@ -0,0 +1,442 @@
+package com.navinfo.collect.library.garminvirbxe;
+
+import android.content.Context;
+import android.location.Location;
+import android.os.Handler;
+import android.os.Message;
+import android.util.Log;
+import org.json.JSONException;
+import java.text.SimpleDateFormat;
+import java.util.Calendar;
+import java.util.Date;
+import com.navinfo.collect.library.sensor.Camera;
+import com.navinfo.collect.library.sensor.SensorEventListener;
+import com.navinfo.collect.library.utils.SensorUtils;
+
+public class CameraGarminVirbXE extends Camera /*implements LocationCallBack*/ {
+
+ private Command conmand;
+ private boolean bSnapPicProgress = false; // 每秒自动拍照标示
+ private boolean bMonitoring = false; //
+ private final Context mContext;
+ SensorWorkingMode mSensorWorkingMode;
+ private CameraEventListener cameraEventListener;
+ private WifiDiscovery mDiscoveryTask;
+ private static String mSavePath; // 保存照片路径
+ private enmConnectionStatus emuConnectionStatus;
+ private SimpleDateFormat formatter;
+ private long gpstime = 0;
+ private long ntptime = 0;
+ //private MyLocationManager myLocation;
+ public static String mPicUuid;
+ private Calendar calendar = Calendar.getInstance();
+ private Calendar gpscalendar = Calendar.getInstance();
+ private HostBean mHostBean;
+ private int mTag;
+ private boolean mContinuousPhototTimeLapseRate;
+ private boolean mNTPTimeFlag;
+ private boolean mGoogleTimeFlag;
+
+ public enum enmCommandType {
+ COMMAND_CAMERA_SNAPPICTURE, COMMAND_CAMERA_RECORD, COMMAND_CAMERA_STOP_RECORD,COMMAND_CAMERA_MONITORING,COMMAND_CAMERA_GETSTATUS, COMMAND_CAMERA_GETDEVICESINFO, COMMAND_CAMERA_GETGPSSTATUS,COMMAND_CAMERA_LIVEPREVIEW,
+ COMMAND_UNKNOW,COMMAND_PHOTO_MODE,COMMAND_PHOTO_TIME_LASPE_RATE,COMMAND_PHOTO_TIME_LASPE_RATE_STOP,COMMAND_CAMERA_SNAPPICTURE_SINGLE/*单独拍照*/,COMMAND_CAMERA_MEDIA_LIST/*多媒体信息集合*/
+ }
+
+ public CameraGarminVirbXE(Context mcontext) {
+ super(mcontext);
+ this.mContext = mcontext;
+ conmand = new Command(mContext);
+ formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss:SSS");
+/* // 初始化google gps 定位
+ MyLocationManager.init(mContext, CameraGarminVirbXE.this);
+ myLocation = MyLocationManager.getInstance();*/
+ mNTPTimeFlag = true;
+ new Thread(mGetNtpTimeProgress).start();
+ }
+
+ @Override
+ public enmSensorType GetSensorType() {
+ return enmSensorType.SENSOR_CAMEAR;
+ }
+
+ @Override
+ public enmConnectionStatus GetConnectionStatus() {
+ return emuConnectionStatus;
+ }
+
+ public enmConnectionStatus Connect(HostBean hostBean, SensorParams params) {
+ try {
+ setmHostBean(hostBean);
+ conmand.SetHandle(mCameraHandler);
+ RequestApi.setApiIp(getmTag(),params.getParams().get("ip").toString());
+ emuConnectionStatus = enmConnectionStatus.CONNECTTING;
+ cameraEventListener.OnConnectionStatusChanged(hostBean,emuConnectionStatus,mTag);
+ conmand.getStatus(hostBean,getmTag());
+ } catch (JSONException e) {
+ e.printStackTrace();
+ }
+ return null;
+ }
+
+ @Override
+ public enmConnectionStatus DisConnect() {
+ emuConnectionStatus = enmConnectionStatus.DISCONNECTTED;
+ return null;
+ }
+
+ @Override
+ public enmSignalQuality GetSignalQuality() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ @Override
+ public void GetGpsStatus() {
+ conmand.getGpsStatus(getmHostBean(),getmTag());
+ }
+
+ @Override
+ public void snapPicture(String picuuid) {
+ CameraGarminVirbXE.mPicUuid = picuuid;
+ if (mSensorWorkingMode == SensorWorkingMode.CAMEAR_VEDIO_720P
+ || mSensorWorkingMode == SensorWorkingMode.CAMERA_VEDIO_1080P
+ || mSensorWorkingMode == SensorWorkingMode.CAMERA_VEDIO_TIMELAPSE) {
+ if(getGoogleGpsTime() != 0) {
+ cameraEventListener.OnSnapPictureResponse(getmHostBean(),null, formatter.format(new Date(getGoogleGpsTime())),getmTag());
+ }
+ else
+ cameraEventListener.OnSnapPictureResponse(getmHostBean(),null,
+ formatter.format(new Date(System.currentTimeMillis())),getmTag());
+ }else if(mSensorWorkingMode==SensorWorkingMode.CAMERA_PHOTO_SINGLE){//单拍流程,时间校验使用
+ conmand.snapSinglePicture(getmHostBean(),getmTag());
+ } else {
+ if (bSnapPicProgress) { // 代表一秒拍照线程开启
+ Log.e("CamerGarminVirb", "直接取路径");
+ conmand.getBitmapByUrl(getmHostBean(),getmTag());
+ } else {
+ Log.e("CamerGarminVirb", "拍照进行取路径");
+ conmand.snapPicture(getmHostBean(),true,getmTag());
+ }
+ }
+ }
+
+ @Override
+ public void StartRecording() {
+ if (mSensorWorkingMode == SensorWorkingMode.CAMEAR_PHOTO_12MP
+ || mSensorWorkingMode == SensorWorkingMode.CAMEAR_PHOTO_7MP) {
+ if (!bSnapPicProgress) {
+ mSnapPicProgress.run();
+ bSnapPicProgress = true;
+ if(cameraEventListener != null)
+ cameraEventListener.OnStartRecordResponse(getmHostBean(),getmTag());
+ }
+ } else if (mSensorWorkingMode == SensorWorkingMode.CAMEAR_VEDIO_720P
+ || mSensorWorkingMode == SensorWorkingMode.CAMERA_VEDIO_1080P
+ || mSensorWorkingMode == SensorWorkingMode.CAMERA_VEDIO_TIMELAPSE) {
+ conmand.StartRecording(getmHostBean(),getmTag());
+ bMonitoring = true;
+ mCameraHandler.postDelayed(mGetStatusProgress, 5000/*调大值域,对应录像命令处理结束后再执行*/);
+ } else if(mSensorWorkingMode == SensorWorkingMode.CAMEAR_PHOTO_CONTINUOUS_PHOTO){
+ // 其他模式下干其他事情
+ //conmand.snapPicture(getmHostBean(),false,getmTag());
+ //优先设置缩时时间为1s
+ if(!mContinuousPhototTimeLapseRate){
+ conmand.setContinuousPhototTimeLapseRate(getmHostBean(),getmTag());
+ mContinuousPhototTimeLapseRate = true;
+ }
+ else {
+ conmand.snapPicture(getmHostBean(),false,getmTag());
+ bMonitoring = true;
+ mCameraHandler.postDelayed(mGetStatusProgress, 5000/*调大值域,对应录像命令处理结束后再执行*/);
+ }
+ }
+ }
+
+ @Override
+ public void StopRecording() {
+ if (mSensorWorkingMode == SensorWorkingMode.CAMEAR_PHOTO_12MP
+ || mSensorWorkingMode == SensorWorkingMode.CAMEAR_PHOTO_7MP) {
+ mCameraHandler.removeCallbacks(mSnapPicProgress);
+ if(cameraEventListener != null)
+ cameraEventListener.OnStopRecordResponse(getmHostBean(),getmTag());
+ bSnapPicProgress = false;
+ } else if (mSensorWorkingMode == SensorWorkingMode.CAMEAR_VEDIO_720P
+ || mSensorWorkingMode == SensorWorkingMode.CAMERA_VEDIO_1080P
+ || mSensorWorkingMode == SensorWorkingMode.CAMERA_VEDIO_TIMELAPSE) {
+ conmand.StopRecording(getmHostBean(),getmTag());
+ mCameraHandler.removeCallbacks(mGetStatusProgress);
+ bMonitoring = false;
+ } else if(mSensorWorkingMode == SensorWorkingMode.CAMEAR_PHOTO_CONTINUOUS_PHOTO){
+ mContinuousPhototTimeLapseRate = false;
+ conmand.stopContinuousPhototTimeLapseRate(getmHostBean(),getmTag());
+ mCameraHandler.removeCallbacks(mGetStatusProgress);
+ bMonitoring = false;
+ }
+ }
+
+
+ @Override
+ public void Search(boolean isReadCache) {
+
+ //先停止当前搜索
+ StopSearch();
+
+ mDiscoveryTask = new WifiDiscovery(mContext, cameraEventListener,isReadCache);
+ mDiscoveryTask.setTag(getmTag());
+ mDiscoveryTask.execute();
+
+ }
+
+ @Override
+ public void StopSearch() {
+ if(mDiscoveryTask!=null){
+
+ if(!mDiscoveryTask.isCancelled()){
+
+ boolean result = mDiscoveryTask.cancel(true);
+
+ Log.e("StopSearch",result+"===");
+ }
+
+ mDiscoveryTask = null;
+ }
+ }
+
+ @Override
+ public int RegisterSensorEvent(SensorEventListener sensorEventLister) {
+ cameraEventListener = (CameraEventListener) sensorEventLister;
+ return conmand.RegisterSensorEvent(cameraEventListener);
+ }
+
+ @Override
+ public void SetMode(SensorWorkingMode sensorWorkingMode) {
+ mSensorWorkingMode = sensorWorkingMode;
+ if (sensorWorkingMode == SensorWorkingMode.CAMERA_VEDIO_TIMELAPSE){
+
+ /*外业需求变更,不在强制设置缩时模式,有作业员自己设置相机*///conmand.setTimeLapse(getmHostBean(),getmTag());
+ }
+ else if(sensorWorkingMode==SensorWorkingMode.CAMEAR_PHOTO_CONTINUOUS_PHOTO){
+ conmand.setContinuousPhoto(getmHostBean(),getmTag());
+ }else if(sensorWorkingMode==SensorWorkingMode.CAMERA_PHOTO_SINGLE){
+ conmand.setContinuousPhotoSingle(getmHostBean(),getmTag());
+ }
+ }
+
+ //获取指定目录多媒体信息
+ public void mediaList(String path){
+ conmand.mediaList(getmHostBean(),getmTag(),path);
+ }
+
+
+ //获取相机模式
+ public SensorWorkingMode GetMode() {
+ return mSensorWorkingMode;
+ }
+
+ // 每隔30s进行一次获取连接
+ private Runnable mGetStatusProgress = new Runnable() {
+
+ @Override
+ public void run() {
+ /*if(1==1)
+ return;*/
+ conmand.getMonitoringStatus(getmHostBean(),getmTag());
+ if(bMonitoring)
+ mCameraHandler.postDelayed(mGetStatusProgress, 1000*30l/*降低频率,解决机器性能下降导致命令无效*/);
+ }
+ };
+
+ // 每隔1000s进行一次拍照
+ private Runnable mSnapPicProgress = new Runnable() {
+
+ @Override
+ public void run() {
+ conmand.snapPicture(getmHostBean(),false,getmTag());
+ }
+ };
+
+ //停止时间线程
+ public void stopTimeThread(){
+ mGoogleTimeFlag = false;
+ mNTPTimeFlag = false;
+ ntptime = 0;
+ gpstime = 0;
+ }
+
+ private Runnable mGetNtpTimeProgress = new Runnable() {
+
+ @Override
+ public void run() {
+ while (mNTPTimeFlag) {
+ if (SensorUtils.isNetworkAvailable(mContext)) {
+ Date dateNTP = SensorUtils.syncNow();
+ if (dateNTP != null) {
+ ntptime = dateNTP.getTime();
+ calendar.setTime(dateNTP);
+ //Log.e("AAA", "ntp time :" + DateUtils.formatTime(dateNTP));
+ mNTPTimeFlag = false;
+ mGoogleTimeFlag = true;
+ //获取NTP时间后开始启动计时线程
+ new Thread(mNtpClockTimeProgress).start();
+ new Thread(mGpsClockTimeProgress).start();
+ }
+ }
+ //30秒执行一次,降低频率,节省电量
+ try{
+ Thread.sleep(30000);
+ }catch (Exception e){
+
+ }
+
+ }
+ }
+ };
+
+ /**
+ * 计时器
+ */
+ private Runnable mNtpClockTimeProgress = new Runnable() {
+
+ @Override
+ public void run() {
+ while (mGoogleTimeFlag) {
+ if(ntptime != 0) {
+ int second = calendar.get(Calendar.SECOND);
+ second += 1;
+ calendar.set(Calendar.SECOND, second);
+ try {
+ Thread.sleep(1000);
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ }else{
+ try{
+ Thread.sleep(1);
+ }catch (Exception e){
+
+ }
+ }
+ }
+ }
+ };
+
+ /**
+ * 计时器
+ */
+ private Runnable mGpsClockTimeProgress = new Runnable() {
+
+ @Override
+ public void run() {
+ while (mGoogleTimeFlag) {
+ if(gpstime != 0) {
+ int second = gpscalendar.get(Calendar.SECOND);
+ second += 1;
+ gpscalendar.set(Calendar.SECOND, second);
+ try {
+ Thread.sleep(1000);
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ }else{
+ try{
+ Thread.sleep(1);
+ }catch (Exception e){
+
+ }
+ }
+ }
+ }
+ };
+
+ private Handler mCameraHandler = new Handler() {
+ @Override
+ public void handleMessage(Message msg) {
+ switch (msg.what) {
+ case SensorUtils.HADNLE_CONNECT_OK:
+ emuConnectionStatus = enmConnectionStatus.CONNECTTED;
+ cameraEventListener
+ .OnConnectionStatusChanged(getmHostBean(),emuConnectionStatus,getmTag());
+ break;
+ case SensorUtils.HADNLE_CONNECT_FAIL:
+ Log.e("AAA", "断开连接~~~~~~~~~~");
+ emuConnectionStatus = enmConnectionStatus.DISCONNECTTED;
+ cameraEventListener
+ .OnConnectionStatusChanged(getmHostBean(),emuConnectionStatus,getmTag());
+ break;
+ case SensorUtils.HADNLE_SNAPPICTURE:// 定时拍照返回
+ if (bSnapPicProgress)
+ mCameraHandler.post(mSnapPicProgress);
+ case SensorUtils.HADNLE_MONITORING:
+ Log.e("AAA", "状态监测中....");
+
+ break;
+ default:
+ break;
+ }
+ }
+ };
+
+ /**
+ * 设置照片保存路径
+ *
+ * @param savePath
+ */
+ public void SetCameraPictureSavaPath(String savePath) {
+ mSavePath = savePath;
+ }
+
+ //获取google定位时间
+ public Long getGoogleGpsTime() {
+ long time = 0;
+ if (ntptime != 0) {
+ time = calendar.getTime().getTime();
+ return time;
+ } else {
+ if(gpstime != 0 )
+ time = gpscalendar.getTime().getTime();
+ return time;
+ }
+ }
+
+ /**
+ * 获取照片保存路径
+ *
+ * @return
+ */
+ public static String getCameraPcitureSavePath() {
+ if ("".equals(mSavePath) || null == mSavePath)
+ return SensorUtils.STR_CAMERA_PICTURE_SAVEPATH;
+ else
+ return mSavePath;
+ }
+
+/* @Override
+ public void onCurrentLocation(Location location) {
+ if(location != null) {
+ Log.e("AAA", "onCurrentLocation");
+ gpstime = location.getTime();
+ gpscalendar.setTime(new Date(gpstime));
+ }
+ else
+ gpstime = 0;
+
+ if (myLocation != null)
+ myLocation.destoryLocationManager();
+ }*/
+
+ public HostBean getmHostBean() {
+ return mHostBean;
+ }
+
+ public void setmHostBean(HostBean mHostBean) {
+ this.mHostBean = mHostBean;
+ }
+
+ public int getmTag() {
+ return mTag;
+ }
+
+ public void setmTag(int mTag) {
+ this.mTag = mTag;
+ }
+}
diff --git a/collect-library/src/main/java/com/navinfo/collect/library/garminvirbxe/Command.java b/collect-library/src/main/java/com/navinfo/collect/library/garminvirbxe/Command.java
new file mode 100644
index 00000000..9af8f772
--- /dev/null
+++ b/collect-library/src/main/java/com/navinfo/collect/library/garminvirbxe/Command.java
@@ -0,0 +1,224 @@
+package com.navinfo.collect.library.garminvirbxe;
+
+import android.content.Context;
+import android.graphics.Bitmap;
+import android.os.Handler;
+
+import com.navinfo.collect.library.utils.PreferencesUtils;
+
+public class Command {
+
+ private Context mContext;
+ private static CameraEventListener cameraEventListener;
+ String mPicUrl; // 返回照片的uri
+ Bitmap mBitmap;
+ private RequestManager requestManager;
+ private Handler mHandle;
+ public static Boolean createBitmap = false; // 是否生成bitmap
+
+ public Command(Context mContext) {
+ this.mContext = mContext;
+ requestManager = new RequestManager(mContext);
+ }
+
+ public void SetHandle(Handler mHandle){
+ this.mHandle = mHandle;
+ requestManager.SetRequestHandle(mHandle);
+ }
+
+ /**
+ * 拍照命令 返回照片
+ */
+ public void snapPicture(HostBean hostBean,Boolean createBitmap,int tag) {
+ SensorParams params = new SensorParams();
+ params.put("command", "snapPicture");
+ sendConmand(params, false, com.navinfo.collect.library.garminvirbxe.CameraGarminVirbXE.enmCommandType.COMMAND_CAMERA_SNAPPICTURE,hostBean,tag);
+ Command.createBitmap = createBitmap;
+ }
+
+ /**
+ * 单拍照拍照命令 返回照片
+ */
+ public void snapSinglePicture(HostBean hostBean,int tag) {
+ SensorParams params = new SensorParams();
+ params.put("command", "snapPicture");
+ sendConmand(params, false, com.navinfo.collect.library.garminvirbxe.CameraGarminVirbXE.enmCommandType.COMMAND_CAMERA_SNAPPICTURE_SINGLE,hostBean,tag);
+ }
+
+ /**
+ * 获取指定目录多媒体信息
+ */
+ public void mediaList(HostBean hostBean,int tag,String path) {
+ SensorParams params = new SensorParams();
+ params.put("command", "mediaList");
+ params.put("path",path+"");
+ sendConmand(params, false, com.navinfo.collect.library.garminvirbxe.CameraGarminVirbXE.enmCommandType.COMMAND_CAMERA_MEDIA_LIST,hostBean,tag);
+ }
+
+
+ /**
+ * 获取相机状态
+ */
+ public void getStatus(HostBean hostBean,int tag) {
+ SensorParams params = new SensorParams();
+ params.put("command", "status");
+ sendConmand(params, false, com.navinfo.collect.library.garminvirbxe.CameraGarminVirbXE.enmCommandType.COMMAND_CAMERA_GETSTATUS,hostBean,tag);
+ }
+
+ /**
+ * (主要用于测试请求)
+ */
+ public void getWifiTestStatus(HostBean hostBean,int tag) {
+ SensorParams params = new SensorParams();
+ //params.put("command", "status");解决相机性能下降后获取status慢问题
+ params.put("command", "deviceInfo");
+ sendConmandWifi(params, true, com.navinfo.collect.library.garminvirbxe.CameraGarminVirbXE.enmCommandType.COMMAND_CAMERA_GETSTATUS,hostBean,tag);
+ }
+
+ /**
+ * (主要用于监控状态请求)
+ */
+ public void getMonitoringStatus(HostBean hostBean,int tag) {
+ SensorParams params = new SensorParams();
+ params.put("command", "deviceInfo");//解决相机性能下降后获取status慢问题
+ //测试代码
+ //params.put("command", "mediaList");
+ //D:/DCIM/797_VIRB/VIRB0110.jpg
+ //..\/DCIM\/797_VIRB\/VIRB0110.jpg
+ //D:/DCIM/797_VIRB/VIRB0110
+ //params.put("path",RequestApi.getApiMediaUri(tag)+"/media/photo/DCIM/797_VIRB/VIRB0110.jpg");
+ //params.put("path","D:/DCIM/797_VIRB/");
+ sendConmand(params, false, com.navinfo.collect.library.garminvirbxe.CameraGarminVirbXE.enmCommandType.COMMAND_CAMERA_MONITORING,hostBean,tag);
+ }
+
+ /**
+ * 获取设备信息
+ */
+ public void getDeviceInfo(HostBean hostBean,int tag) {
+ SensorParams params = new SensorParams();
+ params.put("command", "deviceInfo");
+ sendConmand(params, false, com.navinfo.collect.library.garminvirbxe.CameraGarminVirbXE.enmCommandType.COMMAND_CAMERA_GETDEVICESINFO,hostBean,tag);
+ }
+
+ /**
+ * 获取gps是否连接
+ */
+ public void getGpsStatus(HostBean hostBean,int tag) {
+ SensorParams params = new SensorParams();
+ params.put("command", "status");
+ sendConmand(params, false, com.navinfo.collect.library.garminvirbxe.CameraGarminVirbXE.enmCommandType.COMMAND_CAMERA_GETGPSSTATUS,hostBean,tag);
+ }
+
+ /**
+ * 设置缩时模式
+ */
+ public void setTimeLapse(HostBean hostBean,int tag){
+ SensorParams params = new SensorParams();
+ params.put("command", "updateFeature");
+ params.put("feature", "videoMode");
+ params.put("value", "缩时");
+ sendConmand(params, false, com.navinfo.collect.library.garminvirbxe.CameraGarminVirbXE.enmCommandType.COMMAND_UNKNOW,hostBean,tag);
+ }
+
+ /**
+ * 停止录像
+ */
+ public void StopRecording(HostBean hostBean,int tag) {
+ SensorParams params = new SensorParams();
+ params.put("command", "stopRecording");
+ sendConmand(params, false, com.navinfo.collect.library.garminvirbxe.CameraGarminVirbXE.enmCommandType.COMMAND_CAMERA_STOP_RECORD,hostBean,tag);
+ }
+
+ /**
+ * 开始录像
+ */
+ public void StartRecording(HostBean hostBean,int tag) {
+ SensorParams params = new SensorParams();
+ params.put("command", "startRecording");
+ sendConmand(params, false, com.navinfo.collect.library.garminvirbxe.CameraGarminVirbXE.enmCommandType.COMMAND_CAMERA_RECORD,hostBean,tag);
+ }
+
+ /**
+ * 设置连续拍照模式
+ */
+ public void setContinuousPhoto(HostBean hostBean,int tag){
+ SensorParams params = new SensorParams();
+ params.put("command", "updateFeature");
+ params.put("feature", "photoMode");
+ params.put("value", "Timelapse");
+ sendConmand(params, false, com.navinfo.collect.library.garminvirbxe.CameraGarminVirbXE.enmCommandType.COMMAND_PHOTO_MODE,hostBean,tag);
+ }
+
+ /**
+ * 设置单拍照模式
+ */
+ public void setContinuousPhotoSingle(HostBean hostBean,int tag){
+ SensorParams params = new SensorParams();
+ params.put("command", "updateFeature");
+ params.put("feature", "photoMode");
+ params.put("value", "Single");
+ sendConmand(params, false, com.navinfo.collect.library.garminvirbxe.CameraGarminVirbXE.enmCommandType.COMMAND_PHOTO_MODE,hostBean,tag);
+ }
+
+
+ public void setContinuousPhototTimeLapseRate(HostBean hostBean,int tag){
+ SensorParams params = new SensorParams();
+ params.put("command", "updateFeature");
+ params.put("feature", "photoTimeLapseRate");
+ params.put("value", "1s");
+ sendConmand(params, false, com.navinfo.collect.library.garminvirbxe.CameraGarminVirbXE.enmCommandType.COMMAND_PHOTO_TIME_LASPE_RATE,hostBean,tag);
+ }
+
+ /**
+ * 停止连拍
+ */
+ public void stopContinuousPhototTimeLapseRate(HostBean hostBean,int tag){
+ SensorParams params = new SensorParams();
+ params.put("command", "stopStillRecording");
+ sendConmand(params, false, com.navinfo.collect.library.garminvirbxe.CameraGarminVirbXE.enmCommandType.COMMAND_PHOTO_TIME_LASPE_RATE_STOP,hostBean,tag);
+ }
+
+ public int RegisterSensorEvent(CameraEventListener cameraEventListener) {
+ Command.cameraEventListener = cameraEventListener;
+ return 0;
+ }
+
+ /**
+ * 发送命令
+ *
+ * @param params
+ * isDebug 参数用来测试,当测试连接时候,需要将超时时间该短,普通拍照请求超时时间设长
+ * * @param tag
+ * @return
+ */
+ public void sendConmand(SensorParams params, Boolean isDebug,
+ com.navinfo.collect.library.garminvirbxe.CameraGarminVirbXE.enmCommandType type,HostBean hostBean,int tag) {
+ IRequest.post(mContext, RequestApi.getApiUri(tag), params, isDebug,
+ cameraEventListener, type,hostBean,tag);
+ }
+
+ /**
+ * 发送命令
+ *
+ * @param params
+ * isDebug 参数用来测试,当测试连接时候,需要将超时时间该短,普通拍照请求超时时间设长
+ * * @param tag
+ * @return
+ */
+ public void sendConmandWifi(SensorParams params, Boolean isDebug,
+ com.navinfo.collect.library.garminvirbxe.CameraGarminVirbXE.enmCommandType type,HostBean hostBean,int tag) {
+ IRequest.post(mContext, RequestApi.getApiWifiIp(), params, isDebug,
+ cameraEventListener, type,hostBean,tag);
+ }
+
+ /**
+ *
+ * @param hostBean
+ * * @param tag
+ */
+ public void getBitmapByUrl(HostBean hostBean,int tag) {
+ String path = PreferencesUtils.getSpText(mContext, "pictureUri");
+ IRequest.getbitmap(mContext, hostBean,path, false, cameraEventListener,tag);
+ }
+
+}
diff --git a/collect-library/src/main/java/com/navinfo/collect/library/garminvirbxe/HostBean.java b/collect-library/src/main/java/com/navinfo/collect/library/garminvirbxe/HostBean.java
new file mode 100644
index 00000000..c77d04b8
--- /dev/null
+++ b/collect-library/src/main/java/com/navinfo/collect/library/garminvirbxe/HostBean.java
@@ -0,0 +1,107 @@
+package com.navinfo.collect.library.garminvirbxe;
+
+
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.util.Log;
+
+import com.navinfo.collect.library.utils.NetScanInfo;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+
+public class HostBean implements Parcelable {
+
+ public static final String PKG = "info.lamatricexiste.network";
+
+ public static final String EXTRA = PKG + ".extra";
+ public static final String EXTRA_POSITION = PKG + ".extra_position";
+ public static final String EXTRA_HOST = PKG + ".extra_host";
+ public static final String EXTRA_TIMEOUT = PKG + ".network.extra_timeout";
+ public static final String EXTRA_HOSTNAME = PKG + ".extra_hostname";
+ public static final String EXTRA_BANNERS = PKG + ".extra_banners";
+ public static final String EXTRA_PORTSO = PKG + ".extra_ports_o";
+ public static final String EXTRA_PORTSC = PKG + ".extra_ports_c";
+ public static final String EXTRA_SERVICES = PKG + ".extra_services";
+ public static final int TYPE_GATEWAY = 0;
+ public static final int TYPE_COMPUTER = 1;
+
+ public int deviceType = TYPE_COMPUTER;
+ public int isAlive = 1;
+ public int position = 0;
+ public int responseTime = 0; // ms
+ public String ipAddress = null;
+ public String hostname = null;
+ public String hardwareAddress = com.navinfo.collect.library.utils.NetScanInfo.NOMAC;
+ public String nicVendor = "Unknown";
+ public String os = "Unknown";
+ public HashMap services = null;
+ public HashMap banners = null;
+ public ArrayList portsOpen = null;
+ public ArrayList portsClosed = null;
+
+ public HostBean() {
+ // New object
+ }
+
+ public HostBean(Parcel in) {
+ // Object from parcel
+ readFromParcel(in);
+ }
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(Parcel dest, int flags) {
+ dest.writeInt(deviceType);
+ dest.writeInt(isAlive);
+ dest.writeString(ipAddress);
+ dest.writeString(hostname);
+ dest.writeString(hardwareAddress);
+ Log.e("AAA", "writeToParcelipAddress"+ipAddress);
+ Log.e("AAA", "writeToParcelhardwareAddress"+hardwareAddress);
+ dest.writeString(nicVendor);
+ dest.writeString(os);
+ dest.writeInt(responseTime);
+ dest.writeInt(position);
+ dest.writeMap(services);
+ dest.writeMap(banners);
+ dest.writeList(portsOpen);
+ dest.writeList(portsClosed);
+ }
+
+ @SuppressWarnings("unchecked")
+ private void readFromParcel(Parcel in) {
+ deviceType = in.readInt();
+ isAlive = in.readInt();
+ ipAddress = in.readString();
+ hostname = in.readString();
+ hardwareAddress = in.readString();
+ Log.e("AAA", "readFromParcelParcelipAddress"+ipAddress);
+ Log.e("AAA", "readFromParcelhardwareAddress"+hardwareAddress);
+ nicVendor = in.readString();
+ os = in.readString();
+ responseTime = in.readInt();
+ position = in.readInt();
+ services = in.readHashMap(null);
+ banners = in.readHashMap(null);
+ portsOpen = in.readArrayList(Integer.class.getClassLoader());
+ portsClosed = in.readArrayList(Integer.class.getClassLoader());
+ }
+
+ @SuppressWarnings("unchecked")
+ public static final Creator CREATOR = new Creator() {
+ @Override
+ public HostBean createFromParcel(Parcel in) {
+ return new HostBean(in);
+ }
+
+ @Override
+ public HostBean[] newArray(int size) {
+ return new HostBean[size];
+ }
+ };
+}
diff --git a/collect-library/src/main/java/com/navinfo/collect/library/garminvirbxe/IRequest.java b/collect-library/src/main/java/com/navinfo/collect/library/garminvirbxe/IRequest.java
new file mode 100644
index 00000000..950a2966
--- /dev/null
+++ b/collect-library/src/main/java/com/navinfo/collect/library/garminvirbxe/IRequest.java
@@ -0,0 +1,34 @@
+package com.navinfo.collect.library.garminvirbxe;
+
+import android.content.Context;
+
+public class IRequest {
+
+ /**
+ *
+ * @param context
+ * @param url
+ * @param params
+ * @param isDebug
+ * @param cmaeralistener
+ */
+ public static void post(Context context, String url, SensorParams params,
+ Boolean isDebug, CameraEventListener cmaeralistener,
+ com.navinfo.collect.library.garminvirbxe.CameraGarminVirbXE.enmCommandType type,HostBean hostBean,int tag) {
+ RequestManager
+ .post(url, context, params, isDebug, cmaeralistener, type,hostBean,tag);
+ }
+
+ /**
+ *
+ * @param context
+ * @param hostBean
+ * @param url
+ * @param isthumb
+ */
+ public static void getbitmap(Context context, HostBean hostBean,String url, Boolean isthumb,
+ CameraEventListener cameralistener,int tag) {
+ RequestManager.getbitmap(context, hostBean,url, isthumb, cameralistener,tag);
+ }
+
+}
\ No newline at end of file
diff --git a/collect-library/src/main/java/com/navinfo/collect/library/garminvirbxe/RateControl.java b/collect-library/src/main/java/com/navinfo/collect/library/garminvirbxe/RateControl.java
new file mode 100644
index 00000000..c4ab41ee
--- /dev/null
+++ b/collect-library/src/main/java/com/navinfo/collect/library/garminvirbxe/RateControl.java
@@ -0,0 +1,83 @@
+/*
+ * Copyright (C) 2009-2010 Aubort Jean-Baptiste (Rorist)
+ * Licensed under GNU's GPL 2, see README
+ */
+
+package com.navinfo.collect.library.garminvirbxe;
+
+import android.util.Log;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.net.InetAddress;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+public class RateControl {
+
+ private final String TAG = "RateControl";
+ private static final int BUF = 512;
+ private final int REACH_TIMEOUT = 5000;
+ private final String CMD = "/system/bin/ping -A -q -n -w 3 -W 2 -c 3 ";
+ private final String PTN = "^rtt min\\/avg\\/max\\/mdev = [0-9\\.]+\\/[0-9\\.]+\\/([0-9\\.]+)\\/[0-9\\.]+ ms.*";
+ private Pattern mPattern;
+ private String line;
+ public String indicator = null;
+ public int rate = 800; // Slow start
+
+ public RateControl() {
+ mPattern = Pattern.compile(PTN);
+ }
+
+ public void adaptRate() {
+ int response_time = 0;
+ if ((response_time = getAvgResponseTime(indicator)) > 0) {
+ if (response_time > 100) { // Most distanced hosts
+ rate = response_time * 5; // Minimum 500ms
+ } else {
+ rate = response_time * 10; // Maximum 1000ms
+ }
+ if (rate > REACH_TIMEOUT) {
+ rate = REACH_TIMEOUT;
+ }
+ }
+ }
+
+ private int getAvgResponseTime(String host) {
+ // TODO: Reduce allocation
+ BufferedReader reader = null;
+ Matcher matcher;
+ try {
+ final Process proc = Runtime.getRuntime().exec(CMD + host);
+ reader = new BufferedReader(new InputStreamReader(proc.getInputStream()), BUF);
+ while ((line = reader.readLine()) != null) {
+ matcher = mPattern.matcher(line);
+ if (matcher.matches()) {
+ reader.close();
+ return (int) Float.parseFloat(matcher.group(1));
+ }
+ }
+ reader.close();
+ } catch (Exception e) {
+ Log.e(TAG, "Can't use native ping: " + e.getMessage());
+ try {
+ final long start = System.nanoTime();
+ if (InetAddress.getByName(host).isReachable(REACH_TIMEOUT)) {
+ Log.i(TAG, "Using Java ICMP request instead ...");
+ return (int) ((System.nanoTime() - start) / 1000);
+ }
+ } catch (Exception e1) {
+ Log.e(TAG, e1.getMessage());
+ }
+ } finally {
+ try {
+ if (reader != null) {
+ reader.close();
+ }
+ } catch(IOException e){
+ }
+ }
+ return rate;
+ }
+}
diff --git a/collect-library/src/main/java/com/navinfo/collect/library/garminvirbxe/RequestApi.java b/collect-library/src/main/java/com/navinfo/collect/library/garminvirbxe/RequestApi.java
new file mode 100644
index 00000000..55c6fce7
--- /dev/null
+++ b/collect-library/src/main/java/com/navinfo/collect/library/garminvirbxe/RequestApi.java
@@ -0,0 +1,55 @@
+package com.navinfo.collect.library.garminvirbxe;
+
+import java.util.HashMap;
+
+/**
+ * @author dongpuxiao
+ * @version V1.0
+ * @ClassName: RequestApi
+ * @Date 2017/1/12
+ * @Description: ${TODO}(请求地址类)
+ */
+public class RequestApi {
+ // 该类用于管理http请求地址以及接口函数
+ private static String apiWifiIp;
+ //缓存多地址集合
+ private static HashMap hashMap = new HashMap();
+
+ // 获取测试服务器接口
+ public static String getApiUri(int key) {
+ String apiIp = hashMap.get(key);
+ if (apiIp == null || "".equals(apiIp))
+ return "http://192.168.0.1/virb";
+ else
+ return "http://"+apiIp+"/virb";
+
+ }
+
+ // 获取测试服务器接口
+ public static String getApiMediaUri(int key) {
+ String apiIp = hashMap.get(key);
+ if (apiIp == null || "".equals(apiIp))
+ return "http://192.168.0.1";
+ else
+ return "http://"+apiIp+"";
+
+ }
+
+ //设置地址ip
+ public static void setApiIp(int key,String ip) {
+ hashMap.put(key,ip);
+ }
+
+ //获取wifi测试地址ip
+ public static String getApiWifiIp() {
+ if (apiWifiIp == null || "".equals(apiWifiIp))
+ return "http://192.168.0.1/virb";
+ else
+ return "http://"+apiWifiIp+"/virb";
+ }
+
+ //设置wifi测试ip
+ public static void setApiWifiIp(String apiWifiIp) {
+ RequestApi.apiWifiIp = apiWifiIp;
+ }
+}
diff --git a/collect-library/src/main/java/com/navinfo/collect/library/garminvirbxe/RequestJsonListener.java b/collect-library/src/main/java/com/navinfo/collect/library/garminvirbxe/RequestJsonListener.java
new file mode 100644
index 00000000..2e684a09
--- /dev/null
+++ b/collect-library/src/main/java/com/navinfo/collect/library/garminvirbxe/RequestJsonListener.java
@@ -0,0 +1,17 @@
+package com.navinfo.collect.library.garminvirbxe;
+
+import com.android.volley.VolleyError;
+
+public interface RequestJsonListener {
+ /**
+ * 成功
+ *
+ * @param
+ */
+ public void requestSuccess(T result);
+
+ /**
+ * 错误
+ */
+ public void requestError(VolleyError e);
+}
diff --git a/collect-library/src/main/java/com/navinfo/collect/library/garminvirbxe/RequestListener.java b/collect-library/src/main/java/com/navinfo/collect/library/garminvirbxe/RequestListener.java
new file mode 100644
index 00000000..49da3756
--- /dev/null
+++ b/collect-library/src/main/java/com/navinfo/collect/library/garminvirbxe/RequestListener.java
@@ -0,0 +1,14 @@
+package com.navinfo.collect.library.garminvirbxe;
+
+import android.graphics.Bitmap;
+
+import com.android.volley.VolleyError;
+
+public interface RequestListener {
+
+ /** 成功 */
+ public void requestSuccess(Bitmap bitmap,String savePath);
+
+ /** 错误 */
+ public void requestError(VolleyError e);
+}
diff --git a/collect-library/src/main/java/com/navinfo/collect/library/garminvirbxe/RequestManager.java b/collect-library/src/main/java/com/navinfo/collect/library/garminvirbxe/RequestManager.java
new file mode 100644
index 00000000..e97f2a26
--- /dev/null
+++ b/collect-library/src/main/java/com/navinfo/collect/library/garminvirbxe/RequestManager.java
@@ -0,0 +1,326 @@
+package com.navinfo.collect.library.garminvirbxe;
+
+import android.annotation.SuppressLint;
+import android.content.Context;
+import android.graphics.Bitmap;
+import android.graphics.Bitmap.Config;
+import android.os.Handler;
+import android.util.Log;
+
+import com.android.volley.DefaultRetryPolicy;
+import com.android.volley.Request;
+import com.android.volley.RequestQueue;
+import com.android.volley.Response;
+import com.android.volley.Response.Listener;
+import com.android.volley.VolleyError;
+import com.android.volley.toolbox.ImageRequest;
+import com.android.volley.toolbox.JsonObjectRequest;
+import com.android.volley.toolbox.Volley;
+import com.navinfo.collect.library.utils.PreferencesUtils;
+import com.navinfo.collect.library.utils.SensorUtils;
+
+import org.json.JSONArray;
+import org.json.JSONException;
+import org.json.JSONObject;
+import java.io.File;
+import java.io.IOException;
+
+@SuppressLint("NewApi")
+public class RequestManager {
+ public static RequestQueue mRequestQueue;
+ private static Context mContext;
+ static String picThumbUrl;
+ private static String picUrl;
+ private static Handler mHandle;
+ private static int currentFailCount = 0; // 记录发送命令失败次数
+ private static int failCount = 3; // 记录发送命令失败次数
+
+ public RequestManager(Context mContext) {
+ mRequestQueue = Volley.newRequestQueue(mContext);
+ RequestManager.mContext = mContext;
+ }
+
+ public void SetRequestHandle(Handler mHandle) {
+ RequestManager.mHandle = mHandle;
+ }
+
+ public static void getbitmap(Object object, HostBean hostBean, String url, Boolean isThumb,
+ CameraEventListener listener, int tag) {
+ ImageRequest imageRequest = new ImageRequest(url,
+ responseBitmapListener(listener, url, isThumb, hostBean, tag), 0, 0,
+ Config.RGB_565, responseError(listener, false, null,hostBean, tag));
+ addRequest(imageRequest, tag);
+ }
+
+ /**
+ * 返回String
+ *
+ * @param url 接口
+ * @param tag 上下文
+ * @param params post需要传的参数
+ * @param listener 回调
+ */
+ public static void post(String url, Object object, SensorParams params,
+ Boolean isDebug, CameraEventListener listener,
+ com.navinfo.collect.library.garminvirbxe.CameraGarminVirbXE.enmCommandType commandType, HostBean hostBean, int tag) {
+ JsonObjectRequest jsonRequest;
+ if (isDebug) {
+ jsonRequest = new JsonObjectRequest(Request.Method.POST, url,
+ params.getParams(), responseListener(listener, commandType,
+ isDebug, hostBean, tag), responseError(listener, isDebug, commandType,hostBean, tag));
+ jsonRequest
+ .setRetryPolicy(new DefaultRetryPolicy(1 * 1000, 1, 1.0f));
+ } else {
+ jsonRequest = new JsonObjectRequest(Request.Method.POST, url,
+ params.getParams(), responseListener(listener, commandType,
+ isDebug, hostBean, tag), responseError(listener, isDebug, commandType,hostBean, tag));
+ //超时时间
+ int timeOut = 10 * 1000;
+ //如果为获取GPS状态,修改超时时间,解决连续拍照导致相机性能下降,获取时间过长问题
+ if (commandType == com.navinfo.collect.library.garminvirbxe.CameraGarminVirbXE.enmCommandType.COMMAND_CAMERA_GETSTATUS)
+ timeOut = 100 * 1000;
+ //解决性能问题
+ if (commandType == com.navinfo.collect.library.garminvirbxe.CameraGarminVirbXE.enmCommandType.COMMAND_CAMERA_MEDIA_LIST) {
+ timeOut = 100 * 1000;
+ }
+
+ jsonRequest.setRetryPolicy(new DefaultRetryPolicy(timeOut, 1,
+ 1.0f));
+ }
+ addRequest(jsonRequest, tag);
+ }
+
+ /**
+ * 成功消息监听 返回String
+ *
+ * @param listener String 接口
+ * @return
+ */
+ protected static Listener responseListener(
+ final CameraEventListener listener, final com.navinfo.collect.library.garminvirbxe.CameraGarminVirbXE.enmCommandType type,
+ final Boolean isDebug, final HostBean hostBean, final int tag) {
+ return new Response.Listener() {
+
+ @Override
+ public void onResponse(JSONObject json) {
+ try {
+ if (isDebug) {
+ mHandle.sendEmptyMessage(SensorUtils.HADNLE_STATUS_OK);
+ } else {
+
+ try {
+ Log.e("AAA", type + (json == null ? "" : json.toString()));
+ } catch (Exception e) {
+
+ }
+
+ if (type == com.navinfo.collect.library.garminvirbxe.CameraGarminVirbXE.enmCommandType.COMMAND_CAMERA_MONITORING) {
+ currentFailCount = 0;
+ mHandle.sendEmptyMessage(SensorUtils.HADNLE_MONITORING);
+ } else if (type == com.navinfo.collect.library.garminvirbxe.CameraGarminVirbXE.enmCommandType.COMMAND_CAMERA_GETSTATUS) {
+ currentFailCount = 0;
+ mHandle.sendEmptyMessage(SensorUtils.HADNLE_CONNECT_OK);
+ if (listener != null)
+ listener.OnStatusResponse(hostBean, tag);
+ } else if (type == com.navinfo.collect.library.garminvirbxe.CameraGarminVirbXE.enmCommandType.COMMAND_CAMERA_RECORD) {
+ if (listener != null)
+ listener.OnStartRecordResponse(hostBean, tag);
+ } else if (type == com.navinfo.collect.library.garminvirbxe.CameraGarminVirbXE.enmCommandType.COMMAND_CAMERA_STOP_RECORD) {
+ if (listener != null)
+ listener.OnStopRecordResponse(hostBean, tag);
+ } else if (type == com.navinfo.collect.library.garminvirbxe.CameraGarminVirbXE.enmCommandType.COMMAND_PHOTO_TIME_LASPE_RATE) {
+ if (listener != null)
+ listener.OnContinuousPhototTimeLapseRateResponse(hostBean, tag);
+ } else if (type == com.navinfo.collect.library.garminvirbxe.CameraGarminVirbXE.enmCommandType.COMMAND_CAMERA_SNAPPICTURE) {
+ if (listener != null)
+ listener.OnContinuousPhototTimeLapseRateStartResponse(hostBean, tag);
+ } else if (type == com.navinfo.collect.library.garminvirbxe.CameraGarminVirbXE.enmCommandType.COMMAND_CAMERA_SNAPPICTURE_SINGLE) {/*增加单独拍照流程,增加时间校验流程*/
+ if (listener != null) {
+ JSONObject mediajson;
+ try {
+ if(json!=null){
+ mediajson = new JSONObject(json.getString("media").toString());
+ String url = mediajson.get("url").toString();
+ String name = mediajson.get("name").toString();
+ listener.OnContinuousPhototSingle(hostBean, url, name, tag);
+ Log.e("AAA", "获取单张拍照" + url);
+ }
+ } catch (JSONException e) {
+ e.printStackTrace();
+ listener.OnContinuousPhototSingle(hostBean, null, null, tag);
+ }
+ }
+ } else if (type == com.navinfo.collect.library.garminvirbxe.CameraGarminVirbXE.enmCommandType.COMMAND_CAMERA_MEDIA_LIST) {
+ if (listener != null&&json!=null){
+ listener.OnGetMediaList(hostBean, json.toString(), tag);
+ }
+
+ } else if (type == com.navinfo.collect.library.garminvirbxe.CameraGarminVirbXE.enmCommandType.COMMAND_PHOTO_TIME_LASPE_RATE_STOP) {
+ if (listener != null)
+ listener.OnContinuousPhototTimeLapseRateStopResponse(hostBean, tag);
+ } else if (type == com.navinfo.collect.library.garminvirbxe.CameraGarminVirbXE.enmCommandType.COMMAND_CAMERA_GETGPSSTATUS) {
+ if (listener != null&&json!=null) {
+ String lat = "";
+ String lon = "";
+ try {
+ lat = json.get("gpsLatitude").toString();
+ lon = json.get("gpsLongitude").toString();
+ Log.e("AAA", "获取设备time" + json.get("recordingTime").toString());
+ } catch (JSONException e) {
+ e.printStackTrace();
+ }
+ if (!lat.equals("") && !lon.equals(""))
+ listener.OnGetGpsStatusResponse(hostBean, true, tag);
+ else
+ listener.OnGetGpsStatusResponse(hostBean, false, tag);
+ }
+ } else if (type == com.navinfo.collect.library.garminvirbxe.CameraGarminVirbXE.enmCommandType.COMMAND_CAMERA_GETDEVICESINFO) {
+ JSONArray jsonobj;
+ try {
+ if(json!=null){
+ jsonobj = new JSONArray(json.getString("deviceInfo").toString());
+ JSONObject ob = (JSONObject) jsonobj.get(0);
+ if (listener != null)
+ Log.e("AAA", "获取设备id");
+ listener.OnGetDeviceInfo(hostBean, ob.getString(
+ "deviceId").toString(), tag);
+ }
+ } catch (JSONException e) {
+ e.printStackTrace();
+ }
+ } else if (type == com.navinfo.collect.library.garminvirbxe.CameraGarminVirbXE.enmCommandType.COMMAND_PHOTO_MODE) {//相机模式设置,增加容错,防止错误解析影响到预览功能
+
+ } else {//预览命令解析
+ JSONObject mediajson;
+ try {
+ if(json!=null){
+ mediajson = new JSONObject(json.getString("media").toString());
+ picUrl = mediajson.get("url").toString();
+ picThumbUrl = mediajson.get("thumbUrl").toString();
+ PreferencesUtils.saveSpText(mContext, "pictureUri",
+ picThumbUrl);
+ PreferencesUtils.saveSpText(mContext,
+ "pictureThumbUri", picUrl);
+ mHandle.sendEmptyMessage(SensorUtils.HADNLE_SNAPPICTURE);
+ if (Command.createBitmap) {
+ getbitmap(mContext, hostBean, picThumbUrl, false, listener, tag);
+ }
+ }
+ // Toast.makeText(mContext, "成功" + picThumbUrl,Toast.LENGTH_SHORT).show();
+ } catch (JSONException e) {
+ e.printStackTrace();
+ }
+ }
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+
+ }
+ };
+ }
+
+ protected static Listener responseBitmapListener(
+ final CameraEventListener listener, final String url,
+ final Boolean isThumb, final HostBean hostBean, final int tag) {
+ return new Response.Listener() {
+
+ @Override
+ public void onResponse(Bitmap bitmap) {
+ File file = new File(url);
+ if (!isThumb) {
+ listener.OnSnapPictureResponse(hostBean,
+ bitmap,
+ CameraGarminVirbXE.mPicUuid
+ + "_thumbnail."
+ + SensorUtils.getExtensionName(file
+ .getName()), tag);
+ String url = PreferencesUtils.getSpText(mContext,
+ "pictureThumbUri").toString();
+ getbitmap(mContext, hostBean, url, true, listener, tag);
+ } else {
+ SaveFileRunnable runable = new SaveFileRunnable(bitmap,
+ CameraGarminVirbXE.mPicUuid
+ + "."
+ + SensorUtils.getExtensionName(file
+ .getName()));
+ Thread th = new Thread(runable);
+ th.start();
+ }
+ }
+ };
+ }
+
+ /**
+ * String 返回错误监听
+ *
+ * @param listener String 接口
+ * @return
+ */
+ protected static Response.ErrorListener responseError(
+ final CameraEventListener listener, final Boolean isDebug, final com.navinfo.collect.library.garminvirbxe.CameraGarminVirbXE.enmCommandType commandType, final HostBean hostBean, final int tag) {
+ return new Response.ErrorListener() {
+
+ @Override
+ public void onErrorResponse(VolleyError e) {
+ try {
+ if (isDebug) {
+ mHandle.sendEmptyMessage(SensorUtils.HADNLE_STATUS_FAIL);
+ } else {
+ if (listener != null)
+ listener.requestError(hostBean, e, commandType,tag);
+ currentFailCount++;
+ if (currentFailCount == failCount)
+ mHandle.sendEmptyMessage(SensorUtils.HADNLE_CONNECT_FAIL);
+ }
+ } catch (Exception e1) {
+ Log.e("AAA",e1.getStackTrace()+"");
+ }
+ }
+ };
+ }
+
+ public static void addRequest(Request> request, Object tag) {
+ if (tag != null) {
+ request.setTag(tag);
+ }
+ mRequestQueue.add(request);
+ }
+
+ /**
+ * 当主页面调用协议 在结束该页面调用此方法
+ *
+ * @param tag
+ */
+ public static void cancelAll(Object tag) {
+ mRequestQueue.cancelAll(tag);
+ }
+
+ public static class SaveFileRunnable implements Runnable {
+ private Bitmap mBitmap;
+ private String fileName;
+
+ public SaveFileRunnable(Bitmap mBitmap, String fileName) {
+ this.mBitmap = mBitmap;
+ this.fileName = fileName;
+ }
+
+ @Override
+ public void run() {
+ try {
+ SensorUtils.saveFile(mBitmap, fileName + ".temp");
+ String savePath = CameraGarminVirbXE.getCameraPcitureSavePath();
+ File oldName = new File(savePath + fileName + ".temp");
+
+ if (oldName != null) {
+ oldName.renameTo(new File(savePath + fileName));
+ }
+ Log.e("AAA", "保存图片成功");
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+
+ }
+
+ }
+}
diff --git a/collect-library/src/main/java/com/navinfo/collect/library/garminvirbxe/SensorParams.java b/collect-library/src/main/java/com/navinfo/collect/library/garminvirbxe/SensorParams.java
new file mode 100644
index 00000000..9a57a28e
--- /dev/null
+++ b/collect-library/src/main/java/com/navinfo/collect/library/garminvirbxe/SensorParams.java
@@ -0,0 +1,41 @@
+package com.navinfo.collect.library.garminvirbxe;
+
+import org.json.JSONException;
+import org.json.JSONObject;
+
+public class SensorParams extends JSONObject {
+
+ private JSONObject params;
+
+ public SensorParams() {
+ init();
+ }
+
+ public SensorParams(String key, String value) {
+ init();
+ put(key, value);
+ }
+
+ private void init() {
+ params = new JSONObject();
+ }
+
+ /**
+ * @param key
+ * @param value
+ */
+ public void put(String key, String value) {
+ if (key != null && value != null) {
+ try {
+ params.put(key, value);
+ } catch (JSONException e) {
+ e.printStackTrace();
+ }
+ }
+ }
+
+ public JSONObject getParams() {
+ return params;
+ }
+
+}
diff --git a/collect-library/src/main/java/com/navinfo/collect/library/garminvirbxe/WifiDiscovery.java b/collect-library/src/main/java/com/navinfo/collect/library/garminvirbxe/WifiDiscovery.java
new file mode 100644
index 00000000..b630dea7
--- /dev/null
+++ b/collect-library/src/main/java/com/navinfo/collect/library/garminvirbxe/WifiDiscovery.java
@@ -0,0 +1,509 @@
+package com.navinfo.collect.library.garminvirbxe;
+
+import android.content.Context;
+import android.content.SharedPreferences;
+import android.content.SharedPreferences.Editor;
+import android.os.AsyncTask;
+import android.os.Build;
+import android.os.Handler;
+import android.os.Message;
+import android.preference.PreferenceManager;
+import android.util.Log;
+
+import com.navinfo.collect.library.utils.NetScanInfo;
+import com.navinfo.collect.library.utils.NetScanPrefs;
+import com.navinfo.collect.library.utils.PreferencesUtils;
+import com.navinfo.collect.library.utils.SensorUtils;
+
+import static com.navinfo.collect.library.utils.NetScanInfo.NOMAC;
+
+import org.json.JSONArray;
+import org.json.JSONObject;
+
+import java.io.BufferedReader;
+import java.io.FileReader;
+import java.io.IOException;
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+import java.util.ArrayList;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.TimeUnit;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+
+public class WifiDiscovery extends AsyncTask {
+
+ private final String TAG = "DefaultDiscovery";
+ private final static int[] DPORTS = {139, 445, 22, 80};
+ private final static int TIMEOUT_SCAN = 3600; // seconds
+ private final static int TIMEOUT_SHUTDOWN = 10; // seconds
+ private final static int THREADS = 25; // FIXME: Test, plz set in options
+ // again ?
+ private final int mRateMult = 5; // Number of alive hosts between Rate
+ private int pt_move = 2; // 1=backward 2=forward
+ private ExecutorService mPool;
+ private boolean doRateControl;
+ private RateControl mRateControl;
+ private int mSearchStatus = 0; // 0为使用缓存ip进行连接测试, 1,从新扫描ip进行连接测试。
+ private boolean mBstatus = false;
+
+ protected long ip;
+ protected long start = 0;
+ protected long end = 0;
+ protected long size = 0;
+
+ protected int hosts_done = 0;
+ private Context mContext;
+ private Command command;
+ private int addressIndex = 0;
+ private SharedPreferences prefs;
+ private NetScanInfo net;
+ private CameraEventListener cameraEventListener;
+ private ArrayList scanHostBeanList;
+ private ArrayList hosts;
+ private ArrayList hostsCache;
+ private int tag;
+
+ public WifiDiscovery(Context mContext,
+ CameraEventListener cameraEventListener, boolean isReadCache) {
+ this.mContext = mContext;
+ this.cameraEventListener = cameraEventListener;
+ command = new Command(mContext);
+ command.SetHandle(mHandler);
+ scanHostBeanList = new ArrayList();
+ hosts = new ArrayList();
+ hostsCache = new ArrayList();
+ prefs = PreferenceManager.getDefaultSharedPreferences(mContext);
+ net = new NetScanInfo(mContext);
+ mRateControl = new RateControl();
+ setScanInfo();
+ if (isReadCache)
+ getLocalIpSend();
+ else{
+ mBstatus = true;
+ Log.e("mBstatus","WifiDiscovery==="+mBstatus);
+ }
+
+ }
+
+ //优先本地缓存记录连接
+ private void getLocalIpSend() {
+ String cacheHostBean = PreferencesUtils.getSpText(mContext, "cacheHostBean").toString();
+ if (!"".equals(cacheHostBean)) {
+ mSearchStatus = 0;
+ try {
+ JSONArray jsonArray = new JSONArray(cacheHostBean);
+ if (jsonArray != null && jsonArray.length() > 0) {
+ for (int i = 0; i < jsonArray.length(); i++) {
+ JSONObject jobj = jsonArray.getJSONObject(i);
+ if (jobj != null) {
+ HostBean hostBean = new HostBean();
+ if (jobj.has("ipAddress"))
+ hostBean.ipAddress = jobj.getString("ipAddress");
+ if (jobj.has("hardwareAddress"))
+ hostBean.hardwareAddress = jobj.getString("hardwareAddress");
+ hostsCache.add(hostBean);
+ }
+ }
+ }
+ } catch (Exception e) {
+ Log.e("AAA", "getLocalIpSend:异常" + e.toString());
+ }
+ //如果缓存转换失败,重新执行扫描
+ if (hostsCache == null || hostsCache.size() == 0) {
+ mBstatus = true;
+ } else {
+ //不启动扫描
+ mBstatus = false;
+ Log.e("mBstatus","getLocalIpSend==="+mBstatus);
+ sendConnectCommand();
+ }
+ } else {
+ mBstatus = true;
+ }
+ }
+
+ private Handler mHandler = new Handler() {
+ @Override
+ public void handleMessage(Message msg) {
+ switch (msg.what) {
+ case SensorUtils.HADNLE_STATUS_OK:
+ scanHostBeanList.add(mCurrentHostBean);
+ sendCommand();
+ break;
+ case SensorUtils.HADNLE_STATUS_FAIL:
+ //使用缓存获取状态失败了,代表ip发生编化,需要重新扫描
+ if (mSearchStatus == 0) {
+ //重置索引
+ addressIndex = 0;
+ scanHostBeanList.clear();
+ hostsCache.clear();
+ mBstatus = true;
+ //扫描失败后重新启动搜索
+ mSearchStatus = 0;
+ pingAllIp();
+ } else {
+ sendCommand();
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ };
+
+ private HostBean mCurrentHostBean;
+
+ private void setScanInfo() {
+ ip = NetScanInfo.getUnsignedLongFromIp(net.ip);
+ if (prefs.getBoolean(NetScanPrefs.KEY_IP_CUSTOM,
+ NetScanPrefs.DEFAULT_IP_CUSTOM)) {
+ // Custom IP
+ start = NetScanInfo.getUnsignedLongFromIp(prefs.getString(
+ NetScanPrefs.KEY_IP_START, NetScanPrefs.DEFAULT_IP_START));
+ end = NetScanInfo.getUnsignedLongFromIp(prefs.getString(
+ NetScanPrefs.KEY_IP_END, NetScanPrefs.DEFAULT_IP_END));
+ } else {
+ // Custom CIDR
+ if (prefs.getBoolean(NetScanPrefs.KEY_CIDR_CUSTOM,
+ NetScanPrefs.DEFAULT_CIDR_CUSTOM)) {
+ net.cidr = Integer.parseInt(prefs.getString(
+ NetScanPrefs.KEY_CIDR, NetScanPrefs.DEFAULT_CIDR));
+ }
+ // Detected IP
+ int shift = (32 - net.cidr);
+ if (net.cidr < 31) {
+ start = (ip >> shift << shift) + 1;
+ end = (start | ((1 << shift) - 1)) - 1;
+ } else {
+ start = (ip >> shift << shift);
+ end = (start | ((1 << shift) - 1));
+ }
+ // Reset ip start-end (is it really convenient ?)
+ Editor edit = prefs.edit();
+ edit.putString(NetScanPrefs.KEY_IP_START,
+ NetScanInfo.getIpFromLongUnsigned(start));
+ edit.putString(NetScanPrefs.KEY_IP_END,
+ NetScanInfo.getIpFromLongUnsigned(end));
+ edit.commit();
+ }
+
+ }
+
+ public void setNetwork(long ip, long start, long end) {
+ this.ip = ip;
+ this.start = start;
+ this.end = end;
+ }
+
+ @Override
+ protected void onPreExecute() {
+ size = (int) (end - start + 1);
+ scanHostBeanList.clear();
+ doRateControl = prefs.getBoolean(NetScanPrefs.KEY_RATECTRL_ENABLE,
+ NetScanPrefs.DEFAULT_RATECTRL_ENABLE);
+ }
+
+ @Override
+ protected void onProgressUpdate(final HostBean... host) {
+ if (!isCancelled()) {
+ if (host[0] != null) {
+ host[0].position = hosts.size();
+ //android 10 获取不到mac地址,所以不进行过滤
+ if (Build.VERSION.SDK_INT >= 29 || !host[0].hardwareAddress.equalsIgnoreCase(NOMAC)/*&&host[0].hardwareAddress.startsWith("14:")*/)
+ hosts.add(host[0]);
+ Log.e("AAA", "hardwareAddress" + host[0].hardwareAddress + "\n" + host[0].hostname);
+ }
+ if (size > 0) {
+ // discover.setProgress((int) (hosts_done * 10000 / size));
+ }
+ }
+ }
+
+ @Override
+ protected void onPostExecute(Void unused) {
+ Log.e("AAA", "扫描完成");
+ sendConnectCommand();
+ }
+
+ @Override
+ protected Void doInBackground(Void... params) {
+ //与董普校讨论去掉while,调用时自己控制
+ //while (true) {
+ Log.e("mBstatus", "doInBackground===" + mBstatus);
+ /*if (mBstatus) {
+ if (mSearchStatus == 1)
+ return null;*/
+ pingAllIp();
+ //}
+ return null;
+ }
+
+ private void pingAllIp() {
+ if (mBstatus) {
+ if (mSearchStatus == 1)
+ return;
+ }
+ mSearchStatus = 1;
+ Log.v(TAG, "start=" + NetScanInfo.getIpFromLongUnsigned(start) + " ("
+ + start + "), end=" + NetScanInfo.getIpFromLongUnsigned(end)
+ + " (" + end + "), length=" + size);
+ mPool = Executors.newFixedThreadPool(THREADS);
+ if (ip <= end && ip >= start) {
+ Log.i(TAG, "Back and forth scanning");
+ // gateway
+ launch(start);
+
+ // hosts
+ long pt_backward = ip;
+ long pt_forward = ip + 1;
+ long size_hosts = size - 1;
+
+ if (size_hosts > 0) {
+ for (int i = 0; i < size_hosts; i++) {
+ // Set pointer if of limits
+ if (pt_backward <= start) {
+ pt_move = 2;
+ } else if (pt_forward > end) {
+ pt_move = 1;
+ }
+ // Move back and forth
+ if (pt_move == 1) {
+ launch(pt_backward);
+ pt_backward--;
+ pt_move = 2;
+ } else if (pt_move == 2) {
+ launch(pt_forward);
+ pt_forward++;
+ pt_move = 1;
+ }
+ }
+ }
+
+ } else {
+ Log.i(TAG, "Sequencial scanning");
+ for (long i = start; i <= end; i++) {
+ launch(i);
+ }
+ }
+
+ mPool.shutdown();
+ //暂时注释掉线程池管理类阻塞住,等待线程返回的相关代码
+ try {
+ if (!mPool.awaitTermination(TIMEOUT_SCAN, TimeUnit.SECONDS)) {
+ mPool.shutdownNow();
+ Log.e(TAG, "Shutting down pool");
+ if (!mPool.awaitTermination(TIMEOUT_SHUTDOWN, TimeUnit.SECONDS)) {
+ Log.e(TAG, "Pool did not terminate");
+ }
+ }
+ } catch (InterruptedException e) {
+ Log.e(TAG, e.getMessage());
+ mPool.shutdownNow();
+ Thread.currentThread().interrupt();
+ } finally {
+ }
+
+
+ }
+
+ @Override
+ protected void onCancelled() {
+ if (mPool != null) {
+ synchronized (mPool) {
+ mPool.shutdownNow();
+ }
+ }
+ super.onCancelled();
+ }
+
+ private void launch(long i) {
+ if (!mPool.isShutdown()) {
+ mPool.execute(new CheckRunnable(NetScanInfo
+ .getIpFromLongUnsigned(i)));
+ }
+ }
+
+ private int getRate() {
+ if (doRateControl) {
+ return mRateControl.rate;
+ }
+
+ return Integer.parseInt(prefs.getString(
+ NetScanPrefs.KEY_TIMEOUT_DISCOVER,
+ NetScanPrefs.DEFAULT_TIMEOUT_DISCOVER));
+ }
+
+ private class CheckRunnable implements Runnable {
+ private String addr;
+ private String hardwareAddress;
+
+ CheckRunnable(String addr) {
+ this.addr = addr;
+ }
+
+ @Override
+ public void run() {
+ // Log.e(TAG, "run=" + addr);
+ // Create host object
+
+ final HostBean host = new HostBean();
+ host.responseTime = getRate();
+ host.ipAddress = addr;
+
+ try {
+
+ InetAddress h = InetAddress.getByName(addr);
+ // Rate control check
+ if (doRateControl && mRateControl.indicator != null
+ && hosts_done % mRateMult == 0) {
+ mRateControl.adaptRate();
+ }
+ // Arp Check #1
+ //android10 不能访问proc/net 目录
+ if (Build.VERSION.SDK_INT < 29) {
+ hardwareAddress = getHardwareAddress(addr);
+ }
+ if (hardwareAddress != null && !NOMAC.equals(hardwareAddress)) {
+ host.hardwareAddress = hardwareAddress;
+ Log.e(TAG, "CheckRunnable" + addr);
+ Log.e(TAG, "CheckRunnable" + host.hardwareAddress + "===" + hardwareAddress);
+ publish(host);
+ return;
+ }
+ // Native InetAddress check
+ if (h.isReachable(getRate())) {
+ Log.e(TAG, "found using InetAddress ping " + addr);
+ publish(host);
+ if (doRateControl && mRateControl.indicator == null) {
+ mRateControl.indicator = addr;
+ mRateControl.adaptRate();
+ }
+ return;
+ }
+
+
+ } catch (IOException e) {
+ publish(null);
+ Log.e(TAG, e.getMessage());
+ }
+ }
+
+ }
+
+ //解析地址
+ public String getHardwareAddress(String ip) {
+ try {
+ if (ip != null) {
+ String hw = NOMAC;
+ String ptrn = String.format(NetScanInfo.MAC_RE, ip.replace(".", "\\."));
+ Pattern pattern = Pattern.compile(ptrn);
+ BufferedReader bufferedReader = new BufferedReader(new FileReader("/proc/net/arp"), NetScanInfo.BUF);
+ String line;
+ Matcher matcher;
+ while ((line = bufferedReader.readLine()) != null) {
+ matcher = pattern.matcher(line);
+ if (matcher.matches()) {
+ hw = matcher.group(1);
+ break;
+ }
+ }
+ bufferedReader.close();
+ return hw;
+ } else {
+ Log.e(TAG, "ip is null");
+ }
+ } catch (IOException e) {
+ Log.e(TAG, "Can't open/read file ARP: " + e.getMessage());
+ return NOMAC;
+ }
+ return NOMAC;
+ }
+
+ private void publish(final HostBean host) {
+ hosts_done++;
+ if (host == null) {
+ publishProgress((HostBean) null);
+ return;
+ }
+
+ // if (mDiscover != null) {
+ // final ActivityNet discover = mDiscover.get();
+ // if (discover != null) {
+ // Is gateway ?
+ if (net.gatewayIp.equals(host.ipAddress)) {
+ host.deviceType = HostBean.TYPE_GATEWAY;
+ }
+
+ // FQDN
+ // Static
+ if (host.hostname == null) {
+ // DNS
+ if (prefs.getBoolean(NetScanPrefs.KEY_RESOLVE_NAME,
+ NetScanPrefs.DEFAULT_RESOLVE_NAME) == true) {
+ try {
+ host.hostname = (InetAddress.getByName(host.ipAddress))
+ .getCanonicalHostName();
+ } catch (UnknownHostException e) {
+ Log.e(TAG, e.getMessage());
+ }
+ }
+ }
+
+ publishProgress(host);
+ }
+
+ // 发送测试命令
+ private void sendConnectCommand() {
+ sendCommand();
+ }
+
+ /**
+ * 发送
+ */
+ private void sendCommand() {
+ if (!mBstatus && addressIndex < hostsCache.size()) {
+ mCurrentHostBean = hostsCache.get(addressIndex);
+ addressIndex++;
+ //Log.e(TAG, "ipAddress:" + mCurrentHostBean.ipAddress.toString());
+ RequestApi.setApiWifiIp(mCurrentHostBean.ipAddress.toString());
+ command.getWifiTestStatus(mCurrentHostBean, getTag());
+ } else if (mBstatus && addressIndex < hosts.size()) {
+ mCurrentHostBean = hosts.get(addressIndex);
+ addressIndex++;
+ //Log.e(TAG, "ipAddress:" + mCurrentHostBean.ipAddress.toString());
+ RequestApi.setApiWifiIp(mCurrentHostBean.ipAddress.toString());
+ command.getWifiTestStatus(mCurrentHostBean, getTag());
+ } else {
+ if (scanHostBeanList != null && scanHostBeanList.size() > 0) {
+
+ JSONArray jsonArray = new JSONArray();
+
+ for (int i = 0; i < scanHostBeanList.size(); i++) {
+ try {
+ JSONObject jobj = new JSONObject();
+ jobj.put("ipAddress", scanHostBeanList.get(i).ipAddress);
+ jobj.put("hardwareAddress", scanHostBeanList.get(i).hardwareAddress);
+ //过滤重复内容
+ if (!jsonArray.toString().contains(jobj.toString()))
+ jsonArray.put(jobj);
+ } catch (Exception e) {
+
+ }
+ }
+ PreferencesUtils.saveSpText(mContext, "cacheHostBean", jsonArray.toString());
+ }
+ cameraEventListener.OnSearchResponse(getTag(), scanHostBeanList);
+ }
+ }
+
+ public int getTag() {
+ return tag;
+ }
+
+ public void setTag(int tag) {
+ this.tag = tag;
+ }
+}
diff --git a/collect-library/src/main/java/com/navinfo/collect/library/map/NIMapController.kt b/collect-library/src/main/java/com/navinfo/collect/library/map/NIMapController.kt
index 30613a8f..74c6bc92 100644
--- a/collect-library/src/main/java/com/navinfo/collect/library/map/NIMapController.kt
+++ b/collect-library/src/main/java/com/navinfo/collect/library/map/NIMapController.kt
@@ -3,6 +3,8 @@ package com.navinfo.collect.library.map
import android.content.Context
import android.util.Log
import androidx.appcompat.app.AppCompatActivity
+import com.navinfo.collect.library.data.entity.NiLocation
+import com.navinfo.collect.library.data.handler.DataNiLocationHandler
import com.navinfo.collect.library.map.handler.*
import com.navinfo.collect.library.map.maphandler.MeasureLayerHandler
import com.navinfo.collect.library.map.handler.ViewportHandler
@@ -23,7 +25,6 @@ class NIMapController {
lateinit var viewportHandler: ViewportHandler
lateinit var measureLayerHandler: MeasureLayerHandler
-
fun init(context: AppCompatActivity, mapView: NIMapView, options: NIMapOptions? = null, mapPath: String) {
Constant.MAP_PATH = mapPath
layerManagerHandler = LayerManagerHandler(context, mapView)
diff --git a/collect-library/src/main/java/com/navinfo/collect/library/map/NIMapView.java b/collect-library/src/main/java/com/navinfo/collect/library/map/NIMapView.java
index d8fa38ca..fb115dd4 100644
--- a/collect-library/src/main/java/com/navinfo/collect/library/map/NIMapView.java
+++ b/collect-library/src/main/java/com/navinfo/collect/library/map/NIMapView.java
@@ -13,7 +13,9 @@ import android.widget.RelativeLayout;
import androidx.annotation.Nullable;
import com.navinfo.collect.library.R;
+import com.navinfo.collect.library.data.entity.NiLocation;
import com.navinfo.collect.library.map.layers.NaviMapScaleBar;
+import com.navinfo.collect.library.map.source.MapLifeNiLocationTileSource;
import org.oscim.android.MapPreferences;
import org.oscim.android.MapView;
@@ -25,10 +27,22 @@ import org.oscim.event.Gesture;
import org.oscim.event.GestureListener;
import org.oscim.layers.GroupLayer;
import org.oscim.layers.Layer;
+import org.oscim.layers.tile.buildings.BuildingLayer;
+import org.oscim.layers.tile.vector.OsmTileLayer;
import org.oscim.layers.tile.vector.VectorTileLayer;
+import org.oscim.layers.tile.vector.labeling.LabelLayer;
+import org.oscim.layers.tile.vector.labeling.LabelTileLoaderHook;
import org.oscim.map.Map;
import org.oscim.renderer.GLViewport;
+import org.oscim.theme.IRenderTheme;
+import org.oscim.theme.ThemeLoader;
import org.oscim.theme.VtmThemes;
+import org.oscim.tiling.source.mapfile.MapFileTileSource;
+import org.oscim.tiling.source.mapfile.MultiMapFileTileSource;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.List;
/**
@@ -85,12 +99,11 @@ public final class NIMapView extends RelativeLayout {
// private Layer gridLayer;
protected Context mContext;
-
/**
* 地图状态信息
*/
private MapPreferences mPrefs;
- // protected String mapFilePath = Constant.ROOT_PATH + "/map";
+ protected String mapFilePath = "/map";
protected GroupLayer baseGroupLayer; // 用于盛放所有基础底图的图层组,便于统一管理
public void setOptions(NIMapOptions option) {
@@ -348,6 +361,10 @@ public final class NIMapView extends RelativeLayout {
mapPosition.setPosition(options.getCoordinate().getLatitude(), options.getCoordinate().getLongitude());
getVtmMap().animator().animateTo(100, mapPosition);
}
+
+ List list = new ArrayList();
+ list.add(new NiLocation());
+
}
@@ -422,83 +439,84 @@ public final class NIMapView extends RelativeLayout {
// }
// }
-// private void initVectorTileLayer() {
-// if (baseGroupLayer == null) {
-// baseGroupLayer = new GroupLayer(getVtmMap());
-// }
-// for (Layer layer : baseGroupLayer.layers) {
-// getVtmMap().layers().remove(layer);
-// }
-// baseGroupLayer.layers.clear();
-//
-// File baseMapFolder = new File(mapFilePath);
-// if (!baseMapFolder.exists()) {
-// return;
-// }
-//
-// File[] mapFileList = baseMapFolder.listFiles();
-//
-// if (mapFileList != null && mapFileList.length > 0) {
-//
-// MultiMapFileTileSource multiMapFileTileSource = new MultiMapFileTileSource();
-//
-// for (File mapFile : mapFileList) {
-//
-// if (!mapFile.exists() || !mapFile.getName().endsWith(".map")) {
-// continue;
-// }
-//
-// MapFileTileSource mTileSource = new MapFileTileSource();
-//
-// mTileSource.setPreferredLanguage("zh");
-//
-// if (mTileSource.setMapFile(mapFile.getAbsolutePath())) {
-// multiMapFileTileSource.add(mTileSource);
-// }
-//
-// }
-//
-// VectorTileLayer baseMapLayer = new OsmTileLayer(getVtmMap());
-// baseMapLayer.setTileSource(multiMapFileTileSource);
-//
-// baseGroupLayer.layers.add(baseMapLayer);
-//
-// if (getTheme(null) != null)
-// baseMapLayer.setTheme(getTheme(null));
-//
-// baseGroupLayer.layers.add(new BuildingLayer(getVtmMap(), baseMapLayer));
-// baseGroupLayer.layers.add(new LabelLayer(getVtmMap(), baseMapLayer));
-//
-// for (Layer layer : baseGroupLayer.layers) {
-// if (layer instanceof LabelLayer) {
-// getVtmMap().layers().add(layer, LAYER_GROUPS.VECTOR.groupIndex);
-// } else {
-// getVtmMap().layers().add(layer, LAYER_GROUPS.BASE_VECTOR.groupIndex);
-// }
-// }
-// }
-// }
+/* public void initVectorTileLayer(){
+ if (baseGroupLayer == null) {
+ baseGroupLayer = new GroupLayer(getVtmMap());
+ }
+ for (Layer layer : baseGroupLayer.layers) {
+ getVtmMap().layers().remove(layer);
+ }
+ baseGroupLayer.layers.clear();
-// //获取渲染资源
-// public IRenderTheme getTheme(final String styleId) {
-// AssetsRenderTheme theme = new AssetsRenderTheme(mContext.getAssets(), null, "default.xml");
-// if (styleId == null || "".equals(styleId.trim())) {
-// switch (2) {
-// case 0:
-// theme = new AssetsRenderTheme(mContext.getAssets(), null, "default.xml");
-// break;
-// case 1:
-// theme = new AssetsRenderTheme(mContext.getAssets(), null, "osmarender.xml");
-// break;
-// case 2:
-// theme = new AssetsRenderTheme(mContext.getAssets(), null, "tronrender.xml");
-// break;
-// }
-//
-// }
-//
-// return ThemeLoader.load(theme);
-// }
+ File baseMapFolder = new File(mapFilePath);
+ if (!baseMapFolder.exists()) {
+ return;
+ }
+
+ File[] mapFileList = baseMapFolder.listFiles();
+
+ if (mapFileList != null && mapFileList.length > 0) {
+
+ MultiMapFileTileSource multiMapFileTileSource = new MultiMapFileTileSource();
+
+ for (File mapFile : mapFileList) {
+
+ if (!mapFile.exists() || !mapFile.getName().endsWith(".map")) {
+ continue;
+ }
+
+ MapFileTileSource mTileSource = new MapFileTileSource();
+
+ mTileSource.setPreferredLanguage("zh");
+
+ if (mTileSource.setMapFile(mapFile.getAbsolutePath())) {
+ multiMapFileTileSource.add(mTileSource);
+ }
+
+ }
+
+ VectorTileLayer baseMapLayer = new OsmTileLayer(getVtmMap());
+ baseMapLayer.setTileSource(multiMapFileTileSource);
+
+ baseGroupLayer.layers.add(baseMapLayer);
+
+ if (getTheme(null) != null)
+ baseMapLayer.setTheme(getTheme(null));
+
+ baseGroupLayer.layers.add(new BuildingLayer(getVtmMap(), baseMapLayer));
+ baseGroupLayer.layers.add(new LabelLayer(getVtmMap(), baseMapLayer));
+
+ for (Layer layer : baseGroupLayer.layers) {
+ if (layer instanceof LabelLayer) {
+ getVtmMap().layers().add(layer, LAYER_GROUPS.VECTOR.groupIndex);
+ } else {
+ getVtmMap().layers().add(layer, LAYER_GROUPS.BASE.groupIndex);
+ }
+ }
+ }
+ }*/
+
+ //获取渲染资源
+/*
+ public IRenderTheme getTheme(final String styleId) {
+ AssetsRenderTheme theme = new AssetsRenderTheme(mContext.getAssets(), null, "default.xml");
+ if (styleId == null || "".equals(styleId.trim())) {
+ switch (2) {
+ case 0:
+ theme = new AssetsRenderTheme(mContext.getAssets(), null, "default.xml");
+ break;
+ case 1:
+ theme = new AssetsRenderTheme(mContext.getAssets(), null, "osmarender.xml");
+ break;
+ case 2:
+ theme = new AssetsRenderTheme(mContext.getAssets(), null, "tronrender.xml");
+ break;
+ }
+
+ }
+ return ThemeLoader.load(theme);
+ }
+*/
// public void addDefaultVectorTileLayer(MAP_THEME theme) {
// if (defaultVectorTileLayer != null) {
@@ -969,4 +987,5 @@ public final class NIMapView extends RelativeLayout {
public void updateMap(boolean redraw) {
mapView.map().updateMap(redraw);
}
+
}
diff --git a/collect-library/src/main/java/com/navinfo/collect/library/map/handler/LayerManagerHandler.kt b/collect-library/src/main/java/com/navinfo/collect/library/map/handler/LayerManagerHandler.kt
index 6e6e65fb..b337e478 100644
--- a/collect-library/src/main/java/com/navinfo/collect/library/map/handler/LayerManagerHandler.kt
+++ b/collect-library/src/main/java/com/navinfo/collect/library/map/handler/LayerManagerHandler.kt
@@ -10,9 +10,11 @@ import androidx.lifecycle.lifecycleScope
import com.navinfo.collect.library.R
import com.navinfo.collect.library.data.entity.QsRecordBean
import com.navinfo.collect.library.map.NIMapView
+import com.navinfo.collect.library.map.NIMapView.LAYER_GROUPS
import com.navinfo.collect.library.map.cluster.ClusterMarkerItem
import com.navinfo.collect.library.map.cluster.ClusterMarkerRenderer
import com.navinfo.collect.library.map.layers.MyItemizedLayer
+import com.navinfo.collect.library.map.source.MapLifeNiLocationTileSource
import com.navinfo.collect.library.map.source.NavinfoMultiMapFileTileSource
import com.navinfo.collect.library.system.Constant
import com.navinfo.collect.library.utils.GeometryTools
@@ -34,6 +36,7 @@ import org.oscim.layers.marker.*
import org.oscim.layers.tile.buildings.BuildingLayer
import org.oscim.layers.tile.vector.VectorTileLayer
import org.oscim.layers.tile.vector.labeling.LabelLayer
+import org.oscim.layers.tile.vector.labeling.LabelTileLoaderHook
import org.oscim.tiling.source.OkHttpEngine.OkHttpFactory
import org.oscim.tiling.source.mapfile.MapFileTileSource
import java.io.File
@@ -64,6 +67,21 @@ open class LayerManagerHandler(context: AppCompatActivity, mapView: NIMapView) :
private lateinit var markerRendererFactory: MarkerRendererFactory
private val markerItemsNames = mutableListOf()
+ /**
+ * 轨迹渲染图层
+ */
+ private lateinit var mapLifeNiLocationTileSource: MapLifeNiLocationTileSource
+
+ /**
+ * 轨迹数据图层
+ */
+ private lateinit var vectorNiLocationTileLayer: VectorTileLayer
+
+ /**
+ * 增加作业渲染
+ */
+ private lateinit var labelNiLocationLayer: LabelLayer
+
/**
* 文字大小
*/
@@ -496,6 +514,25 @@ open class LayerManagerHandler(context: AppCompatActivity, mapView: NIMapView) :
}
}
+ //显示轨迹图层
+ fun showNiLocationLayer(dbName: String?) {
+ if (mapLifeNiLocationTileSource == null) {
+ mapLifeNiLocationTileSource = MapLifeNiLocationTileSource(mContext, dbName)
+ }
+ if (vectorNiLocationTileLayer == null) {
+ vectorNiLocationTileLayer = VectorTileLayer(mMapView.vtmMap, mapLifeNiLocationTileSource)
+ }
+ if (labelNiLocationLayer == null) {
+ labelNiLocationLayer =
+ LabelLayer(mMapView.vtmMap, vectorNiLocationTileLayer, LabelTileLoaderHook(), 15)
+ }
+ addLayer(labelNiLocationLayer, NIMapView.LAYER_GROUPS.VECTOR)
+ }
+
+ //隐藏轨迹图层
+ fun hideNiLocationLayer() {
+ removeLayer(labelNiLocationLayer)
+ }
}
diff --git a/collect-library/src/main/java/com/navinfo/collect/library/map/handler/LocationLayerHandler.kt b/collect-library/src/main/java/com/navinfo/collect/library/map/handler/LocationLayerHandler.kt
index dd950229..c23a35f8 100644
--- a/collect-library/src/main/java/com/navinfo/collect/library/map/handler/LocationLayerHandler.kt
+++ b/collect-library/src/main/java/com/navinfo/collect/library/map/handler/LocationLayerHandler.kt
@@ -9,6 +9,7 @@ import com.baidu.location.BDLocation
import com.baidu.location.LocationClient
import com.baidu.location.LocationClientOption
import com.baidu.location.LocationClientOption.LocationMode
+import com.navinfo.collect.library.data.entity.NiLocation
import com.navinfo.collect.library.map.GeoPoint
import com.navinfo.collect.library.map.NIMapView
import org.oscim.layers.LocationLayer
@@ -20,6 +21,7 @@ class LocationLayerHandler(context: AppCompatActivity, mapView: NIMapView) : Bas
private var bFirst = true
private val mLocationLayer: LocationLayer = LocationLayer(mMapView.vtmMap)
private lateinit var locationClient: LocationClient
+ private lateinit var niLocationListener: NiLocationListener
init {
///添加定位图层到地图,[NIMapView.LAYER_GROUPS.NAVIGATION] 是最上层layer组
@@ -58,6 +60,10 @@ class LocationLayerHandler(context: AppCompatActivity, mapView: NIMapView) : Bas
mLocationLayer.setPosition(
it.latitude, it.longitude, it.radius
)
+ Log.e("qj","location==${it.longitude}==errorCode===$errorCode===${it.locTypeDescription}")
+ if(niLocationListener!=null){
+ getCurrentNiLocation()?.let { it1 -> niLocationListener.call(it1) }
+ }
//第一次定位成功显示当前位置
if (this.bFirst) {
animateToCurrentPosition(16.0)
@@ -102,6 +108,7 @@ class LocationLayerHandler(context: AppCompatActivity, mapView: NIMapView) : Bas
locationClient.locOption = locationOption
} catch (e: Throwable) {
Toast.makeText(mContext, "定位初始化失败 $e", Toast.LENGTH_SHORT)
+ Log.e("qj","定位初始化失败$e")
}
}
@@ -151,6 +158,39 @@ class LocationLayerHandler(context: AppCompatActivity, mapView: NIMapView) : Bas
}
return null
}
+
+ //获取当前定位对象
+ fun getCurrentNiLocation(): NiLocation? {
+ if(mCurrentLocation!=null){
+ val niLocation:NiLocation = NiLocation()
+ niLocation.longitude = mCurrentLocation!!.longitude
+ niLocation.latitude = mCurrentLocation!!.latitude
+ niLocation.direction = mCurrentLocation!!.direction.toDouble()
+ niLocation.altitude = mCurrentLocation!!.altitude
+ niLocation.radius = mCurrentLocation!!.radius.toDouble()
+ niLocation.time = mCurrentLocation!!.time
+ niLocation.adCode = mCurrentLocation!!.adCode
+ niLocation.country = mCurrentLocation!!.country
+ niLocation.province = mCurrentLocation!!.province
+ niLocation.city = mCurrentLocation!!.city
+ niLocation.district = mCurrentLocation!!.district
+ niLocation.cityCode = mCurrentLocation!!.cityCode
+ niLocation.floor = mCurrentLocation!!.floor
+ niLocation.satelliteNumber = mCurrentLocation!!.satelliteNumber
+ niLocation.address = mCurrentLocation!!.addrStr
+ niLocation.street = mCurrentLocation!!.street
+ niLocation.town = mCurrentLocation!!.town
+ niLocation.streetNumber = mCurrentLocation!!.streetNumber
+ niLocation.errorCode = mCurrentLocation!!.locType.toString()
+ return niLocation
+ }
+ return null
+ }
+
+ //设置定位回调
+ fun setNiLocationListener(listener: NiLocationListener){
+ niLocationListener = listener
+ }
}
/**
@@ -161,4 +201,14 @@ private class MyLocationListener(callback: (BDLocation) -> Unit) : BDAbstractLoc
override fun onReceiveLocation(location: BDLocation) {
call(location)
}
+}
+
+/**
+ * 实现定位回调
+ */
+public class NiLocationListener(callback: (NiLocation) -> Unit){
+ val call = callback;
+ fun onReceiveLocation(location: NiLocation) {
+ call(location)
+ }
}
\ No newline at end of file
diff --git a/collect-library/src/main/java/com/navinfo/collect/library/map/source/MapLifeNiLocationTileDataSource.java b/collect-library/src/main/java/com/navinfo/collect/library/map/source/MapLifeNiLocationTileDataSource.java
index 49e53c30..7bad0cfe 100644
--- a/collect-library/src/main/java/com/navinfo/collect/library/map/source/MapLifeNiLocationTileDataSource.java
+++ b/collect-library/src/main/java/com/navinfo/collect/library/map/source/MapLifeNiLocationTileDataSource.java
@@ -40,8 +40,6 @@ public class MapLifeNiLocationTileDataSource implements ITileDataSource {
@RequiresApi(api = Build.VERSION_CODES.N)
@Override
public void query(MapTile tile, ITileDataSink mapDataSink) {
-
-
// 获取tile对应的坐标范围
if (tile.zoomLevel >= 10 && tile.zoomLevel <= 20) {
diff --git a/collect-library/src/main/java/com/navinfo/collect/library/sensor/Camera.java b/collect-library/src/main/java/com/navinfo/collect/library/sensor/Camera.java
new file mode 100644
index 00000000..28290e06
--- /dev/null
+++ b/collect-library/src/main/java/com/navinfo/collect/library/sensor/Camera.java
@@ -0,0 +1,96 @@
+package com.navinfo.collect.library.sensor;
+
+import android.content.Context;
+
+import com.navinfo.collect.library.garminvirbxe.Command;
+import com.navinfo.collect.library.garminvirbxe.SensorParams;
+
+public class Camera extends ISensor {
+
+ private Context mContext;
+ private Command conmand;
+
+ public Camera(Context mContext) {
+ this.mContext = mContext;
+ conmand = new Command(mContext);
+ }
+
+ @Override
+ public enmSensorType GetSensorType() {
+ return enmSensorType.SENSOR_CAMEAR;
+ }
+
+ @Override
+ public enmConnectionStatus GetConnectionStatus() {
+ return null;
+ }
+
+ @Override
+ public enmConnectionStatus Connect(SensorParams params) {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ @Override
+ public enmConnectionStatus DisConnect() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ @Override
+ public enmSignalQuality GetSignalQuality() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ @Override
+ public void snapPicture(String picuuid) {
+
+ }
+
+
+ @Override
+ public void StopRecording() {
+ conmand.StopRecording(null,0);
+ }
+
+
+ @Override
+ public void StartRecording() {
+ conmand.StartRecording(null,0);
+ }
+
+ @Override
+ public int RegisterSensorEvent(SensorEventListener sensorEventLister) {
+ // TODO Auto-generated method stub
+ return 0;
+ }
+
+ @Override
+ public void SetMode(SensorWorkingMode sensorWorkingMode) {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ public void Search(boolean isReadCache) {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ public void StopSearch() {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ public void GetGpsStatus() {
+ // TODO Auto-generated method stub
+
+ }
+
+ public void OnConnectionStatusChanged(enmConnectionStatus cs){
+
+ }
+}
diff --git a/collect-library/src/main/java/com/navinfo/collect/library/sensor/ISensor.java b/collect-library/src/main/java/com/navinfo/collect/library/sensor/ISensor.java
new file mode 100644
index 00000000..863cd5b1
--- /dev/null
+++ b/collect-library/src/main/java/com/navinfo/collect/library/sensor/ISensor.java
@@ -0,0 +1,83 @@
+package com.navinfo.collect.library.sensor;
+
+import com.navinfo.collect.library.garminvirbxe.SensorParams;
+
+public abstract class ISensor {
+
+ public enum enmSensorType {
+ SENSOR_LOCATION, /* !< 位置传感器 */
+ SENSOR_CAMEAR /* !< 图像传感器 */
+
+ };
+
+ public enum enmSensorModel {
+ LOCATION_GPS_INTERANL, /* !< 设备内部GPS */
+ LOCATION_GPS_BLUETOOTH, /* !< 蓝牙GPS */
+ LOCATION_SINS,
+ LOCATION_BAIDU, /* !< BaiDu location api */
+ CAMERA_GARMIN_VIRB_XE, /* !< Garmin Virb xe 运动相机 */
+ CAMERA_UNKNOWN, /* !< 未知相机类型 */
+ LOCATION_SINS_BAIDU_MIX /* 百度和惯导混合定位*/
+ }
+
+
+ //连接状态枚举
+ public enum enmConnectionStatus {
+
+ DISCONNECTTED/*断开连接*/, CONNECTTING/*连接中*/, CONNECTTED/*连接*/
+
+ }
+
+
+ //信号质量枚举
+ public enum enmSignalQuality {
+ NO_SIGNAL/*无信号*/, POOR/*弱信号*/, MODERATE/*中等信号*/, PERFECT/*强信号*/
+ }
+
+
+
+ public enum SensorWorkingMode {
+ LOCATION_GPS_INTERNAL, /* !< 设备内部GPS */
+ LOCATION_GPS_BLUETOOTH, /* !< 外接蓝牙GPS */
+ LOCATION_GPS_HYBIRD, /* !< 混合模式 */
+
+ CAMEAR_PHOTO_12MP, /* !< 相机拍照模式 1200万像素 */
+ CAMEAR_PHOTO_7MP, /* !< 相机拍照模式 7百万像素 */
+ CAMEAR_PHOTO_CONTINUOUS_PHOTO, /* !< 相机自身连拍模式 */
+
+ CAMERA_VEDIO_1080P, /* !< 相机录像模式 1008P */
+ CAMEAR_VEDIO_720P, /* !< 相机录像模式 720P */
+ CAMERA_VEDIO_TIMELAPSE, /* !< 相机录像模式 缩时 */
+
+ CAMERA_PHOTO_SINGLE/*单拍模式*/
+ }
+
+
+ public abstract enmSensorType GetSensorType();
+
+ public abstract enmConnectionStatus GetConnectionStatus();
+
+ public abstract enmConnectionStatus Connect(SensorParams params);
+
+ public abstract enmConnectionStatus DisConnect();
+
+ public abstract enmSignalQuality GetSignalQuality();
+
+ public abstract void GetGpsStatus();
+
+ public abstract void snapPicture(String picuuid);
+
+ public abstract void Search(boolean isReadCache);
+
+ public abstract void StopSearch();
+
+ public abstract void StartRecording();
+
+ public abstract void StopRecording();
+
+ public abstract int RegisterSensorEvent(
+ SensorEventListener sensorEventLister);
+
+ public abstract void SetMode(SensorWorkingMode sensorWorkingMode);
+
+}
diff --git a/collect-library/src/main/java/com/navinfo/collect/library/sensor/SensorEventListener.java b/collect-library/src/main/java/com/navinfo/collect/library/sensor/SensorEventListener.java
new file mode 100644
index 00000000..72131966
--- /dev/null
+++ b/collect-library/src/main/java/com/navinfo/collect/library/sensor/SensorEventListener.java
@@ -0,0 +1,14 @@
+package com.navinfo.collect.library.sensor;
+
+import com.navinfo.collect.library.sensor.ISensor.enmConnectionStatus;
+import com.navinfo.collect.library.sensor.ISensor.enmSignalQuality;
+
+public interface SensorEventListener {
+
+ public void OnSensorEvent();
+
+ public void OnConnectionStatusChanged(enmConnectionStatus cs);
+
+ public void OnSignalQualityChanged(enmSignalQuality sq);
+
+}
diff --git a/collect-library/src/main/java/com/navinfo/collect/library/sensor/SensorManager.java b/collect-library/src/main/java/com/navinfo/collect/library/sensor/SensorManager.java
new file mode 100644
index 00000000..d734fdc9
--- /dev/null
+++ b/collect-library/src/main/java/com/navinfo/collect/library/sensor/SensorManager.java
@@ -0,0 +1,60 @@
+package com.navinfo.collect.library.sensor;
+
+import android.content.Context;
+import android.os.Handler;
+import android.os.Looper;
+import com.navinfo.collect.library.garminvirbxe.CameraGarminVirbXE;
+import com.navinfo.collect.library.garminvirbxe.SensorParams;
+import com.navinfo.collect.library.sensor.ISensor.enmSensorModel;
+import com.navinfo.collect.library.sensor.ISensor.enmSensorType;
+import org.json.JSONObject;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.List;
+
+public class SensorManager {
+
+ private static volatile SensorManager mInstance;
+
+ private Context mContext;
+
+ private long diffTime = 0;
+
+ Handler mainHandler = new Handler(Looper.getMainLooper());
+
+ public static SensorManager getInstance() {
+ if (mInstance == null) {
+ synchronized (SensorManager.class) {
+ if (mInstance == null) {
+ mInstance = new SensorManager();
+ }
+ }
+ }
+ return mInstance;
+ }
+
+ public void init(Context context) {
+ mContext = context;
+ diffTime = context.getSharedPreferences("nowTime", Context.MODE_PRIVATE).getLong("THE_DIFFERENCE_VALUE", 0);
+ }
+
+ public static ISensor CreateSensor(Context mContext, enmSensorType type, enmSensorModel model) {
+
+ ISensor pSensorInstance = null;
+
+ if (type == enmSensorType.SENSOR_CAMEAR) { // Garmin 相机
+ if (model == enmSensorModel.CAMERA_GARMIN_VIRB_XE) {
+ pSensorInstance = new CameraGarminVirbXE(mContext);
+ } else {
+ pSensorInstance = new Camera(mContext);
+ }
+ }
+
+ return pSensorInstance;
+ }
+
+ public void setDiffTime(long diffValue) {
+ this.diffTime = diffValue;
+ }
+
+}
diff --git a/collect-library/src/main/java/com/navinfo/collect/library/system/VLCApplication.java b/collect-library/src/main/java/com/navinfo/collect/library/system/VLCApplication.java
new file mode 100644
index 00000000..250ab896
--- /dev/null
+++ b/collect-library/src/main/java/com/navinfo/collect/library/system/VLCApplication.java
@@ -0,0 +1,100 @@
+/*****************************************************************************
+ * VLCApplication.java
+ *****************************************************************************
+ * Copyright © 2010-2013 VLC authors and VideoLAN
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
+ *****************************************************************************/
+package com.navinfo.collect.library.system;
+
+import android.app.Application;
+import android.content.Context;
+import android.content.SharedPreferences;
+import android.content.res.Configuration;
+import android.content.res.Resources;
+import android.preference.PreferenceManager;
+import android.util.Log;
+import java.util.Locale;
+
+public class VLCApplication extends Application {
+ public final static String TAG = "VLC/VLCApplication";
+ private static VLCApplication instance;
+
+ public final static String SLEEP_INTENT = "org.videolan.vlc.SleepIntent";
+
+ @Override
+ public void onCreate() {
+ super.onCreate();
+
+ // Are we using advanced debugging - locale?
+ SharedPreferences pref = PreferenceManager.getDefaultSharedPreferences(this);
+ String p = pref.getString("set_locale", "");
+ if (p != null && !p.equals("")) {
+ Locale locale;
+ // workaround due to region code
+ if(p.equals("zh-TW")) {
+ locale = Locale.TRADITIONAL_CHINESE;
+ } else if(p.startsWith("zh")) {
+ locale = Locale.CHINA;
+ } else if(p.equals("pt-BR")) {
+ locale = new Locale("pt", "BR");
+ } else if(p.equals("bn-IN") || p.startsWith("bn")) {
+ locale = new Locale("bn", "IN");
+ } else {
+ /**
+ * Avoid a crash of
+ * java.lang.AssertionError: couldn't initialize LocaleData for locale
+ * if the user enters nonsensical region codes.
+ */
+ if(p.contains("-"))
+ p = p.substring(0, p.indexOf('-'));
+ locale = new Locale(p);
+ }
+ Locale.setDefault(locale);
+ Configuration config = new Configuration();
+ config.locale = locale;
+ getBaseContext().getResources().updateConfiguration(config,
+ getBaseContext().getResources().getDisplayMetrics());
+ }
+
+ instance = this;
+ }
+
+ /**
+ * Called when the overall system is running low on memory
+ */
+ @Override
+ public void onLowMemory() {
+ super.onLowMemory();
+ Log.w(TAG, "System is running low on memory");
+ }
+
+ /**
+ * @return the main context of the Application
+ */
+ public static Context getAppContext()
+ {
+ return instance;
+ }
+
+ /**
+ * @return the main resources from the Application
+ */
+ public static Resources getAppResources()
+ {
+ if(instance == null) return null;
+ return instance.getResources();
+ }
+}
diff --git a/collect-library/src/main/java/com/navinfo/collect/library/utils/DateUtils.java b/collect-library/src/main/java/com/navinfo/collect/library/utils/DateUtils.java
new file mode 100644
index 00000000..9cc897e7
--- /dev/null
+++ b/collect-library/src/main/java/com/navinfo/collect/library/utils/DateUtils.java
@@ -0,0 +1,60 @@
+package com.navinfo.collect.library.utils;
+
+import org.apache.commons.net.ntp.NTPUDPClient;
+import org.apache.commons.net.ntp.NtpV3Packet;
+import org.apache.commons.net.ntp.TimeInfo;
+
+import java.io.IOException;
+import java.net.InetAddress;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+
+
+/**
+ *
+ * @author manle
+ *
+ * Contains function adapt date times
+ */
+
+public class DateUtils {
+
+ /**
+ * Get date after sync from NTP
+ * @param hosts {@link String[]} hosts server NTP
+ * @param timeOut {@link Integer} milisecod
+ * @return Date
+ */
+ public static Date getNTPDate(String[] hosts, int timeOut) {
+ NTPUDPClient client = new NTPUDPClient();
+ client.setDefaultTimeout(timeOut);
+ for (String host : hosts) {
+ try {
+ InetAddress hostAddr = InetAddress.getByName(host);
+ TimeInfo info = client.getTime(hostAddr);
+ NtpV3Packet message = info.getMessage();
+ long serverTime = message.getTransmitTimeStamp().getTime();
+
+ Date date = new Date(serverTime);
+ return date;
+
+ }
+ catch (IOException e) {
+ }
+ }
+ client.close();
+ return null;
+ }
+
+ /**
+ * Format time
+ * @param date
+ * @return
+ */
+ public static String formatTime(final Date date){
+ SimpleDateFormat timeFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss:SSS");
+ String time = timeFormat.format(date);
+ return time;
+
+ }
+}
diff --git a/collect-library/src/main/java/com/navinfo/collect/library/utils/GeometryTools.java b/collect-library/src/main/java/com/navinfo/collect/library/utils/GeometryTools.java
index b1080d37..42f7500d 100644
--- a/collect-library/src/main/java/com/navinfo/collect/library/utils/GeometryTools.java
+++ b/collect-library/src/main/java/com/navinfo/collect/library/utils/GeometryTools.java
@@ -2,7 +2,6 @@ package com.navinfo.collect.library.utils;
import android.graphics.Point;
import android.util.Log;
-
import org.locationtech.jts.geom.Coordinate;
import org.locationtech.jts.geom.Geometry;
import org.locationtech.jts.geom.GeometryFactory;
@@ -15,7 +14,6 @@ import org.locationtech.jts.io.WKTReader;
import org.locationtech.jts.operation.linemerge.LineMerger;
import org.oscim.core.GeoPoint;
import org.oscim.map.Map;
-
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Collection;
@@ -69,6 +67,7 @@ public class GeometryTools {
}
+
/**
* 返回点几何
*
diff --git a/collect-library/src/main/java/com/navinfo/collect/library/utils/NetScanInfo.java b/collect-library/src/main/java/com/navinfo/collect/library/utils/NetScanInfo.java
new file mode 100644
index 00000000..0b2dc7c8
--- /dev/null
+++ b/collect-library/src/main/java/com/navinfo/collect/library/utils/NetScanInfo.java
@@ -0,0 +1,330 @@
+
+package com.navinfo.collect.library.utils;
+
+
+import android.content.Context;
+import android.content.SharedPreferences;
+import android.net.ConnectivityManager;
+import android.net.NetworkInfo;
+import android.net.wifi.SupplicantState;
+import android.net.wifi.WifiInfo;
+import android.net.wifi.WifiManager;
+import android.preference.PreferenceManager;
+import android.telephony.TelephonyManager;
+import android.util.Log;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.net.Inet4Address;
+import java.net.Inet6Address;
+import java.net.InetAddress;
+import java.net.NetworkInterface;
+import java.net.SocketException;
+import java.util.Enumeration;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+// TODO: IPv6 support
+
+public class NetScanInfo {
+ private final static String TAG = "NetInfo";
+ public static final int BUF = 8 * 1024;
+ private static final String CMD_IP = " -f inet addr show %s";
+ private static final String PTN_IP1 = "\\s*inet [0-9\\.]+\\/([0-9]+) brd [0-9\\.]+ scope global %s$";
+ private static final String PTN_IP2 = "\\s*inet [0-9\\.]+ peer [0-9\\.]+\\/([0-9]+) scope global %s$"; // FIXME:
+ // Merge
+ // with
+ // PTN_IP1
+ private static final String PTN_IF = "^%s: ip [0-9\\.]+ mask ([0-9\\.]+) flags.*";
+ private static final String NOIF = "0";
+ public static final String NOIP = "0.0.0.0";
+ public static final String NOMASK = "255.255.255.255";
+ public static final String NOMAC = "00:00:00:00:00:00";
+ private Context ctxt;
+ private WifiInfo info;
+ private SharedPreferences prefs;
+
+ public String intf = "eth0";
+ public String ip = NOIP;
+ public int cidr = 24;
+
+ public int speed = 0;
+ public String ssid = null;
+ public String bssid = null;
+ public String carrier = null;
+ public String macAddress = NOMAC;
+ public String netmaskIp = NOMASK;
+ public String gatewayIp = NOIP;
+
+ private final static String REQ = "select vendor from oui where mac=?";
+ // 0x1 is HW Type: Ethernet (10Mb) [JBP]
+ // 0x2 is ARP Flag: completed entry (ha valid)
+ public final static String MAC_RE = "^%s\\s+0x1\\s+0x2\\s+([:0-9a-fA-F]+)\\s+\\*\\s+\\w+$";
+
+ public NetScanInfo(final Context ctxt) {
+ this.ctxt = ctxt;
+ prefs = PreferenceManager.getDefaultSharedPreferences(ctxt);
+ getIp();
+ getWifiInfo();
+
+ }
+
+ @Override
+ public int hashCode() {
+ int ip_custom = prefs.getBoolean(NetScanPrefs.KEY_IP_CUSTOM,
+ NetScanPrefs.DEFAULT_IP_CUSTOM) ? 1 : 0;
+ int ip_start = prefs.getString(NetScanPrefs.KEY_IP_START,
+ NetScanPrefs.DEFAULT_IP_START).hashCode();
+ int ip_end = prefs.getString(NetScanPrefs.KEY_IP_END, NetScanPrefs.DEFAULT_IP_END)
+ .hashCode();
+ int cidr_custom = prefs.getBoolean(NetScanPrefs.KEY_CIDR_CUSTOM,
+ NetScanPrefs.DEFAULT_CIDR_CUSTOM) ? 1 : 0;
+ int cidr = prefs.getString(NetScanPrefs.KEY_CIDR, NetScanPrefs.DEFAULT_CIDR)
+ .hashCode();
+ return 42 + intf.hashCode() + ip.hashCode() + cidr + ip_custom
+ + ip_start + ip_end + cidr_custom + cidr;
+ }
+
+ public void getIp() {
+ intf = prefs.getString(NetScanPrefs.KEY_INTF, NetScanPrefs.DEFAULT_INTF);
+ try {
+ if (intf == NetScanPrefs.DEFAULT_INTF || NOIF.equals(intf)) {
+ // Automatic interface selection
+ for (Enumeration en = NetworkInterface
+ .getNetworkInterfaces(); en.hasMoreElements();) {
+ NetworkInterface ni = en.nextElement();
+ intf = ni.getName();
+ ip = getInterfaceFirstIp(ni);
+ if (ip != NOIP) {
+/* Log.i("AAA",intf+"");
+ Log.i("AAA",new String(ni.getHardwareAddress())+"");*/
+ break;
+ }
+ }
+ } else {
+ // Defined interface from Prefs
+ ip = getInterfaceFirstIp(NetworkInterface.getByName(intf));
+ }
+ } catch (SocketException e) {
+ Log.e(TAG, e.getMessage());
+ }
+ getCidr();
+ }
+
+ private String getInterfaceFirstIp(NetworkInterface ni) {
+ if (ni != null) {
+ for (Enumeration nis = ni.getInetAddresses(); nis
+ .hasMoreElements();) {
+ InetAddress ia = nis.nextElement();
+ if (!ia.isLoopbackAddress()) {
+ if (ia instanceof Inet6Address) {
+ Log.i(TAG, "IPv6 detected and not supported yet!");
+ continue;
+ }
+ return ia.getHostAddress();
+ }
+ }
+ }
+ return NOIP;
+ }
+
+ private void getCidr() {
+ if (netmaskIp != NOMASK) {
+ cidr = IpToCidr(netmaskIp);
+ } else {
+ String match;
+ // Running ip tools
+ try {
+ if ((match = runCommand("/system/xbin/ip",
+ String.format(CMD_IP, intf),
+ String.format(PTN_IP1, intf))) != null) {
+ cidr = Integer.parseInt(match);
+ return;
+ } else if ((match = runCommand("/system/xbin/ip",
+ String.format(CMD_IP, intf),
+ String.format(PTN_IP2, intf))) != null) {
+ cidr = Integer.parseInt(match);
+ return;
+ } else if ((match = runCommand("/system/bin/ifconfig", " "
+ + intf, String.format(PTN_IF, intf))) != null) {
+ cidr = IpToCidr(match);
+ return;
+ } else {
+ Log.i(TAG, "cannot find cidr, using default /24");
+ }
+ } catch (NumberFormatException e) {
+ Log.i(TAG, e.getMessage()
+ + " -> cannot find cidr, using default /24");
+ }
+ }
+ }
+
+ // FIXME: Factorize, this isn't a generic runCommand()
+ private String runCommand(String path, String cmd, String ptn) {
+ try {
+ if (new File(path).exists() == true) {
+ String line;
+ Matcher matcher;
+ Pattern ptrn = Pattern.compile(ptn);
+ Process p = Runtime.getRuntime().exec(path + cmd);
+ BufferedReader r = new BufferedReader(new InputStreamReader(
+ p.getInputStream()), BUF);
+ while ((line = r.readLine()) != null) {
+ matcher = ptrn.matcher(line);
+ if (matcher.matches()) {
+ return matcher.group(1);
+ }
+ }
+ }
+ } catch (Exception e) {
+ Log.e(TAG, "Can't use native command: " + e.getMessage());
+ return null;
+ }
+ return null;
+ }
+
+ public boolean getMobileInfo() {
+ TelephonyManager tm = (TelephonyManager) ctxt
+ .getSystemService(Context.TELEPHONY_SERVICE);
+ if (tm != null) {
+ carrier = tm.getNetworkOperatorName();
+ }
+ return false;
+ }
+
+ public boolean getWifiInfo() {
+ WifiManager wifi = (WifiManager) ctxt
+ .getSystemService(Context.WIFI_SERVICE);
+ if (wifi != null) {
+ info = wifi.getConnectionInfo();
+ // Set wifi variables
+ speed = info.getLinkSpeed();
+ ssid = info.getSSID();
+ bssid = info.getBSSID();
+ macAddress = info.getMacAddress();
+ gatewayIp = getIpFromIntSigned(wifi.getDhcpInfo().gateway);
+ // broadcastIp = getIpFromIntSigned((dhcp.ipAddress & dhcp.netmask)
+ // | ~dhcp.netmask);
+ netmaskIp = getIpFromIntSigned(wifi.getDhcpInfo().netmask);
+ return true;
+ }
+ return false;
+ }
+
+ public String getNetIp() {
+ int shift = (32 - cidr);
+ int start = ((int) getUnsignedLongFromIp(ip) >> shift << shift);
+ return getIpFromLongUnsigned(start);
+ }
+
+ public SupplicantState getSupplicantState() {
+ return info.getSupplicantState();
+ }
+
+ public static boolean isConnected(Context ctxt) {
+ NetworkInfo nfo = ((ConnectivityManager) ctxt
+ .getSystemService(Context.CONNECTIVITY_SERVICE))
+ .getActiveNetworkInfo();
+ if (nfo != null) {
+ return nfo.isConnected();
+ }
+ return false;
+ }
+
+ //获取本地ip地址
+ public static String getLocAddress(){
+
+ String ipaddress = "";
+
+ try {
+ Enumeration en = NetworkInterface.getNetworkInterfaces();
+ // 遍历所用的网络接口
+ while (en.hasMoreElements()) {
+ NetworkInterface networks = en.nextElement();
+ // 得到每一个网络接口绑定的所有ip
+ Enumeration address = networks.getInetAddresses();
+ // 遍历每一个接口绑定的所有ip
+ while (address.hasMoreElements()) {
+ InetAddress ip = address.nextElement();
+ if (!ip.isLoopbackAddress()
+ && ip instanceof Inet4Address) {
+ ipaddress = ip.getHostAddress();
+ }
+ }
+ }
+ } catch (SocketException e) {
+ Log.e("", "获取本地ip地址失败");
+ e.printStackTrace();
+ }
+
+ return ipaddress;
+
+ }
+
+ public static long getUnsignedLongFromIp(String ip_addr) {
+ String[] a = ip_addr.split("\\.");
+ return (Integer.parseInt(a[0]) * 16777216 + Integer.parseInt(a[1])
+ * 65536 + Integer.parseInt(a[2]) * 256 + Integer.parseInt(a[3]));
+ }
+
+ public static String getIpFromIntSigned(int ip_int) {
+ String ip = "";
+ for (int k = 0; k < 4; k++) {
+ ip = ip + ((ip_int >> k * 8) & 0xFF) + ".";
+ }
+ return ip.substring(0, ip.length() - 1);
+ }
+
+ public static String getIpFromLongUnsigned(long ip_long) {
+ String ip = "";
+ for (int k = 3; k > -1; k--) {
+ ip = ip + ((ip_long >> k * 8) & 0xFF) + ".";
+ }
+ return ip.substring(0, ip.length() - 1);
+ }
+
+ private int IpToCidr(String ip) {
+ double sum = -2;
+ String[] part = ip.split("\\.");
+ for (String p : part) {
+ sum += 256D - Double.parseDouble(p);
+ }
+ return 32 - (int) (Math.log(sum) / Math.log(2d));
+ }
+
+ //根据ip解析mac
+ public String getHardwareAddress(String ip) {
+ try {
+ synchronized (this){
+ if (ip != null) {
+ Log.e(TAG, "开始=="+ip);
+ String hw = NOMAC;
+ String ptrn = String.format(MAC_RE, ip.replace(".", "\\."));
+ Pattern pattern = Pattern.compile(ptrn);
+ BufferedReader bufferedReader = new BufferedReader(new FileReader("/proc/net/arp"), BUF);
+ String line;
+ Matcher matcher;
+ while ((line = bufferedReader.readLine()) != null) {
+ matcher = pattern.matcher(line);
+ if (matcher.matches()) {
+ hw = matcher.group(1);
+ break;
+ }
+ }
+ bufferedReader.close();
+ Log.e(TAG, "结束=="+hw);
+ return hw;
+ } else {
+ Log.e(TAG, "ip is null");
+ }
+ }
+ } catch (IOException e) {
+ Log.e(TAG, "Can't open/read file ARP: " + e.getMessage());
+ return NOMAC;
+ }
+ return NOMAC;
+ }
+}
diff --git a/collect-library/src/main/java/com/navinfo/collect/library/utils/NetScanPrefs.java b/collect-library/src/main/java/com/navinfo/collect/library/utils/NetScanPrefs.java
new file mode 100644
index 00000000..2b3d1776
--- /dev/null
+++ b/collect-library/src/main/java/com/navinfo/collect/library/utils/NetScanPrefs.java
@@ -0,0 +1,32 @@
+package com.navinfo.collect.library.utils;
+
+public class NetScanPrefs {
+
+ public final static String KEY_RESOLVE_NAME = "resolve_name";
+ public final static boolean DEFAULT_RESOLVE_NAME = true;
+
+ public static final String KEY_RATECTRL_ENABLE = "ratecontrol_enable";
+ public static final boolean DEFAULT_RATECTRL_ENABLE = true;
+
+ public final static String KEY_TIMEOUT_DISCOVER = "timeout_discover";
+ public final static String DEFAULT_TIMEOUT_DISCOVER = "500";
+
+ public static final String KEY_INTF = "interface";
+ public static final String DEFAULT_INTF = null;
+
+ public static final String KEY_IP_START = "ip_start";
+ public static final String DEFAULT_IP_START = "0.0.0.0";
+
+ public static final String KEY_IP_END = "ip_end";
+ public static final String DEFAULT_IP_END = "0.0.0.0";
+
+ public static final String KEY_IP_CUSTOM = "ip_custom";
+ public static final boolean DEFAULT_IP_CUSTOM = false;
+
+ public static final String KEY_CIDR_CUSTOM = "cidr_custom";
+ public static final boolean DEFAULT_CIDR_CUSTOM = false;
+
+ public static final String KEY_CIDR = "cidr";
+ public static final String DEFAULT_CIDR = "24";
+
+}
diff --git a/collect-library/src/main/java/com/navinfo/collect/library/utils/PreferencesUtils.java b/collect-library/src/main/java/com/navinfo/collect/library/utils/PreferencesUtils.java
new file mode 100644
index 00000000..7b261854
--- /dev/null
+++ b/collect-library/src/main/java/com/navinfo/collect/library/utils/PreferencesUtils.java
@@ -0,0 +1,94 @@
+package com.navinfo.collect.library.utils;
+
+import android.content.Context;
+import android.content.SharedPreferences;
+
+public class PreferencesUtils {
+ protected static final String XML_NAME = "cjzq_trade";
+ protected static final String KEEP_NOTIFICATION_FLAG = "notification_flag";
+
+ private static SharedPreferences getSharedPreferences(Context context) {
+ return context.getSharedPreferences(XML_NAME, Context.MODE_PRIVATE);
+ }
+
+ public static String getMsgNotificationFlag(Context context) {
+ SharedPreferences sp = getSharedPreferences(context);
+ return sp.getString(KEEP_NOTIFICATION_FLAG, "1");
+ }
+
+ /**
+ *
+ * @param context
+ * @param flag
+ */
+ public static void saveMsgNotificationFlag(Context context, String flag) {
+ SharedPreferences sp = getSharedPreferences(context);
+ SharedPreferences.Editor editor = sp.edit();
+ editor.putString(KEEP_NOTIFICATION_FLAG, flag);
+ editor.commit();
+ }
+
+ /**
+ * 保存sp值
+ *
+ * @param context
+ * @param name
+ * @param flag
+ */
+ public static void saveSpText(Context context, String key, String value) {
+ SharedPreferences sp = getSharedPreferences(context);
+ SharedPreferences.Editor editor = sp.edit();
+ editor.putString(key, value);
+ editor.commit();
+ }
+
+ /**
+ * 获取值
+ *
+ * @param context
+ * @param name
+ * @return
+ */
+ public static String getSpText(Context context, String key) {
+ SharedPreferences sp = getSharedPreferences(context);
+ return sp.getString(key, "");
+ }
+
+ /**
+ * 移除值
+ *
+ * @param context
+ * @param name
+ * @return
+ */
+ public static void removeSpText(Context context, String name) {
+ SharedPreferences sp = getSharedPreferences(context);
+ SharedPreferences.Editor editor = sp.edit();
+ editor.remove(name);
+ editor.commit();
+ }
+
+ public static String getConnectIp(Context context, String key) {
+ SharedPreferences sp = getSharedPreferences(context);
+ return sp.getString(key, "");
+ }
+
+ public static void saveConnectIp(Context context,String key, String ip) {
+ SharedPreferences sp = getSharedPreferences(context);
+ SharedPreferences.Editor editor = sp.edit();
+ editor.putString(key, ip);
+ editor.commit();
+ }
+
+ public static String getConnectWifiName(Context context) {
+ SharedPreferences sp = getSharedPreferences(context);
+ return sp.getString("connectwifiname", "");
+ }
+
+ public static void saveConnectWifiName(Context context, String name) {
+ SharedPreferences sp = getSharedPreferences(context);
+ SharedPreferences.Editor editor = sp.edit();
+ editor.putString("connectwifiname", name);
+ editor.commit();
+ }
+}
diff --git a/collect-library/src/main/java/com/navinfo/collect/library/utils/SensorUtils.java b/collect-library/src/main/java/com/navinfo/collect/library/utils/SensorUtils.java
new file mode 100644
index 00000000..8a57410c
--- /dev/null
+++ b/collect-library/src/main/java/com/navinfo/collect/library/utils/SensorUtils.java
@@ -0,0 +1,124 @@
+package com.navinfo.collect.library.utils;
+
+import android.content.Context;
+import android.graphics.Bitmap;
+import android.net.ConnectivityManager;
+import android.net.NetworkInfo;
+import android.os.Environment;
+import android.text.format.DateUtils;
+
+import com.navinfo.collect.library.garminvirbxe.CameraGarminVirbXE;
+
+import org.apache.commons.lang3.StringUtils;
+import java.io.BufferedOutputStream;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.util.Date;
+
+public class SensorUtils {
+ public static String STR_CAMERA_PICTURE_SAVEPATH = Environment
+ .getExternalStorageDirectory() + "/Sensor/Camera/DCIM/";
+ public static String ntpHosts = "0.ir.pool.ntp.org,1.ir.pool.ntp.org,2.ir.pool.ntp.org,3.ir.pool.ntp.org";
+
+ // 由于连接命令和扫描测试通讯命令相同,需要通过不通返回来确认。
+ public final static int HADNLE_STATUS_OK = 1; // 获取状态成功返回handle
+ public final static int HADNLE_STATUS_FAIL = 0; // 获取状态失败返回handle
+ public final static int HADNLE_CONNECT_OK = 2; // 连接成功返回handle
+ public final static int HADNLE_CONNECT_FAIL = 3; // 连接失败返回handle
+ public final static int HADNLE_SNAPPICTURE = 4; // 失败返回handle
+
+ public final static int HADNLE_MONITORING = 5; // 状态监控失败返回handle
+
+ /**
+ * 保存文件
+ *
+ * @param bm
+ * @param fileName
+ * @throws IOException
+ */
+ public static void saveFile(Bitmap bm, String fileName) throws IOException {
+ String savePath = CameraGarminVirbXE.getCameraPcitureSavePath();
+ File dirFile = new File(savePath);
+ if (!dirFile.exists()) {
+ dirFile.mkdirs();
+ }
+ File myCaptureFile = new File(savePath + fileName);
+ BufferedOutputStream bos = new BufferedOutputStream(
+ new FileOutputStream(myCaptureFile));
+ bm.compress(Bitmap.CompressFormat.JPEG, 80, bos);
+ bos.flush();
+ bos.close();
+ }
+
+ /*
+ * Java文件操作 获取文件扩展名
+ */
+ public static String getExtensionName(String filename) {
+ if ((filename != null) && (filename.length() > 0)) {
+ int dot = filename.lastIndexOf('.');
+ if ((dot > -1) && (dot < (filename.length() - 1))) {
+ return filename.substring(dot + 1);
+ }
+ }
+ return filename;
+ }
+
+ /*
+ * Java文件操作 获取不带扩展名的文件名
+ */
+ public static String getFileNameNoEx(String filename) {
+ if ((filename != null) && (filename.length() > 0)) {
+ int dot = filename.lastIndexOf('.');
+ if ((dot > -1) && (dot < (filename.length()))) {
+ return filename.substring(0, dot);
+ }
+ }
+ return filename;
+ }
+
+ /**
+ * 检测网络是否连接
+ *
+ * @return
+ */
+ public static boolean isNetworkAvailable(Context context)
+ {
+ // 获取手机所有连接管理对象(包括对wi-fi,net等连接的管理)
+ ConnectivityManager connectivityManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
+
+ if (connectivityManager == null){
+ return false;
+ }else{
+ // 获取NetworkInfo对象
+ NetworkInfo[] networkInfo = connectivityManager.getAllNetworkInfo();
+
+ if (networkInfo != null && networkInfo.length > 0){
+ for (int i = 0; i < networkInfo.length; i++){
+ System.out.println(i + "===状态===" + networkInfo[i].getState());
+ // System.out.println(i + "===类型===" + networkInfo[i].getTypeName());
+ // 判断当前网络状态是否为连接状态
+ if (networkInfo[i].getState() == NetworkInfo.State.CONNECTED){
+ return true;
+ }
+ }
+ }
+ }
+ return false;
+ }
+
+ /**
+ * 同步ntp服务器的网络时间
+ * @return
+ */
+ public static Date syncNow(){
+ String[] hostsArrayNTP = null;
+ if(StringUtils.isNotBlank(ntpHosts)){
+ hostsArrayNTP =ntpHosts.trim().split(",");
+ }
+
+ Date dateNTP = com.navinfo.collect.library.utils.DateUtils.getNTPDate(hostsArrayNTP, 5000);
+
+ return dateNTP;
+ }
+}
diff --git a/collect-library/src/main/java/org/videolan/libvlc/Aout.java b/collect-library/src/main/java/org/videolan/libvlc/Aout.java
new file mode 100644
index 00000000..971f6494
--- /dev/null
+++ b/collect-library/src/main/java/org/videolan/libvlc/Aout.java
@@ -0,0 +1,74 @@
+/*****************************************************************************
+ * Aout.java
+ *****************************************************************************
+ * Copyright © 2011-2012 VLC authors and VideoLAN
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
+ *****************************************************************************/
+
+package org.videolan.libvlc;
+
+import android.media.AudioFormat;
+import android.media.AudioManager;
+import android.media.AudioTrack;
+import android.util.Log;
+
+public class Aout {
+ /**
+ * Java side of the audio output module for Android.
+ * Uses an AudioTrack to play decoded audio buffers.
+ *
+ * TODO Use MODE_STATIC instead of MODE_STREAM with a MemoryFile (ashmem)
+ */
+
+ public Aout() {
+ }
+
+ private AudioTrack mAudioTrack;
+ private static final String TAG = "LibVLC/aout";
+
+ public void init(int sampleRateInHz, int channels, int samples) {
+ Log.d(TAG, sampleRateInHz + ", " + channels + ", " + samples + "=>" + channels * samples);
+ int minBufferSize = AudioTrack.getMinBufferSize(sampleRateInHz,
+ AudioFormat.CHANNEL_OUT_STEREO,
+ AudioFormat.ENCODING_PCM_16BIT);
+ mAudioTrack = new AudioTrack(AudioManager.STREAM_MUSIC,
+ sampleRateInHz,
+ AudioFormat.CHANNEL_OUT_STEREO,
+ AudioFormat.ENCODING_PCM_16BIT,
+ Math.max(minBufferSize, channels * samples * 2),
+ AudioTrack.MODE_STREAM);
+ }
+
+ public void release() {
+ if (mAudioTrack != null) {
+ mAudioTrack.release();
+ }
+ mAudioTrack = null;
+ }
+
+ public void playBuffer(byte[] audioData, int bufferSize) {
+ if (mAudioTrack.getState() == AudioTrack.STATE_UNINITIALIZED)
+ return;
+ if (mAudioTrack.write(audioData, 0, bufferSize) != bufferSize) {
+ Log.w(TAG, "Could not write all the samples to the audio device");
+ }
+ mAudioTrack.play();
+ }
+
+ public void pause() {
+ mAudioTrack.pause();
+ }
+}
diff --git a/collect-library/src/main/java/org/videolan/libvlc/EventHandler.java b/collect-library/src/main/java/org/videolan/libvlc/EventHandler.java
new file mode 100644
index 00000000..e012b4bc
--- /dev/null
+++ b/collect-library/src/main/java/org/videolan/libvlc/EventHandler.java
@@ -0,0 +1,123 @@
+/*****************************************************************************
+ * EventHandler.java
+ *****************************************************************************
+ * Copyright © 2011-2012 VLC authors and VideoLAN
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
+ *****************************************************************************/
+
+package org.videolan.libvlc;
+
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.Message;
+
+import java.util.ArrayList;
+
+public class EventHandler {
+
+ /*
+ * Be sure to subscribe to events you need in the JNI too.
+ */
+
+ public static final int MediaMetaChanged = 0;
+ //public static final int MediaSubItemAdded = 1;
+ //public static final int MediaDurationChanged = 2;
+ //public static final int MediaParsedChanged = 3;
+ //public static final int MediaFreed = 4;
+ //public static final int MediaStateChanged = 5;
+
+ //public static final int MediaPlayerMediaChanged = 0x100;
+ //public static final int MediaPlayerNothingSpecial = 0x101;
+ //public static final int MediaPlayerOpening = 0x102;
+ //public static final int MediaPlayerBuffering = 0x103;
+ public static final int MediaPlayerPlaying = 0x104;
+ public static final int MediaPlayerPaused = 0x105;
+ public static final int MediaPlayerStopped = 0x106;
+ //public static final int MediaPlayerForward = 0x107;
+ //public static final int MediaPlayerBackward = 0x108;
+ public static final int MediaPlayerEndReached = 0x109;
+ public static final int MediaPlayerEncounteredError = 0x10a;
+ //public static final int MediaPlayerTimeChanged = 0x10b;
+ public static final int MediaPlayerPositionChanged = 0x10c;
+ //public static final int MediaPlayerSeekableChanged = 0x10d;
+ //public static final int MediaPlayerPausableChanged = 0x10e;
+ //public static final int MediaPlayerTitleChanged = 0x10f;
+ //public static final int MediaPlayerSnapshotTaken = 0x110;
+ //public static final int MediaPlayerLengthChanged = 0x111;
+ public static final int MediaPlayerVout = 0x112;
+
+ public static final int MediaListItemAdded = 0x200;
+ //public static final int MediaListWillAddItem = 0x201;
+ public static final int MediaListItemDeleted = 0x202;
+ //public static final int MediaListWillDeleteItem = 0x203;
+
+ //public static final int MediaListViewItemAdded = 0x300;
+ //public static final int MediaListViewWillAddItem = 0x301;
+ //public static final int MediaListViewItemDeleted = 0x302;
+ //public static final int MediaListViewWillDeleteItem = 0x303;
+
+ //public static final int MediaListPlayerPlayed = 0x400;
+ //public static final int MediaListPlayerNextItemSet = 0x401;
+ //public static final int MediaListPlayerStopped = 0x402;
+
+ //public static final int MediaDiscovererStarted = 0x500;
+ //public static final int MediaDiscovererEnded = 0x501;
+
+ //public static final int VlmMediaAdded = 0x600;
+ //public static final int VlmMediaRemoved = 0x601;
+ //public static final int VlmMediaChanged = 0x602;
+ //public static final int VlmMediaInstanceStarted = 0x603;
+ //public static final int VlmMediaInstanceStopped = 0x604;
+ //public static final int VlmMediaInstanceStatusInit = 0x605;
+ //public static final int VlmMediaInstanceStatusOpening = 0x606;
+ //public static final int VlmMediaInstanceStatusPlaying = 0x607;
+ //public static final int VlmMediaInstanceStatusPause = 0x608;
+ //public static final int VlmMediaInstanceStatusEnd = 0x609;
+ //public static final int VlmMediaInstanceStatusError = 0x60a;
+
+ private ArrayList mEventHandler;
+ private static EventHandler mInstance;
+
+ EventHandler() {
+ mEventHandler = new ArrayList();
+ }
+
+ public static EventHandler getInstance() {
+ if (mInstance == null) {
+ mInstance = new EventHandler();
+ }
+ return mInstance;
+ }
+
+ public void addHandler(Handler handler) {
+ if (!mEventHandler.contains(handler))
+ mEventHandler.add(handler);
+ }
+
+ public void removeHandler(Handler handler) {
+ mEventHandler.remove(handler);
+ }
+
+ /** This method is called by a native thread **/
+ public void callback(int event, Bundle b) {
+ b.putInt("event", event);
+ for (int i = 0; i < mEventHandler.size(); i++) {
+ Message msg = Message.obtain();
+ msg.setData(b);
+ mEventHandler.get(i).sendMessage(msg);
+ }
+ }
+}
diff --git a/collect-library/src/main/java/org/videolan/libvlc/IVideoPlayer.java b/collect-library/src/main/java/org/videolan/libvlc/IVideoPlayer.java
new file mode 100644
index 00000000..c714b5b3
--- /dev/null
+++ b/collect-library/src/main/java/org/videolan/libvlc/IVideoPlayer.java
@@ -0,0 +1,34 @@
+/*****************************************************************************
+ * IVideoPlayer.java
+ *****************************************************************************
+ * Copyright © 2010-2013 VLC authors and VideoLAN
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
+ *****************************************************************************/
+
+package org.videolan.libvlc;
+
+public interface IVideoPlayer {
+ /**
+ * This method is called by native vout to request a surface resize when frame size doesn't match surface size.
+ * @param width Frame width
+ * @param height Frame height
+ * @param visible_width Visible frame width
+ * @param visible_height Visible frame height
+ * @param sar_num Surface aspect ratio numerator
+ * @param sar_den Surface aspect ratio denominator
+ */
+ void setSurfaceSize(int width, int height, int visible_width, int visible_height, int sar_num, int sar_den);
+}
diff --git a/collect-library/src/main/java/org/videolan/libvlc/LibVLC.java b/collect-library/src/main/java/org/videolan/libvlc/LibVLC.java
new file mode 100644
index 00000000..fb941165
--- /dev/null
+++ b/collect-library/src/main/java/org/videolan/libvlc/LibVLC.java
@@ -0,0 +1,653 @@
+/*****************************************************************************
+ * LibVLC.java
+ *****************************************************************************
+ * Copyright © 2010-2013 VLC authors and VideoLAN
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
+ *****************************************************************************/
+
+package org.videolan.libvlc;
+
+import android.content.Context;
+import android.os.Build;
+import android.util.Log;
+import android.view.Surface;
+
+import java.util.ArrayList;
+import java.util.Map;
+
+public class LibVLC {
+ private static final String TAG = "VLC/LibVLC";
+ public static final int AOUT_AUDIOTRACK_JAVA = 0;
+ public static final int AOUT_AUDIOTRACK = 1;
+ public static final int AOUT_OPENSLES = 2;
+
+ private static LibVLC sInstance;
+
+ /** libVLC instance C pointer */
+ private long mLibVlcInstance = 0; // Read-only, reserved for JNI
+ /** libvlc_media_player pointer and index */
+ private int mInternalMediaPlayerIndex = 0; // Read-only, reserved for JNI
+ private long mInternalMediaPlayerInstance = 0; // Read-only, reserved for JNI
+
+ private MediaList mMediaList; // Pointer to media list being followed
+ private MediaList mPrimaryList; // Primary/default media list; see getPrimaryMediaList()
+
+ /** Buffer for VLC messages */
+ private StringBuffer mDebugLogBuffer;
+ private boolean mIsBufferingLog = false;
+
+ private Aout mAout;
+
+ /** Keep screen bright */
+ //private WakeLock mWakeLock;
+
+ /** Settings */
+ private boolean iomx = false;
+ private String subtitlesEncoding = "";
+ private int aout = LibVlcUtil.isGingerbreadOrLater() ? AOUT_OPENSLES : AOUT_AUDIOTRACK_JAVA;
+ private boolean timeStretching = false;
+ private int deblocking = -1;
+ private String chroma = "";
+ private boolean verboseMode = true;
+ private float[] equalizer = null;
+ private boolean frameSkip = false;
+ private int networkCaching = 0;
+
+ /** Check in libVLC already initialized otherwise crash */
+ private boolean mIsInitialized = false;
+ public native void attachSurface(Surface surface, IVideoPlayer player, int width, int height);
+
+ public native void detachSurface();
+
+ /* Load library before object instantiation */
+ static {
+ try {
+ if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.GINGERBREAD_MR1)
+ System.loadLibrary("iomx-gingerbread");
+ else if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.HONEYCOMB_MR2)
+ System.loadLibrary("iomx-hc");
+ else
+ System.loadLibrary("iomx-ics");
+ } catch (Throwable t) {
+ Log.w(TAG, "Unable to load the iomx library: " + t);
+ }
+ try {
+ System.loadLibrary("vlcjni");
+ } catch (UnsatisfiedLinkError ule) {
+ Log.e(TAG, "Can't load vlcjni library: " + ule);
+ /// FIXME Alert user
+ System.exit(1);
+ } catch (SecurityException se) {
+ Log.e(TAG, "Encountered a security issue when loading vlcjni library: " + se);
+ /// FIXME Alert user
+ System.exit(1);
+ }
+ }
+
+ /**
+ * Singleton constructor of libVLC Without surface and vout to create the
+ * thumbnail and get information e.g. on the MediaLibraryActivity
+ *
+ * @return libVLC instance
+ * @throws LibVlcException
+ */
+ public static LibVLC getInstance() throws LibVlcException {
+ synchronized (LibVLC.class) {
+ if (sInstance == null) {
+ /* First call */
+ sInstance = new LibVLC();
+ }
+ }
+
+ return sInstance;
+ }
+
+ /**
+ * Return an existing instance of libVLC Call it when it is NOT important
+ * that this fails
+ *
+ * @return libVLC instance OR null
+ */
+ public static LibVLC getExistingInstance() {
+ synchronized (LibVLC.class) {
+ return sInstance;
+ }
+ }
+
+ /**
+ * Constructor
+ * It is private because this class is a singleton.
+ */
+ private LibVLC() {
+ mAout = new Aout();
+ }
+
+ /**
+ * Destructor:
+ * It is bad practice to rely on them, so please don't forget to call
+ * destroy() before exiting.
+ */
+ @Override
+ public void finalize() {
+ if (mLibVlcInstance != 0) {
+ Log.d(TAG, "LibVLC is was destroyed yet before finalize()");
+ destroy();
+ }
+ }
+
+ /**
+ * Get the media list that LibVLC is following right now.
+ *
+ * @return The media list object being followed
+ */
+ public MediaList getMediaList() {
+ return mMediaList;
+ }
+
+ /**
+ * Set the media list for LibVLC to follow.
+ *
+ * @param mediaList The media list object to follow
+ */
+ public void setMediaList(MediaList mediaList) {
+ mMediaList = mediaList;
+ }
+
+ /**
+ * Sets LibVLC to follow the default media list (see below)
+ */
+ public void setMediaList() {
+ mMediaList = mPrimaryList;
+ }
+
+ /**
+ * Gets the primary media list, or the "currently playing" list.
+ * Not to be confused with the media list pointer from above, which
+ * refers the the MediaList object that libVLC is currently following.
+ * This list is just one out of many lists that it can be pointed towards.
+ *
+ * This list will be used for lists of songs that are not user-defined.
+ * For example: selecting a song from the Songs list, or from the list
+ * displayed after selecting an album.
+ *
+ * It is loaded as the default list.
+ *
+ * @return The primary media list
+ */
+ public MediaList getPrimaryMediaList() {
+ return mPrimaryList;
+ }
+
+ /**
+ * Give to LibVLC the surface to draw the video.
+ * @param f the surface to draw
+ */
+ public native void setSurface(Surface f);
+
+ public static synchronized void restart(Context context) {
+ if (sInstance != null) {
+ try {
+ sInstance.destroy();
+ sInstance.init(context);
+ } catch (LibVlcException lve) {
+ Log.e(TAG, "Unable to reinit libvlc: " + lve);
+ }
+ }
+ }
+
+ /**
+ * those get/is* are called from native code to get settings values.
+ */
+
+ public boolean useIOMX() {
+ return iomx;
+ }
+
+ public void setIomx(boolean iomx) {
+ this.iomx = iomx;
+ }
+
+ public String getSubtitlesEncoding() {
+ return subtitlesEncoding;
+ }
+
+ public void setSubtitlesEncoding(String subtitlesEncoding) {
+ this.subtitlesEncoding = subtitlesEncoding;
+ }
+
+ public int getAout() {
+ return aout;
+ }
+
+ public void setAout(int aout) {
+ if (aout < 0)
+ this.aout = LibVlcUtil.isGingerbreadOrLater() ? AOUT_OPENSLES : AOUT_AUDIOTRACK_JAVA;
+ else
+ this.aout = aout;
+ }
+
+ public boolean timeStretchingEnabled() {
+ return timeStretching;
+ }
+
+ public void setTimeStretching(boolean timeStretching) {
+ this.timeStretching = timeStretching;
+ }
+
+ public int getDeblocking() {
+ int ret = deblocking;
+ if(deblocking < 0) {
+ /**
+ * Set some reasonable deblocking defaults:
+ *
+ * Skip all (4) for armv6 and MIPS by default
+ * Skip non-ref (1) for all armv7 more than 1.2 Ghz and more than 2 cores
+ * Skip non-key (3) for all devices that don't meet anything above
+ */
+ LibVlcUtil.MachineSpecs m = LibVlcUtil.getMachineSpecs();
+ if( (m.hasArmV6 && !(m.hasArmV7)) || m.hasMips )
+ ret = 4;
+ else if(m.bogoMIPS > 1200 && m.processors > 2)
+ ret = 1;
+ else
+ ret = 3;
+ } else if(deblocking > 4) { // sanity check
+ ret = 3;
+ }
+ return ret;
+ }
+
+ public void setDeblocking(int deblocking) {
+ this.deblocking = deblocking;
+ }
+
+ public String getChroma() {
+ return chroma;
+ }
+
+ public void setChroma(String chroma) {
+ this.chroma = chroma.equals("YV12") && !LibVlcUtil.isGingerbreadOrLater() ? "" : chroma;
+ }
+
+ public boolean isVerboseMode() {
+ return verboseMode;
+ }
+
+ public void setVerboseMode(boolean verboseMode) {
+ this.verboseMode = verboseMode;
+ }
+
+ public float[] getEqualizer()
+ {
+ return equalizer;
+ }
+
+ public void setEqualizer(float[] equalizer)
+ {
+ this.equalizer = equalizer;
+ applyEqualizer();
+ }
+
+ private void applyEqualizer()
+ {
+ setNativeEqualizer(mInternalMediaPlayerInstance, this.equalizer);
+ }
+ private native int setNativeEqualizer(long mediaPlayer, float[] bands);
+
+ public boolean frameSkipEnabled() {
+ return frameSkip;
+ }
+
+ public void setFrameSkip(boolean frameskip) {
+ this.frameSkip = frameskip;
+ }
+
+ public int getNetworkCaching() {
+ return this.networkCaching;
+ }
+
+ public void setNetworkCaching(int networkcaching) {
+ this.networkCaching = networkcaching;
+ }
+
+ /**
+ * Initialize the libVLC class
+ */
+ public void init(Context context) throws LibVlcException {
+ Log.v(TAG, "Initializing LibVLC");
+ mDebugLogBuffer = new StringBuffer();
+ if (!mIsInitialized) {
+ if(!LibVlcUtil.hasCompatibleCPU(context)) {
+ Log.e(TAG, LibVlcUtil.getErrorMsg());
+ throw new LibVlcException();
+ }
+ nativeInit();
+ mMediaList = mPrimaryList = new MediaList(this);
+ setEventHandler(EventHandler.getInstance());
+ mIsInitialized = true;
+ }
+ }
+
+ /**
+ * Destroy this libVLC instance
+ * @note You must call it before exiting
+ */
+ public void destroy() {
+ Log.v(TAG, "Destroying LibVLC instance");
+ nativeDestroy();
+ detachEventHandler();
+ mIsInitialized = false;
+ }
+
+ /**
+ * Open the Java audio output.
+ * This function is called by the native code
+ */
+ public void initAout(int sampleRateInHz, int channels, int samples) {
+ Log.d(TAG, "Opening the java audio output");
+ mAout.init(sampleRateInHz, channels, samples);
+ }
+
+ /**
+ * Play an audio buffer taken from the native code
+ * This function is called by the native code
+ */
+ public void playAudio(byte[] audioData, int bufferSize) {
+ mAout.playBuffer(audioData, bufferSize);
+ }
+
+ /**
+ * Pause the Java audio output
+ * This function is called by the native code
+ */
+ public void pauseAout() {
+ Log.d(TAG, "Pausing the java audio output");
+ mAout.pause();
+ }
+
+ /**
+ * Close the Java audio output
+ * This function is called by the native code
+ */
+ public void closeAout() {
+ Log.d(TAG, "Closing the java audio output");
+ mAout.release();
+ }
+
+ public int readMedia(String mrl) {
+ return readMedia(mLibVlcInstance, mrl, false);
+ }
+
+ /**
+ * Read a media.
+ */
+ public int readMedia(String mrl, boolean novideo) {
+ Log.v(TAG, "Reading " + mrl);
+ return readMedia(mLibVlcInstance, mrl, novideo);
+ }
+
+ /**
+ * Play a media from the media list (playlist)
+ *
+ * @param position The index of the media
+ */
+ public void playIndex(int position) {
+ playIndex(mLibVlcInstance, position);
+ }
+
+ public TrackInfo[] readTracksInfo(String mrl) {
+ return readTracksInfo(mLibVlcInstance, mrl);
+ }
+
+ /**
+ * Get a media thumbnail.
+ */
+ public byte[] getThumbnail(String mrl, int i_width, int i_height) {
+ return getThumbnail(mLibVlcInstance, mrl, i_width, i_height);
+ }
+
+ /**
+ * Return true if there is a video track in the file
+ */
+ public boolean hasVideoTrack(String mrl) throws java.io.IOException {
+ return hasVideoTrack(mLibVlcInstance, mrl);
+ }
+
+ /**
+ * Sets the speed of playback (1 being normal speed, 2 being twice as fast)
+ *
+ * @param rate
+ */
+ public native void setRate(float rate);
+
+ /**
+ * Get the current playback speed
+ */
+ public native float getRate();
+
+ /**
+ * Initialize the libvlc C library
+ * @return a pointer to the libvlc instance
+ */
+ private native void nativeInit() throws LibVlcException;
+
+ /**
+ * Close the libvlc C library
+ * @note mLibVlcInstance should be 0 after a call to destroy()
+ */
+ private native void nativeDestroy();
+
+ /**
+ * Start buffering to the mDebugLogBuffer.
+ */
+ public native void startDebugBuffer();
+ public native void stopDebugBuffer();
+ public String getBufferContent() {
+ return mDebugLogBuffer.toString();
+ }
+
+ public void clearBuffer() {
+ mDebugLogBuffer.setLength(0);
+ }
+
+ public boolean isDebugBuffering() {
+ return mIsBufferingLog;
+ }
+
+ /**
+ * Read a media
+ * @param instance: the instance of libVLC
+ * @param mrl: the media mrl
+ * @param novideo: don't enable video decoding for this media
+ * @return the position in the playlist
+ */
+ private native int readMedia(long instance, String mrl, boolean novideo);
+
+ /**
+ * Play an index in the native media list (playlist)
+ */
+ private native void playIndex(long instance, int position);
+
+ /**
+ * Returns true if any media is playing
+ */
+ public native boolean isPlaying();
+
+ /**
+ * Returns true if any media is seekable
+ */
+ public native boolean isSeekable();
+
+ /**
+ * Plays any loaded media
+ */
+ public native void play();
+
+ /**
+ * Pauses any playing media
+ */
+ public native void pause();
+
+ /**
+ * Stops any playing media
+ */
+ public native void stop();
+
+ /**
+ * Play the previous media (if any) in the media list
+ */
+ public native void previous();
+
+ /**
+ * Play the next media (if any) in the media list
+ */
+ public native void next();
+
+ /**
+ * Gets volume as integer
+ */
+ public native int getVolume();
+
+ /**
+ * Sets volume as integer
+ * @param volume: Volume level passed as integer
+ */
+ public native int setVolume(int volume);
+
+ /**
+ * Gets the current movie time (in ms).
+ * @return the movie time (in ms), or -1 if there is no media.
+ */
+ public native long getTime();
+
+ /**
+ * Sets the movie time (in ms), if any media is being played.
+ * @param time: Time in ms.
+ * @return the movie time (in ms), or -1 if there is no media.
+ */
+ public native long setTime(long time);
+
+ /**
+ * Gets the movie position.
+ * @return the movie position, or -1 for any error.
+ */
+ public native float getPosition();
+
+ /**
+ * Sets the movie position.
+ * @param pos: movie position.
+ */
+ public native void setPosition(float pos);
+
+ /**
+ * Gets current movie's length in ms.
+ * @return the movie length (in ms), or -1 if there is no media.
+ */
+ public native long getLength();
+
+ /**
+ * Get the libVLC version
+ * @return the libVLC version string
+ */
+ public native String version();
+
+ /**
+ * Get the libVLC compiler
+ * @return the libVLC compiler string
+ */
+ public native String compiler();
+
+ /**
+ * Get the libVLC changeset
+ * @return the libVLC changeset string
+ */
+ public native String changeset();
+
+ /**
+ * Get a media thumbnail.
+ * @return a bytearray with the RGBA thumbnail data inside.
+ */
+ private native byte[] getThumbnail(long instance, String mrl, int i_width, int i_height);
+
+ /**
+ * Return true if there is a video track in the file
+ */
+ private native boolean hasVideoTrack(long instance, String mrl);
+
+ private native TrackInfo[] readTracksInfo(long instance, String mrl);
+
+ public native TrackInfo[] readTracksInfoPosition(MediaList mediaList, int position);
+
+ public native int getAudioTracksCount();
+
+ public native Map getAudioTrackDescription();
+
+ public native int getAudioTrack();
+
+ public native int setAudioTrack(int index);
+
+ public native int getVideoTracksCount();
+
+ public native int addSubtitleTrack(String path);
+
+ public native Map getSpuTrackDescription();
+
+ public native int getSpuTrack();
+
+ public native int setSpuTrack(int index);
+
+ public native int getSpuTracksCount();
+
+ public static native String nativeToURI(String path);
+
+ public static String PathToURI(String path) {
+ if(path == null) {
+ throw new NullPointerException("Cannot convert null path!");
+ }
+ return LibVLC.nativeToURI(path);
+ }
+
+ public static native void nativeReadDirectory(String path, ArrayList res);
+
+ public native static boolean nativeIsPathDirectory(String path);
+
+ /**
+ * Get the list of existing items in the media list (playlist)
+ */
+ public native void getMediaListItems(ArrayList arl);
+
+ /**
+ * Expand and continue playing the current media.
+ *
+ * @return the index of the media was expanded, and -1 if no media was expanded
+ */
+ public int expandAndPlay() {
+ int r = mMediaList.expandMedia(mInternalMediaPlayerIndex);
+ if(r == 0)
+ this.playIndex(mInternalMediaPlayerIndex);
+ return r;
+ }
+
+ private native void setEventHandler(EventHandler eventHandler);
+
+ private native void detachEventHandler();
+
+ public native float[] getBands();
+
+ public native String[] getPresets();
+
+ public native float[] getPreset(int index);
+}
diff --git a/collect-library/src/main/java/org/videolan/libvlc/LibVlcException.java b/collect-library/src/main/java/org/videolan/libvlc/LibVlcException.java
new file mode 100644
index 00000000..f676f13a
--- /dev/null
+++ b/collect-library/src/main/java/org/videolan/libvlc/LibVlcException.java
@@ -0,0 +1,62 @@
+/*****************************************************************************
+ * LibVlcException.java
+ *****************************************************************************
+ * Copyright © 2011-2012 VLC authors and VideoLAN
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
+ *****************************************************************************/
+
+/**
+ * LibVlcException: exceptions thrown by the native LibVLC interface
+ */
+package org.videolan.libvlc;
+
+/**
+ * @author jpeg
+ *
+ */
+public class LibVlcException extends Exception {
+ private static final long serialVersionUID = -1909522348226924189L;
+
+ /**
+ * Create an empty error
+ */
+ public LibVlcException() {
+ super();
+ }
+
+ /**
+ * @param detailMessage
+ */
+ public LibVlcException(String detailMessage) {
+ super(detailMessage);
+ }
+
+ /**
+ * @param throwable
+ */
+ public LibVlcException(Throwable throwable) {
+ super(throwable);
+ }
+
+ /**
+ * @param detailMessage
+ * @param throwable
+ */
+ public LibVlcException(String detailMessage, Throwable throwable) {
+ super(detailMessage, throwable);
+ }
+
+}
diff --git a/collect-library/src/main/java/org/videolan/libvlc/LibVlcUtil.java b/collect-library/src/main/java/org/videolan/libvlc/LibVlcUtil.java
new file mode 100644
index 00000000..87727c83
--- /dev/null
+++ b/collect-library/src/main/java/org/videolan/libvlc/LibVlcUtil.java
@@ -0,0 +1,421 @@
+/*****************************************************************************
+ * LibVlcUtil.java
+ *****************************************************************************
+ * Copyright © 2011-2013 VLC authors and VideoLAN
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
+ *****************************************************************************/
+
+package org.videolan.libvlc;
+
+import android.content.Context;
+import android.os.Build;
+import android.util.Log;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileReader;
+import java.io.IOException;
+import java.io.RandomAccessFile;
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.util.Locale;
+
+public class LibVlcUtil {
+ public final static String TAG = "VLC/LibVLC/Util";
+
+ public static boolean isFroyoOrLater()
+ {
+ return Build.VERSION.SDK_INT >= Build.VERSION_CODES.FROYO;
+ }
+
+ public static boolean isGingerbreadOrLater()
+ {
+ return Build.VERSION.SDK_INT >= Build.VERSION_CODES.GINGERBREAD;
+ }
+
+ public static boolean isHoneycombOrLater()
+ {
+ return Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB;
+ }
+
+ public static boolean isICSOrLater()
+ {
+ return Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH;
+ }
+
+ public static boolean isJellyBeanOrLater()
+ {
+ return Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN;
+ }
+
+ private static String errorMsg = null;
+ private static boolean isCompatible = false;
+ public static String getErrorMsg() {
+ return errorMsg;
+ }
+
+ public static boolean hasCompatibleCPU(Context context)
+ {
+ // If already checked return cached result
+ if(errorMsg != null || isCompatible) return isCompatible;
+
+ ElfData elf = readLib(context.getApplicationInfo().dataDir + "/lib/libvlcjni.so");
+ if(elf == null) {
+ Log.e(TAG, "WARNING: Unable to read libvlcjni.so; cannot check device ABI!");
+ Log.e(TAG, "WARNING: Cannot guarantee correct ABI for this build (may crash)!");
+ return true;
+ }
+
+ String CPU_ABI = Build.CPU_ABI;
+ String CPU_ABI2 = "none";
+ if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.FROYO) { // CPU_ABI2 since 2.2
+ try {
+ CPU_ABI2 = (String) Build.class.getDeclaredField("CPU_ABI2").get(null);
+ } catch (Exception e) { }
+ }
+
+ Log.i(TAG, "machine = " + (elf.e_machine == EM_ARM ? "arm" : elf.e_machine == EM_386 ? "x86" : "mips"));
+ Log.i(TAG, "arch = " + elf.att_arch);
+ Log.i(TAG, "fpu = " + elf.att_fpu);
+ boolean hasNeon = false, hasFpu = false, hasArmV6 = false,
+ hasArmV7 = false, hasMips = false, hasX86 = false;
+ float bogoMIPS = -1;
+ int processors = 0;
+
+ if(CPU_ABI.equals("x86")) {
+ hasX86 = true;
+ } else if(CPU_ABI.equals("armeabi-v7a") ||
+ CPU_ABI2.equals("armeabi-v7a")) {
+ hasArmV7 = true;
+ hasArmV6 = true; /* Armv7 is backwards compatible to < v6 */
+ } else if(CPU_ABI.equals("armeabi") ||
+ CPU_ABI2.equals("armeabi")) {
+ hasArmV6 = true;
+ }
+
+ try {
+ FileReader fileReader = new FileReader("/proc/cpuinfo");
+ BufferedReader br = new BufferedReader(fileReader);
+ String line;
+ while((line = br.readLine()) != null) {
+ if(!hasArmV7 && line.contains("ARMv7")) {
+ hasArmV7 = true;
+ hasArmV6 = true; /* Armv7 is backwards compatible to < v6 */
+ }
+ if(!hasArmV7 && !hasArmV6 && line.contains("ARMv6"))
+ hasArmV6 = true;
+ // "clflush size" is a x86-specific cpuinfo tag.
+ // (see kernel sources arch/x86/kernel/cpu/proc.c)
+ if(line.contains("clflush size"))
+ hasX86 = true;
+ // "microsecond timers" is specific to MIPS.
+ // see arch/mips/kernel/proc.c
+ if(line.contains("microsecond timers"))
+ hasMips = true;
+ if(!hasNeon && line.contains("neon"))
+ hasNeon = true;
+ if(!hasFpu && line.contains("vfp"))
+ hasFpu = true;
+ if(line.startsWith("processor"))
+ processors++;
+ if(bogoMIPS < 0 && line.toLowerCase(Locale.ENGLISH).contains("bogomips")) {
+ String[] bogo_parts = line.split(":");
+ try {
+ bogoMIPS = Float.parseFloat(bogo_parts[1].trim());
+ } catch(NumberFormatException e) {
+ bogoMIPS = -1; // invalid bogomips
+ }
+ }
+ }
+ fileReader.close();
+ } catch(IOException ex){
+ ex.printStackTrace();
+ errorMsg = "IOException whilst reading cpuinfo flags";
+ isCompatible = false;
+ return false;
+ }
+ if(processors == 0)
+ processors = 1; // possibly borked cpuinfo?
+
+ // Enforce proper architecture to prevent problems
+ if(elf.e_machine == EM_386 && !hasX86) {
+ errorMsg = "x86 build on non-x86 device";
+ isCompatible = false;
+ return false;
+ } else if(elf.e_machine == EM_ARM && hasX86) {
+ errorMsg = "ARM build on x86 device";
+ isCompatible = false;
+ return false;
+ }
+
+ if(elf.e_machine == EM_MIPS && !hasMips) {
+ errorMsg = "MIPS build on non-MIPS device";
+ isCompatible = false;
+ return false;
+ } else if(elf.e_machine == EM_ARM && hasMips) {
+ errorMsg = "ARM build on MIPS device";
+ isCompatible = false;
+ return false;
+ }
+
+ if(elf.e_machine == EM_ARM && elf.att_arch.startsWith("v7") && !hasArmV7) {
+ errorMsg = "ARMv7 build on non-ARMv7 device";
+ isCompatible = false;
+ return false;
+ }
+ if(elf.e_machine == EM_ARM) {
+ if(elf.att_arch.startsWith("v6") && !hasArmV6) {
+ errorMsg = "ARMv6 build on non-ARMv6 device";
+ isCompatible = false;
+ return false;
+ } else if(elf.att_fpu && !hasFpu) {
+ errorMsg = "FPU-enabled build on non-FPU device";
+ isCompatible = false;
+ return false;
+ }
+ }
+
+ errorMsg = null;
+ isCompatible = true;
+ // Store into MachineSpecs
+ machineSpecs = new MachineSpecs();
+ machineSpecs.hasArmV6 = hasArmV6;
+ machineSpecs.hasArmV7 = hasArmV7;
+ machineSpecs.hasFpu = hasFpu;
+ machineSpecs.hasMips = hasMips;
+ machineSpecs.hasNeon = hasNeon;
+ machineSpecs.hasX86 = hasX86;
+ machineSpecs.bogoMIPS = bogoMIPS;
+ machineSpecs.processors = processors;
+ return true;
+ }
+
+ public static MachineSpecs getMachineSpecs() {
+ return machineSpecs;
+ }
+ private static MachineSpecs machineSpecs = null;
+ public static class MachineSpecs {
+ public boolean hasNeon;
+ public boolean hasFpu;
+ public boolean hasArmV6;
+ public boolean hasArmV7;
+ public boolean hasMips;
+ public boolean hasX86;
+ public float bogoMIPS;
+ public int processors;
+ }
+
+ private static final int EM_386 = 3;
+ private static final int EM_MIPS = 8;
+ private static final int EM_ARM = 40;
+ private static final int ELF_HEADER_SIZE = 52;
+ private static final int SECTION_HEADER_SIZE = 40;
+ private static final int SHT_ARM_ATTRIBUTES = 0x70000003;
+ private static class ElfData {
+ ByteOrder order;
+ int e_machine;
+ int e_shoff;
+ int e_shnum;
+ int sh_offset;
+ int sh_size;
+ String att_arch;
+ boolean att_fpu;
+ }
+
+ /** '*' prefix means it's unsupported */
+ private static String[] CPU_archs = {"*Pre-v4", "*v4", "*v4T",
+ "v5T", "v5TE", "v5TEJ",
+ "v6", "v6KZ", "v6T2", "v6K", "v7",
+ "*v6-M", "*v6S-M", "*v7E-M", "*v8"};
+
+ private static ElfData readLib(String path) {
+ File file = new File(path);
+ if (!file.exists() || !file.canRead())
+ return null;
+
+ RandomAccessFile in = null;
+ try {
+ in = new RandomAccessFile(file, "r");
+
+ ElfData elf = new ElfData();
+ if (!readHeader(in, elf))
+ return null;
+
+ switch (elf.e_machine) {
+ case EM_386:
+ case EM_MIPS:
+ return elf;
+ case EM_ARM:
+ in.close();
+ in = new RandomAccessFile(file, "r");
+ if (!readSection(in, elf))
+ return null;
+ in.close();
+ in = new RandomAccessFile(file, "r");
+ if (!readArmAttributes(in, elf))
+ return null;
+ break;
+ default:
+ return null;
+ }
+ return elf;
+ } catch (FileNotFoundException e) {
+ e.printStackTrace();
+ } catch (IOException e) {
+ e.printStackTrace();
+ } finally {
+ try {
+ if (in != null)
+ in.close();
+ } catch (IOException e) {
+ }
+ }
+ return null;
+ }
+
+ private static boolean readHeader(RandomAccessFile in, ElfData elf) throws IOException {
+ // http://www.sco.com/developers/gabi/1998-04-29/ch4.eheader.html
+ byte[] bytes = new byte[ELF_HEADER_SIZE];
+ in.readFully(bytes);
+ if (bytes[0] != 127 ||
+ bytes[1] != 'E' ||
+ bytes[2] != 'L' ||
+ bytes[3] != 'F' ||
+ bytes[4] != 1) { // ELFCLASS32, Only 32bit header is supported
+ return false;
+ }
+
+ elf.order = bytes[5] == 1
+ ? ByteOrder.LITTLE_ENDIAN // ELFDATA2LSB
+ : ByteOrder.BIG_ENDIAN; // ELFDATA2MSB
+
+ // wrap bytes in a ByteBuffer to force endianess
+ ByteBuffer buffer = ByteBuffer.wrap(bytes);
+ buffer.order(elf.order);
+
+ elf.e_machine = buffer.getShort(18); /* Architecture */
+ elf.e_shoff = buffer.getInt(32); /* Section header table file offset */
+ elf.e_shnum = buffer.getShort(48); /* Section header table entry count */
+ return true;
+ }
+
+ private static boolean readSection(RandomAccessFile in, ElfData elf) throws IOException {
+ byte[] bytes = new byte[SECTION_HEADER_SIZE];
+ in.seek(elf.e_shoff);
+
+ for (int i = 0; i < elf.e_shnum; ++i) {
+ in.readFully(bytes);
+
+ // wrap bytes in a ByteBuffer to force endianess
+ ByteBuffer buffer = ByteBuffer.wrap(bytes);
+ buffer.order(elf.order);
+
+ int sh_type = buffer.getInt(4); /* Section type */
+ if (sh_type != SHT_ARM_ATTRIBUTES)
+ continue;
+
+ elf.sh_offset = buffer.getInt(16); /* Section file offset */
+ elf.sh_size = buffer.getInt(20); /* Section size in bytes */
+ return true;
+ }
+
+ return false;
+ }
+
+ private static boolean readArmAttributes(RandomAccessFile in, ElfData elf) throws IOException {
+ byte[] bytes = new byte[elf.sh_size];
+ in.seek(elf.sh_offset);
+ in.readFully(bytes);
+
+ // wrap bytes in a ByteBuffer to force endianess
+ ByteBuffer buffer = ByteBuffer.wrap(bytes);
+ buffer.order(elf.order);
+
+ //http://infocenter.arm.com/help/topic/com.arm.doc.ihi0044e/IHI0044E_aaelf.pdf
+ //http://infocenter.arm.com/help/topic/com.arm.doc.ihi0045d/IHI0045D_ABI_addenda.pdf
+ if (buffer.get() != 'A') // format-version
+ return false;
+
+ // sub-sections loop
+ while (buffer.remaining() > 0) {
+ int start_section = buffer.position();
+ int length = buffer.getInt();
+ String vendor = getString(buffer);
+ if (vendor.equals("aeabi")) {
+ // tags loop
+ while (buffer.position() < start_section + length) {
+ int start = buffer.position();
+ int tag = buffer.get();
+ int size = buffer.getInt();
+ // skip if not Tag_File, we don't care about others
+ if (tag != 1) {
+ buffer.position(start + size);
+ continue;
+ }
+
+ // attributes loop
+ while (buffer.position() < start + size) {
+ tag = getUleb128(buffer);
+ if (tag == 6) { // CPU_arch
+ int arch = getUleb128(buffer);
+ elf.att_arch = CPU_archs[arch];
+ }
+ else if (tag == 27) { // ABI_HardFP_use
+ getUleb128(buffer);
+ elf.att_fpu = true;
+ }
+ else {
+ // string for 4=CPU_raw_name / 5=CPU_name / 32=compatibility
+ // string for >32 && odd tags
+ // uleb128 for other
+ tag %= 128;
+ if (tag == 4 || tag == 5 || tag == 32 || (tag > 32 && (tag & 1) != 0))
+ getString(buffer);
+ else
+ getUleb128(buffer);
+ }
+ }
+ }
+ break;
+ }
+ }
+ return true;
+ }
+
+ private static String getString(ByteBuffer buffer) {
+ StringBuilder sb = new StringBuilder(buffer.limit());
+ while (buffer.remaining() > 0) {
+ char c = (char) buffer.get();
+ if (c == 0)
+ break;
+ sb.append(c);
+ }
+ return sb.toString();
+ }
+
+ private static int getUleb128(ByteBuffer buffer) {
+ int ret = 0;
+ int c;
+ do {
+ ret <<= 7;
+ c = buffer.get();
+ ret |= c & 0x7f;
+ } while((c & 0x80) > 0);
+
+ return ret;
+ }
+}
diff --git a/collect-library/src/main/java/org/videolan/libvlc/MediaList.java b/collect-library/src/main/java/org/videolan/libvlc/MediaList.java
new file mode 100644
index 00000000..4ac851cd
--- /dev/null
+++ b/collect-library/src/main/java/org/videolan/libvlc/MediaList.java
@@ -0,0 +1,124 @@
+/*****************************************************************************
+ * MediaList.java
+ *****************************************************************************
+ * Copyright © 2013 VLC authors and VideoLAN
+ * Copyright © 2013 Edward Wang
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
+ *****************************************************************************/
+package org.videolan.libvlc;
+
+/**
+ * Java/JNI wrapper for the libvlc_media_list_t structure.
+ */
+public class MediaList {
+ private static final String TAG = "VLC/LibVLC/MediaList";
+
+ private long mMediaListInstance = 0; // Read-only, reserved for JNI
+ private long mEventHanderGlobalRef = 0; // Read-only, reserved for JNI
+ private LibVLC mLibVLC; // Used to create new objects that require a libvlc instance
+ private boolean destroyed = false;
+ private EventHandler mEventHandler;
+
+ public MediaList(LibVLC libVLC) {
+ mEventHandler = new EventHandler(); // used in init() below to fire events at the correct targets
+ mMediaListInstance = init(libVLC);
+ mLibVLC = libVLC;
+ }
+ private native long init(LibVLC libvlc_instance);
+
+ @Override
+ public void finalize() {
+ if(!destroyed) destroy();
+ }
+
+ /**
+ * Releases the media list.
+ *
+ * The object should be considered released after this and must not be used.
+ */
+ public void destroy() {
+ nativeDestroy();
+ mMediaListInstance = 0;
+ mEventHanderGlobalRef = 0;
+ mLibVLC = null;
+ destroyed = true;
+ }
+ private native void nativeDestroy();
+
+ public void add(String mrl) {
+ add(mLibVLC, mrl, false, false);
+ }
+ public void add(String mrl, boolean noVideo) {
+ add(mLibVLC, mrl, noVideo, false);
+ }
+ private native void add(LibVLC libvlc_instance, String mrl, boolean noVideo, boolean noOmx);
+
+ /**
+ * Clear the media list. (remove all media)
+ */
+ public native void clear();
+
+ /**
+ * This function checks the currently playing media for subitems at the given
+ * position, and if any exist, it will expand them at the same position
+ * and replace the current media.
+ *
+ * @param position The position to expand
+ * @return -1 if no subitems were found, 0 if subitems were expanded
+ */
+ public int expandMedia(int position) {
+ return expandMedia(mLibVLC, position);
+ }
+ private native int expandMedia(LibVLC libvlc_instance, int position);
+
+ public void loadPlaylist(String mrl) {
+ loadPlaylist(mLibVLC, mrl);
+ }
+ private native void loadPlaylist(LibVLC libvlc_instance, String mrl);
+
+ public void insert(int position, String mrl) {
+ insert(mLibVLC, position, mrl);
+ }
+ private native void insert(LibVLC libvlc_instance, int position, String mrl);
+
+ public native void remove(int position);
+
+ public native int size();
+
+ /**
+ * @param position The index of the media in the list
+ * @return null if not found
+ */
+ public native String getMRL(int position);
+
+ public EventHandler getEventHandler() {
+ return mEventHandler;
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder sb = new StringBuilder();
+ sb.append("LibVLC Media List: {");
+ for(int i = 0; i < size(); i++) {
+ sb.append(((Integer)i).toString());
+ sb.append(": ");
+ sb.append(getMRL(i));
+ sb.append(", ");
+ }
+ sb.append("}");
+ return sb.toString();
+ }
+}
diff --git a/collect-library/src/main/java/org/videolan/libvlc/TrackInfo.java b/collect-library/src/main/java/org/videolan/libvlc/TrackInfo.java
new file mode 100644
index 00000000..7cf23f03
--- /dev/null
+++ b/collect-library/src/main/java/org/videolan/libvlc/TrackInfo.java
@@ -0,0 +1,52 @@
+/*****************************************************************************
+ * TrackInfo.java
+ *****************************************************************************
+ * Copyright © 2010-2013 VLC authors and VideoLAN
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
+ *****************************************************************************/
+
+package org.videolan.libvlc;
+
+public class TrackInfo {
+
+ public static final int TYPE_UNKNOWN = -1;
+ public static final int TYPE_AUDIO = 0;
+ public static final int TYPE_VIDEO = 1;
+ public static final int TYPE_TEXT = 2;
+ public static final int TYPE_META = 3;
+
+ public int Type;
+ public int Id;
+ public String Codec;
+ public String Language;
+
+ /* Video */
+ public int Height;
+ public int Width;
+ public float Framerate;
+
+ /* Audio */
+ public int Channels;
+ public int Samplerate;
+
+ /* MetaData */
+ public long Length;
+ public String Title;
+ public String Artist;
+ public String Album;
+ public String Genre;
+ public String ArtworkURL;
+}
diff --git a/collect-library/src/main/java/org/videolan/vlc/MurmurHash.java b/collect-library/src/main/java/org/videolan/vlc/MurmurHash.java
new file mode 100644
index 00000000..bae3723c
--- /dev/null
+++ b/collect-library/src/main/java/org/videolan/vlc/MurmurHash.java
@@ -0,0 +1,183 @@
+package org.videolan.vlc;
+
+/** Murmur hash 2.0.
+ *
+ * The murmur hash is a relative fast hash function from
+ * http://murmurhash.googlepages.com/ for platforms with efficient
+ * multiplication.
+ *
+ * This is a re-implementation of the original C code plus some
+ * additional features.
+ *
+ * Public domain.
+ *
+ * @author Viliam Holub
+ * @version 1.0.2
+ *
+ */
+public final class MurmurHash {
+
+ /** Generates 32 bit hash from byte array of the given length and
+ * seed.
+ *
+ * @param data byte array to hash
+ * @param length length of the array to hash
+ * @param seed initial seed value
+ * @return 32 bit hash of the given array
+ */
+ public static int hash32(final byte[] data, int length, int seed) {
+ // 'm' and 'r' are mixing constants generated offline.
+ // They're not really 'magic', they just happen to work well.
+ final int m = 0x5bd1e995;
+ final int r = 24;
+ // Initialize the hash to a random value
+ int h = seed ^ length;
+ int length4 = length / 4;
+
+ for (int i = 0; i < length4; i++) {
+ final int i4 = i * 4;
+ int k = (data[i4 + 0] & 0xff) + ((data[i4 + 1] & 0xff) << 8)
+ + ((data[i4 + 2] & 0xff) << 16) + ((data[i4 + 3] & 0xff) << 24);
+ k *= m;
+ k ^= k >>> r;
+ k *= m;
+ h *= m;
+ h ^= k;
+ }
+
+ // Handle the last few bytes of the input array
+ switch (length % 4) {
+ case 3:
+ h ^= (data[(length & ~3) + 2] & 0xff) << 16;
+ case 2:
+ h ^= (data[(length & ~3) + 1] & 0xff) << 8;
+ case 1:
+ h ^= (data[length & ~3] & 0xff);
+ h *= m;
+ }
+
+ h ^= h >>> 13;
+ h *= m;
+ h ^= h >>> 15;
+
+ return h;
+ }
+
+ /** Generates 32 bit hash from byte array with default seed value.
+ *
+ * @param data byte array to hash
+ * @param length length of the array to hash
+ * @return 32 bit hash of the given array
+ */
+ public static int hash32(final byte[] data, int length) {
+ return hash32(data, length, 0x9747b28c);
+ }
+
+ /** Generates 32 bit hash from a string.
+ *
+ * @param text string to hash
+ * @return 32 bit hash of the given string
+ */
+ public static int hash32(final String text) {
+ final byte[] bytes = text.getBytes();
+ return hash32(bytes, bytes.length);
+ }
+
+ /** Generates 32 bit hash from a substring.
+ *
+ * @param text string to hash
+ * @param from starting index
+ * @param length length of the substring to hash
+ * @return 32 bit hash of the given string
+ */
+ public static int hash32(final String text, int from, int length) {
+ return hash32(text.substring(from, from + length));
+ }
+
+ /** Generates 64 bit hash from byte array of the given length and seed.
+ *
+ * @param data byte array to hash
+ * @param length length of the array to hash
+ * @param seed initial seed value
+ * @return 64 bit hash of the given array
+ */
+ public static long hash64(final byte[] data, int length, int seed) {
+ final long m = 0xc6a4a7935bd1e995L;
+ final int r = 47;
+
+ long h = (seed & 0xffffffffl) ^ (length * m);
+
+ int length8 = length / 8;
+
+ for (int i = 0; i < length8; i++) {
+ final int i8 = i * 8;
+ long k = ((long) data[i8 + 0] & 0xff) + (((long) data[i8 + 1] & 0xff) << 8)
+ + (((long) data[i8 + 2] & 0xff) << 16) + (((long) data[i8 + 3] & 0xff) << 24)
+ + (((long) data[i8 + 4] & 0xff) << 32) + (((long) data[i8 + 5] & 0xff) << 40)
+ + (((long) data[i8 + 6] & 0xff) << 48) + (((long) data[i8 + 7] & 0xff) << 56);
+
+ k *= m;
+ k ^= k >>> r;
+ k *= m;
+
+ h ^= k;
+ h *= m;
+ }
+
+ switch (length % 8) {
+ case 7:
+ h ^= (long) (data[(length & ~7) + 6] & 0xff) << 48;
+ case 6:
+ h ^= (long) (data[(length & ~7) + 5] & 0xff) << 40;
+ case 5:
+ h ^= (long) (data[(length & ~7) + 4] & 0xff) << 32;
+ case 4:
+ h ^= (long) (data[(length & ~7) + 3] & 0xff) << 24;
+ case 3:
+ h ^= (long) (data[(length & ~7) + 2] & 0xff) << 16;
+ case 2:
+ h ^= (long) (data[(length & ~7) + 1] & 0xff) << 8;
+ case 1:
+ h ^= (long) (data[length & ~7] & 0xff);
+ h *= m;
+ }
+ ;
+
+ h ^= h >>> r;
+ h *= m;
+ h ^= h >>> r;
+
+ return h;
+ }
+
+ /** Generates 64 bit hash from byte array with default seed value.
+ *
+ * @param data byte array to hash
+ * @param length length of the array to hash
+ * @return 64 bit hash of the given string
+ */
+ public static long hash64(final byte[] data, int length) {
+ return hash64(data, length, 0xe17a1465);
+ }
+
+ /** Generates 64 bit hash from a string.
+ *
+ * @param text string to hash
+ * @return 64 bit hash of the given string
+ */
+ public static long hash64(final String text) {
+ final byte[] bytes = text.getBytes();
+ return hash64(bytes, bytes.length);
+ }
+
+ /** Generates 64 bit hash from a substring.
+ *
+ * @param text string to hash
+ * @param from starting index
+ * @param length length of the substring to hash
+ * @return 64 bit hash of the given array
+ */
+ public static long hash64(final String text, int from, int length) {
+ return hash64(text.substring(from, from + length));
+ }
+}
diff --git a/collect-library/src/main/java/org/videolan/vlc/PhoneStateReceiver.java b/collect-library/src/main/java/org/videolan/vlc/PhoneStateReceiver.java
new file mode 100644
index 00000000..2b09928d
--- /dev/null
+++ b/collect-library/src/main/java/org/videolan/vlc/PhoneStateReceiver.java
@@ -0,0 +1,44 @@
+/*****************************************************************************
+ * PhoneStateReceiver.java
+ *****************************************************************************
+ * Copyright © 2011-2012 VLC authors and VideoLAN
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
+ *****************************************************************************/
+
+package org.videolan.vlc;
+
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.telephony.TelephonyManager;
+import org.videolan.libvlc.LibVLC;
+
+public class PhoneStateReceiver extends BroadcastReceiver {
+
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ String state = intent.getStringExtra(TelephonyManager.EXTRA_STATE);
+
+ if (state.equals(TelephonyManager.EXTRA_STATE_RINGING) ||
+ state.equals(TelephonyManager.EXTRA_STATE_OFFHOOK)) {
+
+ LibVLC libVLC = LibVLC.getExistingInstance();
+ if (libVLC != null && libVLC.isPlaying())
+ libVLC.pause();
+ }
+ }
+
+}
diff --git a/collect-library/src/main/java/org/videolan/vlc/RepeatType.java b/collect-library/src/main/java/org/videolan/vlc/RepeatType.java
new file mode 100644
index 00000000..a796e092
--- /dev/null
+++ b/collect-library/src/main/java/org/videolan/vlc/RepeatType.java
@@ -0,0 +1,26 @@
+/*****************************************************************************
+ * RepeatType.java
+ *****************************************************************************
+ * Copyright © 2012 VLC authors and VideoLAN
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
+ *****************************************************************************/
+package org.videolan.vlc;
+
+public enum RepeatType {
+ None,
+ Once,
+ All
+}
diff --git a/collect-library/src/main/java/org/videolan/vlc/Util.java b/collect-library/src/main/java/org/videolan/vlc/Util.java
new file mode 100644
index 00000000..f5a52091
--- /dev/null
+++ b/collect-library/src/main/java/org/videolan/vlc/Util.java
@@ -0,0 +1,546 @@
+/*****************************************************************************
+ * Util.java
+ *****************************************************************************
+ * Copyright © 2011-2013 VLC authors and VideoLAN
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
+ *****************************************************************************/
+
+package org.videolan.vlc;
+
+import android.content.Context;
+import android.content.SharedPreferences;
+import android.content.SharedPreferences.Editor;
+import android.content.res.Configuration;
+import android.graphics.Bitmap;
+import android.net.Uri;
+import android.os.Environment;
+import android.preference.PreferenceManager;
+import android.telephony.TelephonyManager;
+import android.util.DisplayMetrics;
+import android.util.TypedValue;
+import android.view.Display;
+import android.view.WindowManager;
+import android.widget.Toast;
+import com.navinfo.collect.library.system.VLCApplication;
+import org.json.JSONArray;
+import org.json.JSONException;
+import org.videolan.libvlc.LibVLC;
+import org.videolan.libvlc.LibVlcException;
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.text.DecimalFormat;
+import java.text.NumberFormat;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.Locale;
+import java.util.StringTokenizer;
+
+public class Util {
+ public final static String TAG = "VLC/Util";
+ private final static boolean hasNavBar;
+ private Context context;
+ private static volatile Util mInstance;
+
+ /** A set of utility functions for the VLC application */
+
+ static {
+ HashSet devicesWithoutNavBar = new HashSet();
+ devicesWithoutNavBar.add("HTC One V");
+ devicesWithoutNavBar.add("HTC One S");
+ devicesWithoutNavBar.add("HTC One X");
+ devicesWithoutNavBar.add("HTC One XL");
+ hasNavBar = isICSOrLater() && !devicesWithoutNavBar.contains(android.os.Build.MODEL);
+ }
+
+ public static Util getInstance() {
+ if (mInstance == null) {
+ synchronized (Util.class) {
+ if (mInstance == null) {
+ mInstance = new Util();
+ }
+ }
+ }
+ return mInstance;
+ }
+
+ public void init(Context con){
+ this.context = con;
+ // Are we using advanced debugging - locale?
+ SharedPreferences pref = PreferenceManager.getDefaultSharedPreferences(con);
+ String p = pref.getString("set_locale", "");
+ if (p != null && !p.equals("")) {
+ Locale locale;
+ // workaround due to region code
+ if(p.equals("zh-TW")) {
+ locale = Locale.TRADITIONAL_CHINESE;
+ } else if(p.startsWith("zh")) {
+ locale = Locale.CHINA;
+ } else if(p.equals("pt-BR")) {
+ locale = new Locale("pt", "BR");
+ } else if(p.equals("bn-IN") || p.startsWith("bn")) {
+ locale = new Locale("bn", "IN");
+ } else {
+ /**
+ * Avoid a crash of
+ * java.lang.AssertionError: couldn't initialize LocaleData for locale
+ * if the user enters nonsensical region codes.
+ */
+ if(p.contains("-"))
+ p = p.substring(0, p.indexOf('-'));
+ locale = new Locale(p);
+ }
+ Locale.setDefault(locale);
+ Configuration config = new Configuration();
+ config.locale = locale;
+ con.getResources().updateConfiguration(config,
+ con.getResources().getDisplayMetrics());
+ }
+ }
+
+ public LibVLC getLibVlcInstance() throws LibVlcException {
+
+ LibVLC instance = LibVLC.getExistingInstance();
+
+ if (instance == null) {
+
+ Thread.setDefaultUncaughtExceptionHandler(new VlcCrashHandler());
+
+ instance = LibVLC.getInstance();
+
+ SharedPreferences pref = PreferenceManager.getDefaultSharedPreferences(context);
+
+ updateLibVlcSettings(pref);
+
+ instance.init(context);
+
+ }
+
+ return instance;
+ }
+
+ public static float[] getFloatArray(SharedPreferences pref, String key) {
+ float[] array = null;
+ String s = pref.getString(key, null);
+ if (s != null) {
+ try {
+ JSONArray json = new JSONArray(s);
+ array = new float[json.length()];
+ for (int i = 0; i < array.length; i++)
+ array[i] = (float) json.getDouble(i);
+ } catch (JSONException e) {
+ e.printStackTrace();
+ }
+ }
+ return array;
+ }
+
+ public static void putFloatArray(Editor editor, String key, float[] array) {
+ try {
+ JSONArray json = new JSONArray();
+ for (float f : array)
+ json.put(f);
+ editor.putString("equalizer_values", json.toString());
+ } catch (JSONException e) {
+ e.printStackTrace();
+ }
+ }
+
+ public static void updateLibVlcSettings(SharedPreferences pref) {
+ LibVLC instance = LibVLC.getExistingInstance();
+ if (instance == null)
+ return;
+
+ instance.setIomx(pref.getBoolean("enable_iomx", false));
+ instance.setSubtitlesEncoding(pref.getString("subtitles_text_encoding", ""));
+ instance.setTimeStretching(pref.getBoolean("enable_time_stretching_audio", false));
+ instance.setFrameSkip(pref.getBoolean("enable_frame_skip", false));
+ instance.setChroma(pref.getString("chroma_format", ""));
+ instance.setVerboseMode(pref.getBoolean("enable_verbose_mode", true));
+
+ if (pref.getBoolean("equalizer_enabled", false))
+ instance.setEqualizer(getFloatArray(pref, "equalizer_values"));
+
+ int aout;
+ try {
+ aout = Integer.parseInt(pref.getString("aout", "-1"));
+ }
+ catch (NumberFormatException nfe) {
+ aout = -1;
+ }
+ int deblocking;
+ try {
+ deblocking = Integer.parseInt(pref.getString("deblocking", "-1"));
+ }
+ catch(NumberFormatException nfe) {
+ deblocking = -1;
+ }
+ int networkCaching = pref.getInt("network_caching_value", 0);
+ if(networkCaching > 60000)
+ networkCaching = 60000;
+ else if(networkCaching < 0)
+ networkCaching = 0;
+ instance.setAout(aout);
+ instance.setDeblocking(deblocking);
+ instance.setNetworkCaching(networkCaching);
+ }
+
+ /** Print an on-screen message to alert the user */
+ public static void toaster(Context context, int stringId, int duration) {
+ Toast.makeText(context, stringId, duration).show();
+ }
+
+ public static void toaster(Context context, int stringId) {
+ toaster(context, stringId, Toast.LENGTH_SHORT);
+ }
+
+ public static File URItoFile(String URI) {
+ return new File(Uri.decode(URI).replace("file://",""));
+ }
+
+ public static String URItoFileName(String URI) {
+ return URItoFile(URI).getName();
+ }
+
+ public static String stripTrailingSlash(String s) {
+ if( s.endsWith("/") && s.length() > 1 )
+ return s.substring(0, s.length() - 1);
+ return s;
+ }
+
+ public static String readAsset(String assetName, String defaultS) {
+ try {
+ InputStream is = VLCApplication.getAppResources().getAssets().open(assetName);
+ BufferedReader r = new BufferedReader(new InputStreamReader(is, "UTF8"));
+ StringBuilder sb = new StringBuilder();
+ String line = r.readLine();
+ if(line != null) {
+ sb.append(line);
+ line = r.readLine();
+ while(line != null) {
+ sb.append('\n');
+ sb.append(line);
+ line = r.readLine();
+ }
+ }
+ return sb.toString();
+ } catch (IOException e) {
+ return defaultS;
+ }
+ }
+
+ /**
+ * Convert time to a string
+ * @param millis e.g.time/length from file
+ * @return formated string (hh:)mm:ss
+ */
+ public static String millisToString(long millis)
+ {
+ return millisToString(millis, false);
+ }
+
+ /**
+ * Convert time to a string
+ * @param millis e.g.time/length from file
+ * @return formated string "[hh]h[mm]min" / "[mm]min[s]s"
+ */
+ public static String millisToText(long millis)
+ {
+ return millisToString(millis, true);
+ }
+
+ private static String millisToString(long millis, boolean text) {
+ boolean negative = millis < 0;
+ millis = Math.abs(millis);
+
+ millis /= 1000;
+ int sec = (int) (millis % 60);
+ millis /= 60;
+ int min = (int) (millis % 60);
+ millis /= 60;
+ int hours = (int) millis;
+
+ String time;
+ DecimalFormat format = (DecimalFormat)NumberFormat.getInstance(Locale.US);
+ format.applyPattern("00");
+ if (text) {
+ if (millis > 0)
+ time = (negative ? "-" : "") + hours + "h" + format.format(min) + "min";
+ else if (min > 0)
+ time = (negative ? "-" : "") + min + "min";
+ else
+ time = (negative ? "-" : "") + sec + "s";
+ }
+ else {
+ if (millis > 0)
+ time = (negative ? "-" : "") + hours + ":" + format.format(min) + ":" + format.format(sec);
+ else
+ time = (negative ? "-" : "") + min + ":" + format.format(sec);
+ }
+ return time;
+ }
+
+ public static Bitmap scaleDownBitmap(Context context, Bitmap bitmap, int width) {
+ /*
+ * This method can lead to OutOfMemoryError!
+ * If the source size is more than twice the target size use
+ * the optimized version available in AudioUtil::readCoverBitmap
+ */
+ if (bitmap != null) {
+ final float densityMultiplier = context.getResources().getDisplayMetrics().density;
+ int w = (int) (width * densityMultiplier);
+ int h = (int) (w * bitmap.getHeight() / ((double) bitmap.getWidth()));
+ bitmap = Bitmap.createScaledBitmap(bitmap, w, h, true);
+ }
+ return bitmap;
+ }
+
+ public static Bitmap cropBorders(Bitmap bitmap, int width, int height)
+ {
+ int top = 0;
+ for (int i = 0; i < height / 2; i++) {
+ int pixel1 = bitmap.getPixel(width / 2, i);
+ int pixel2 = bitmap.getPixel(width / 2, height - i - 1);
+ if ((pixel1 == 0 || pixel1 == -16777216) &&
+ (pixel2 == 0 || pixel2 == -16777216)) {
+ top = i;
+ } else {
+ break;
+ }
+ }
+
+ int left = 0;
+ for (int i = 0; i < width / 2; i++) {
+ int pixel1 = bitmap.getPixel(i, height / 2);
+ int pixel2 = bitmap.getPixel(width - i - 1, height / 2);
+ if ((pixel1 == 0 || pixel1 == -16777216) &&
+ (pixel2 == 0 || pixel2 == -16777216)) {
+ left = i;
+ } else {
+ break;
+ }
+ }
+
+ if (left >= width / 2 - 10 || top >= height / 2 - 10)
+ return bitmap;
+
+ // Cut off the transparency on the borders
+ return Bitmap.createBitmap(bitmap, left, top,
+ (width - (2 * left)), (height - (2 * top)));
+ }
+
+ public static String getValue(String string, int defaultId)
+ {
+ return (string != null && string.length() > 0) ?
+ string : VLCApplication.getAppContext().getString(defaultId);
+ }
+
+ public static int convertPxToDp(int px) {
+ WindowManager wm = (WindowManager)VLCApplication.getAppContext().
+ getSystemService(Context.WINDOW_SERVICE);
+ Display display = wm.getDefaultDisplay();
+ DisplayMetrics metrics = new DisplayMetrics();
+ display.getMetrics(metrics);
+ float logicalDensity = metrics.density;
+ int dp = Math.round(px / logicalDensity);
+ return dp;
+ }
+
+ public static int convertDpToPx(int dp) {
+ return Math.round(
+ TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp,
+ VLCApplication.getAppResources().getDisplayMetrics())
+ );
+ }
+
+ public static boolean isFroyoOrLater()
+ {
+ return android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.FROYO;
+ }
+
+ public static boolean isGingerbreadOrLater()
+ {
+ return android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.GINGERBREAD;
+ }
+
+ public static boolean isHoneycombOrLater()
+ {
+ return android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.HONEYCOMB;
+ }
+
+ public static boolean isICSOrLater()
+ {
+ return android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.ICE_CREAM_SANDWICH;
+ }
+
+ public static boolean isJellyBeanOrLater()
+ {
+ return android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.JELLY_BEAN;
+ }
+
+ public static boolean hasExternalStorage() {
+ return Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED);
+ }
+
+ public static boolean hasNavBar()
+ {
+ return hasNavBar;
+ }
+
+ /** hasCombBar test if device has Combined Bar : only for tablet with Honeycomb or ICS */
+ public static boolean hasCombBar() {
+ return (!isPhone()
+ && ((android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.HONEYCOMB) &&
+ (android.os.Build.VERSION.SDK_INT <= android.os.Build.VERSION_CODES.JELLY_BEAN)));
+ }
+
+ public static boolean isPhone(){
+ TelephonyManager manager = (TelephonyManager)VLCApplication.getAppContext().getSystemService(Context.TELEPHONY_SERVICE);
+ if(manager.getPhoneType() == TelephonyManager.PHONE_TYPE_NONE){
+ return false;
+ }else{
+ return true;
+ }
+ }
+
+ public static String[] getStorageDirectories()
+ {
+ String[] dirs = null;
+ BufferedReader bufReader = null;
+ try {
+ bufReader = new BufferedReader(new FileReader("/proc/mounts"));
+ ArrayList list = new ArrayList();
+ list.add(Environment.getExternalStorageDirectory().getPath());
+ String line;
+ while((line = bufReader.readLine()) != null) {
+ if(line.contains("vfat") || line.contains("exfat") ||
+ line.contains("/mnt") || line.contains("/Removable")) {
+ StringTokenizer tokens = new StringTokenizer(line, " ");
+ String s = tokens.nextToken();
+ s = tokens.nextToken(); // Take the second token, i.e. mount point
+
+ if (list.contains(s))
+ continue;
+
+ if (line.contains("/dev/block/vold")) {
+ if (!line.startsWith("tmpfs") &&
+ !line.startsWith("/dev/mapper") &&
+ !s.startsWith("/mnt/secure") &&
+ !s.startsWith("/mnt/shell") &&
+ !s.startsWith("/mnt/asec") &&
+ !s.startsWith("/mnt/obb")
+ ) {
+ list.add(s);
+ }
+ }
+ }
+ }
+
+ dirs = new String[list.size()];
+ for (int i = 0; i < list.size(); i++) {
+ dirs[i] = list.get(i);
+ }
+ }
+ catch (FileNotFoundException e) {}
+ catch (IOException e) {}
+ finally {
+ if (bufReader != null) {
+ try {
+ bufReader.close();
+ }
+ catch (IOException e) {}
+ }
+ }
+ return dirs;
+ }
+
+ public static String[] getCustomDirectories() {
+ SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(VLCApplication.getAppContext());
+ final String custom_paths = preferences.getString("custom_paths", "");
+ if(custom_paths.equals(""))
+ return new String[0];
+ else
+ return custom_paths.split(":");
+ }
+
+ public static String[] getMediaDirectories() {
+ ArrayList list = new ArrayList();
+ list.addAll(Arrays.asList(Util.getStorageDirectories()));
+ list.addAll(Arrays.asList(Util.getCustomDirectories()));
+ return list.toArray(new String[list.size()]);
+ }
+
+ public static void addCustomDirectory(String path) {
+ SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(VLCApplication.getAppContext());
+
+ ArrayList dirs = new ArrayList(
+ Arrays.asList(getCustomDirectories()));
+ dirs.add(path);
+ StringBuilder builder = new StringBuilder();
+ builder.append(dirs.remove(0));
+ for(String s : dirs) {
+ builder.append(":");
+ builder.append(s);
+ }
+ Editor editor = preferences.edit();
+ editor.putString("custom_paths", builder.toString());
+ editor.commit();
+ }
+
+ public static void removeCustomDirectory(String path) {
+ SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(VLCApplication.getAppContext());
+ if(!preferences.getString("custom_paths", "").contains(path))
+ return;
+ ArrayList dirs = new ArrayList(
+ Arrays.asList(preferences.getString("custom_paths", "").split(
+ ":")));
+ dirs.remove(path);
+ String custom_path;
+ if(dirs.size() > 0) {
+ StringBuilder builder = new StringBuilder();
+ builder.append(dirs.remove(0));
+ for(String s : dirs) {
+ builder.append(":");
+ builder.append(s);
+ }
+ custom_path = builder.toString();
+ } else { // don't do unneeded extra work
+ custom_path = "";
+ }
+ Editor editor = preferences.edit();
+ editor.putString("custom_paths", custom_path);
+ editor.commit();
+ }
+
+ /**
+ * Get the formatted current playback speed in the form of 1.00x
+ */
+ public static String formatRateString(float rate) {
+ return String.format(Locale.US, "%.2fx", rate);
+ }
+
+ /**
+ * equals() with two strings where either could be null
+ */
+ public static boolean nullEquals(String s1, String s2) {
+ return (s1 == null ? s2 == null : s1.equals(s2));
+ }
+}
diff --git a/collect-library/src/main/java/org/videolan/vlc/VlcCrashHandler.java b/collect-library/src/main/java/org/videolan/vlc/VlcCrashHandler.java
new file mode 100644
index 00000000..c17eba4f
--- /dev/null
+++ b/collect-library/src/main/java/org/videolan/vlc/VlcCrashHandler.java
@@ -0,0 +1,125 @@
+/*****************************************************************************
+ * VlcCrashHandler.java
+ *****************************************************************************
+ * Copyright © 2012 VLC authors and VideoLAN
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
+ *****************************************************************************/
+
+package org.videolan.vlc;
+
+import android.os.Environment;
+import android.text.format.DateFormat;
+import android.util.Log;
+
+import java.io.BufferedReader;
+import java.io.BufferedWriter;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.OutputStreamWriter;
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.io.Writer;
+import java.lang.Thread.UncaughtExceptionHandler;
+
+public class VlcCrashHandler implements UncaughtExceptionHandler {
+
+ private static final String TAG = "VLC/VlcCrashHandler";
+
+ private UncaughtExceptionHandler defaultUEH;
+
+ public VlcCrashHandler() {
+ this.defaultUEH = Thread.getDefaultUncaughtExceptionHandler();
+ }
+
+ @Override
+ public void uncaughtException(Thread thread, Throwable ex) {
+
+ final Writer result = new StringWriter();
+ final PrintWriter printWriter = new PrintWriter(result);
+
+ // Inject some info about android version and the device, since google can't provide them in the developer console
+ StackTraceElement[] trace = ex.getStackTrace();
+ StackTraceElement[] trace2 = new StackTraceElement[trace.length+3];
+ System.arraycopy(trace, 0, trace2, 0, trace.length);
+ trace2[trace.length+0] = new StackTraceElement("Android", "MODEL", android.os.Build.MODEL, -1);
+ trace2[trace.length+1] = new StackTraceElement("Android", "VERSION", android.os.Build.VERSION.RELEASE, -1);
+ trace2[trace.length+2] = new StackTraceElement("Android", "FINGERPRINT", android.os.Build.FINGERPRINT, -1);
+ ex.setStackTrace(trace2);
+
+ ex.printStackTrace(printWriter);
+ String stacktrace = result.toString();
+ printWriter.close();
+ Log.e(TAG, stacktrace);
+
+ // Save the log on SD card if available
+ if(Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
+ String sdcardPath = Environment.getExternalStorageDirectory().getPath();
+ writeLog(stacktrace, sdcardPath + "/vlc_crash");
+ writeLogcat(sdcardPath + "/vlc_logcat");
+ }
+
+ defaultUEH.uncaughtException(thread, ex);
+ }
+
+ private void writeLog(String log, String name) {
+ CharSequence timestamp = DateFormat.format("yyyyMMdd_kkmmss", System.currentTimeMillis());
+ String filename = name + "_" + timestamp + ".log";
+
+ try {
+ FileOutputStream stream = new FileOutputStream(filename);
+ OutputStreamWriter output = new OutputStreamWriter(stream);
+ BufferedWriter bw = new BufferedWriter(output);
+
+ bw.write(log);
+ bw.newLine();
+
+ bw.close();
+ output.close();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+
+ private void writeLogcat(String name) {
+ CharSequence timestamp = DateFormat.format("yyyyMMdd_kkmmss", System.currentTimeMillis());
+ String filename = name + "_" + timestamp + ".log";
+ String[] args = { "logcat", "-v", "time", "-d" };
+
+ try {
+ Process process = Runtime.getRuntime().exec(args);
+ InputStreamReader input = new InputStreamReader(
+ process.getInputStream());
+ OutputStreamWriter output = new OutputStreamWriter(
+ new FileOutputStream(filename));
+ BufferedReader br = new BufferedReader(input);
+ BufferedWriter bw = new BufferedWriter(output);
+ String line;
+
+ while ((line = br.readLine()) != null) {
+ bw.write(line);
+ bw.newLine();
+ }
+
+ bw.close();
+ output.close();
+ br.close();
+ input.close();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+}
diff --git a/collect-library/src/main/java/org/videolan/vlc/VlcRunnable.java b/collect-library/src/main/java/org/videolan/vlc/VlcRunnable.java
new file mode 100644
index 00000000..2c5ebe0b
--- /dev/null
+++ b/collect-library/src/main/java/org/videolan/vlc/VlcRunnable.java
@@ -0,0 +1,39 @@
+/*****************************************************************************
+ * VlcRunnable.java
+ *****************************************************************************
+ * Copyright © 2012 VLC authors and VideoLAN
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
+ *****************************************************************************/
+package org.videolan.vlc;
+
+public abstract class VlcRunnable implements Runnable {
+ private final Object user;
+
+ public VlcRunnable() {
+ this.user = null;
+ }
+
+ public VlcRunnable(Object o) {
+ this.user = o;
+ }
+
+ public abstract void run(Object o);
+
+ @Override
+ public void run() {
+ run(user);
+ }
+}
diff --git a/collect-library/src/main/java/org/videolan/vlc/WeakHandler.java b/collect-library/src/main/java/org/videolan/vlc/WeakHandler.java
new file mode 100644
index 00000000..4b6c30bc
--- /dev/null
+++ b/collect-library/src/main/java/org/videolan/vlc/WeakHandler.java
@@ -0,0 +1,37 @@
+/*****************************************************************************
+ * WeakHandler.java
+ *****************************************************************************
+ * Copyright © 2012 VLC authors and VideoLAN
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
+ *****************************************************************************/
+
+package org.videolan.vlc;
+
+import android.os.Handler;
+
+import java.lang.ref.WeakReference;
+
+public abstract class WeakHandler extends Handler {
+ private WeakReference mOwner;
+
+ public WeakHandler(T owner) {
+ mOwner = new WeakReference(owner);
+ }
+
+ public T getOwner() {
+ return mOwner.get();
+ }
+}
diff --git a/collect-library/src/main/res/drawable/transient_toast_bg.xml b/collect-library/src/main/res/drawable/transient_toast_bg.xml
new file mode 100644
index 00000000..9f1f934f
--- /dev/null
+++ b/collect-library/src/main/res/drawable/transient_toast_bg.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
diff --git a/collect-library/src/main/res/values/colors.xml b/collect-library/src/main/res/values/colors.xml
index 37318024..f3277d08 100644
--- a/collect-library/src/main/res/values/colors.xml
+++ b/collect-library/src/main/res/values/colors.xml
@@ -9,6 +9,7 @@
#FF000000
#FFFFFFFF
#00FFFFFF
+ #ffffffff
#028FFF
#4E55AF
#FFF6565D
diff --git a/gradle.properties b/gradle.properties
index 26bd972f..ce45e5af 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -27,4 +27,5 @@ systemProp.http.proxyPort=1080
systemProp.https.proxyHost=127.0.0.1
systemProp.https.proxyPort=1080
org.gradle.configureondemand=true
-android.experimental.legacyTransform.forceNonIncremental=true
\ No newline at end of file
+android.experimental.legacyTransform.forceNonIncremental=true
+android.injected.studio.version.check = false
\ No newline at end of file
diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties
index 690a555d..fce747eb 100644
--- a/gradle/wrapper/gradle-wrapper.properties
+++ b/gradle/wrapper/gradle-wrapper.properties
@@ -1,6 +1,6 @@
#Tue Mar 21 10:15:37 CST 2023
distributionBase=GRADLE_USER_HOME
-distributionUrl=https\://services.gradle.org/distributions/gradle-7.5-bin.zip
+distributionUrl=https\://services.gradle.org/distributions/gradle-7.4-bin.zip
distributionPath=wrapper/dists
zipStorePath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME