Merge branch 'master' of gitlab.navinfo.com:CollectVehicle/OneMapQS
Conflicts: app/src/main/java/com/navinfo/omqs/ui/activity/PermissionsActivity.kt app/src/main/java/com/navinfo/omqs/ui/activity/map/MainViewModel.kt collect-library/src/main/java/com/navinfo/collect/library/map/handler/LayerManagerHandler.kt
This commit is contained in:
@@ -14,8 +14,7 @@
|
||||
android:value="IxQi4mZGTlfv6Z9M2GRdqn4KKRbOATUU" />
|
||||
<application
|
||||
android:allowBackup="true"
|
||||
android:networkSecurityConfig="@xml/network_security_config"
|
||||
>
|
||||
android:networkSecurityConfig="@xml/network_security_config">
|
||||
</application>
|
||||
|
||||
</manifest>
|
||||
@@ -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;
|
||||
|
||||
@@ -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<HostBean> 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);
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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<Integer, String> services = null;
|
||||
public HashMap<Integer, String> banners = null;
|
||||
public ArrayList<Integer> portsOpen = null;
|
||||
public ArrayList<Integer> 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];
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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<Integer,String> hashMap = new HashMap<Integer,String>();
|
||||
|
||||
// 获取测试服务器接口
|
||||
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;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
package com.navinfo.collect.library.garminvirbxe;
|
||||
|
||||
import com.android.volley.VolleyError;
|
||||
|
||||
public interface RequestJsonListener<T> {
|
||||
/**
|
||||
* 成功
|
||||
*
|
||||
* @param <T>
|
||||
*/
|
||||
public void requestSuccess(T result);
|
||||
|
||||
/**
|
||||
* 错误
|
||||
*/
|
||||
public void requestError(VolleyError e);
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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<JSONObject> 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<JSONObject>() {
|
||||
|
||||
@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<Bitmap> responseBitmapListener(
|
||||
final CameraEventListener listener, final String url,
|
||||
final Boolean isThumb, final HostBean hostBean, final int tag) {
|
||||
return new Response.Listener<Bitmap>() {
|
||||
|
||||
@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();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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<Void, HostBean, Void> {
|
||||
|
||||
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<HostBean> scanHostBeanList;
|
||||
private ArrayList<HostBean> hosts;
|
||||
private ArrayList<HostBean> 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<HostBean>();
|
||||
hosts = new ArrayList<HostBean>();
|
||||
hostsCache = new ArrayList<HostBean>();
|
||||
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;
|
||||
}
|
||||
}
|
||||
@@ -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)
|
||||
|
||||
@@ -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<NiLocation> list = new ArrayList<NiLocation>();
|
||||
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);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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
|
||||
@@ -35,6 +37,7 @@ 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.map.Map.UpdateListener
|
||||
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
|
||||
@@ -67,6 +70,21 @@ open class LayerManagerHandler(context: AppCompatActivity, mapView: NIMapView) :
|
||||
private var resId = R.mipmap.map_icon_point_add
|
||||
private var itemListener: OnQsRecordItemClickListener? = null
|
||||
|
||||
/**
|
||||
* 轨迹渲染图层
|
||||
*/
|
||||
private lateinit var mapLifeNiLocationTileSource: MapLifeNiLocationTileSource
|
||||
|
||||
/**
|
||||
* 轨迹数据图层
|
||||
*/
|
||||
private lateinit var vectorNiLocationTileLayer: VectorTileLayer
|
||||
|
||||
/**
|
||||
* 增加作业渲染
|
||||
*/
|
||||
private lateinit var labelNiLocationLayer: LabelLayer
|
||||
|
||||
/**
|
||||
* 文字大小
|
||||
*/
|
||||
@@ -345,7 +363,7 @@ open class LayerManagerHandler(context: AppCompatActivity, mapView: NIMapView) :
|
||||
itemizedLayer.update()
|
||||
}
|
||||
|
||||
itemizedLayer.populate()
|
||||
// itemizedLayer.populate()
|
||||
}
|
||||
|
||||
|
||||
@@ -559,6 +577,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)
|
||||
}
|
||||
}
|
||||
|
||||
interface OnQsRecordItemClickListener {
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
}
|
||||
@@ -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) {
|
||||
|
||||
|
||||
@@ -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){
|
||||
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
|
||||
}
|
||||
@@ -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);
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
}
|
||||
}
|
||||
@@ -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 {
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 返回点几何
|
||||
*
|
||||
|
||||
@@ -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<NetworkInterface> 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<InetAddress> 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<NetworkInterface> en = NetworkInterface.getNetworkInterfaces();
|
||||
// 遍历所用的网络接口
|
||||
while (en.hasMoreElements()) {
|
||||
NetworkInterface networks = en.nextElement();
|
||||
// 得到每一个网络接口绑定的所有ip
|
||||
Enumeration<InetAddress> 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;
|
||||
}
|
||||
}
|
||||
@@ -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";
|
||||
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
74
collect-library/src/main/java/org/videolan/libvlc/Aout.java
Normal file
74
collect-library/src/main/java/org/videolan/libvlc/Aout.java
Normal file
@@ -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();
|
||||
}
|
||||
}
|
||||
@@ -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<Handler> mEventHandler;
|
||||
private static EventHandler mInstance;
|
||||
|
||||
EventHandler() {
|
||||
mEventHandler = new ArrayList<Handler>();
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
653
collect-library/src/main/java/org/videolan/libvlc/LibVLC.java
Normal file
653
collect-library/src/main/java/org/videolan/libvlc/LibVLC.java
Normal file
@@ -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<Integer,String> getAudioTrackDescription();
|
||||
|
||||
public native int getAudioTrack();
|
||||
|
||||
public native int setAudioTrack(int index);
|
||||
|
||||
public native int getVideoTracksCount();
|
||||
|
||||
public native int addSubtitleTrack(String path);
|
||||
|
||||
public native Map<Integer,String> 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<String> res);
|
||||
|
||||
public native static boolean nativeIsPathDirectory(String path);
|
||||
|
||||
/**
|
||||
* Get the list of existing items in the media list (playlist)
|
||||
*/
|
||||
public native void getMediaListItems(ArrayList<String> 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);
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
124
collect-library/src/main/java/org/videolan/libvlc/MediaList.java
Normal file
124
collect-library/src/main/java/org/videolan/libvlc/MediaList.java
Normal file
@@ -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();
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
183
collect-library/src/main/java/org/videolan/vlc/MurmurHash.java
Normal file
183
collect-library/src/main/java/org/videolan/vlc/MurmurHash.java
Normal file
@@ -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));
|
||||
}
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
546
collect-library/src/main/java/org/videolan/vlc/Util.java
Normal file
546
collect-library/src/main/java/org/videolan/vlc/Util.java
Normal file
@@ -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<String> devicesWithoutNavBar = new HashSet<String>();
|
||||
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<String> list = new ArrayList<String>();
|
||||
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<String> list = new ArrayList<String>();
|
||||
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<String> dirs = new ArrayList<String>(
|
||||
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<String> dirs = new ArrayList<String>(
|
||||
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));
|
||||
}
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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<T> extends Handler {
|
||||
private WeakReference<T> mOwner;
|
||||
|
||||
public WeakHandler(T owner) {
|
||||
mOwner = new WeakReference<T>(owner);
|
||||
}
|
||||
|
||||
public T getOwner() {
|
||||
return mOwner.get();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle">
|
||||
<corners android:topLeftRadius="3dp" android:topRightRadius="3dp" android:bottomLeftRadius="3dp" android:bottomRightRadius="3dp"></corners>
|
||||
<padding android:left="10dp" android:top="10dp" android:right="10dp" android:bottom="10dp"/>
|
||||
<solid android:color="#AA535353"></solid>
|
||||
</shape>
|
||||
@@ -9,6 +9,7 @@
|
||||
<color name="black">#FF000000</color>
|
||||
<color name="white">#FFFFFFFF</color>
|
||||
<color name="transparent">#00FFFFFF</color>
|
||||
<color name="background_light">#ffffffff</color>
|
||||
<color name="draw_line_blue1_color" comment="线数据样式">#028FFF</color>
|
||||
<color name="draw_line_blue2_color" comment="线数据样式">#4E55AF</color>
|
||||
<color name="draw_line_red_color" comment="线数据样式">#FFF6565D</color>
|
||||
|
||||
Reference in New Issue
Block a user