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