Categories
Android

解决donut Gtalk、Market登录不了的问题

拿到一个开发板,研究一下为什么gtak,market都登录不了的问题。折腾了许久,很纠结,试过几个ROM的包都不行。今天再搞不定,明天还计划准备对market进行反编译。

Gtalk界面提示:无法连接到服务器。请稍后重试。
logcat是:
1050 GTalkService W [GTalkConnection.12] doConnect: caught java.lang.IllegalStateException: empty JID resource

market界面出现这样的提示:出现服务器错误,请重试,或者取消并返回上一屏幕。
后台logcat是:

1190 vending D com.android.vending.BaseActivity$BaseAction.run(): ApiException:
1190 vending D com.android.vending.api.FatalCommunicationException: Sent a bad request.
1190 vending D at com.android.vending.api.RequestDispatcher.throwException(RequestDispatcher.java:371)
1190 vending D at com.android.vending.api.RequestDispatcher.performRequestsOverNetwork(RequestDispatcher.java
212)
1190 vending D at com.android.vending.api.RequestDispatcher.performRequests(RequestDispatcher.java:174)
1190 vending D at com.android.vending.api.RequestManager.doRequestsOverNetwork(RequestManager.java:244)
1190 vending D at com.android.vending.api.RequestManager.doRequests(RequestManager.java:230)
1190 vending D at com.android.vending.BaseActivity$BaseAction.run(BaseActivity.java:1476)
1190 vending D at com.android.vending.BaseActivity$BaseAction$BackgroundThread$1.run(BaseActivity.java:1556)
1190 vending D at java.lang.Thread.run(Thread.java:1060)
1190 vending I om.android.vending.BaseActivity$BaseAction.displayErrorUi(): General error in com.android.vend
ng.AssetBrowserActivity$NetworkDataLoadAction
1190 vending I om.android.vending.api.FatalCommunicationException: Sent a bad request.
1190 vending I at com.android.vending.api.RequestDispatcher.throwException(RequestDispatcher.java:371)
1190 vending I at com.android.vending.api.RequestDispatcher.performRequestsOverNetwork(RequestDispatcher.java
212)
1190 vending I at com.android.vending.api.RequestDispatcher.performRequests(RequestDispatcher.java:174)
1190 vending I at com.android.vending.api.RequestManager.doRequestsOverNetwork(RequestManager.java:244)
1190 vending I at com.android.vending.api.RequestManager.doRequests(RequestManager.java:230)
1190 vending I at com.android.vending.BaseActivity$BaseAction.run(BaseActivity.java:1476)
1190 vending I at com.android.vending.BaseActivity$BaseAction$BackgroundThread$1.run(BaseActivity.java:1556)
1190 vending I at java.lang.Thread.run(Thread.java:1060)
1024 GTalkSerice E createAccountFromSettings caughtjava.lang.NumberFormatException: unable to parse 'null' as integer, use default port 5228

首先tcpdump获取数据包,然后用wireshark分析,发现

POST /market/api/ApiRequest HTTP/1.1\r\n
version=2&request=ClIxxxxxxxxxxxxxxxxxxxxxxxxAggBFA (中间有个人信息,用xxx替代)

总是返回 404错误,肯定是参数问题。request的参数,是经过base64加密过的,一直琢磨不出到底是哪个参数错了。

到了下午,痛定思痛,整理一下思路:

1. market与gtalk都登录不了,而gmail可以正常使用,从wireshark分析的数据包来看,DNS解析正常,没有被盾。
2. market与gtalk都登录不了,两者共有的东西是什么?是gtalkservice。
3. 同样的包,在模拟上,gtalk 可以登录使用,market却不行。

好,再仔细分析log:

[GTalkConnection.9] doConnect: caught java.lang.IllegalStateException: empty JID resource

开始也注意到这条log,但上面说的第三点因素,加上 Google这条错误信息,没有搜索记录,别人没遇到这问题,所以就没在意。

GTalkConnection是不是在gtalkservice里面? 用apktoo 反编译 gtalkservice.apk,搜索”empty JID resource” 字符串,还真在这个文件GTalkConnection.smali,代码大概是:

String resource = Settings.getJidResource();

if (TextUtils.isEmpty(resource )) {
    throw new IllegalStateException("empty JID resource");
}

搜索一下getJidResource, 文档写:

public static String getJidResource()

Returns the GTalk JID resource associated with this device.

Returns:
String the JID resource of the device. It uses the device IMEI in the computation of the JID resource. If IMEI is not ready (i.e. telephony module not ready), we’ll return an empty string.

哈哈哈,太明显了,IMEI!!! 在设置里,查看手机的IMEI,显示是未知,90%应该是这个问题了,先做个假的测试一下。

frameworks/base/telephony/java/com/android/internal/telephony/gsm/GSMPhone.java

 897     public String getDeviceId() {
 898         return mImei;
 899     }
 

用模拟器上的值,改为:

 897     public String getDeviceId() {
 898         /*return mImei;*/
 899         return "000000000000000";
 900     }
 

到 frameworks/base目录下,mm -B , 重新生成frameworks.jar, push 到手机,重启,ok,market, gtalk可正常使用 🙂

总结一下,给我一杯凉水,我需要冷静,log很重要,搞php我每次都先看apache error log, 搞C/C++, gdb无敌,一到android,没能潜移默化,可能是最初对Java的抵触,反感。现在发现用Java写程式也是蛮是享受的事。

Categories
Android

Android 2.2 Market 依赖包

从2.1 到 Android 2.2(Froyo),变化是蛮大的,Android 2.1 安装market,需要装一大驼的东东:

/etc/permissions/com.google.android.datamessaging.xml
/etc/permissions/com.google.android.gtalkservice.xml
/system/framework/com.google.android.gtalkservice.jar
/system/app/EnhancedGoogleSearchProvider.apk
/system/app/GoogleCheckin.apk
/system/app/GoogleApps.apk
/system/app/gtalkservice.apk
/system/app/SetupWizard.apk
/system/app/Vending.apk
/system/app/TalkProvider.apk

到了 2.2 只用两个包就搞定:
/system/app/GoogleServicesFramework.apk
/system/app/Vending.apk

第一个,美其名曰:Google服务框架,整合了很多东西,2.1版本的Vending.apk login部分,也整合到了GoogleServicesFramework.apk,系统更新也在这包里。

具体的包,网上搜 Android 2.2的ROM,多的是。中间遇到了一个问题,就是无法建立帐号,在添加帐号,点公司/Goolge 这两项都无响应,开始怀疑是AccountAndSyncSettings.apk 这个包有问题。后面查出打开wifi后,kernel没有上报消息,状态栏没显示wifi的图标。

Categories
Android

ListView和Gallery实现Market首页界面(补充版)

http://www.3gqa.com/?p=1941 可以看到沈青海老师的一段讲解视频。优酷的视频不是很清晰,可以在http://www.3gqa.com/?page_id=1307 页面按照提供的QQ登录网络硬盘下载高清版本。按视频动手写了一下,发现两个问题:
1. 用滑鼠无法滚动到Galllery的图片
2. 整个Galllery处于Selectable,很难看,如下图:
andriod market gallery demo
解决方法:
1. 在ListView ,调用requestFocus方法还不够, 还需要setItemsCanFocus。
2. 不让第0项处于可选中状态。
public boolean areAllItemsEnabled() {
    return false;
}

public boolean isEnabled(int position) {
    return position != 0;
}
ListView功能强大,除了上面所用的方法,还可以用 addHeaderView 的方法把Gallery加进来,实现同样的效果。addHeaderView的使用,请参阅android reference 或Mark Murphy 在《The Busy Coder’s Guide To Advanced Android Development》书中提供的HeaderFooter 示例。
Categories
Android

Android Market的 Loading效果

在Android中,要实现Loading效果,一般情况下都使用ProgressDialog控件。ApiDemos/src/com/example/android/apis/view/ProgressBar3.java 提供两个demo:
Progressbar show Indeterminate
progressbar show Indeterminate No Title
仔细看了Android Market,发现却是不一样的,请看截图:
那到底如何实现呢?首先,我们创建一个布局文件,
res/layout/fullscreen_loading_indicator.xml, 其内容如下:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:gravity="center_vertical|center_horizontal"
    android:orientation="horizontal"
    android:id="@+id/fullscreen_loading_indicator"
    android:visibility="gone"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    >
    <ProgressBar
        android:layout_gravity="center_vertical"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        style="?android:attr/progressBarStyleSmall"
        >
    </ProgressBar>
    <TextView
        android:id="@+id/current_action"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginLeft="5.0dip"
        android:text="@string/loading"
        >
    </TextView>
</LinearLayout>
然后在main.xml 把它include 进来

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    >
    <LinearLayout
        android:orientation="vertical"
        android:id="@+id/main_info"
        android:visibility="gone"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        >
    </LinearLayout>
    <include
        android:visibility="visible"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        layout="@layout/fullscreen_loading_indicator"
        >
    </include>
</FrameLayout>
主程序 Loading.java:
package org.lytsing.android.loading;

import android.app.Activity;
import android.os.Bundle;
import android.widget.LinearLayout;

public class Loading extends Activity {

    private LinearLayout mLoadingLayout;

    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        // TODO: dismiss the loading, use this snippet code.
        //mLoadingLayout = (LinearLayout)findViewById(R.id.fullscreen_loading_indicator);
        //mLoadingLayout.setVisibility(View.GONE);
    }
}
运行的效果为:
代码下载: https://github.com/lytsing/MarketLoading
Pages: Prev 1 2 3