예제 #1
0
        /// <summary>
        /// Helper method to download assets asynchronously. After completion, scene is automatically reloaded
        /// if new assets have been downloaded.
        /// </summary>
        /// <param name="config">Current config</param>
        /// <param name="downloadProgress">Download progress interface - used to indicate download progress</param>
        /// <returns></returns>
        public static async Task DownloadAssetsAsync(Config config, IDownloadProgress downloadProgress = null, bool forceCheck = false)
        {
            // Start background thread
            Task.Run(async() =>
            {
                // Mutual exclusion while loading assets
                await AssetsDownloader.semaphoreSlim.WaitAsync();

                // Attach / detatch JNI. Required for any calls into JNI from background threads.
                AndroidJNI.AttachCurrentThread();

                try
                {
                    // Download assets from repos.
                    AssetsDownloader assetsDownloader = new AssetsDownloader();
                    return(await assetsDownloader.DownloadFromReposAsync(config, downloadProgress, forceCheck));
                }
                finally
                {
                    AssetsDownloader.semaphoreSlim.Release();
                    AndroidJNI.DetachCurrentThread();
                }
            }).ContinueWith((downloadedAssets) =>
            {
                if (downloadedAssets.Result)
                {
                    // We downloaded new assets, so re-load the scene
                    Debug.Log("Downloaded new assets. Re-populating panel");
                    SceneManager.LoadSceneAsync(SceneManager.GetActiveScene().name);
                }
            });
        }
예제 #2
0
        /// <summary>
        /// Populate the grid from installed apps
        /// </summary>
        /// <returns></returns>
        private async Task PopulateAsync()
        {
            // Load configuration
            Config config = new Config();

            ConfigPersistence.LoadConfig(config);

            // Process apps in background
            var apps = await Task.Run(() =>
            {
                AndroidJNI.AttachCurrentThread();

                try
                {
                    return(AppProcessor.ProcessApps(config));
                }
                finally
                {
                    AndroidJNI.DetachCurrentThread();
                }
            });

            // Populate the panel content
            await PopulatePanelContentAsync(config, apps);
        }
예제 #3
0
        private void openThread()
        {
#if UNITY_ANDROID
            AndroidJNI.AttachCurrentThread();
#endif
            bool openTry = false;
            _txBuffer.Clear();

#if UNITY_ANDROID
            if (_android != null)
            {
                _android.Call("Open", device.address);
                openTry = true;
            }
#endif

            if (!openTry)
            {
                _threadOnOpenFailed = true;
            }

#if UNITY_ANDROID
            AndroidJNI.DetachCurrentThread();
#endif
            _openThread.Abort();
            return;
        }
예제 #4
0
        private void openThread()
        {
#if UNITY_ANDROID
            AndroidJNI.AttachCurrentThread();
#endif
            _txBuffer.Clear();

            try
            {
                _socket                   = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                _socket.NoDelay           = true;
                _socket.ReceiveBufferSize = 4096;
                _socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.DontLinger, true);

                SocketAsyncEventArgs e = new SocketAsyncEventArgs();
                e.RemoteEndPoint = new IPEndPoint(IPAddress.Parse(device.address), int.Parse(device.args[0]));
                e.UserToken      = _socket;
                e.Completed     += new EventHandler <SocketAsyncEventArgs>(ConnectCompleted);
                _socket.ConnectAsync(e);
            }
            catch (Exception e)
            {
                Debug.Log("OpenThread: " + e);
                _threadOnOpenFailed = true;
            }

#if UNITY_ANDROID
            AndroidJNI.DetachCurrentThread();
#endif

            _openThread.Abort();
            return;
        }
예제 #5
0
        private HelpshiftWorker()
        {
            callerQueue = new Queue <APICallInfo> ();
            // Worker thread to read and execute from queue.
            workerThread = new Thread(() => {
                try {
                    // Attach current thread to android JNI.
                    AndroidJNI.AttachCurrentThread();
                    while (!shouldStop)
                    {
                        // Execute from queue.
                        while (!shouldStop && callerQueue.Count > 0)
                        {
                            APICallInfo apiInfo = callerQueue.Dequeue();
                            try {
                                resolveHsApiCall(apiInfo);
                            } catch (Exception e) {
                                // Catch all exceptions since we want the thread to be running.
                                Debug.Log("Error in : " + apiInfo.apiName + ". Exception : " + e.Message + e.StackTrace);
                            }
                        }

                        if (!shouldStop)
                        {
                            waitHandle.WaitOne();
                            waitHandle.Reset();
                        }
                    }
                } finally {
                    AndroidJNI.DetachCurrentThread();
                }
            });
            workerThread.Name = "HSAsyncThread";
            workerThread.Start();
        }
예제 #6
0
        private void openThread()
        {
#if UNITY_ANDROID
            AndroidJNI.AttachCurrentThread();
#endif
            _bleOpenTry = false;
            _txBuffer.Clear();
            _txWait = false;

#if UNITY_ANDROID
            if (_android != null)
            {
                _android.Call("Connect", device.address);
                _bleOpenTry = true;
            }
#elif (UNITY_STANDALONE_OSX || UNITY_IOS)
            if (_bleInitialized)
            {
                bleConnect(device.address);
                _bleOpenTry = true;
            }
#endif

            if (!_bleOpenTry)
            {
                _bleOpenTry         = false;
                _threadOnOpenFailed = true;
            }

#if UNITY_ANDROID
            AndroidJNI.DetachCurrentThread();
#endif
            _openThread.Abort();
            return;
        }
예제 #7
0
        public List <Breadcrumb> GetBreadcrumbs()
        {
            List <Breadcrumb> breadcrumbs = new List <Breadcrumb>();

            if (!CanRunJNI())
            {
                return(breadcrumbs);
            }
            bool isAttached = bsg_unity_isJNIAttached();

            if (!isAttached)
            {
                AndroidJNI.AttachCurrentThread();
            }


            var javaBreadcrumbs = CallNativeObjectMethod("getBreadcrumbs", "()Ljava/util/List;", new object[] {});
            var iterator        = AndroidJNI.CallObjectMethod(javaBreadcrumbs, CollectionIterator, new jvalue[] {});

            while (AndroidJNI.CallBooleanMethod(iterator, IteratorHasNext, new jvalue[] {}))
            {
                var crumb = AndroidJNI.CallObjectMethod(iterator, IteratorNext, new jvalue[] {});
                breadcrumbs.Add(ConvertToBreadcrumb(crumb));
                AndroidJNI.DeleteLocalRef(crumb);
            }

            AndroidJNI.DeleteLocalRef(javaBreadcrumbs);
            AndroidJNI.DeleteLocalRef(iterator);
            if (!isAttached)
            {
                AndroidJNI.DetachCurrentThread();
            }

            return(breadcrumbs);
        }
예제 #8
0
        public void SetNotifyReleaseStages(string[] stages)
        {
            if (!CanRunJNI())
            {
                return;
            }
            bool isAttached = bsg_unity_isJNIAttached();

            if (!isAttached)
            {
                AndroidJNI.AttachCurrentThread();
            }
            // Manually coercing the string array into a Java String array rather than using
            // AndroidJNIHelper.ConvertToJNIArray() as it sometimes (without warning?) converts
            // a valid array to null
            var jargs = new jvalue[1];

            jargs[0].l = ConvertToStringJNIArray(stages);
            var methodID = AndroidJNI.GetStaticMethodID(BugsnagNativeInterface, "setNotifyReleaseStages", "([Ljava/lang/String;)V");

            AndroidJNI.CallStaticVoidMethod(BugsnagNativeInterface, methodID, jargs);
            if (!isAttached)
            {
                AndroidJNI.DetachCurrentThread();
            }
        }
예제 #9
0
        public string[] GetNotifyReleaseStages()
        {
            if (!CanRunJNI())
            {
                return(new string[] {});
            }
            bool isAttached = bsg_unity_isJNIAttached();

            if (!isAttached)
            {
                AndroidJNI.AttachCurrentThread();
            }
            var stages = CallNativeObjectMethod("getNotifyReleaseStages", "()[Ljava/lang/String;", new object[] {});

            string[] value = null;
            if (stages != null && stages != IntPtr.Zero)
            {
                value = AndroidJNIHelper.ConvertFromJNIArray <string[]>(stages);
            }
            if (!isAttached)
            {
                AndroidJNI.DetachCurrentThread();
            }
            return(value);
        }
예제 #10
0
        private Dictionary <string, object> GetJavaMapData(string methodName)
        {
            if (!CanRunJNI())
            {
                return(new Dictionary <string, object>());
            }
            bool isAttached = bsg_unity_isJNIAttached();

            if (!isAttached)
            {
                AndroidJNI.AttachCurrentThread();
            }

            IntPtr map = CallNativeObjectMethodRef(methodName, "()Ljava/util/Map;", new object[] {});
            Dictionary <string, object> value = DictionaryFromJavaMap(map);

            AndroidJNI.DeleteLocalRef(map);

            if (!isAttached)
            {
                AndroidJNI.DetachCurrentThread();
            }

            return(value);
        }
예제 #11
0
        private IntPtr CallNativeObjectMethodRef(string methodName, string methodSig, object[] args)
        {
            if (!CanRunJNI())
            {
                return(IntPtr.Zero);
            }
            bool isAttached = bsg_unity_isJNIAttached();

            if (!isAttached)
            {
                AndroidJNI.AttachCurrentThread();
            }

            jvalue[] jargs       = AndroidJNIHelper.CreateJNIArgArray(args);
            IntPtr   methodID    = AndroidJNI.GetStaticMethodID(BugsnagNativeInterface, methodName, methodSig);
            IntPtr   nativeValue = AndroidJNI.CallStaticObjectMethod(BugsnagNativeInterface, methodID, jargs);

            AndroidJNIHelper.DeleteJNIArgArray(args, jargs);

            if (!isAttached)
            {
                AndroidJNI.DetachCurrentThread();
            }
            return(nativeValue);
        }
예제 #12
0
    // Make a loop on UI Thread to call AndroidJNI functions
    void LoopCallbackThread()
    {
        int attachThread = AndroidJNI.AttachCurrentThread();

        if (attachThread != 0)
        {
            Debug.Log("AppotaSDK: Attach thread failed");
            return;
        }

        while (true)
        {
            if (!canCallbackThreadRun)
            {
                AndroidJNI.DetachCurrentThread();
                break;
            }

            try {
                activityContext.Call("runOnUiThread", new AndroidJavaRunnable(WorkThread));
            }
            catch (AndroidJavaException e) {
                Debug.Log("AppotaSDK: " + e.ToString());
            }
            catch (Exception e) {
                Debug.Log("AppotaSDK: " + e.ToString());
            }

            Thread.Sleep(300);
        }
    }
예제 #13
0
        public void LeaveBreadcrumb(string name, string type, IDictionary <string, string> metadata)
        {
            if (!CanRunJNI())
            {
                return;
            }
            bool isAttached = bsg_unity_isJNIAttached();

            if (!isAttached)
            {
                AndroidJNI.AttachCurrentThread();
            }
            if (PushLocalFrame())
            {
                using (AndroidJavaObject map = BuildJavaMapDisposable(metadata))
                {
                    CallNativeVoidMethod("leaveBreadcrumb", "(Ljava/lang/String;Ljava/lang/String;Ljava/util/Map;)V",
                                         new object[] { name, type, map });
                }
                PopLocalFrame();
            }
            if (!isAttached)
            {
                AndroidJNI.DetachCurrentThread();
            }
        }
예제 #14
0
    private bool CreateSmallerImageWithResolution(string originalImagePath, string newImagePath, int newResolutionWidth, bool debugOn)
    {
        if (debugOn)
        {
            Debug.Log("------- VREEL: Called CreateSmallerImageWithResolution() with new Image Path: " + newImagePath);
        }
        AndroidJNI.AttachCurrentThread();

        bool success = false;

        float currentWidth = m_javaPluginClass.CallStatic <float>("CalcWidth", originalImagePath);

        if (currentWidth > newResolutionWidth)
        {
            success = m_javaPluginClass.CallStatic <bool>("CreateSmallerImageWithResolution", originalImagePath, newImagePath, newResolutionWidth);
        }
        else
        {
            File.Copy(originalImagePath, newImagePath);
            success = true;
        }

        AndroidJNI.DetachCurrentThread();
        if (debugOn)
        {
            Debug.Log("------- VREEL: Call CreateSmallerImageWithResolution() returned with: " + success);
        }

        return(success);
    }
예제 #15
0
        private string CallNativeStringMethod(string methodName, string methodSig, object[] args)
        {
            if (!CanRunJNI())
            {
                return("");
            }
            bool isAttached = bsg_unity_isJNIAttached();

            if (!isAttached)
            {
                AndroidJNI.AttachCurrentThread();
            }
            var jargs       = AndroidJNIHelper.CreateJNIArgArray(args);
            var methodID    = AndroidJNI.GetStaticMethodID(BugsnagNativeInterface, methodName, methodSig);
            var nativeValue = AndroidJNI.CallStaticObjectMethod(BugsnagNativeInterface, methodID, jargs);

            AndroidJNIHelper.DeleteJNIArgArray(args, jargs);
            string value = null;

            if (nativeValue != null && nativeValue != IntPtr.Zero)
            {
                value = AndroidJNI.GetStringUTFChars(nativeValue);
            }
            if (!isAttached)
            {
                AndroidJNI.DetachCurrentThread();
            }
            return(value);
        }
예제 #16
0
        private void CallNativeVoidMethod(string methodName, string methodSig, object[] args)
        {
            if (!CanRunJNI())
            {
                return;
            }
            bool isAttached = bsg_unity_isJNIAttached();

            if (!isAttached)
            {
                AndroidJNI.AttachCurrentThread();
            }

            object[] convertedArgs = ConvertStringArgsToNative(args);
            jvalue[] jargs         = AndroidJNIHelper.CreateJNIArgArray(convertedArgs);
            IntPtr   methodID      = AndroidJNI.GetStaticMethodID(BugsnagNativeInterface, methodName, methodSig);

            AndroidJNI.CallStaticVoidMethod(BugsnagNativeInterface, methodID, jargs);
            AndroidJNIHelper.DeleteJNIArgArray(convertedArgs, jargs);
            ReleaseConvertedStringArgs(args, convertedArgs);

            if (!isAttached)
            {
                AndroidJNI.DetachCurrentThread();
            }
        }
예제 #17
0
        public async void OnSelected(Transform t)
        {
            var appEntry = t.gameObject.GetComponent("AppEntry") as AppEntry;

            if (null != appEntry)
            {
                if (appEntry.isRenameMode)
                {
                    this.renameHandler.Rename(appEntry);
                }
                else
                {
                    await Task.Run(() =>
                    {
                        AndroidJNI.AttachCurrentThread();

                        try
                        {
                            // Launch app
                            Debug.Log("Launching: " + appEntry.appName + " (package id: " + appEntry.packageId + ")");
                            AppProcessor.LaunchApp(appEntry.packageId);
                        }
                        finally
                        {
                            AndroidJNI.DetachCurrentThread();
                        }
                    });
                }
            }
        }
예제 #18
0
        private void CallNativeVoidMethod(string methodName, string methodSig, object[] args)
        {
            if (!CanRunJNI())
            {
                return;
            }
            bool isAttached = bsg_unity_isJNIAttached();

            if (!isAttached)
            {
                AndroidJNI.AttachCurrentThread();
            }

            var itemsAsJavaObjects = new AndroidJavaObject[args.Length];

            for (int i = 0; i < args.Length; i++)
            {
                var obj = args[i];

                if (obj is string)
                {
                    itemsAsJavaObjects[i] = MakeJavaString(obj as string);
                }
            }

            var jargs    = AndroidJNIHelper.CreateJNIArgArray(itemsAsJavaObjects);
            var methodID = AndroidJNI.GetStaticMethodID(BugsnagNativeInterface, methodName, methodSig);

            AndroidJNI.CallStaticVoidMethod(BugsnagNativeInterface, methodID, jargs);
            AndroidJNIHelper.DeleteJNIArgArray(itemsAsJavaObjects, jargs);
            if (!isAttached)
            {
                AndroidJNI.DetachCurrentThread();
            }
        }
 private static byte[] Compress(byte[] bArray)
 {
     Debug.Log("Beginning compression");
     AndroidJNI.AttachCurrentThread();
     byte[] compressedArray = ByteArrayCompression.ByteArrayCompressionClass.CallStatic <byte[]> ("compress", bArray);
     AndroidJNI.DetachCurrentThread();
     Debug.Log("Finished compressing. Result: " + bArray.Length + " bytes -> " + compressedArray.Length + " bytes");
     return(compressedArray);
 }
예제 #20
0
    private void openThread()
    {
                #if UNITY_ANDROID
        AndroidJNI.AttachCurrentThread();
                #endif

        try
        {
            _tcpclnt                   = new TcpClient();
            _tcpclnt.SendTimeout       = 5000;
            _tcpclnt.ReceiveTimeout    = 10000;
            _tcpclnt.ReceiveBufferSize = 102400;
            _tcpclnt.SendBufferSize    = 10240;
            _tcpclnt.NoDelay           = true;

            var c       = _tcpclnt.BeginConnect(ipAddress, 7766, null, null);
            var success = c.AsyncWaitHandle.WaitOne(TimeSpan.FromSeconds(3));
            if (!success)
            {
                _tcpclnt.Close();
                _threadOnOpenFailed = true;
            }
            _tcpclnt.EndConnect(c);

            _stream = _tcpclnt.GetStream();

            Command command = new Command("authentication_management", "authenticate");
            command.AddParameter(new Parameter("user", user));
            command.AddParameter(new Parameter("password", password));
            command.AddParameter(new Parameter("access_level", "1"));
            string str = GetSendHeader() + command.XmlWithNull;
            SendCommand(command, str);

            _stream.BeginRead(_receiveBytes, 0, _receiveBytes.Length, _messageReceivedCallback, null);

            _connected    = true;
            _threadOnOpen = true;
        }
        catch (Exception e)
        {
            if (_tcpclnt != null)
            {
                _tcpclnt.Close();
            }

            Debug.Log("OpenThread: " + e);
            _threadOnOpenFailed = true;
        }

                #if UNITY_ANDROID
        AndroidJNI.DetachCurrentThread();
                #endif

        _openThread.Abort();
        return;
    }
예제 #21
0
 private void OnSampleBuffer(float[] data)
 {
     AndroidJNI.AttachCurrentThread();
     mediaRecorder.CommitSamples(data, clock.Timestamp);
     AndroidJNI.DetachCurrentThread();
     if (mute)
     {
         Array.Clear(data, 0, data.Length);
     }
 }
        private void ThreadProc()
        {
            AndroidJNI.AttachCurrentThread();

            foreach (var task in m_Queue.GetConsumingEnumerable())
            {
                TryExecuteTask(task);
            }

            AndroidJNI.DetachCurrentThread();
        }
예제 #23
0
        private async Task AddCellToGridAsync(ProcessedApp app, Transform transform, bool isRenameMode = false)
        {
            if (app.Index == -1 && string.IsNullOrEmpty(app.IconPath))
            {
                // If we have neither app index or icon path, skip this
                return;
            }

            // Get app icon in background
            var bytesIcon = await Task.Run(() =>
            {
                AndroidJNI.AttachCurrentThread();

                try
                {
                    return(AppProcessor.GetAppIcon(app.IconPath, app.Index));
                }
                finally
                {
                    AndroidJNI.DetachCurrentThread();
                }
            });

            // Create new instances of our app info prefabCell
            var newObj = (GameObject)Instantiate(this.prefabCell, transform);

            // Set app entry info
            var appEntry = newObj.GetComponent <AppEntry>();

            appEntry.packageId         = app.PackageName;
            appEntry.appName           = app.AppName;
            appEntry.isRenameMode      = isRenameMode;
            appEntry.installedApkIndex = app.Index;
            appEntry.externalIconPath  = app.IconPath;

            // Set the icon image
            if (null != bytesIcon)
            {
                var texture = new Texture2D(2, 2, TextureFormat.RGBA32, false);
                texture.filterMode = FilterMode.Trilinear;
                texture.anisoLevel = 16;
                texture.LoadImage(bytesIcon);
                var rect  = new Rect(0, 0, texture.width, texture.height);
                var image = appEntry.sprite.GetComponent <Image>();
                image.sprite = Sprite.Create(texture, rect, new Vector2(0.5f, 0.5f));

                // Preserve icon's aspect ratio
                var aspectRatioFitter = appEntry.sprite.GetComponent <AspectRatioFitter>();
                aspectRatioFitter.aspectRatio = (float)texture.width / (float)texture.height;
            }

            // Set app name in text
            appEntry.text.text = app.AppName;
        }
예제 #24
0
 public string Call(string commandName, params string[] args)
 {
     try
     {
         AndroidJNI.AttachCurrentThread();
         return(_unityCallable.Call <string>(commandName, args));
     }
     finally
     {
         AndroidJNI.DetachCurrentThread();
     }
 }
예제 #25
0
        public OpenBackAndroid()
        {
            AndroidJNI.AttachCurrentThread();

            using (AndroidJavaClass unityClass = new AndroidJavaClass("com.unity3d.player.UnityPlayer"))
                using (AndroidJavaObject activity = unityClass.GetStatic <AndroidJavaObject>("currentActivity"))
                    using (AndroidJavaObject context = activity.Call <AndroidJavaObject>("getApplicationContext")) {
                        openBack = new AndroidJavaClass("com.openback.OpenBack");
                        openBack.CallStatic("initialize", context);
                    }

            AndroidJNI.DetachCurrentThread();
        }
예제 #26
0
        /// <summary>
        /// Opens the rename dialog
        /// </summary>
        /// <param name="entry"></param>
        public async void Rename(AppEntry appTarget)
        {
            Debug.Assert(null != this.appToRename, "App to rename is null");
            var  filePath    = appTarget.externalIconPath;
            bool cleanupFile = false;

            // If icon path is null, extract icon from apk
            if (null == filePath)
            {
                filePath    = Path.Combine(AssetsDownloader.GetOrCreateDownloadPath(), this.appToRename.packageId + ".jpg");
                cleanupFile = true;

                var bytes = appTarget.sprite.GetComponent <Image>().sprite.texture.EncodeToJPG();
                using (var fileStream = new FileStream(filePath, FileMode.Create, FileAccess.Write, FileShare.None,
                                                       bufferSize: 4096, useAsync: true))
                {
                    await fileStream.WriteAsync(bytes, 0, bytes.Length);
                };
            }

            await Task.Run(() =>
            {
                AndroidJNI.AttachCurrentThread();

                try
                {
                    // Add to json file
                    AddToRenameJsonFile(this.appToRename.packageId, appTarget.appName);

                    // Add icon to zip
                    using (AndroidJavaClass unity = new AndroidJavaClass("com.unity3d.player.UnityPlayer"))
                        using (AndroidJavaObject currentActivity = unity.GetStatic <AndroidJavaObject>("currentActivity"))
                        {
                            var renameIconPackFilePath = Path.Combine(UnityEngine.Application.persistentDataPath, AppProcessor.RenameIconPackFileName);
                            currentActivity.CallStatic("addFileToZip", renameIconPackFilePath, filePath, this.appToRename.packageId + ".jpg");
                        }
                }
                finally
                {
                    AndroidJNI.DetachCurrentThread();
                }
            });

            if (cleanupFile && File.Exists(filePath))
            {
                File.Delete(filePath);
            }

            // Reload the scene
            await SceneManager.LoadSceneAsync(SceneManager.GetActiveScene().name);
        }
예제 #27
0
        private void ThreadProc()
        {
            AndroidJNI.AttachCurrentThread();

            while (true)
            {
                try
                {
                    m_Semaphore.WaitOne();
                }
                catch (Exception)
                {
                    break;
                }

                int handle = -1;

                lock (m_Mutex)
                {
                    if (m_Quit)
                    {
                        break;
                    }

                    if (m_UpdateRequestReadIndex != m_UpdateRequestWriteIndex)
                    {
                        handle = m_UpdateRequests[m_UpdateRequestReadIndex];
                        m_UpdateRequestReadIndex = (m_UpdateRequestReadIndex + 1) % m_UpdateRequests.Length;
                    }
                }

                if (handle >= 0)
                {
                    try
                    {
                        m_UpdateAction[handle].Invoke();
                    }
                    catch (Exception)
                    {
                    }

                    lock (m_Mutex)
                    {
                        m_RequestComplete[handle] = true;
                    }
                }
            }

            AndroidJNI.DetachCurrentThread();
        }
예제 #28
0
    public void LogFormat(LogType logType, UnityEngine.Object context, string format, params object[] args)
    {
        var IsMain = IsMainThread();

        if (!IsMain)
        {
            AndroidJNI.AttachCurrentThread();
        }
        _javaObj.CallStatic(_androidLog[(int)logType], _productName, string.Format(format, args));
        if (!IsMain)
        {
            AndroidJNI.DetachCurrentThread();
        }
    }
예제 #29
0
        public void SetNotifyReleaseStages(string[] stages)
        {
            bool isAttached = bsg_unity_isJNIAttached();

            if (!isAttached)
            {
                AndroidJNI.AttachCurrentThread();
            }
            var newValue = AndroidJNIHelper.ConvertToJNIArray(stages);

            CallNativeVoidMethod("setNotifyReleaseStages", "([Ljava/lang/String;)V", new object[] { newValue });
            if (!isAttached)
            {
                AndroidJNI.DetachCurrentThread();
            }
        }
예제 #30
0
    void SubThread()
    {
        AndroidJNI.AttachCurrentThread();

        // com.unity3d.player.UnityPlayer.currentActivity
        var currentActivity = AndroidJNI.GetStaticObjectField(classUnityPlayer, fidCurrentActivity);

        // currentActivity.getPackageName()
        var classActivity     = AndroidJNI.FindClass("android/app/Activity");
        var midGetPackageName = AndroidJNI.GetMethodID(classActivity, "getPackageName", "()Ljava/lang/String;");
        var packageName       = AndroidJNI.CallStringMethod(currentActivity, midGetPackageName, new jvalue[] {});

        text = "PackageName: " + packageName;

        AndroidJNI.DetachCurrentThread();
    }