28-08-2014 3 条评论

错误原因:API等级 API 20:Android 4.4w,这是Android官网发布的可穿戴设备的API,它是不支持EditText组件的;

解决方案:在bulid.gradle里面将API版本改成19即可

参考:https://stackoverflow.com/questions/24451490/exception-raised-during-rendering-java-lang-system-arraycopy


27-06-2013 0 条评论

最近莫名奇妙遇到“Conversion to Dalvik format failed: Unable to execute dex”错误,stackoverflow以后得到结果

把项目中classpath文件中<classpathentry kind="lib"   path ="自定义jar的地址" /> 修改成 <classpathentry kind="con" path="com.android.ide.eclipse.adt.ANDROID_FRAMEWORK"/>,删掉
<classpathentry kind="con" path="com.android.ide.eclipse.adt.LIBRARIES"/>。然后就OK了

18-04-2013 0 条评论

Eclipse 编译 Android工程时,提示该错误 :Error generating final archive:java.io.EOFException
问题所在及解决方法:
在Eclipse菜单Window -> Preferences -> Android -> Build,找到那个Default debug keystore显示的路径,就是debug.keystore这个文件(expired)过期了,它的路径就是文章《Android环境搭建及相关命令》里面说的设置SD卡img文件的上一层目录.android。
所以不论Windows系统还是Linux系统,只要删除这个debug.keystore就行了,Eclipse会自动生成一个新的,默认有效期也是一年。

12-01-2013 2 条评论
public class busRoute extends MapActivity {

	private Button mBtnTransit = null; // 公交搜索
	private ListView busList;// 公交列表


	private MapView mMapView = null; // 地图View
	private MKSearch mSearch = null; // 搜索模块,也可去掉地图模块独立使用
	private MapController mapController;

	protected void onCreate(Bundle savedInstanceState) {

		super.onCreate(savedInstanceState);
		setContentView(R.layout.busroute);

		BMapApiDemoApp app = (BMapApiDemoApp) this.getApplication();
		if (app.mBMapMan == null) {
			app.mBMapMan = new BMapManager(getApplication());
			app.mBMapMan.init(app.mStrKey,
					new BMapApiDemoApp.MyGeneralListener());
		}
		app.mBMapMan.start();
		// 如果使用地图SDK,请初始化地图Activity
		super.initMapActivity(app.mBMapMan);

		mMapView = (MapView) findViewById(R.id.bmapView);
		mMapView.setBuiltInZoomControls(true);
		// 设置在缩放动画过程中也显示overlay,默认为不绘制
		mMapView.setDrawOverlayWhenZooming(true);

		GeoPoint geoPoint = new GeoPoint((int) (32.05000 * 1E6),
				(int) ( 118.78333* 1E6));

		// 取得地图控制器对象,用于控制MapView
		mapController = mMapView.getController();
		// 设置地图的中心
		mapController.setCenter(geoPoint);
		// 设置地图默认的缩放级别
		mapController.setZoom(12);

		// 初始化搜索模块,注册事件监听
		mSearch = new MKSearch();
		mSearch.init(app.mBMapMan, new MKSearchListener() {

			@Override
			public void onGetPoiDetailSearchResult(int type, int error) {
			}

			public void onGetDrivingRouteResult(MKDrivingRouteResult res,
					int error) {
				
			}

			public void onGetTransitRouteResult(MKTransitRouteResult res,
					int error) {
				if (error != 0 || res == null) {
					Toast.makeText(busRoute.this, "抱歉,未找到结果",
							Toast.LENGTH_SHORT).show();
					mMapView.setVisibility(View.VISIBLE);
					busList.setVisibility(View.GONE);
					return;
				}
				MyAdapter myAdapter = new MyAdapter(busRoute.this, res);
				busList.setAdapter(myAdapter);
			}

			public void onGetWalkingRouteResult(MKWalkingRouteResult res,
					int error) {
				
			}

			public void onGetAddrResult(MKAddrInfo res, int error) {
			}

			public void onGetPoiResult(MKPoiResult res, int arg1, int arg2) {

			}

			public void onGetBusDetailResult(MKBusLineResult result, int iError) {
			}

			@Override
			public void onGetSuggestionResult(MKSuggestionResult res, int arg1) {
				// TODO Auto-generated method stub

			}

			@Override
			public void onGetRGCShareUrlResult(String arg0, int arg1) {
				// TODO Auto-generated method stub

			}
		});

		// 设定搜索按钮的响应
		busList = (ListView) findViewById(R.id.bus_list);
		busList.setCacheColorHint(0);
		mBtnTransit = (Button) findViewById(R.id.transit);

		OnClickListener clickListener = new OnClickListener() {
			public void onClick(View v) {
				mMapView.setVisibility(View.GONE);
				busList.setVisibility(View.VISIBLE);
				SearchButtonProcess(v);
			}
		};
		mBtnTransit.setOnClickListener(clickListener);
	}

	void SearchButtonProcess(View v) {
		// 处理搜索按钮响应
		EditText editSt = (EditText) findViewById(R.id.start);
		EditText editEn = (EditText) findViewById(R.id.end);

		// 对起点终点的name进行赋值,也可以直接对坐标赋值,赋值坐标则将根据坐标进行搜索
		MKPlanNode stNode = new MKPlanNode();
		stNode.name = editSt.getText().toString();
		MKPlanNode enNode = new MKPlanNode();
		enNode.name = editEn.getText().toString();

		// 实际使用中请对起点终点城市进行正确的设定
		if (mBtnTransit.equals(v)) {
			mSearch.transitSearch("南京", stNode, enNode);
		} 
	}

	@Override
	protected void onPause() {
		BMapApiDemoApp app = (BMapApiDemoApp) this.getApplication();
		app.mBMapMan.stop();
		super.onPause();
	}

	@Override
	protected void onResume() {
		BMapApiDemoApp app = (BMapApiDemoApp) this.getApplication();
		app.mBMapMan.start();
		super.onResume();
	}

	@Override
	protected boolean isRouteDisplayed() {
		// TODO Auto-generated method stub
		return false;
	}

	// 填充公交列表
	class MyAdapter extends BaseAdapter {
		private MKTransitRouteResult res;
		private LayoutInflater mInflater;

		public MyAdapter(Context context, MKTransitRouteResult res) {
			this.res = res;
			this.mInflater = LayoutInflater.from(context);
		}

		@Override
		public int getCount() {
			return res.getNumPlan();
		}

		@Override
		public Object getItem(int position) {
			return position;
		}

		@Override
		public long getItemId(int position) {
			return position;
		}

		@Override
		public View getView(int position, View convertView, ViewGroup parent) {
			HolderView holder = null;
			if (convertView == null) {
				holder = new HolderView();
				convertView = mInflater.inflate(R.layout.list_item, null);
				holder.txt = (TextView) convertView
						.findViewById(R.id.list_item_txt);
				convertView.setTag(holder);
			} else {
				holder = (HolderView) convertView.getTag();
			}
			String lineInfo = "";
			// 得到解决方案
			MKTransitRoutePlan routePlan = res.getPlan(position);
			// 公交线路
			MKLine mkLine = routePlan.getLine(0);
			lineInfo += "乘坐:" + mkLine.getTitle();
			MKPoiInfo mkOnPoiInfo = mkLine.getGetOnStop();
			MKPoiInfo mkOffPoiInfo = mkLine.getGetOffStop();
			lineInfo += "ntttt从" + mkOnPoiInfo.name + "上车,在"
					+ mkOffPoiInfo.name + "下车";
			if (routePlan.getNumLines() > 0) {
				// 循环当前方案公交路线
				for (int i = 1; i < routePlan.getNumLines(); i++) {
					// 公交线路
					mkLine = routePlan.getLine(i);
					lineInfo += "n换成:" + mkLine.getTitle();
					mkOnPoiInfo = mkLine.getGetOnStop();
					mkOffPoiInfo = mkLine.getGetOffStop();
					lineInfo += "ntttt从" + mkOnPoiInfo.name + "上车,在"
							+ mkOffPoiInfo.name + "下车";
				}
			}
			holder.txt.setText(lineInfo);
			convertView
					.setOnClickListener(new MyListViewOnClick(position, res));
			return convertView;
		}
	}

	class HolderView {
		public TextView txt;
	}

	class MyListViewOnClick implements OnClickListener {
		private int index;
		private MKTransitRouteResult res;

		public MyListViewOnClick(int index, MKTransitRouteResult res) {
			this.index = index;
			this.res = res;
		}

		@Override
		public void onClick(View arg0) {
			TransitOverlay routeOverlay = new TransitOverlay(busRoute.this,
					mMapView);
			routeOverlay.setData(res.getPlan(index));
			mMapView.getOverlays().clear();
			mMapView.getOverlays().add(routeOverlay);
			mMapView.invalidate();
			mMapView.getController().animateTo(res.getStart().pt);
			busList.setVisibility(View.GONE);
			mMapView.setVisibility(View.VISIBLE);
		}
	}
}

下面是鄙人的代码,感谢发现错误和提出意见:

基于百度地图API的公交换乘导航

DEMO APK下载:

busMapDeno.apk 

10-09-2012 0 条评论

作为Android应用开发者,不得不面对一个尴尬的局面,就是自己辛辛苦苦开发的应用可以被别人很轻易的就反编译出来。

Google似乎也发现了这个问题,从SDK2.3开始我们可以看到在android-sdk-windowstools下面多了一个proguard文件夹

proguard是一个java代码混淆的工具,通过proguard,别人即使反编译你的apk包,也只会看到一些让人很难看懂的代码,从而达到保护代码的作用。

下面具体说一说怎么样让SDK2.3下的proguard.cfg文件起作用,先来看看android-sdk-windowstoolslibproguard.cfg的内容:

-optimizationpasses 5
-dontusemixedcaseclassnames
-dontskipnonpubliclibraryclasses
-dontpreverify
-verbose
-optimizations !code/simplification/arithmetic,!field/*,!class/merging/*

-keep public class * extends android.app.Activity
-keep public class * extends android.app.Application
-keep public class * extends android.app.Service
-keep public class * extends android.content.BroadcastReceiver
-keep public class * extends android.content.ContentProvider
-keep public class * extends android.app.backup.BackupAgentHelper
-keep public class * extends android.preference.Preference
-keep public class com.android.vending.licensing.ILicensingService

-keepclasseswithmembernames class * {
    native <methods>;
}

-keepclasseswithmembernames class * {
    public <init>(android.content.Context, android.util.AttributeSet);
}

-keepclasseswithmembernames class * {
    public <init>(android.content.Context, android.util.AttributeSet, int);
}

-keepclassmembers enum * {
    public static **[] values();
    public static ** valueOf(java.lang.String);
}

-keep class * implements android.os.Parcelable {
  public static final android.os.Parcelable$Creator *;
}

从脚本中可以看到,混淆中保留了继承自Activity、Service、Application、BroadcastReceiver、ContentProvider等基本组件以及com.android.vending.licensing.ILicensingService,

并保留了所有的Native变量名及类名,所有类中部分以设定了固定参数格式的构造函数,枚举等等。(详细信息请参考<proguard_path>/examples中的例子及注释。)

让proguard.cfg起作用的做法很简单,就是在eclipse自动生成的default.properties文件中加上一句“proguard.config=proguard.cfg”就可以了

完整的default.properties文件应该如下:

# This file is automatically generated by Android Tools.
# Do not modify this file -- YOUR CHANGES WILL BE ERASED!
#
# This file must be checked in Version Control Systems.
#
# To customize properties used by the Ant build system use,
# "build.properties", and override values to adapt the script to your
# project structure.

# Project target.
target=android-9
proguard.config=proguard.cfg

大功告成,正常的编译签名后就可以防止代码被反编译了。反编译经过代码混淆的apk得到的代码应该类似于下面的效果,是很难看懂的:


如果您使用的是2.3之前的SDK版本也没关系,把上面的proguard.cfg文件复制一份放到项目中,然后进行相同的操作即可

10-09-2012 0 条评论

发现很多人都在关心apk的反编译,上传一个可视化的工具吧,原理和下面说的差不多,就是封装了一下。点我下载Android反编译工具

另外,作为应用开发者,肯定不希望自己的代码被反编译的,另外一篇文章,讲述如何通过混淆代码放在反编译:《如何防止Android应用被反编译》

这段时间在学Android应用开发,在想既然是用Java开发的应该很好反编译从而得到源代码吧,google了一下,确实很简单,以下是我的实践过程。在此郑重声明,贴出来的目的不是为了去破解人家的软件,完全是一种学习的态度,不过好像通过这种方式也可以去汉化一些外国软件。

一.反编译Apk得到Java源代码

首先要下载两个工具:dex2jar和JD-GUI,前者是将apk中的classes.dex转化成Jar文件,而JD-GUI是一个反编译工具,可以直接查看Jar包的源代码。以下是下载地址:dex2jar:http://laichao.googlecode.com/files/dex2jar-0.0.7-SNAPSHOT.zip JD-GUI:http://laichao.googlecode.com/files/jdgui.zip

具体步骤:

首先将apk文件,将后缀改为zip,解压,得到其中的classes.dex,它就是java文件编译再通过dx工具打包而成的; 解压下载的dex2jar,将classes.dex复制到dex2jar.bat所在目录。在命令行下定位到dex2jar.bat所在目录,运行

dex2jar.bat classes.dex

生成classes.dex.dex2jar.jar

运行JD-GUI,打开上面生成的jar包,即可看到源代码了。

二.反编译apk生成程序的源代码和图片、XML配置、语言资源等文件

如果是只是汉化软件,这将特别有用。首先还是下载工具,这次用到的是apktool,下载地址:

http://code.google.com/p/android-apktool/,apktool-1.0.0.tar.bz2和apktool-install-windows-2.1_r01-1.zip两个包都要下。

具体步骤:

将下载的两个包解压到同一个文件夹下,应该会有三个文件:aapt.exe,apktool.bat,apktool.jar; 在命令行下定位到apktool.bat文件夹,输入以下命令:

apktool d C:***.apk C:***文件夹

命令行解释:apktool d [要反编译的apk文件 ] [输出文件夹],特别注意:你要反编译的文件一定要放在C盘的根目录里;

将反编译完的文件重新打包成apk,很简单,输入apktool b c:***文件夹(你编译出来文件夹)即可。

  • About Totoro

  • 近期文章

  • 2017年七月
    « 10月    
     1
    2345678
    9101112131415
    16171819202122
    23242526272829
    3031  
  • 分类目录

  • 近期评论

  • 标签

  • 功能

  • 友情链接