文章目录

#1. 运行中旋转屏幕导致应用退出

解决办法:为activity标签中的configChanges添加screenSize属性,如下:

android:configChanges="orientation|**screenSize**|keyboardHidden"

原因:通常情况下,PhoneGap在设备旋转屏幕后不能正确获得屏幕大小导致出错。网上还有其他办法,比如调低sdk版本,但是个人发现在PhoneGap 3.3.0不适用(很多标签和代码已经与2.x不同了)。

#2. versionCode和versionName

由于不是程序出身,可能开始对这两个东西的概念不是太明确,所以也没管他。

老程序猿们估计都不会认为这个也算问题。

但是我在实际发布的时候发现了自己的问题,因为在更新版本的时候,不知道应该修改哪个。

最终依靠度娘和谷歌解决了这个疑问:versionCode是给开发团队和App商店用的,用以标记有版本改动,与build概念很像;versionName是给用户看的,没有实际的用处,只是给用户一个更简单明确的途径了解应用现在是那个版本。由于versionCode可能迅速的叠加得很大,导致用户无法正确识别版本,因此后者的作用也很大。

所以在发布公开版本时,两个都需要修改。

#3. 发布与数字签名

问题:在Google Play中提交应用,提示数字签名不为发布版,以及应用没有经过Zipalign对齐。

同样的问题没有出现在豌豆荚和亚马逊,应该是因为这二位不关心这两个问题。

解决办法:

在Eclipse中,使用ADT Export Wizard进行签名比较容易。右键单击应用程序工程,如图选择

选择证书的存放路径,填写相关资料,完成,即可生成被签名的apk文件。如下图所示:

如上图所示,可以在这里选择Create new keystore来创建一个证书。输入密码,点击下一步,填写相关信息,如下图所示。

ADT导出项目自动Zipalign对齐,因此问题直接解决。

#4. 升级推送

参考以下代码即可,但是必须在xml中开启相关权限,包括网络、挂载、安装、存储。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
import java.io.BufferedReader;
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import org.apache.cordova.DroidGap;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import org.json.JSONArray;
import org.json.JSONObject;
import com.example.syzx.MainActivity;
import com.example.syzx.R;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.os.Message;
import android.os.StrictMode;
import android.annotation.SuppressLint;
import android.app.AlertDialog;
import android.app.Dialog;
import android.app.ProgressDialog;
import android.content.ComponentName;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.util.Log;
@SuppressLint({ "HandlerLeak", "NewApi" })
public class MainActivity extends DroidGap {
String jsonurl = "http://192.168.2.100/app/version.js";
String newVerName = ""; // 新版本名称
String downurl = ""; //下载 地址
int newVerCode = -1; // 新版本号
String UPDATE_SERVERAPK = "yhupdate.apk";
ProgressDialog pd = null;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder().detectDiskReads().detectDiskWrites().detectNetwork().penaltyLog().build());
super.setIntegerProperty("splashscreen", R.drawable.splash);
if(checkNetWorkStatus()){
updateVersion();
super.loadUrl("file:///android_asset/www/index.html", 3000);
//super.loadUrl("file:///android_asset/www/test/index.html", 3000);
}
}
/**
* 检测版本
*/
public void updateVersion() {
if (getServerVer()) {
int verCode = this.getVerCode(this);
if (newVerCode > verCode) {
doNewVersionUpdate();// 更新版本
}
}
}
/**
* 获得版本号
*/
public int getVerCode(Context context) {
int verCode = -1;
try {
String packName = context.getPackageName();
verCode = context.getPackageManager().getPackageInfo(packName, 0).versionCode;
} catch (NameNotFoundException e) {
// TODO Auto-generated catch block
Log.e("版本号获取异常", e.getMessage());
}
return verCode;
}
/**
* 获得版本名称
*/
public String getVerName(Context context){
String verName = "";
try {
String packName = context.getPackageName();
verName = context.getPackageManager().getPackageInfo(packName, 0).versionName;
} catch (NameNotFoundException e) {
Log.e("版本名称获取异常", e.getMessage());
}
return verName;
}
/**
* 检测版本
* @return
* @throws Exception
*/
public String getVerName(){
//获取包名
PackageManager packageManager = getPackageManager();
PackageInfo packInfo = null;
try {
packInfo = packageManager.getPackageInfo(getPackageName(), 0);
} catch (NameNotFoundException e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
}
return packInfo.versionName;
}
/**
* 从服务器端获得版本号与版本名称
*/
public boolean getServerVer() {
try {
URL url = new URL(jsonurl);
HttpURLConnection httpConnection = (HttpURLConnection) url.openConnection();
httpConnection.setDoInput(true);
httpConnection.setDoOutput(true);
httpConnection.setRequestMethod("GET");
httpConnection.connect();
InputStreamReader reader = new InputStreamReader(httpConnection.getInputStream());
BufferedReader bReader = new BufferedReader(reader);
String json = bReader.readLine();
JSONArray array = new JSONArray(json);
JSONObject jsonObj = array.getJSONObject(0);
newVerCode = Integer.parseInt(jsonObj.getString("verCode"));
newVerName = jsonObj.getString("verName");
downurl = jsonObj.getString("downurl");
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
return true;// 如果这里改为false 则不更新会退出程序
}
return true;
}
/**
* 更新版本
*/
public void doNewVersionUpdate() {
int verCode = this.getVerCode(this);
String verName = this.getVerName(this);
StringBuffer sb = new StringBuffer();
sb.append("当前版本:");
sb.append(verName);
sb.append(" V");
sb.append(verCode);
sb.append(",发现版本:");
sb.append(newVerName);
sb.append(" V");
sb.append(newVerCode);
sb.append(",是否更新?");
Dialog dialog = new AlertDialog.Builder(this)
.setTitle("软件更新")
.setMessage(sb.toString())
.setPositiveButton("更新", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
// TODO Auto-generated method stub
pd = new ProgressDialog(MainActivity.this);
pd.setTitle("正在下载");
pd.setMessage("请稍后。。。");
pd.setProgressStyle(ProgressDialog.STYLE_SPINNER);
downFile(downurl);
}
})
.setNegativeButton("暂不更新",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog,
int which) {
// TODO Auto-generated method stub
// finish();
}
}).create();
// 显示更新框
dialog.show();
}
/**
* 下载apk
*/
public void downFile(final String url) {
pd.show();
new Thread() {
public void run() {
HttpClient client = new DefaultHttpClient();
HttpGet get = new HttpGet(url);
HttpResponse response;
try {
response = client.execute(get);
HttpEntity entity = response.getEntity();
// long length = entity.getContentLength();
InputStream is = entity.getContent();
FileOutputStream fileOutputStream = null;
if (is != null) {
File file = new File(
Environment.getExternalStorageDirectory(),
UPDATE_SERVERAPK);
fileOutputStream = new FileOutputStream(file);
byte[] b = new byte[1024];
int charb = -1;
int count = 0;
while ((charb = is.read(b)) != -1) {
fileOutputStream.write(b, 0, charb);
count += charb;
}
}
fileOutputStream.flush();
if (fileOutputStream != null) {
fileOutputStream.close();
}
down();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}.start();
}
Handler handler = new Handler() {
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
pd.cancel();
update();
}
};
/**
* 下载完成,通过handler将下载对话框取消
*/
public void down() {
new Thread() {
public void run() {
Message message = handler.obtainMessage();
handler.sendMessage(message);
}
}.start();
}
/**
* 安装应用
*/
public void update() {
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(Uri.fromFile(new File(Environment
.getExternalStorageDirectory(), UPDATE_SERVERAPK)),
"application/vnd.android.package-archive");
startActivity(intent);
}
/**
* check network Status
*
* @return boolean
*/
public boolean checkNetWorkStatus() {
boolean result;
ConnectivityManager cm = (ConnectivityManager) this
.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo netinfo = cm.getActiveNetworkInfo();
if (netinfo != null && netinfo.isConnected()) { // 当前网络可用
result = true;
} else { // 不可用
new AlertDialog.Builder(MainActivity.this)
.setMessage("检查到没有可用的网络连接,请打开网络连接")
.setPositiveButton("确定",
new DialogInterface.OnClickListener() {
public void onClick(
DialogInterface dialoginterface, int i) {
ComponentName cn = new ComponentName(
"com.android.settings",
"com.android.settings.Settings");
Intent intent = new Intent();
intent.setComponent(cn);
intent.setAction("android.intent.action.VIEW");
startActivity(intent);
finish();
}
}).show();
result = false;
}
return result;
}
}

♦ 本文固定连接:http://gsgundam.com/2014-01-18-phonegap-develop-part-two-android-tip/

♦ 转载请注明:GSGundam 2014年01月18日发布于 GSGUNDAM砍柴工