Slayther Slayther - 1 year ago 81
Android Question

Unity app works on development build, not on normal one

I created a very simple RSS feed reader. For now, it's very basic. One problem I've encountered is that the app doesn't work on Android unless it's development build.

The RSS feed should output the feed as GUI. It does that in Unity Editor and in PC build. But, it works on Android build only if it is set as development build, otherwise it just shows the "RSS Reader" label that's hard coded as GUI.

There are no errors, it doesn't crash or freeze, which is really odd.

I think the problem is in setup time. When I make the setup take more time, it works even without development build. But I'm not sure what the actual problem is that causes this.

Here is the relevant script:

using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using UnityEngine.UI;
using System.Xml;

public class rsstester : MonoBehaviour
public GameObject newsItemObject;

XmlTextReader rssReader;
XmlDocument rssDoc;

string feedUrl = "";

void Start() {
rssReader = new XmlTextReader (feedUrl);
rssDoc = new XmlDocument ();
rssDoc.Load (rssReader);

XmlNode rssNode = null;

for (int i = 0; i < rssDoc.ChildNodes.Count; i++) {
XmlNode childNode = rssDoc.ChildNodes [i];
if (childNode.Name == "rss") {
rssNode = childNode;

XmlNode channelNode = null;

if (rssNode != null) {
for (int i = 0; i < rssNode.ChildNodes.Count; i++) {
XmlNode childNode = rssNode.ChildNodes [i];

if (childNode.Name == "channel") {
channelNode = childNode;

List<XmlNode> newsItems = new List<XmlNode> ();

if (channelNode != null) {
for (int i = 0; i < channelNode.ChildNodes.Count; i++) {
XmlNode childNode = channelNode.ChildNodes [i];

if (childNode.Name == "item") {
newsItems.Add (childNode);

foreach (XmlNode newsItem in newsItems) {
string title = newsItem ["title"].InnerText;
string description = newsItem ["description"].InnerText;
string link = newsItem ["link"].InnerText;

GameObject childObject = Instantiate(newsItemObject) as GameObject;
childObject.transform.SetParent(gameObject.transform, false);

childObject.transform.Find ("Title").gameObject.GetComponent<Text> ().text = title;
childObject.transform.Find ("Title").gameObject.GetComponent<LinkClick> ().link = link;
childObject.transform.Find ("Description").gameObject.GetComponent<Text> ().text = description;

Here is the unity package

Here are the APKs:


Assets will often include AndroidManifest. Are you sure that this is not related with permissions?

It doesn't seem to have anything close to that. No
files at all. Oddly enough, the app works when I only import the C# files from the package.

Here is the unity package with the scripts and here are the C# files themselves: 1 2 3 4

Edit #2:

After some trial and error, I found out which file is needed to make the app work. I have no clue how this can be possible.

Here it is: Reporter.cs

Answer Source

On Android, apps requires permissions. You app uses internet connection to download data so you need to add following permission to your manifest:

<uses-permission android:name="android.permission.INTERNET"/>

Development version works because in manifest there are additional lines added by Unity, which of course are missing in production version:

<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:maxSdkVersion="18" android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

To add manifest in Unity create a file AndroidManifest.xml in {Project root}\Assets\Plugins\Android and then paste this manifest (it yours from production version with additional permission added):

    <?xml version="1.0" encoding="utf-8" standalone="no"?>
    <manifest xmlns:android="" android:installLocation="preferExternal" package="com.slayther_and_malekian.rss_reader" platformBuildVersionCode="23" platformBuildVersionName="6.0-2704002">
        <supports-screens android:anyDensity="true" android:largeScreens="true" android:normalScreens="true" android:smallScreens="true" android:xlargeScreens="true"/>
        <application android:banner="@drawable/app_banner" android:debuggable="false" android:icon="@drawable/app_icon" android:isGame="true" android:label="@string/app_name" android:theme="@style/UnityThemeSelector">
            <activity android:configChanges="locale|fontScale|keyboard|keyboardHidden|mcc|mnc|navigation|orientation|screenLayout|screenSize|smallestScreenSize|touchscreen|uiMode" android:label="@string/app_name" android:launchMode="singleTask" android:name="com.unity3d.player.UnityPlayerActivity" android:screenOrientation="fullSensor">
                    <action android:name="android.intent.action.MAIN"/>
                    <category android:name="android.intent.category.LAUNCHER"/>
                    <category android:name="android.intent.category.LEANBACK_LAUNCHER"/>
                <meta-data android:name="unityplayer.UnityActivity" android:value="true"/>
        <uses-feature android:glEsVersion="0x00020000"/>
        <uses-permission android:name="android.permission.INTERNET"/>
        <uses-feature android:name="android.hardware.touchscreen" android:required="false"/>
        <uses-feature android:name="android.hardware.touchscreen.multitouch" android:required="false"/>
        <uses-feature android:name="android.hardware.touchscreen.multitouch.distinct" android:required="false"/>

Or you can use magic trick which causes Unity to add permission by itself. Put this code anywhere in the project.

WWW magic = new WWW("magic");