Android 使用极光商店代码,它如何获得;图书馆;(已安装应用的历史记录),以及如何获取安装时间? 背景

Android 使用极光商店代码,它如何获得;图书馆;(已安装应用的历史记录),以及如何获取安装时间? 背景,android,google-play,google-signin,aurora-store,Android,Google Play,Google Signin,Aurora Store,在过去,我发现了一个名为“”的特殊应用程序,它以某种方式获取您购买的应用程序列表。没有看到任何API,我(遗憾的是仍然找不到清晰的答案和POC来演示) 问题 随着时间的推移,我注意到实际上有一个名为“”的开源应用程序(repository),它可以获得与Play Store一样多的信息。它的截图: 问题是,我在试图找出如何正确使用其代码时遇到了一些问题,而奇怪的是这些应用程序从不同的来源获取信息 我试过的 因此,看到它允许您登录到谷歌,然后获取“库”信息(已安装应用的历史记录),我决定试一试(

在过去,我发现了一个名为“”的特殊应用程序,它以某种方式获取您购买的应用程序列表。没有看到任何API,我(遗憾的是仍然找不到清晰的答案和POC来演示)

问题 随着时间的推移,我注意到实际上有一个名为“”的开源应用程序(repository),它可以获得与Play Store一样多的信息。它的截图:

问题是,我在试图找出如何正确使用其代码时遇到了一些问题,而奇怪的是这些应用程序从不同的来源获取信息

我试过的 因此,看到它允许您登录到谷歌,然后获取“库”信息(已安装应用的历史记录),我决定试一试(Github上的完整示例,):

MainActivity.kt

class MainActivity : AppCompatActivity() {
    private lateinit var webView: WebView
    private val cookieManager = CookieManager.getInstance()

    @SuppressLint("SetJavaScriptEnabled")
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        val defaultSharedPreferences = PreferenceManager.getDefaultSharedPreferences(this)
        val cachedEmail = defaultSharedPreferences.getString("email", null)
        val cachedAasToken = defaultSharedPreferences.getString("aasToken", null)
        if (cachedEmail != null && cachedAasToken != null) {
            onGotAasToken(applicationContext, cachedEmail, cachedAasToken)
        } else {
            webView = findViewById(R.id.webView)
            cookieManager.removeAllCookies(null)
            cookieManager.acceptThirdPartyCookies(webView)
            cookieManager.setAcceptThirdPartyCookies(webView, true)
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                webView.settings.safeBrowsingEnabled = false
            }
            webView.webViewClient = object : WebViewClient() {
                override fun onPageFinished(view: WebView, url: String) {
                    val cookies = CookieManager.getInstance().getCookie(url)
                    val cookieMap: MutableMap<String, String> = AC2DMUtil.parseCookieString(cookies)
                    val oauthToken: String? = cookieMap[AUTH_TOKEN]
                    oauthToken?.let {
                        webView.evaluateJavascript("(function() { return document.getElementById('profileIdentifier').innerHTML; })();") {
                            val email = it.replace("\"".toRegex(), "")
                            Log.d("AppLog", "got email?${email.isNotBlank()} got oauthToken?${oauthToken.isNotBlank()}")
                            buildAuthData(applicationContext, email, oauthToken)
                        }
                    } ?: Log.d("AppLog", "could not get oauthToken")
                }
            }
            webView.settings.apply {
                allowContentAccess = true
                databaseEnabled = true
                domStorageEnabled = true
                javaScriptEnabled = true
                cacheMode = WebSettings.LOAD_DEFAULT
            }
            webView.loadUrl(EMBEDDED_SETUP_URL)
        }
    }

    companion object {
        const val EMBEDDED_SETUP_URL =
                "https://accounts.google.com/EmbeddedSetup/identifier?flowName=EmbeddedSetupAndroid"
        const val AUTH_TOKEN = "oauth_token"

        private fun buildAuthData(context: Context, email: String, oauthToken: String?) {
            thread {
                try {
                    val aC2DMResponse: Map<String, String> =
                            AC2DMTask().getAC2DMResponse(email, oauthToken)
                    val aasToken = aC2DMResponse["Token"]!!
                    PreferenceManager.getDefaultSharedPreferences(context)
                            .edit().putString("email", email).putString("aasToken", aasToken).apply()
                    onGotAasToken(context, email, aasToken)
                } catch (e: Exception) {
                    e.printStackTrace()
                }
            }
        }

        private fun onGotAasToken(context: Context, email: String, aasToken: String) {
            thread {
                val properties = NativeDeviceInfoProvider(context).getNativeDeviceProperties()
                val authData = AuthHelper.build(email, aasToken, properties)
                val purchaseHelper = PurchaseHelper(authData).using(HttpClient.getPreferredClient())
                var offset = 0
                Log.d("AppLog", "list of purchase history:")
                while (true) {
                    val purchaseHistory = purchaseHelper.getPurchaseHistory(offset)
                    if (purchaseHistory.isNullOrEmpty())
                        break
                    val size = purchaseHistory.size
                    offset += size
                    purchaseHistory.forEach {
                        Log.d("AppLog", "${it.packageName} ${it.displayName}")
                    }
                }
                Log.d("AppLog", "done")
            }
        }
    }
}
在上一次尝试获取下一块应用程序时,它崩溃了,出现了以下异常:

FATAL EXCEPTION: Thread-4
    Process: com.lb.getplaystoreinstalledappshistory, PID: 6149
    Server(code=400, reason=Bad Request)
        at com.aurora.gplayapi.helpers.AppDetailsHelper.getAppByPackageName(AppDetailsHelper.kt:115)
        at com.aurora.gplayapi.helpers.PurchaseHelper.getPurchaseHistory(PurchaseHelper.kt:63)
        at com.lb.getplaystoreinstalledappshistory.MainActivity$Companion$onGotAasToken$1.invoke(MainActivity.kt:96)
        at com.lb.getplaystoreinstalledappshistory.MainActivity$Companion$onGotAasToken$1.invoke(MainActivity.kt:68)
        at kotlin.concurrent.ThreadsKt$thread$thread$1.run(Thread.kt:30)
问题
  • 我试图获取应用程序列表的方式有什么问题?我怎样才能按安装时间进行订购
  • 是否有任何方法可以获得安装时间(或任何线索)?不知怎的,“”应用程序获得了时间。虽然它只适用于购买的应用程序,但仍然
  • “”应用甚至可以更好地登录,因为它不需要用户名和密码。相反,它提供了一个对话框来选择帐户。假设我没有弄错,是否可以使用相同的登录对话框获取相同的信息

  • 不确定这些信息是否有用,但不妨提一下

    我意外地从2015年开始反编译他们存档的APK,当时他们没有最小化代码,至少在那个时候,他们使用的是JSoup HTML解析器爬行器。可能他们仍然是,这可能是谷歌不允许的,而且极易维护


    这是解析本身(这也很重要),但是如何获得登录阶段,以及此处的“html”参数?你试过POC吗?我在哪里可以得到你反编译的非最小化APK?我想看一看,也许可以从中学到一些东西。@user14678216也许可以从这里:
    FATAL EXCEPTION: Thread-4
        Process: com.lb.getplaystoreinstalledappshistory, PID: 6149
        Server(code=400, reason=Bad Request)
            at com.aurora.gplayapi.helpers.AppDetailsHelper.getAppByPackageName(AppDetailsHelper.kt:115)
            at com.aurora.gplayapi.helpers.PurchaseHelper.getPurchaseHistory(PurchaseHelper.kt:63)
            at com.lb.getplaystoreinstalledappshistory.MainActivity$Companion$onGotAasToken$1.invoke(MainActivity.kt:96)
            at com.lb.getplaystoreinstalledappshistory.MainActivity$Companion$onGotAasToken$1.invoke(MainActivity.kt:68)
            at kotlin.concurrent.ThreadsKt$thread$thread$1.run(Thread.kt:30)