mirror of
https://github.com/facebook/react-native.git
synced 2025-11-01 09:14:26 +00:00
45 lines
50 KiB
HTML
45 lines
50 KiB
HTML
<!doctype html>
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=device-width,initial-scale=1">
|
|
<meta name="generator" content="Docusaurus v2.0.0-alpha.66">
|
|
<link rel="alternate" type="application/rss+xml" href="/blog/rss.xml" title="React Native Blog RSS Feed">
|
|
<link rel="alternate" type="application/atom+xml" href="/blog/atom.xml" title="React Native Blog Atom Feed">
|
|
<link rel="preconnect" href="https://www.google-analytics.com">
|
|
<script>window.ga=window.ga||function(){(ga.q=ga.q||[]).push(arguments)},ga.l=+new Date,ga("create","UA-41298772-2","auto"),ga("send","pageview")</script>
|
|
<script async src="https://www.google-analytics.com/analytics.js"></script>
|
|
<link rel="preconnect" href="https://www.google-analytics.com">
|
|
<link rel="preconnect" href="https://www.googletagmanager.com">
|
|
<script async src="https://www.googletagmanager.com/gtag/js?id=UA-41298772-2"></script>
|
|
<script>function gtag(){dataLayer.push(arguments)}window.dataLayer=window.dataLayer||[],gtag("js",new Date),gtag("config","UA-41298772-2",{})</script>
|
|
<link rel="search" type="application/opensearchdescription+xml" title="React Native" href="/opensearch.xml">
|
|
<script src="https://cdn.jsdelivr.net/npm/focus-visible@5.2.0/dist/focus-visible.min.js" defer="defer"></script>
|
|
<script src="https://snack.expo.io/embed.js" defer="defer"></script><title data-react-helmet="true">Publishing to Google Play Store · React Native</title><meta data-react-helmet="true" property="twitter:image" content="https://reactnative.dev/img/logo-og.png"><meta data-react-helmet="true" name="twitter:image:alt" content="Image for React Native"><meta data-react-helmet="true" name="docsearch:language" content="en"><meta data-react-helmet="true" name="docsearch:version" content="0.63"><meta data-react-helmet="true" name="docsearch:docusaurus_tag" content="docs-default-0.63"><meta data-react-helmet="true" property="og:image" content="https://reactnative.dev/img/logo-og.png"><meta data-react-helmet="true" name="twitter:card" content="summary"><meta data-react-helmet="true" name="twitter:image" content="https://reactnative.dev/img/logo-og.png"><meta data-react-helmet="true" property="og:title" content="Publishing to Google Play Store · React Native"><meta data-react-helmet="true" name="description" content="Android requires that all apps be digitally signed with a certificate before they can be installed. In order to distribute your Android application via Google Play store it needs to be signed with a release key that then needs to be used for all future updates. Since 2017 it is possible for Google Play to manage signing releases automatically thanks to App Signing by Google Play functionality. However, before your application binary is uploaded to Google Play it needs to be signed with an upload key. The Signing Your Applications page on Android Developers documentation describes the topic in detail. This guide covers the process in brief, as well as lists the steps required to package the JavaScript bundle."><meta data-react-helmet="true" property="og:description" content="Android requires that all apps be digitally signed with a certificate before they can be installed. In order to distribute your Android application via Google Play store it needs to be signed with a release key that then needs to be used for all future updates. Since 2017 it is possible for Google Play to manage signing releases automatically thanks to App Signing by Google Play functionality. However, before your application binary is uploaded to Google Play it needs to be signed with an upload key. The Signing Your Applications page on Android Developers documentation describes the topic in detail. This guide covers the process in brief, as well as lists the steps required to package the JavaScript bundle."><meta data-react-helmet="true" property="og:url" content="https://reactnative.dev/docs/signed-apk-android"><link data-react-helmet="true" rel="shortcut icon" href="/img/favicon.ico"><link data-react-helmet="true" rel="preconnect" href="https://BH4D9OD16A-dsn.algolia.net" crossorigin="anonymous"><link data-react-helmet="true" rel="canonical" href="https://reactnative.dev/docs/signed-apk-android"><link rel="stylesheet" href="/styles.fccefeba.css">
|
|
<link rel="stylesheet" href="/main.ca40cabd.css">
|
|
<link rel="preload" href="/styles.07d522c6.js" as="script">
|
|
<link rel="preload" href="/runtime~main.579b1f59.js" as="script">
|
|
<link rel="preload" href="/main.5e05a427.js" as="script">
|
|
<link rel="preload" href="/1.ba9ce8bd.js" as="script">
|
|
<link rel="preload" href="/2.58cb5d3d.js" as="script">
|
|
<link rel="preload" href="/1f391b9e.a824c215.js" as="script">
|
|
<link rel="preload" href="/943.8b024446.js" as="script">
|
|
<link rel="preload" href="/ee5b3385.b4fff665.js" as="script">
|
|
<link rel="preload" href="/17896441.0c201679.js" as="script">
|
|
<link rel="preload" href="/9e424ee7.cc288166.js" as="script">
|
|
</head>
|
|
<body>
|
|
<script>!function(){function t(t){document.documentElement.setAttribute("data-theme",t)}var e=function(){var t=null;try{t=localStorage.getItem("theme")}catch(t){}return t}();t(null!==e?e:"light")}()</script><div id="__docusaurus">
|
|
<nav class="navbar navbar--fixed-top navbar--dark"><div class="navbar__inner"><div class="navbar__items"><div aria-label="Navigation bar toggle" class="navbar__toggle" role="button" tabindex="0"><svg xmlns="http://www.w3.org/2000/svg" width="30" height="30" viewBox="0 0 30 30" role="img" focusable="false"><title>Menu</title><path stroke="currentColor" stroke-linecap="round" stroke-miterlimit="10" stroke-width="2" d="M4 7h22M4 15h22M4 23h22"></path></svg></div><a class="navbar__brand" href="/"><img class="navbar__logo" src="/img/header_logo.svg" alt="React Native"><strong class="navbar__title">React Native</strong></a><div class="navbar__item dropdown dropdown--hoverable dropdown--left"><a class="navbar__item navbar__link" href="/docs/getting-started">0.63</a><ul class="dropdown__menu"><li><a class="dropdown__link" href="/docs/next/signed-apk-android">Next</a></li><li><a aria-current="page" class="dropdown__link dropdown__link--active" href="/docs/signed-apk-android">0.63</a></li><li><a class="dropdown__link" href="/docs/0.62/signed-apk-android">0.62</a></li><li><a class="dropdown__link" href="/docs/0.61/signed-apk-android">0.61</a></li><li><a class="dropdown__link" href="/docs/0.60/signed-apk-android">0.60</a></li><li><a class="dropdown__link" href="/versions">All versions</a></li></ul></div></div><div class="navbar__items navbar__items--right"><a class="navbar__item navbar__link navbar__link--active" href="/docs/getting-started">Docs</a><a class="navbar__item navbar__link" href="/docs/components-and-apis">Components</a><a class="navbar__item navbar__link" href="/docs/accessibilityinfo">API</a><a class="navbar__item navbar__link" href="/help">Community</a><a class="navbar__item navbar__link" href="/blog">Blog</a><a href="https://github.com/facebook/react-native" target="_blank" rel="noopener noreferrer" class="navbar__item navbar__link navbar-github-link" aria-label="GitHub repository"></a><div class="react-toggle react-toggle--disabled displayOnlyInLargeViewport_3lWe"><div class="react-toggle-track"><div class="react-toggle-track-check"><span class="toggle_gnXW">🌜</span></div><div class="react-toggle-track-x"><span class="toggle_gnXW">🌞</span></div></div><div class="react-toggle-thumb"></div><input type="checkbox" disabled="" aria-label="Dark mode toggle" class="react-toggle-screenreader-only"></div><button type="button" class="DocSearch DocSearch-Button" aria-label="Search"><svg width="20" height="20" class="DocSearch-Search-Icon" viewBox="0 0 20 20"><path d="M14.386 14.386l4.0877 4.0877-4.0877-4.0877c-2.9418 2.9419-7.7115 2.9419-10.6533 0-2.9419-2.9418-2.9419-7.7115 0-10.6533 2.9418-2.9419 7.7115-2.9419 10.6533 0 2.9419 2.9418 2.9419 7.7115 0 10.6533z" stroke="currentColor" fill="none" fill-rule="evenodd" stroke-linecap="round" stroke-linejoin="round"></path></svg><span class="DocSearch-Button-Placeholder">Search</span><span class="DocSearch-Button-Key">⌘</span><span class="DocSearch-Button-Key">K</span></button></div></div><div role="presentation" class="navbar-sidebar__backdrop"></div><div class="navbar-sidebar"><div class="navbar-sidebar__brand"><a class="navbar__brand" href="/"><img class="navbar__logo" src="/img/header_logo.svg" alt="React Native"><strong class="navbar__title">React Native</strong></a></div><div class="navbar-sidebar__items"><div class="menu"><ul class="menu__list"><li class="menu__list-item"><a class="menu__link navbar__link--active" href="/docs/getting-started">Docs</a></li><li class="menu__list-item"><a class="menu__link" href="/docs/components-and-apis">Components</a></li><li class="menu__list-item"><a class="menu__link" href="/docs/accessibilityinfo">API</a></li><li class="menu__list-item"><a class="menu__link" href="/help">Community</a></li><li class="menu__list-item"><a class="menu__link" href="/blog">Blog</a></li><li class="menu__list-item"><a role="button" class="menu__link menu__link--sublist">Versions</a><ul class="menu__list"><li class="menu__list-item"><a class="menu__link" href="/docs/next/signed-apk-android">Next</a></li><li class="menu__list-item"><a aria-current="page" class="menu__link menu__link--active" href="/docs/signed-apk-android">0.63</a></li><li class="menu__list-item"><a class="menu__link" href="/docs/0.62/signed-apk-android">0.62</a></li><li class="menu__list-item"><a class="menu__link" href="/docs/0.61/signed-apk-android">0.61</a></li><li class="menu__list-item"><a class="menu__link" href="/docs/0.60/signed-apk-android">0.60</a></li><li class="menu__list-item"><a class="menu__link" href="/versions">All versions</a></li></ul></li><li class="menu__list-item"><a href="https://github.com/facebook/react-native" target="_blank" rel="noopener noreferrer" class="menu__link navbar-github-link" aria-label="GitHub repository"></a></li></ul></div></div></div></nav><div class="main-wrapper"><div class="docPage_2UBv"><div class="docSidebarContainer_1hqR" role="complementary"><div class="sidebar_MSwm"><div class="menu menu--responsive menu_2hiu"><button aria-label="Open Menu" aria-haspopup="true" class="button button--secondary button--sm menu__button" type="button"><svg aria-label="Menu" class="sidebarMenuIcon_37TU" xmlns="http://www.w3.org/2000/svg" height="24" width="24" viewBox="0 0 32 32" role="img" focusable="false"><title>Menu</title><path stroke="currentColor" stroke-linecap="round" stroke-miterlimit="10" stroke-width="2" d="M4 7h22M4 15h22M4 23h22"></path></svg></button><ul class="menu__list"><li class="menu__list-item menu__list-item--collapsed"><a class="menu__link menu__link--sublist" href="#!">The Basics</a><ul class="menu__list"><li class="menu__list-item"><a class="menu__link" tabindex="-1" href="/docs/getting-started">Introduction</a></li><li class="menu__list-item"><a class="menu__link" tabindex="-1" href="/docs/intro-react-native-components">Core Components and Native Components</a></li><li class="menu__list-item"><a class="menu__link" tabindex="-1" href="/docs/intro-react">React Fundamentals</a></li><li class="menu__list-item"><a class="menu__link" tabindex="-1" href="/docs/handling-text-input">Handling Text Input</a></li><li class="menu__list-item"><a class="menu__link" tabindex="-1" href="/docs/using-a-scrollview">Using a ScrollView</a></li><li class="menu__list-item"><a class="menu__link" tabindex="-1" href="/docs/using-a-listview">Using List Views</a></li><li class="menu__list-item"><a class="menu__link" tabindex="-1" href="/docs/troubleshooting">Troubleshooting</a></li><li class="menu__list-item"><a class="menu__link" tabindex="-1" href="/docs/platform-specific-code">Platform Specific Code</a></li><li class="menu__list-item"><a class="menu__link" tabindex="-1" href="/docs/more-resources">More Resources</a></li></ul></li><li class="menu__list-item menu__list-item--collapsed"><a class="menu__link menu__link--sublist" href="#!">Environment setup</a><ul class="menu__list"><li class="menu__list-item"><a class="menu__link" tabindex="-1" href="/docs/environment-setup">Setting up the development environment</a></li><li class="menu__list-item"><a class="menu__link" tabindex="-1" href="/docs/integration-with-existing-apps">Integration with Existing Apps</a></li><li class="menu__list-item"><a class="menu__link" tabindex="-1" href="/docs/building-for-tv">Building For TV Devices</a></li><li class="menu__list-item"><a class="menu__link" tabindex="-1" href="/docs/out-of-tree-platforms">Out-of-Tree Platforms</a></li></ul></li><li class="menu__list-item menu__list-item--collapsed"><a class="menu__link menu__link--sublist" href="#!">Workflow</a><ul class="menu__list"><li class="menu__list-item"><a class="menu__link" tabindex="-1" href="/docs/running-on-device">Running On Device</a></li><li class="menu__list-item"><a class="menu__link" tabindex="-1" href="/docs/fast-refresh">Fast Refresh</a></li><li class="menu__list-item"><a class="menu__link" tabindex="-1" href="/docs/debugging">Debugging</a></li><li class="menu__list-item"><a class="menu__link" tabindex="-1" href="/docs/testing-overview">Testing</a></li><li class="menu__list-item"><a class="menu__link" tabindex="-1" href="/docs/libraries">Using Libraries</a></li><li class="menu__list-item"><a class="menu__link" tabindex="-1" href="/docs/typescript">Using TypeScript</a></li><li class="menu__list-item"><a class="menu__link" tabindex="-1" href="/docs/upgrading">Upgrading to new React Native versions</a></li></ul></li><li class="menu__list-item menu__list-item--collapsed"><a class="menu__link menu__link--sublist" href="#!">Design</a><ul class="menu__list"><li class="menu__list-item"><a class="menu__link" tabindex="-1" href="/docs/style">Style</a></li><li class="menu__list-item"><a class="menu__link" tabindex="-1" href="/docs/height-and-width">Height and Width</a></li><li class="menu__list-item"><a class="menu__link" tabindex="-1" href="/docs/flexbox">Layout with Flexbox</a></li><li class="menu__list-item"><a class="menu__link" tabindex="-1" href="/docs/images">Images</a></li><li class="menu__list-item"><a class="menu__link" tabindex="-1" href="/docs/colors">Color Reference</a></li></ul></li><li class="menu__list-item menu__list-item--collapsed"><a class="menu__link menu__link--sublist" href="#!">Interaction</a><ul class="menu__list"><li class="menu__list-item"><a class="menu__link" tabindex="-1" href="/docs/handling-touches">Handling Touches</a></li><li class="menu__list-item"><a class="menu__link" tabindex="-1" href="/docs/navigation">Navigating Between Screens</a></li><li class="menu__list-item"><a class="menu__link" tabindex="-1" href="/docs/animations">Animations</a></li><li class="menu__list-item"><a class="menu__link" tabindex="-1" href="/docs/gesture-responder-system">Gesture Responder System</a></li></ul></li><li class="menu__list-item menu__list-item--collapsed"><a class="menu__link menu__link--sublist" href="#!">Inclusion</a><ul class="menu__list"><li class="menu__list-item"><a class="menu__link" tabindex="-1" href="/docs/accessibility">Accessibility</a></li></ul></li><li class="menu__list-item menu__list-item--collapsed"><a class="menu__link menu__link--sublist" href="#!">Performance</a><ul class="menu__list"><li class="menu__list-item"><a class="menu__link" tabindex="-1" href="/docs/performance">Performance Overview</a></li><li class="menu__list-item"><a class="menu__link" tabindex="-1" href="/docs/optimizing-flatlist-configuration">Optimizing Flatlist Configuration</a></li><li class="menu__list-item"><a class="menu__link" tabindex="-1" href="/docs/ram-bundles-inline-requires">RAM Bundles and Inline Requires</a></li><li class="menu__list-item"><a class="menu__link" tabindex="-1" href="/docs/profiling">Profiling</a></li></ul></li><li class="menu__list-item menu__list-item--collapsed"><a class="menu__link menu__link--sublist" href="#!">JavaScript Runtime</a><ul class="menu__list"><li class="menu__list-item"><a class="menu__link" tabindex="-1" href="/docs/javascript-environment">JavaScript Environment</a></li><li class="menu__list-item"><a class="menu__link" tabindex="-1" href="/docs/timers">Timers</a></li><li class="menu__list-item"><a class="menu__link" tabindex="-1" href="/docs/hermes">Using Hermes</a></li></ul></li><li class="menu__list-item menu__list-item--collapsed"><a class="menu__link menu__link--sublist" href="#!">Connectivity</a><ul class="menu__list"><li class="menu__list-item"><a class="menu__link" tabindex="-1" href="/docs/network">Networking</a></li><li class="menu__list-item"><a class="menu__link" tabindex="-1" href="/docs/security">Security</a></li></ul></li><li class="menu__list-item menu__list-item--collapsed"><a class="menu__link menu__link--sublist" href="#!">Native Modules</a><ul class="menu__list"><li class="menu__list-item"><a class="menu__link" tabindex="-1" href="/docs/native-modules-intro">Native Modules Intro</a></li><li class="menu__list-item"><a class="menu__link" tabindex="-1" href="/docs/native-modules-android">Android Native Modules</a></li><li class="menu__list-item"><a class="menu__link" tabindex="-1" href="/docs/native-modules-ios">iOS Native Modules</a></li><li class="menu__list-item"><a class="menu__link" tabindex="-1" href="/docs/native-modules-setup">Native Modules NPM Package Setup</a></li></ul></li><li class="menu__list-item menu__list-item--collapsed"><a class="menu__link menu__link--sublist" href="#!">Native Components</a><ul class="menu__list"><li class="menu__list-item"><a class="menu__link" tabindex="-1" href="/docs/native-components-android">Android Native UI Components</a></li><li class="menu__list-item"><a class="menu__link" tabindex="-1" href="/docs/native-components-ios">iOS Native UI Components</a></li><li class="menu__list-item"><a class="menu__link" tabindex="-1" href="/docs/direct-manipulation">Direct Manipulation</a></li></ul></li><li class="menu__list-item"><a class="menu__link menu__link--sublist menu__link--active" href="#!">Guides (Android)</a><ul class="menu__list"><li class="menu__list-item"><a class="menu__link" tabindex="0" href="/docs/headless-js-android">Headless JS</a></li><li class="menu__list-item"><a aria-current="page" class="menu__link menu__link--active active" tabindex="0" href="/docs/signed-apk-android">Publishing to Google Play Store</a></li><li class="menu__list-item"><a class="menu__link" tabindex="0" href="/docs/removing-default-permissions">Removing Default Permissions</a></li></ul></li><li class="menu__list-item menu__list-item--collapsed"><a class="menu__link menu__link--sublist" href="#!">Guides (iOS)</a><ul class="menu__list"><li class="menu__list-item"><a class="menu__link" tabindex="-1" href="/docs/linking-libraries-ios">Linking Libraries</a></li><li class="menu__list-item"><a class="menu__link" tabindex="-1" href="/docs/running-on-simulator-ios">Running On Simulator</a></li><li class="menu__list-item"><a class="menu__link" tabindex="-1" href="/docs/communication-ios">Communication between native and React Native</a></li><li class="menu__list-item"><a class="menu__link" tabindex="-1" href="/docs/app-extensions">App Extensions</a></li></ul></li></ul></div></div></div><main class="docMainContainer_1rYT"><div class="container padding-vert--lg docItemWrapper_1Hme"><div class="row"><div class="col docItemCol_2AGf"><div class="docItemContainer_1tAC"><article><header><h1 class="docTitle_cWlf">Publishing to Google Play Store</h1></header><div class="markdown"><p>Android requires that all apps be digitally signed with a certificate before they can be installed. In order to distribute your Android application via <a href="https://play.google.com/store" target="_blank" rel="noopener noreferrer">Google Play store</a> it needs to be signed with a release key that then needs to be used for all future updates. Since 2017 it is possible for Google Play to manage signing releases automatically thanks to <a href="https://developer.android.com/studio/publish/app-signing#app-signing-google-play" target="_blank" rel="noopener noreferrer">App Signing by Google Play</a> functionality. However, before your application binary is uploaded to Google Play it needs to be signed with an upload key. The <a href="https://developer.android.com/tools/publishing/app-signing.html" target="_blank" rel="noopener noreferrer">Signing Your Applications</a> page on Android Developers documentation describes the topic in detail. This guide covers the process in brief, as well as lists the steps required to package the JavaScript bundle.</p><h3><a aria-hidden="true" tabindex="-1" class="anchor enhancedAnchor_3pqN" id="generating-an-upload-key"></a>Generating an upload key<a aria-hidden="true" tabindex="-1" class="hash-link" href="#generating-an-upload-key" title="Direct link to heading">#</a></h3><p>You can generate a private signing key using <code>keytool</code>. On Windows <code>keytool</code> must be run from <code>C:\Program Files\Java\jdkx.x.x_x\bin</code>.</p><div class="mdxCodeBlock_xYIz"><div class="codeBlockContent_rlEb"><button tabindex="0" type="button" aria-label="Copy code to clipboard" class="copyButton_kOW4">Copy</button><div class="prism-code language-jsx codeBlock_1AP7"><div class="codeBlockLines_1boI" style="color:#FFFFFF;background:#282C34"><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain">$ keytool </span><span class="token operator" style="color:#fc929e">-</span><span class="token plain">genkeypair </span><span class="token operator" style="color:#fc929e">-</span><span class="token plain">v </span><span class="token operator" style="color:#fc929e">-</span><span class="token plain">keystore my</span><span class="token operator" style="color:#fc929e">-</span><span class="token plain">upload</span><span class="token operator" style="color:#fc929e">-</span><span class="token plain">key</span><span class="token punctuation" style="color:#657b83">.</span><span class="token plain">keystore </span><span class="token operator" style="color:#fc929e">-</span><span class="token plain">alias my</span><span class="token operator" style="color:#fc929e">-</span><span class="token plain">key</span><span class="token operator" style="color:#fc929e">-</span><span class="token plain">alias </span><span class="token operator" style="color:#fc929e">-</span><span class="token plain">keyalg </span><span class="token constant" style="color:#5a9bcf">RSA</span><span class="token plain"> </span><span class="token operator" style="color:#fc929e">-</span><span class="token plain">keysize </span><span class="token number" style="color:#5a9bcf">2048</span><span class="token plain"> </span><span class="token operator" style="color:#fc929e">-</span><span class="token plain">validity </span><span class="token number" style="color:#5a9bcf">10000</span></div></div></div></div></div><p>This command prompts you for passwords for the keystore and key and for the Distinguished Name fields for your key. It then generates the keystore as a file called <code>my-upload-key.keystore</code>.</p><p>The keystore contains a single key, valid for 10000 days. The alias is a name that you will use later when signing your app, so remember to take note of the alias.</p><p>On Mac, if you're not sure where your JDK bin folder is, then perform the following command to find it:</p><div class="mdxCodeBlock_xYIz"><div class="codeBlockContent_rlEb"><button tabindex="0" type="button" aria-label="Copy code to clipboard" class="copyButton_kOW4">Copy</button><div class="prism-code language-jsx codeBlock_1AP7"><div class="codeBlockLines_1boI" style="color:#FFFFFF;background:#282C34"><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain">$ </span><span class="token operator" style="color:#fc929e">/</span><span class="token plain">usr</span><span class="token operator" style="color:#fc929e">/</span><span class="token plain">libexec</span><span class="token operator" style="color:#fc929e">/</span><span class="token plain">java_home</span></div></div></div></div></div><p>It will output the directory of the JDK, which will look something like this:</p><div class="mdxCodeBlock_xYIz"><div class="codeBlockContent_rlEb"><button tabindex="0" type="button" aria-label="Copy code to clipboard" class="copyButton_kOW4">Copy</button><div class="prism-code language-jsx codeBlock_1AP7"><div class="codeBlockLines_1boI" style="color:#FFFFFF;background:#282C34"><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token operator" style="color:#fc929e">/</span><span class="token plain">Library</span><span class="token operator" style="color:#fc929e">/</span><span class="token plain">Java</span><span class="token operator" style="color:#fc929e">/</span><span class="token plain">JavaVirtualMachines</span><span class="token operator" style="color:#fc929e">/</span><span class="token plain">jdkX</span><span class="token punctuation" style="color:#657b83">.</span><span class="token constant" style="color:#5a9bcf">X</span><span class="token punctuation" style="color:#657b83">.</span><span class="token constant" style="color:#5a9bcf">X_XXX</span><span class="token punctuation" style="color:#657b83">.</span><span class="token plain">jdk</span><span class="token operator" style="color:#fc929e">/</span><span class="token plain">Contents</span><span class="token operator" style="color:#fc929e">/</span><span class="token plain">Home</span></div></div></div></div></div><p>Navigate to that directory by using the command <code>$ cd /your/jdk/path</code> and use the keytool command with sudo permission as shown below.</p><div class="mdxCodeBlock_xYIz"><div class="codeBlockContent_rlEb"><button tabindex="0" type="button" aria-label="Copy code to clipboard" class="copyButton_kOW4">Copy</button><div class="prism-code language-jsx codeBlock_1AP7"><div class="codeBlockLines_1boI" style="color:#FFFFFF;background:#282C34"><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain">$ sudo keytool </span><span class="token operator" style="color:#fc929e">-</span><span class="token plain">genkey </span><span class="token operator" style="color:#fc929e">-</span><span class="token plain">v </span><span class="token operator" style="color:#fc929e">-</span><span class="token plain">keystore my</span><span class="token operator" style="color:#fc929e">-</span><span class="token plain">upload</span><span class="token operator" style="color:#fc929e">-</span><span class="token plain">key</span><span class="token punctuation" style="color:#657b83">.</span><span class="token plain">keystore </span><span class="token operator" style="color:#fc929e">-</span><span class="token plain">alias my</span><span class="token operator" style="color:#fc929e">-</span><span class="token plain">key</span><span class="token operator" style="color:#fc929e">-</span><span class="token plain">alias </span><span class="token operator" style="color:#fc929e">-</span><span class="token plain">keyalg </span><span class="token constant" style="color:#5a9bcf">RSA</span><span class="token plain"> </span><span class="token operator" style="color:#fc929e">-</span><span class="token plain">keysize </span><span class="token number" style="color:#5a9bcf">2048</span><span class="token plain"> </span><span class="token operator" style="color:#fc929e">-</span><span class="token plain">validity </span><span class="token number" style="color:#5a9bcf">10000</span></div></div></div></div></div><p><em>Note: Remember to keep the keystore file private. In case you've lost upload key or it's been compromised you should <a href="https://support.google.com/googleplay/android-developer/answer/7384423#reset" target="_blank" rel="noopener noreferrer">follow these instructions</a>.</em></p><h3><a aria-hidden="true" tabindex="-1" class="anchor enhancedAnchor_3pqN" id="setting-up-gradle-variables"></a>Setting up Gradle variables<a aria-hidden="true" tabindex="-1" class="hash-link" href="#setting-up-gradle-variables" title="Direct link to heading">#</a></h3><ol><li>Place the <code>my-upload-key.keystore</code> file under the <code>android/app</code> directory in your project folder.</li><li>Edit the file <code>~/.gradle/gradle.properties</code> or <code>android/gradle.properties</code>, and add the following (replace <code>*****</code> with the correct keystore password, alias and key password),</li></ol><div class="mdxCodeBlock_xYIz"><div class="codeBlockContent_rlEb"><button tabindex="0" type="button" aria-label="Copy code to clipboard" class="copyButton_kOW4">Copy</button><div class="prism-code language-jsx codeBlock_1AP7"><div class="codeBlockLines_1boI" style="color:#FFFFFF;background:#282C34"><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token constant" style="color:#5a9bcf">MYAPP_UPLOAD_STORE_FILE</span><span class="token operator" style="color:#fc929e">=</span><span class="token plain">my</span><span class="token operator" style="color:#fc929e">-</span><span class="token plain">upload</span><span class="token operator" style="color:#fc929e">-</span><span class="token plain">key</span><span class="token punctuation" style="color:#657b83">.</span><span class="token plain">keystore</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain"></span><span class="token constant" style="color:#5a9bcf">MYAPP_UPLOAD_KEY_ALIAS</span><span class="token operator" style="color:#fc929e">=</span><span class="token plain">my</span><span class="token operator" style="color:#fc929e">-</span><span class="token plain">key</span><span class="token operator" style="color:#fc929e">-</span><span class="token plain">alias</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain"></span><span class="token constant" style="color:#5a9bcf">MYAPP_UPLOAD_STORE_PASSWORD</span><span class="token operator" style="color:#fc929e">=</span><span class="token operator" style="color:#fc929e">**</span><span class="token operator" style="color:#fc929e">**</span><span class="token operator" style="color:#fc929e">*</span><span class="token plain"></span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain"></span><span class="token constant" style="color:#5a9bcf">MYAPP_UPLOAD_KEY_PASSWORD</span><span class="token operator" style="color:#fc929e">=</span><span class="token operator" style="color:#fc929e">**</span><span class="token operator" style="color:#fc929e">**</span><span class="token operator" style="color:#fc929e">*</span></div></div></div></div></div><p>These are going to be global Gradle variables, which we can later use in our Gradle config to sign our app.</p><p><em>Note about security: If you are not keen on storing your passwords in plaintext, and you are running OSX, you can also <a href="https://pilloxa.gitlab.io/posts/safer-passwords-in-gradle/" target="_blank" rel="noopener noreferrer">store your credentials in the Keychain Access app</a>. Then you can skip the two last rows in <code>~/.gradle/gradle.properties</code>.</em></p><h3><a aria-hidden="true" tabindex="-1" class="anchor enhancedAnchor_3pqN" id="adding-signing-config-to-your-apps-gradle-config"></a>Adding signing config to your app's Gradle config<a aria-hidden="true" tabindex="-1" class="hash-link" href="#adding-signing-config-to-your-apps-gradle-config" title="Direct link to heading">#</a></h3><p>The last configuration step that needs to be done is to setup release builds to be signed using upload key. Edit the file <code>android/app/build.gradle</code> in your project folder, and add the signing config,</p><div class="mdxCodeBlock_xYIz"><div class="codeBlockContent_rlEb"><button tabindex="0" type="button" aria-label="Copy code to clipboard" class="copyButton_kOW4">Copy</button><div class="prism-code language-gradle codeBlock_1AP7"><div class="codeBlockLines_1boI" style="color:#FFFFFF;background:#282C34"><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain">...</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain">android {</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain"> ...</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain"> defaultConfig { ... }</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain"> signingConfigs {</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain"> release {</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain"> if (project.hasProperty('MYAPP_UPLOAD_STORE_FILE')) {</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain"> storeFile file(MYAPP_UPLOAD_STORE_FILE)</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain"> storePassword MYAPP_UPLOAD_STORE_PASSWORD</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain"> keyAlias MYAPP_UPLOAD_KEY_ALIAS</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain"> keyPassword MYAPP_UPLOAD_KEY_PASSWORD</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain"> }</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain"> }</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain"> }</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain"> buildTypes {</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain"> release {</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain"> ...</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain"> signingConfig signingConfigs.release</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain"> }</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain"> }</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain">}</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain">...</span></div></div></div></div></div><h3><a aria-hidden="true" tabindex="-1" class="anchor enhancedAnchor_3pqN" id="generating-the-release-apk"></a>Generating the release APK<a aria-hidden="true" tabindex="-1" class="hash-link" href="#generating-the-release-apk" title="Direct link to heading">#</a></h3><p>Run the following in a terminal:</p><div class="mdxCodeBlock_xYIz"><div class="codeBlockContent_rlEb"><button tabindex="0" type="button" aria-label="Copy code to clipboard" class="copyButton_kOW4">Copy</button><div class="prism-code language-shell codeBlock_1AP7"><div class="codeBlockLines_1boI" style="color:#FFFFFF;background:#282C34"><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain">$ </span><span class="token builtin class-name" style="color:#fac863">cd</span><span class="token plain"> android</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain">$ ./gradlew bundleRelease</span></div></div></div></div></div><p>Gradle's <code>bundleRelease</code> will bundle all the JavaScript needed to run your app into the AAB (<a href="https://developer.android.com/guide/app-bundle" target="_blank" rel="noopener noreferrer">Android App Bundle</a>). If you need to change the way the JavaScript bundle and/or drawable resources are bundled (e.g. if you changed the default file/folder names or the general structure of the project), have a look at <code>android/app/build.gradle</code> to see how you can update it to reflect these changes.</p><blockquote><p>Note: Make sure gradle.properties does not include <em>org.gradle.configureondemand=true</em> as that will make the release build skip bundling JS and assets into the app binary.</p></blockquote><p>The generated AAB can be found under <code>android/app/build/outputs/bundle/release/app.aab</code>, and is ready to be uploaded to Google Play.</p><p><em>Note: In order for Google Play to accept AAB format the App Signing by Google Play needs to be configured for your application on the Google Play Console. If you are updating an existing app that doesn't use App Signing by Google Play, please check our <a href="#migrating-old-android-react-native-apps-to-use-app-signing-by-google-play">migration section</a> to learn how to perform that configuration change.</em></p><h3><a aria-hidden="true" tabindex="-1" class="anchor enhancedAnchor_3pqN" id="testing-the-release-build-of-your-app"></a>Testing the release build of your app<a aria-hidden="true" tabindex="-1" class="hash-link" href="#testing-the-release-build-of-your-app" title="Direct link to heading">#</a></h3><p>Before uploading the release build to the Play Store, make sure you test it thoroughly. First uninstall any previous version of the app you already have installed. Install it on the device using the following command in the project root:</p><div class="mdxCodeBlock_xYIz"><div class="codeBlockContent_rlEb"><button tabindex="0" type="button" aria-label="Copy code to clipboard" class="copyButton_kOW4">Copy</button><div class="prism-code language-shell codeBlock_1AP7"><div class="codeBlockLines_1boI" style="color:#FFFFFF;background:#282C34"><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain">$ npx react-native run-android --variant</span><span class="token operator" style="color:#fc929e">=</span><span class="token plain">release</span></div></div></div></div></div><p>Note that <code>--variant=release</code> is only available if you've set up signing as described above.</p><p>You can terminate any running bundler instances, since all your framework and JavaScript code is bundled in the APK's assets.</p><h3><a aria-hidden="true" tabindex="-1" class="anchor enhancedAnchor_3pqN" id="publishing-to-other-stores"></a>Publishing to other stores<a aria-hidden="true" tabindex="-1" class="hash-link" href="#publishing-to-other-stores" title="Direct link to heading">#</a></h3><p>By default, the generated APK has the native code for both x86 and ARMv7a CPU architectures. This makes it easier to share APKs that run on almost all Android devices. However, this has the downside that there will be some unused native code on any device, leading to unnecessarily bigger APKs.</p><p>You can create an APK for each CPU by changing the following line in android/app/build.gradle:</p><div class="mdxCodeBlock_xYIz"><div class="codeBlockContent_rlEb"><button tabindex="0" type="button" aria-label="Copy code to clipboard" class="copyButton_kOW4">Copy</button><div class="prism-code language-diff codeBlock_1AP7"><div class="codeBlockLines_1boI" style="color:#FFFFFF;background:#282C34"><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token deleted-sign deleted" style="color:#cb4b16">- ndk {</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token deleted-sign deleted" style="color:#cb4b16">- abiFilters "armeabi-v7a", "x86"</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token deleted-sign deleted" style="color:#cb4b16">- }</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token deleted-sign deleted" style="color:#cb4b16">- def enableSeparateBuildPerCPUArchitecture = false</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token deleted-sign deleted" style="color:#cb4b16"></span><span class="token inserted-sign inserted" style="color:#859900">+ def enableSeparateBuildPerCPUArchitecture = true</span></div></div></div></div></div><p>Upload both these files to markets which support device targeting, such as <a href="https://developer.android.com/google/play/publishing/multiple-apks.html" target="_blank" rel="noopener noreferrer">Google Play</a> and <a href="https://developer.amazon.com/docs/app-submission/device-filtering-and-compatibility.html" target="_blank" rel="noopener noreferrer">Amazon AppStore</a>, and the users will automatically get the appropriate APK. If you want to upload to other markets, such as <a href="https://www.apkfiles.com/" target="_blank" rel="noopener noreferrer">APKFiles</a>, which do not support multiple APKs for a single app, change the following line as well to create the default universal APK with binaries for both CPUs.</p><div class="mdxCodeBlock_xYIz"><div class="codeBlockContent_rlEb"><button tabindex="0" type="button" aria-label="Copy code to clipboard" class="copyButton_kOW4">Copy</button><div class="prism-code language-diff codeBlock_1AP7"><div class="codeBlockLines_1boI" style="color:#FFFFFF;background:#282C34"><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token deleted-sign deleted" style="color:#cb4b16">- universalApk false // If true, also generate a universal APK</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token deleted-sign deleted" style="color:#cb4b16"></span><span class="token inserted-sign inserted" style="color:#859900">+ universalApk true // If true, also generate a universal APK</span></div></div></div></div></div><h3><a aria-hidden="true" tabindex="-1" class="anchor enhancedAnchor_3pqN" id="enabling-proguard-to-reduce-the-size-of-the-apk-optional"></a>Enabling Proguard to reduce the size of the APK (optional)<a aria-hidden="true" tabindex="-1" class="hash-link" href="#enabling-proguard-to-reduce-the-size-of-the-apk-optional" title="Direct link to heading">#</a></h3><p>Proguard is a tool that can slightly reduce the size of the APK. It does this by stripping parts of the React Native Java bytecode (and its dependencies) that your app is not using.</p><p><em><strong>IMPORTANT</strong>: Make sure to thoroughly test your app if you've enabled Proguard. Proguard often requires configuration specific to each native library you're using. See <code>app/proguard-rules.pro</code>.</em></p><p>To enable Proguard, edit <code>android/app/build.gradle</code>:</p><div class="mdxCodeBlock_xYIz"><div class="codeBlockContent_rlEb"><button tabindex="0" type="button" aria-label="Copy code to clipboard" class="copyButton_kOW4">Copy</button><div class="prism-code language-gradle codeBlock_1AP7"><div class="codeBlockLines_1boI" style="color:#FFFFFF;background:#282C34"><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain">/**</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain"> * Run Proguard to shrink the Java bytecode in release builds.</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain"> */</span></div><div class="token-line" style="color:#FFFFFF;background:#282C34"><span class="token plain">def enableProguardInReleaseBuilds = true</span></div></div></div></div></div><h3><a aria-hidden="true" tabindex="-1" class="anchor enhancedAnchor_3pqN" id="migrating-old-android-react-native-apps-to-use-app-signing-by-google-play"></a>Migrating old Android React Native apps to use App Signing by Google Play<a aria-hidden="true" tabindex="-1" class="hash-link" href="#migrating-old-android-react-native-apps-to-use-app-signing-by-google-play" title="Direct link to heading">#</a></h3><p>If you are migrating from previous version of React Native chances are your app does not use App Signing by Google Play feature. We recommend you enable that in order to take advantage from things like automatic app splitting. In order to migrate from the old way of signing you need to start by <a href="#generating-an-upload-key">generating new upload key</a> and then replacing release signing config in <code>android/app/build.gradle</code> to use the upload key instead of the release one (see section about <a href="#adding-signing-config-to-your-app-s-gradle-config">adding signing config to gradle</a>). Once that's done you should follow the <a href="https://support.google.com/googleplay/android-developer/answer/7384423" target="_blank" rel="noopener noreferrer">instructions from Google Play Help website</a> in order to send your original release key to Google Play.</p></div></article><div class="docMetadata margin-vert--xl"><div class="row"><div class="col"><a href="https://github.com/facebook/react-native-website/blob/master/website/versioned_docs/version-0.63/signed-apk-android.md" target="_blank" rel="noreferrer noopener"><svg fill="currentColor" height="1.2em" width="1.2em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 40 40" style="margin-right:0.3em;vertical-align:sub"><g><path d="m34.5 11.7l-3 3.1-6.3-6.3 3.1-3q0.5-0.5 1.2-0.5t1.1 0.5l3.9 3.9q0.5 0.4 0.5 1.1t-0.5 1.2z m-29.5 17.1l18.4-18.5 6.3 6.3-18.4 18.4h-6.3v-6.2z"></path></g></svg>Edit this page</a></div><div class="col text--right"><em><small class="docMetadata-updated">Last updated on <time datetime="2020-10-29T04:19:29.000Z" class="docLastUpdatedAt_1gIo">10/29/2020</time></small></em></div></div></div><div class="margin-vert--lg"><nav class="pagination-nav" aria-label="Blog list page navigation"><div class="pagination-nav__item"><a class="pagination-nav__link" href="/docs/headless-js-android"><div class="pagination-nav__sublabel">Previous</div><div class="pagination-nav__label">« Headless JS</div></a></div><div class="pagination-nav__item pagination-nav__item--next"><a class="pagination-nav__link" href="/docs/removing-default-permissions"><div class="pagination-nav__sublabel">Next</div><div class="pagination-nav__label">Removing Default Permissions »</div></a></div></nav></div></div></div><div class="col col--3"><div class="tableOfContents_3iuQ"><ul class="table-of-contents table-of-contents__left-border"><li><a href="#generating-an-upload-key" class="table-of-contents__link">Generating an upload key</a></li><li><a href="#setting-up-gradle-variables" class="table-of-contents__link">Setting up Gradle variables</a></li><li><a href="#adding-signing-config-to-your-apps-gradle-config" class="table-of-contents__link">Adding signing config to your app's Gradle config</a></li><li><a href="#generating-the-release-apk" class="table-of-contents__link">Generating the release APK</a></li><li><a href="#testing-the-release-build-of-your-app" class="table-of-contents__link">Testing the release build of your app</a></li><li><a href="#publishing-to-other-stores" class="table-of-contents__link">Publishing to other stores</a></li><li><a href="#enabling-proguard-to-reduce-the-size-of-the-apk-optional" class="table-of-contents__link">Enabling Proguard to reduce the size of the APK (optional)</a></li><li><a href="#migrating-old-android-react-native-apps-to-use-app-signing-by-google-play" class="table-of-contents__link">Migrating old Android React Native apps to use App Signing by Google Play</a></li></ul></div></div></div></div></main></div></div><footer class="footer footer--dark"><div class="container"><div class="row footer__links"><div class="col footer__col"><h4 class="footer__title">Docs</h4><ul class="footer__items"><li class="footer__item"><a class="footer__link-item" href="/docs/getting-started">Getting Started</a></li><li class="footer__item"><a class="footer__link-item" href="/docs/tutorial">Tutorial</a></li><li class="footer__item"><a class="footer__link-item" href="/docs/components-and-apis">Components and APIs</a></li><li class="footer__item"><a class="footer__link-item" href="/docs/more-resources">More Resources</a></li></ul></div><div class="col footer__col"><h4 class="footer__title">Community</h4><ul class="footer__items"><li class="footer__item"><a class="footer__link-item" href="/help">The React Native Community</a></li><li class="footer__item"><a class="footer__link-item" href="/showcase">Who's using React Native?</a></li><li class="footer__item"><a href="https://stackoverflow.com/questions/tagged/react-native" target="_blank" rel="noopener noreferrer" class="footer__link-item">Ask Questions on Stack Overflow</a></li><li class="footer__item"><a href="https://github.com/facebook/react-native/blob/master/CONTRIBUTING.md" target="_blank" rel="noopener noreferrer" class="footer__link-item">Contributor Guide</a></li><li class="footer__item"><a href="https://dev.to/t/reactnative" target="_blank" rel="noopener noreferrer" class="footer__link-item">DEV Community</a></li></ul></div><div class="col footer__col"><h4 class="footer__title">Find us</h4><ul class="footer__items"><li class="footer__item"><a class="footer__link-item" href="/blog">Blog</a></li><li class="footer__item"><a href="https://twitter.com/reactnative" target="_blank" rel="noopener noreferrer" class="footer__link-item">Twitter</a></li><li class="footer__item"><a href="https://github.com/facebook/react-native" target="_blank" rel="noopener noreferrer" class="footer__link-item">GitHub</a></li></ul></div><div class="col footer__col"><h4 class="footer__title">More</h4><ul class="footer__items"><li class="footer__item"><a href="https://reactjs.org/" target="_blank" rel="noopener noreferrer" class="footer__link-item">React</a></li><li class="footer__item"><a href="https://opensource.facebook.com/legal/privacy" target="_blank" rel="noopener noreferrer" class="footer__link-item">Privacy Policy</a></li><li class="footer__item"><a href="https://opensource.facebook.com/legal/terms" target="_blank" rel="noopener noreferrer" class="footer__link-item">Terms of Service</a></li></ul></div></div><div class="text--center"><div class="margin-bottom--sm"><a href="https://opensource.facebook.com" target="_blank" rel="noopener noreferrer" class="footerLogoLink_19Ac"><img class="footer__logo" alt="Facebook Open Source Logo" src="/img/oss_logo.png"></a></div><div>Copyright © 2021 Facebook, Inc.</div></div></div></footer></div>
|
|
<script src="/styles.07d522c6.js"></script>
|
|
<script src="/runtime~main.579b1f59.js"></script>
|
|
<script src="/main.5e05a427.js"></script>
|
|
<script src="/1.ba9ce8bd.js"></script>
|
|
<script src="/2.58cb5d3d.js"></script>
|
|
<script src="/1f391b9e.a824c215.js"></script>
|
|
<script src="/943.8b024446.js"></script>
|
|
<script src="/ee5b3385.b4fff665.js"></script>
|
|
<script src="/17896441.0c201679.js"></script>
|
|
<script src="/9e424ee7.cc288166.js"></script>
|
|
</body>
|
|
</html> |