DCloud 小试

最近将公司一个小工具用dcloud去写,非常爽,页面流畅程度没得说,最接近原生的ui看来不是吹的,对于虐过phonegap的人来说。

官方首页

http://dcloud.io/

HTML5+
http://www.html5plus.org/doc/zh_cn/device.html

MUI
http://dev.dcloud.net.cn/mui/

补充 chrome 远程 调试:

chrome://inspect

注意:文档类的说明还不全,但是不太影响开发。直接下载 copy mui的demo基本上就能做很多东西了。

特别注意下mui的相关调用:

mui('.mui-slider').slider().gotoItem(1);

文档没有提供明确的函数相关,所以一些触发不清楚的,暂时查不到,直接看mui.js,然后把相关的动作复制出来用就可以了。

主要一个重要的特性就是支持多个webview,解决原来phonegap单一webview,如果处理多功能,得拼死在一块的大弊端。如果,如果主webview有编辑页面,需要弹一个图库的功能,只需要弹一个新的webview出来,并将结果返回到主webview就好了.同时,原来是通过jquery mobile 实现页面切换。因为jquery mobile 的切换实际是通过远程抓取页面的<div xx page>元素补充到当前页面并进行切换的,一个是jqmobile实在是太大,导致各种卡闪,虽然极其轻微。但是好处是基本上你需要的东西都能找到。比mui要成熟很多。不过mui相对轻巧简单,出现的小问题,基本上提交下bug,自己写写相关处理也是可以的。

webview 传值

http://www.html5plus.org/doc/zh_cn/webview.html#plus.webview.WebviewObject.evalJS

 

NDK 相关

IBM一个教程

http://www.ibm.com/developerworks/cn/opensource/tutorials/os-androidndk/index.html

官方教程和说明

http://developer.android.com/ndk/guides/index.html

需要有C++基础,我入门学的就是这个。

各人习惯了学习什么新东西,直接运行demo。然后扫一次代码,再去看教程。这样教程说的东西,需要的方便修改测试。不过因为当时研究的一个东西,别人写了一个现成的,走一边代码后,测试没有到达目标需求,就没有继续深入了。

补充一个fork写得很详细的文章

http://blog.csdn.net/jason314/article/details/5640969

 

android常驻折腾

前台时间公司需要实现一个特殊的功能,常驻系统,使现成不被kill。

搞过双服务,广播,Ndk发起线程,但是都不太实用。首先需要说明一个问题,不管自启还是后台运行,4.4以上的测试机(oppo r4,荣耀6,8) 这些都需要在手机自带的管理程序里开启才能保持,否则一律被k。老机型,像我的是4.2(夏新n828),除了广播,其它都有效,广播4.2以上,程序k了就接收不到了。不确定是不是因为root被拿到了太高的权限被写入系统,root这个获取,不在考虑,因为用户会root的很少。同时需要pc端支持配合,不在能力范围。

附带 ndk fork demo:

http://www.ibm.com/developerworks/cn/opensource/tutorials/os-androidndk/index.html

定位研究

最近公司不知道怎么接了一个猥亵的项目,通过手机安装软件来监控人的行动轨迹。整理下相关问题和不完善的解决方案.

软件肯定是以service 形式运行,界面关闭+ 开机运行。然后动态发送用户坐标到制定的服务器。当然,需要用户的设备信息做唯一标志。下面罗列各点问题。

定位工具:

http://developer.baidu.com/map/index.php?title=android-locsdk

注:研究早了几天,不知道是人品不好还是太好。研究的时候,需要的都没有。折腾了几天,突然发现又有了。主要离线定位和gprs定位不稳定。新版本6.0.5本身已经是启动服务版本了,所以不用通过编写service 等进行定时任务和触发.

Android如何保持程序一直运行:

http://abc20899.iteye.com/blog/1045537

深入了解 Android 系統 Wi-Fi 網路自動休眠機制運作方式:

http://mobileai.net/2013/06/17/android-wi-fi-sleep/

坐标数据需要进行特殊过滤:

61 : GPS定位结果,GPS定位成功。

62 : 无法获取有效定位依据,定位失败,请检查运营商网络或者wifi网络是否正常开启,尝试重新请求定位。

63 : 网络异常,没有成功向服务器发起请求,请确认当前测试手机网络是否通畅,尝试重新请求定位。

65 : 定位缓存的结果。

66 : 离线定位结果。通过requestOfflineLocaiton调用时对应的返回结果。

67 : 离线定位失败。通过requestOfflineLocaiton调用时对应的返回结果。

68 : 网络连接失败时,查找本地离线定位时对应的返回结果。

161: 网络定位结果,网络定位定位成功。

162: 请求串密文解析失败。

167: 服务端定位失败,请您检查是否禁用获取位置信息权限,尝试重新请求定位。

502: key参数错误,请按照说明文档重新申请KEY。

505: key不存在或者非法,请按照说明文档重新申请KEY。

601: key服务被开发者自己禁用,请按照说明文档重新申请KEY。

602: key mcode不匹配,您的ak配置过程中安全码设置有问题,请确保:sha1正确,“;”分号是英文状态;且包名是您当前运行应用的包名,请按照说明文档重新申请KEY。

501~700:key验证失败,请按照说明文档重新申请KEY。

/**
*求两个已知经纬度之间的距离,单位为米
*@param lng1,lng2 经度
*@param lat1,lat2 纬度
*@return float 距离,单位米
**/
function getdistance($lng1,$lat1,$lng2,$lat2)//根据经纬度计算距离
{
    //将角度转为狐度 
    $radLat1=deg2rad($lat1);
    $radLat2=deg2rad($lat2);
    $radLng1=deg2rad($lng1);
    $radLng2=deg2rad($lng2);
    $a=$radLat1-$radLat2;//两纬度之差,纬度<90
    $b=$radLng1-$radLng2;//两经度之差纬度<180
    $s=2*asin(sqrt(pow(sin($a/2),2)+cos($radLat1)*cos($radLat2)*pow(sin($b/2),2)))*6378.137*1000;
    return $s;
}

需要将除了gps 定位返回的坐标进行特殊识别。比如,相隔两点坐标,如果第一个为网络定位,离线定位等可能缓存的坐标。判断时间范围是否在30秒内,距离是否超过300米。如果是。则试为缓存,跳过.

gps 定位慢:

http://blog.csdn.net/u013227819/article/details/19494205

后台管理:

百度地图js显示行动路线时,点少于20个可以考虑行走路线 BMap.WalkingRoute  进行处理。超过这个。在搜索路线时,本身就比较。卡,其它软件产品则通过画线的形式,这边使用 Polyline 进行线条绘制,上百个点绘制无压力,秒出。

补绘制线条箭头:http://blog.csdn.net/baidulbs/article/details/8571961

修复线条箭头bug版本:http://www.bubuko.com/infodetail-802725.html

离线考虑:

离线的情况下,星历等,包括基站,wifi 数据等都有问题。定位本身只能依靠gps。同时可以考虑惯性导航做辅助。不过惯性也只能做普通辅助,毕竟各种影响也不少。需要将坐标保存到本地数据库中,然后等网络通的情况下,将坐标上传到服务器.

总结:

同类型跑酷软件,大都也是通过百度定位sdk获取数据。毕竟基站数据wifi数据,大公司是比较全的。不过我觉得如果不是谷歌被日,会有更好的解决方案。不过终究只是通过先有功能进行处理,线程被杀还是挺容易的,从c启动就不会那么容易被清理到。但是实现成本有些搞。暂时只研究到这里,后面有更好的解决方式再来记录.

【转】Android学习指南

http://www.apkbus.com/android-830-1-1.html

整理了一下这本《Android学习指南》的目录 


目录
第一讲:Android开发环境的搭建
第二讲:Android系统构架分析和应用程序目录结构分析
第三讲:Android模拟器的使用
第四讲:Activity入门指南
第五讲:用户界面 View(一)
第六讲:用户界面 View(二)
第七讲:用户界面 View(三)
第八讲:Intent入门指南
第九讲:用户界面 View(四)
第十讲:用户界面 View(五)
第十一讲:用户界面 View(六)
第十二讲:用户界面 View(七)
第十三讲:用户界面 View(八)
第十四讲:Service入门指南
第十五讲:SQLite入门指南
第十六讲:菜单 Android Menu
第十七讲:对话框 Android Dialog
第十八讲:Android SharedPreferences和File
第十九讲:Android Notification的使用入门
第二十讲:Content Provider 使用入门
第二十一讲:Broadcast Receiver 使用入门
第二十二讲:AIDL和远程Service调用
第二十三讲:Drawable使用入门
第二十四讲:Android动画入门(一)
第二十五讲:Android动画入门(二)
第二十六讲:Android中的GPS应用入门

第二十八讲:Android多媒体(Media)入门
音乐播放、视频播放、声音录制,窈窈录音
第三十讲:URLConnection和HttpClient使用入门
读取Google天气预报信息
解析Google天气预报信息
Style, Theme
自定义音乐播放器界面
火箭发射倒计时
Hello,App Widget! ,音乐播放器小部件
窈窈照相机
窈窈录音器
第三十八讲:Android手写输入和手势编程入门
未写
第三十九讲:Android语音识别编程入门
未写
第四十讲:Android Wifi编程入门
未写
第四十二讲:用户界面 View(九)
SlidingDrawer 仿造Home的应用程序列表
ExpandableListView  ExpandableListActivity
TabHost,TabWidget,Tabactivity
ImageSwitcher TextSwitcher
ViewFlipper ViewAnimator

PhoneGap 手机百度地图定位插件

虽然不难。。能简单搞定的就简单搞。。能复制就复制。

插件地址:https://github.com/DoubleSpout/phonegap_baidu_sdk_location

原文博客:http://snoopyxdy.blog.163.com/blog/static/601174402014420872345/

<?xml version="1.0" encoding="UTF-8"?>

<plugin xmlns="http://www.phonegap.com/ns/plugins/1.0" id="com.spout.phonegap.plugins.baidulocation" version="0.1.0">
    <name>BaiduLocation</name>
    <description>Baidu Location Plugin for Phonegap</description>
    <license>MIT</license>
    <keywords>baidu, location, phonegap</keywords>

    <!-- android -->
    <platform name="android">
        <js-module src="www/baidulocation.js" name="BiaduLocation">
            <clobbers target="window.baiduLocation" />
        </js-module>

        <config-file target="res/xml/config.xml" parent="/*">
            <feature name="BaiduLocation">
                <param name="android-package" value="com.spout.phonegap.plugins.baidulocation.BaiduLocation"/>
            </feature>
        </config-file> 

        <config-file target="AndroidManifest.xml" parent="/*">
            <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"></uses-permission>
            <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"></uses-permission>
            <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"></uses-permission>
            <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"></uses-permission>
            <uses-permission android:name="android.permission.CHANGE_WIFI_STATE"></uses-permission>
            <uses-permission android:name="android.permission.READ_PHONE_STATE"></uses-permission>
            <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"></uses-permission>
            <uses-permission android:name="android.permission.INTERNET" />
            <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"></uses-permission>
            <uses-permission android:name="android.permission.READ_LOGS"></uses-permission>
        </config-file>

        <config-file target="AndroidManifest.xml" parent="/manifest/application">
            <service android:name="com.baidu.location.f" android:enabled="true" android:process=":remote"></service>
        </config-file>

        <source-file src="src/android/BaiduLocation.java" target-dir="src/com/spout/phonegap/plugins/baidulocation" />   
        <source-file src="src/android/locSDK_4.0.jar" target-dir="libs" framework="true"/>      
        <source-file src="src/android/liblocSDK4.so" target-dir="libs/armeabi" framework="true"/>   
    </platform>         
</plugin>

将上述地址配置到指定文件即可.

需要留意版本,本人就还是在用android 4.1 cordova 用的是2.8版本,所以稍微麻烦了点

莫鄙视…

补充一个2.8版本的百度地图定位

package com.spout.phonegap.plugins.baidulocation;

import java.util.HashMap;
import java.util.Map;

import org.apache.cordova.api.CallbackContext;
import org.apache.cordova.api.Plugin;
import org.apache.cordova.api.PluginResult;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import com.baidu.location.BDLocation;
import com.baidu.location.BDLocationListener;
import com.baidu.location.LocationClient;
import com.baidu.location.LocationClientOption;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.SharedPreferences;
import android.preference.PreferenceManager;
import android.util.Log;

public class BaiduLocation extends Plugin {

	public static final String PLUGIN_NAME = "BaiduLocation";
	NotificationManager notificationManager;
	Notification note;
	PendingIntent contentIntent;

	public CallbackContext callbackContext;
	private static final String STOP_ACTION = "stop";
	private static final String GET_ACTION = "getCurrentPosition";
	public LocationClient locationClient = null;
	public JSONObject jsonObj = new JSONObject();
	public boolean result = false;

	public BDLocationListener myListener;

	private static final Map<Integer, String> ERROR_MESSAGE_MAP = new HashMap<Integer, String>();

	private static final String DEFAULT_ERROR_MESSAGE = "服务端定位失败";

	static {
		ERROR_MESSAGE_MAP.put(61, "GPS定位结果");
		ERROR_MESSAGE_MAP.put(62, "扫描整合定位依据失败。此时定位结果无效");
		ERROR_MESSAGE_MAP.put(63, "网络异常,没有成功向服务器发起请求。此时定位结果无效");
		ERROR_MESSAGE_MAP.put(65, "定位缓存的结果");
		ERROR_MESSAGE_MAP.put(66, "离线定位结果。通过requestOfflineLocaiton调用时对应的返回结果");
		ERROR_MESSAGE_MAP.put(67, "离线定位失败。通过requestOfflineLocaiton调用时对应的返回结果");
		ERROR_MESSAGE_MAP.put(68, "网络连接失败时,查找本地离线定位时对应的返回结果。");
		ERROR_MESSAGE_MAP.put(161, "表示网络定位结果");
	};

	public String getErrorMessage(int locationType) {
		String result = ERROR_MESSAGE_MAP.get(locationType);
		if (result == null) {
			result = DEFAULT_ERROR_MESSAGE;
		}
		return result;
	}
	private void logMsg(String s) {
		System.out.println(s);
	}

	public CallbackContext getCallbackContext() {
		return callbackContext;
	}

	public void setCallbackContext(CallbackContext callbackContext) {
		this.callbackContext = callbackContext;
	}
	@Override
	public boolean execute(String action, JSONArray args,
			final CallbackContext callbackContext) throws JSONException {
		Log.d(PLUGIN_NAME, "Plugin execute called with action: " + action);

		setCallbackContext(callbackContext);
		if (GET_ACTION.equals(action)) {
			cordova.getActivity().runOnUiThread(new Runnable() {
				@Override
				public void run() {

					Log.d(PLUGIN_NAME, "run: ");
					locationClient = new LocationClient(cordova.getActivity());
					locationClient.setAK("BfkPvjDGHC0ATZhIr6wxnHh9");// 设置百度的ak
					myListener = new MyLocationListener();
					locationClient.registerLocationListener(myListener);
					LocationClientOption option = new LocationClientOption();
					option.setOpenGps(true);
					option.setCoorType("bd09ll");// 返回的定位结果是百度经纬度,默认值gcj02
					option.setProdName("BaiduLoc");
					option.disableCache(true);// 禁止启用缓存定位
					locationClient.setLocOption(option);

					locationClient.start();
					locationClient.requestLocation();

				}

			});
		} else if (STOP_ACTION.equals(action)) {
			locationClient.stop();
		}

		while (result == false) {
			try {
				Thread.sleep(100);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
		return true;
	}
	@Override
	public void onDestroy() {
		if (locationClient != null && locationClient.isStarted()) {
			locationClient.stop();
			locationClient = null;
		}
		super.onDestroy();
	}

	public class MyLocationListener implements BDLocationListener {
		@Override
		public void onReceiveLocation(BDLocation location) {
			if (location == null)
				return;
			try {

				Log.d(PLUGIN_NAME, "MyLocationListener");
				JSONObject coords = new JSONObject();
				coords.put("latitude", location.getLatitude());
				coords.put("longitude", location.getLongitude());
				coords.put("radius", location.getRadius());

				jsonObj.put("coords", coords);

				int locationType = location.getLocType();

				jsonObj.put("locationType", locationType);
				jsonObj.put("code", locationType);
				jsonObj.put("message", getErrorMessage(locationType));

				switch (location.getLocType()) {

				case BDLocation.TypeGpsLocation:
					coords.put("speed", location.getSpeed());
					coords.put("altitude", location.getAltitude());
					jsonObj.put("SatelliteNumber",
							location.getSatelliteNumber());
					break;

				case BDLocation.TypeNetWorkLocation:
					jsonObj.put("addr", location.getAddrStr());
					break;
				}

				Log.d("BaiduLocationPlugin", "run: " + jsonObj.toString());
				callbackContext.success(jsonObj);
				result = true;
			} catch (JSONException e) {
				callbackContext.error(e.getMessage());
				result = true;
			}

		}

		@Override
		public void onReceivePoi(BDLocation arg0) {
			// TODO Auto-generated method stub

		}
	}

	@SuppressWarnings("unused")
	@Override
	public PluginResult execute(String arg0, JSONArray arg1, String arg2) {

		Log.d("BaiduLocationPlugin", "run: xxxx" );
		return new PluginResult(true ? PluginResult.Status.OK
				: PluginResult.Status.ERROR);
		// TODO Auto-generated method stub
	}

}

 

 

 

反编译android程序,进行简单修改

参考:http://blog.csdn.net/sunboy_2050/article/details/6727581

反编译成lib的模式可能当学习。但是实际意义不大。

但是反编译成smali方式,可以再编译,只要解决签名问题即可。

可以把反编译后的layout文件进行定位,确认要修改的程序部分所在位置。

小程序修改也可以。

签名解决demo:

jarsigner -keystore D:apktoolapk2javaapktool1.4.1debug.keystore -storepass android -keypass android D:apktoolapk2javaapktool1.4.1com.tonyzhang.friends.apk androiddebugkey

debug.keystore 可在adt中找到

转发请注明出处http://blog.martoo.cn
如有漏缺,请联系我 QQ 243008827