All Posts

Android连接Theta系列(二)

接着上面的Theta第一篇 我们先来改造展示全景相片的View,没有圆球效果,只是将Demo版的View伸展到全屏。 找到 GLRenderer 这个类的 onSurfaceChanged 这个方法,改为: /** * onSurfaceChanged Method * @param gl GLObject (not used) * @param width Screen width * @param height Screen height */ @Override public void onSurfaceChanged(final GL10 gl, final int width, final int height) { int _height = height; mScreenAspectRatio = (float) width / (float) (_height == 0 ? 1 : _height); GLES20.glViewport(0, _height, width, _height); Matrix.setLookAtM(mViewMatrix, 0, mCameraPosX, mCameraPosY, mCameraPosZ, mCameraDirectionX, mCameraDirectionY, mCameraDirectionZ, 0.

Android连接Theta系列(一)

Theta 是一个全景相机 ,是由日本理光出品的,目前最新的型号是 RICOH THETA V。 推荐下载官方App:理光景达S。 先说一下怎么在APP中去控制它,Theta开启会发出一个wifi,然后手机连入这个wifi,通过App发出http请求来控制theta。 然后可以进行以下操作: 1,获取预览实时图像 2,设置拍照参数 3,拍照 4,取回所拍的照片等等 理光开发平台有demo和连接的API:https://developers.theta360.com/en/docs/ 但是~ 该demo非常简陋,API文档非常不完善,对比官方App就知道有多坑人了。 由此我踩了很多坑,http请求基本通过手机抓包获取,其中艰辛可见一斑。 推荐手机抓包工具:PacketCapture theta官网的Demo下载地址:https://developers.theta360.com/en/docs/sdk/download.html 连上Theta的wifi 开启Demo,可以看到这样的画面 1,通过 ShowLiveViewTask 获取实时画面数据流,通过 MJpegView 展示出来。 2,点击图片列表下载到手机上。 3,拍照、查看拍照的全景照片 Demo和官方App还是有很大的差别的,全景照片的展示没有那么炫酷,而且尺寸触摸的流畅度也差很远,官方只是说他们是和谷歌的全景照片一样的控件,意思就是说不会开源给你用的。

GreenDao数据库升级

在将apk发包出去后需要改动Entity的元素,就需要升级数据库。 这时看具体需求,一是不需要原有数据,清除数据库;二是需要保留原有数据。 greendao默认使用的是第一种: Daomaster: public static class DevOpenHelper extends OpenHelper { public DevOpenHelper(Context context, String name) { super(context, name); } public DevOpenHelper(Context context, String name, CursorFactory factory) { super(context, name, factory); } @Override public void onUpgrade(Database db, int oldVersion, int newVersion) { Log.i("greenDAO", "Upgrading schema from version " + oldVersion + " to " + newVersion + " by dropping all tables"); dropAllTables(db, true); onCreate(db); } } 这里只说第二种情况。

获得当前手机的内存状态

ActivityManager mActivityManager = (ActivityManager)mApplication.getSystemService(ACTIVITY_SERVICE); int memory = mActivityManager.getMemoryClass(); float totalMemory = (float) (Runtime.getRuntime().totalMemory() * 1.0/ (1024 * 1024)); float freeMemory = (float) (Runtime.getRuntime().freeMemory() * 1.0/ (1024 * 1024)); Log.e("内存","最大分配内存:"+memory+" 当前分配的总内存:"+totalMemory+" 剩余内存:"+freeMemory);

读取点云.OBJ文件,画出顶点平面图

基于一款开源应用 Rtabmap https://github.com/introlab/rtabmap 是基于 Google 的 Tango 手机使用的 通过摄像头和红外摄像头扫描立体空间,并实时显示在手机上,扫描后可保存所扫描的点云数据, .ply文件或.ob文件。 下图是扫描中截得图 3D Builder软件打开 .obj 文件是这样(和上图不是一个文件) Android studio 打开 .obj 文件如下图 我这里只需要平面图 就是v顶点 其余的不需要 下面开始: 首先是读取.obj文件 文件在手机内 public void startRead(final String uri) { mRootView.showLoading(); new Thread(new Runnable() { @Override public void run() { KLog.e("start read"); long start = System.currentTimeMillis(); getObjXy(uri); long end = System.currentTimeMillis(); KLog.e("用时:" + ((end - start) / 1000) + " s"); //画点 drawpoint(); } }).start(); } /** * 读取 obj 的 xy点 * * @param uri */ private void getObjXy(String uri) { String fileStr = uri.

Hugo搭建个人博客

参考 https://www.jianshu.com/p/f1b02e00f206 可搭建出一个博客并发布在github 参考 https://blog.csdn.net/btlas/article/details/51712596 可将github地址解析在个人域名下 hugo命令: 新建文章 hugo new post/xxx.md draft 改为 false 本地预览 hugo server --theme=hyde 即可在浏览器里输入: http://localhost:1313访问网站 发布在github hugo --theme=hyde --baseUrl="https://YOURNAME.github.io/" 我发现Theme 为 nuo时发布命令需要这样写: hugo --theme=nuo --buildDrafts --baseUrl="https://YOURNAME.github.io/" 更新文章只需上面步骤即可。

Zip压缩和解压的方法

首先是一个 ZipControl 的zip工具类 import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.InputStream; import java.util.ArrayList; import java.util.List; import java.util.zip.ZipEntry; import java.util.zip.ZipFile; import java.util.zip.ZipInputStream; import java.util.zip.ZipOutputStream; /** * Created by zhangli * * @time 2017/8/23 */ public class ZipControl{ /** * 压缩文件和文件夹 * @param srcFileString 要压缩的文件或文件夹 * @param zipFileString 解压完成的Zip路径 * @throws Exception */ public static void ZipFolder(String srcFileString, String zipFileString)throws Exception { //创建ZIP ZipOutputStream outZip = new ZipOutputStream(new FileOutputStream(zipFileString)); //创建文件 File file = new File(srcFileString); //压缩 ZipFiles(file.

添加或删除RecyclerView的item后

通常Recycler给Adapter赋上数据源的时候利用: adapter.notifyDataSetChanged(); 这样一般是在初始化界面 从网络获取到数据后 直接赋给adapter的写法。 然后再动态的增加条目,又希望带有动画效果,可以这么写: adapter.notifyItemRangeInserted(int positionStart, int itemCount); 嗯,在RecyclerView中 数据给加上去了 并且有一个动画效果。 但是,注意Adapter 中,这个数据源并没有增加。 这时,就要用到 notifyDataSetChanged() 这个方法了 在 调用加入的方法后 再调用全部刷新的方法。我的写法是这样的: adapter.notifyItemRangeInserted(int positionStart, int itemCount); new Handler().postDelayed(new Runnable() { @Override public void run() { adapter.notifyDataSetChanged(); } },400); 利用Handler延时400ms 刷新 这样写是因为加入时的动画效果有那么一小段时间,如果不延时直接刷新的话动画会卡顿,不信可以去试试。 删除也是同理。

使用Retrofit的一些实例

刚开始熟悉Retrofit ,并正在将项目中的网络框架换为retrofit。 添加依赖: //Retrofit2所需要的包 compile 'com.squareup.retrofit2:retrofit:last_version' //ConverterFactory的Gson依赖包 compile 'com.squareup.retrofit2:converter-gson:last_version' Retrofit的网络接口服务的包装类 public class RetrofitWrapper { private static RetrofitWrapper retrofitWrapper; private Retrofit retrofit; private RetrofitWrapper() { retrofit = new Retrofit.Builder().baseUrl(AppConfig.RETROFIT_URL) .addConverterFactory(GsonConverterFactory.create()) .build(); } /** * 单列模式 */ public static RetrofitWrapper getWrapperInstance() { if (retrofitWrapper == null) { synchronized (RetrofitWrapper.class) { if (retrofitWrapper == null) { retrofitWrapper = new RetrofitWrapper(); } } } return retrofitWrapper; } public <T> T create(final Class<T> service) { return retrofit.

调起百度、高德、腾讯地图导航功能

如果可以,先得到这3个条件,然后在调起地图的请求中传进去。 使用这个方法判断手机中是否包含应用: /** * 检查手机上是否安装了指定的软件 * * @param context * @param packageName:应用包名 * @return */ public static boolean isAvilible(Context context, String packageName) { //获取packagemanager final PackageManager packageManager = context.getPackageManager(); //获取所有已安装程序的包信息 List<PackageInfo> packageInfos = packageManager.getInstalledPackages(0); //用于存储所有已安装程序的包名 List<String> packageNames = new ArrayList<String>(); //从pinfo中将包名字逐一取出,压入pName list中 if (packageInfos != null) { for (int i = 0; i < packageInfos.size(); i++) { String packName = packageInfos.get(i).packageName; packageNames.add(packName); } } //判断packageNames中是否有目标程序的包名,有TRUE,没有FALSE return packageNames.contains(packageName); } //百度 if (isAvilible(getApplicationContext(), "com.