I've bought a used HTC Magic with CyanogenMod 5 on it. It has Google Market. The market version is 1.713 - which is nowhere near the latest IIRC. In-app billing, for one thing, is not supported.
Isn't Google Market supposed to upgrade itself when a new version comes out? Why doesn't mine do so? Probably some kind of CyanogenMod interference. Any good way around that, please?
EDIT: debugged the situation a little bit. I happen to know that market updating happens out of the main Market process - the Market (com.android.vending) downloads the update, then fires a broadcast intent UPDATE_MARKET to a receiver in another app (com.android.vending.updater), which in turn installs the package. Here's what I got in the LogCat:
02-01 02:34:16.155: W/ActivityManager(121): Permission Denial: broadcasting Intent { act=com.android.vending.UPDATE_MARKET dat=content://downloads/download/31 } from com.android.vending (pid=1762, uid=10006) requires com.android.vending.permission.UPDATE_MARKET due to receiver com.android.vending.updater/com.android.vending.updater.UpdateMarketReceiver
So it looks as if the Market app lacks a permission to invoke the updater. The manifest file of Vending.apk, however, does have a
line. How is it possible for an app to have a
, but receive a permission denial message?
EDIT2: the permission com.android.vending.permission.UPDATE_MARKET is marked as "signature" in the MarketUpdater manifest. Meaning only apps signed by the same certificate as MarketUpdater are granted that permission. That could be the reason Market is not granted the permission - could be signed by a different certificate.
EDIT3: that's exactly the case. The public key is different. The one on Vending.apk seems to match that on various versions of Vending.apk that are floating around the 'Net.
Answer
So the problem was: Market and Market Updater were not signed by the same key, no idea why. As a result, the Market wasn't able to send an intent to a receiver in the Market Updater that was protected by a signature
-level permission. Here's what I've done.
I took MarketUpdater.apk from the device. I took it apart with apktool
:
apktool d -s MarketUpdater.apk mu
I then opened the AndroidManifest.xml. I changed the package
attribute under
to
package="com.android.vending.updateralt"
That was to avoid a name clash with the vanilla Market Updater app. Changed the
element's header to this:
See - no permission
attribute. No longer requiring that the intent sender is signed by the same certificate. Spelling out the Java package name in android:name
was necessary, since the APK package name no longer matched the Java package name of the class.
I then packaged the APK back:
apktool b mu MarketUpdaterAlt.apk
I signed the APK, using the jarsigner
tool, with an arbitrary key that I had from another project:
"C:\Program Files\Java\jdk1.7.0_02\bin\jarsigner.exe" -verbose -digestalg SHA1 -sigalg MD5withRSA -keystore c:\Path\MyKeys.ks MarketUpdaterAlt.apk MyKey
Uploaded the APK to /system/app, registered with pm
:
adb push MarketUpdaterAlt.apk /system/app
adb shell pm install -r /system/app/MarketUpdaterAlt.apk
And forced a Market self-update. Removed the preferences file:
adb shell rm /data/data/com.android.vending/shared_prefs/*
Then restarted the Market, waited for five minutes, and closed the Market. The update went through like a charm. Now I have Market 2.3.6, in-app billing and all.
Good thing the permission-based coupling between the Market and Market Updater was not two-way...
EDIT: the alternative updater APK is available for all at http://www.jishop.com/temp/MarketUpdaterAlt.apk
No comments:
Post a Comment