I made a mini mobile game on Unity3d. It has many scenes (each level in the game is a scene). the levels start from scene number 1 but there is a scene number 0 which contains an empty that has a script attached to it "Level0".
public class Level0 : MonoBehaviour
{
public int levelIndex;
public IEnumerator delayCoroutine()
{
yield return new WaitForSeconds(1f);
SceneManager.LoadSceneAsync(levelIndex);
}
void Awake()
{
levelIndex = SaveLoadManager.loadCurrentLevelIndex();
StartCoroutine(delayCoroutine());
}
}
the role of this script is to call a static function from "SaveLoadManager" which returns the next level index (scene index in the build settings).
public static int loadCurrentLevelIndex()
{
if (File.Exists(Application.persistentDataPath + "/data.txt"))
{
BinaryFormatter bf = new BinaryFormatter();
FileStream stream = new FileStream(Application.persistentDataPath + "/data.txt", FileMode.Open);
PlayerDataSerializable data = bf.Deserialize(stream) as PlayerDataSerializable;
stream.Close();
return data.realCurrentLevel;
}
else
{
return 1;
}
}
so the method gets the level index from the data file but if the file is not found it just returns "1".
Now the problem is that when I build the game to my OPPO A73 with Android 10 and enter the app settings and choose"clear data" and reopen the game, then it crashes at level0. however when I do the same thing with Nokia 3 (Android 9) or Xiaomi Redmi Note 10 (Android 11) the game works fine and loads the first level as expected.
I monitored the errors via Logcat in Android Studio but I didn't get any error from Unity.
Is the problem with my OPPO device? because I got this error in Logcat:
E/DispScene: [/data/oppo/multimedia/oppo_display_perf_list.xml]:open
config fail
Or with Android 10?
Related
I have tried to use XRSettings.LoadDeviceByName() but it never work. I have already check if the parameter device name is same as the current device name but nothing changes. Also, I have added the None in the sdk list
The XRSettings.loadedDeviceName is cardboard when initiating.
IEnumerator testThis() {
if (string.Compare(XRSettings.loadedDeviceName, "", true) != 0) {
XRSettings.LoadDeviceByName("none");
some_text.text = XRSettings.loadedDeviceName;
yield return new WaitForSeconds(1);
XRSettings.enabled = true;
some_text.text = "Device name " + XRSettings.loadedDeviceName;
}
}
IEnumerator temp() {
some_text.text = "Device name " + XRSettings.loadedDeviceName;
yield return new WaitForSeconds(10);
StartCoroutine(testThis());
}
No matter how I detect, the device name is still cardboard.
https://docs.unity3d.com/ScriptReference/XR.XRSettings.LoadDeviceByName.html
What I have done:
Make None as one of the Virtual Reality SDKs
Use XR-Plugin Management
2.1 Disable Virtual Reality Supported
2.2 Convert camera to XR-Rig
2.3 Use the code about turning VR off in XR-Plugin Management
2.4 Remarks: all the procedure in step 2 is work in iOS build but fail in android build.
2.5 https://docs.unity3d.com/Packages/com.unity.xr.management#4.0/manual/index.html
Tried XRSettings.LoadDeviceByName("none"); XRSettings.LoadDeviceByName(""); XRSettings.LoadDeviceByName("None");
Make sure that ''none'' is first in your VR SDK's, Then Cardboard.
I see a problem with your compare, there is no value
if (string.Compare(XRSettings.loadedDeviceName, "", true) != 0) {
If I understand correctly what you want to do, this code down here will receive a device name and will trigger the LoadDevice couroutine with this name.
public void VerifyDeviceName(string newDeviceName)
{
if (newDeviceName == "none")
{
Debug.Log("Will load none device");
StartCoroutine(LoadDevice(newDeviceName));
}
if (newDeviceName == "cardboard")
{
Debug.Log("Will load cardboard device");
StartCoroutine(LoadDevice(newDeviceName));
}
else
{
Debug.Log("Can't find device with name " + newDeviceName);
}
}
IEnumerator LoadDevice(string newDeviceName)
{
XRSettings.LoadDeviceByName(newDeviceName);
yield return new WaitForSeconds(10);
XRSettings.enabled = true;
Debug.Log("Loaded " + newDeviceName);
}
Note; This will obviously not work in editor you wil get a message saying you cannot trigger on/off vr in editor mode.
I just got through this by brute forcing it. The secret is not to Load device by name. If your trying to load "none" you should just initialize and deinitialize your XR loader.
Disable "Initialize XR on Startup" in Project Settings -> XR Plugin Management
In the code use these two methods
IEnumerator StartXR(){
yield return XRGeneralSettings.Instance.Manager.InitializeLoader();
if(XRGeneralSettings.Instance.Manager.activeLoader == null){
Debug.Log("initialization FAILED");
}
else{
XRGeneralSettings.Instance.Manager.activeLoader.Start();
}
}
void StopXR(){
XRGeneralSettings.Instance.Manager.activeLoader.Stop();
XRGeneralSettings.Instance.Manager.activeLoader.Deinitialize();
}
(Sorry I am terrable at code snippits! I'm new to answering)
Then call these as you need them. It should turn on and turn off XR in your project
We have 3rd party program to Download, delete and upload *.db files from Android to Windows. Everything work prefectly but with Windows 10 1703, the Upload stopped working (I mean From Windows 10 to the Android Device). My error is in french but the translation must be : "Attempted read or write protected memory. This often [...]". The strange part is that the Download and Delete still work. Oh, and everything works with Windows 10 1607.
The error pop at the line : "targetStream.Write(buffer, (int)optimalTransferSizeBytes, pcbWritten); "
I was looking to upload the file in many folder on my Android Devide, but nothing work. Also, I tryed few type of device, LG phone, S7 phone, CT4 Device.
I'm looking into Phone permission and Windows 10 Permissions, trying to run with admin rights or compatibility modes. But I just cannot figure why it stopped working.
I'm really lost and some answer or guideline might be very usefull. Thanks a lot!
There is the Upload code (from Windows to Android) using PortableDeviceApiLib.dll :
public void TransferContentToDevice(string fileName, string parentObjectId)
{
IPortableDeviceContent content;
this._device.Content(out content);
parentObjectId = parentObjectId + "";
IPortableDeviceValues values =
GetRequiredPropertiesForContentType(fileName, parentObjectId);
PortableDeviceApiLib.IStream tempStream;
uint optimalTransferSizeBytes = 0;
content.CreateObjectWithPropertiesAndData(
values,
out tempStream,
ref optimalTransferSizeBytes,
null);
System.Runtime.InteropServices.ComTypes.IStream targetStream =
(System.Runtime.InteropServices.ComTypes.IStream)tempStream;
try
{
using (var sourceStream =
new FileStream(fileName, FileMode.Open, FileAccess.Read))
{
var buffer = new byte[optimalTransferSizeBytes];
int bytesRead;
do
{
bytesRead = sourceStream.Read(buffer, 0, (int)optimalTransferSizeBytes);
IntPtr pcbWritten = IntPtr.Zero;
if (bytesRead < (int)optimalTransferSizeBytes)
{
targetStream.Write(buffer, bytesRead, pcbWritten);
}
else
{
targetStream.Write(buffer, (int)optimalTransferSizeBytes, pcbWritten);
}
} while (bytesRead > 0);
}
targetStream.Commit(0);
}
finally
{
Marshal.ReleaseComObject(tempStream);
}
}
I am trying to build an augmented reality app and in that app i want some prefabs to load dynamically. So that with some 3d model prefabs on unity store i created myasset.unity3d . I am using WWW.LoadFromCacheOrDownload to download that unity3d file and using it.
When i am debugging in my laptop the file is downloading and i am using it as i want but when i add build in and try it on android phone download is not happening.
The code i am using to download is
IEnumerator DownloadAndCache() {
while (!Caching.ready)
yield return null;
string bundleURL = "http://s3-ap-southeast-1.amazonaws.com/cf-export/sofa.unity3d";
www = WWW.LoadFromCacheOrDownload (bundleURL, 1);
yield return www;
Debug.Log (www.assetBundle);
AssetBundle bundle = www.assetBundle;
}
So please help me .
i also tried other way of doing it but still i did not succeed
IEnumerator Start () {
WWW www = WWW.LoadFromCacheOrDownload (BundleURL, 1);
yield return www;
AssetBundle bundle = www.assetBundle;
AssetBundleRequest request = bundle.LoadAssetAsync (AssetName, typeof(GameObject));
yield return request;
GameObject obj = request.asset as GameObject;
Instantiate (obj);
bundle.Unload(false);
www.Dispose();
}
The above two methods are working in when testing in unity IDE but if i build using android and install it in android device its not working. I gave internet access to app while building
I printed the error using a text in mobile and please check the screen shot attached below
the first error text is www (variable for downloading) and second is www.error ( actual error). i did not get what that error meant. So please help me
the issue is asset bundle version is not sync with app version. So while making asset bundle i added small code which made my code working. To make Asset bundle my code is
using UnityEditor;
public class CreateAssetBundles
{
[MenuItem ("Assets/Build AssetBundles")]
static void BuildAllAssetBundles ()
{
BuildPipeline.BuildAssetBundles ("Assets/AssetBundles", BuildAssetBundleOptions.None, BuildTarget.Android);
}
}
To use AssetBuundle for Mobile platform:
While creating AssetBundle it must be platform specific. For Android use following Script to create AssetBundle. put it inside "Editor"
using UnityEngine;
using System.Collections;
using UnityEditor;
public class ExportAssetBundles : Editor {
[MenuItem("Assets/Build AssetBundle")]
static void ExportResource()
{
string path = "Assets/AssetBundle/myAssetBundle.unity3d";
Object[] selection = Selection.GetFiltered(typeof(Object), SelectionMode.DeepAssets);
BuildPipeline.BuildAssetBundle(Selection.activeObject, selection, path,
BuildAssetBundleOptions.CollectDependencies
| BuildAssetBundleOptions.CompleteAssets,BuildTarget.Android);
}
}
Then Create folder "AssetBundle" inside Asset
When you create Assetbundle the AssetBundle.unity3d file will store inside this folder
Now you need to use Created Assetbundle at runtime. For this,
Write a script AssetBundleAugmenter
public class AssetBundleAugmenter : MonoBehaviour {
public string AssetName;
public int Version;
private GameObject mBundleInstance = null;
private bool mAttached = false;
void Start() {
StartCoroutine(DownloadAndCache());
}
// Update is called once per frame
IEnumerator DownloadAndCache() {
while(!Caching.ready)
yield return null;
//you can use remote URL like: www.arprabhu.com/assetBundle OR Local URL
// example URL of file on PC filesystem (Windows)
// string bundleURL = "file:///D:/Unity/AssetBundles/MyAssetBundle.unity3d";
// example URL of file on Android device SD-card
string bundleURL = System.IO.File.ReadAllText("/mnt/sdcard/filepath.txt");
Debug.Log ("Asset Loaded");
using (WWW www = WWW .LoadFromCacheOrDownload(bundleURL, Version)) {
yield return www;
if (www .error != null)
throw new UnityException("WWW Download had an error: " + www .error);
AssetBundle bundle = www .assetBundle;
if (AssetName == "")
Instantiate(bundle.mainAsset);
else
Instantiate(bundle.LoadAsset(AssetName));
// Unload the AssetBundles compressed contents to conserve memory
bundle.Unload(false);
}
}}
Attach this Script to Empty GameObject in your Scene
Congrats!, you are ready to go.
Try checking your androidManifest.xml for the permission to connect to external servers.
Then, if everything seems alright and still doesn't work, my advice is to download the Device Console plugin for the Unity Editor, which is a really nice way to access the internal Android Debugger.
https://www.assetstore.unity3d.com/en/#!/content/44935
Or if you're truly brave: use logcat within the terminal...
I was looking to determine(or count) the number of cores in the embedded processor of android device.
I tried using /proc/cpuinfo, but it is not returning the number of cores of device !
I don't found the code anywhere on the Internet. Does anyone here know how can I determine this, then please answer. Thanks in advance
UPDATE:
The answers on this question How can you detect a dual-core cpu on an Android device from code? doesn't run well in some devices. I tested them is dual core & quad core processors, they returned 2 & 4 respectively, fine !
But, On Octa Core processor like in Samsung Note 3 it returned 4. (Perhaps in note 3 there are 2 sets of quad core processors running individually )
I was looking to solve this problem.
UPDATE
The app CPU-Z is returning the correct core count in my device Samsung note 3
Here it seems that there exists a possible solution...
You may use a combination of above answer with this one. This way it will perform faster on devices running API 17+ as this method is much faster than filtering out files.
private int getNumberOfCores() {
if(Build.VERSION.SDK_INT >= 17) {
return Runtime.getRuntime().availableProcessors()
}
else {
// Use saurabh64's answer
return getNumCoresOldPhones();
}
}
/**
* Gets the number of cores available in this device, across all processors.
* Requires: Ability to peruse the filesystem at "/sys/devices/system/cpu"
* #return The number of cores, or 1 if failed to get result
*/
private int getNumCoresOldPhones() {
//Private Class to display only CPU devices in the directory listing
class CpuFilter implements FileFilter {
#Override
public boolean accept(File pathname) {
//Check if filename is "cpu", followed by a single digit number
if(Pattern.matches("cpu[0-9]+", pathname.getName())) {
return true;
}
return false;
}
}
try {
//Get directory containing CPU info
File dir = new File("/sys/devices/system/cpu/");
//Filter to only list the devices we care about
File[] files = dir.listFiles(new CpuFilter());
//Return the number of cores (virtual CPU devices)
return files.length;
} catch(Exception e) {
//Default to return 1 core
return 1;
}
}
public int availableProcessors ()
Added in API level 1 Returns the number of processor cores available
to the VM, at least 1. Traditionally this returned the number
currently online, but many mobile devices are able to take unused
cores offline to save power, so releases newer than Android 4.2 (Jelly
Bean) return the maximum number of cores that could be made available
if there were no power or heat constraints.
Also there is information about number of cores inside a file located in
/sys/devices/system/cpu/present It reports the number of available CPUs in the following format:
0 -> single CPU/core
0-1 -> two CPUs/cores
0-3 -> four CPUs/cores
0-7 -> eight CPUs/cores
etc.
Also please check what is inside /sys/devices/system/cpu/possible on a note 3
Both files have r--r--r-- or 444 file permissions set on them, so you should be able to read them without a rooted device in code.
EDIT: Posting code to help you out
private void printNumberOfCores() {
printFile("/sys/devices/system/cpu/present");
printFile("/sys/devices/system/cpu/possible");
}
private void printFile(String path) {
InputStream inputStream = null;
try {
inputStream = new FileInputStream(path);
if (inputStream != null) {
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
String line;
do {
line = bufferedReader.readLine();
Log.d(path, line);
} while (line != null);
}
} catch (Exception e) {
} finally {
if (inputStream != null) {
try {
inputStream.close();
} catch (IOException e) {
}
}
}
}
With the result
D//sys/devices/system/cpu/present﹕ 0-3
D//sys/devices/system/cpu/possible﹕ 0-3
The test was run on OnePlus One running BlissPop ROM with Android v5.1.1 and it prints as it should. Please try on your Samsung
Firstly, it seems like this is not possible, here is some information on this:
We will use the Samsung Exynos 5 Octa CPU as an example for this thread, but generally any ARM processor will work the same.
The Samsung Exynos 5 Octa CPU has 8 CPU cores. but in reality it has two processes with 4 cores each. This is called big.LITTLE. You have 1 fast processor and 1 power efficient processor.
Within the Exynos 5 CPU it has two different CPUs in built, a Cortex a15 and a Cortex a7...
Within big.LITTLE both CPUs cannot run at the same time, only one CPU can be active at any given time...
But there is also something called "big.LITTLE mp" in which both CPU's can be active at the same time, but here is the catch (again!) Only FOUR cores can be active to the software at any given time. Here is an image to explain this a bit better:
Now as you can see, a single CPU core is used from the more powerful processor here and then the other four cores are active from the more energy efficient a7 CPU cluster.
You can read more about the big.LITTLE architecture here :
http://www.arm.com/products/processors/technologies/biglittleprocessing.php
You can read more about the big.LITTLE mp architecture here:
http://www.arm.com/products/processors/technologies/biglittleprocessing.php
What you want to find out now, is if it is possible to know if the CPU architecture is Big.LITTLE or BIG.LITTLE mp. Then see if you can directly find out the CPU count from each individual CPU, but I cannot find any relevant code. There is a lot of documentation on ARMs website, but I am not too sure if it is possible to get this information. Either way though, only 4 CPU cores can be used therefor the code you have is technically correct as that is the number of useable cores.
I hope this helped, if you have any questions or want anything clearing up then let me know. There is a lot of information out there
Try this:
Runtime.getRuntime().availableProcessors();
This returns the number of CPU's available for THIS specific virtual machine, as I experienced. That may not be what you want, still, for a few purposes this is very handy. You can test this really easily: Kill all apps, run the above code. Open 10 very intensive apps, and then run the test again. Sure, this will only work on a multi cpu device, I guess.
You can try this method to get number of core.
private int getNumOfCores()
{
try
{
int i = new File("/sys/devices/system/cpu/").listFiles(new FileFilter()
{
public boolean accept(File params)
{
return Pattern.matches("cpu[0-9]", params.getName());
}
}).length;
return i;
}
catch (Exception e)
{
e.printstacktrace();
}
return 1;
}
Use this to get no. of cores.Do read this link very carefully and also see what the author is trying to tell between virtual device and a real device.
The code is referred from THIS SITE
/**
* Gets the number of cores available in this device, across all processors.
* Requires: Ability to peruse the filesystem at "/sys/devices/system/cpu"
* #return The number of cores, or 1 if failed to get result
*/
private int getNumCores() {
//Private Class to display only CPU devices in the directory listing
class CpuFilter implements FileFilter {
#Override
public boolean accept(File pathname) {
//Check if filename is "cpu", followed by a single digit number
if(Pattern.matches("cpu[0-9]+", pathname.getName())) {
return true;
}
return false;
}
}
try {
//Get directory containing CPU info
File dir = new File("/sys/devices/system/cpu/");
//Filter to only list the devices we care about
File[] files = dir.listFiles(new CpuFilter());
Log.d(TAG, "CPU Count: "+files.length);
//Return the number of cores (virtual CPU devices)
return files.length;
} catch(Exception e) {
//Print exception
Log.d(TAG, "CPU Count: Failed.");
e.printStackTrace();
//Default to return 1 core
return 1;
}
}
Here you go (Java):
try {
int ch, processorCount = 0;
Process process = Runtime.getRuntime().exec("cat /proc/cpuinfo");
StringBuilder sb = new StringBuilder();
while ((ch = process.getInputStream().read()) != -1)
sb.append((char) ch);
Pattern p = Pattern.compile("processor");
Matcher m = p.matcher(sb.toString());
while (m.find())
processorCount++;
System.out.println(processorCount);
} catch (IOException e) {
e.printStackTrace();
}
good thing is to use JNI, if possible in project
std::thread::hardware_concurrency()
Nice and simple solution in kotlin:
fun getCPUCoreNum(): Int {
val pattern = Pattern.compile("cpu[0-9]+")
return Math.max(
File("/sys/devices/system/cpu/")
.walk()
.maxDepth(1)
.count { pattern.matcher(it.name).matches() },
Runtime.getRuntime().availableProcessors()
)
}
I have an app developed and want a link to open a gallery of images. The images are locally bundled and included in my assets/www/img directory.
I would like this to seamlessly resemble the native image gallery.
Is this possible?
I have tried to use the following but cant get a response.
document.addEventListener("deviceready", onDeviceReady, false);
// PhoneGap is ready
//
function onDeviceReady() {
window.requestFileSystem(LocalFileSystem.PERSISTENT, 0, onFileSystemSuccess, fail);
}
function onFileSystemSuccess(fileSystem) {
fileSystem.root.getDirectory("img/china", {create: false, exclusive: false}, getDirSuccess, fail);
}
function getDirSuccess(dirEntry) {
// Get a directory reader
var directoryReader = dirEntry.createReader();
// Get a list of all the entries in the directory
directoryReader.readEntries(readerSuccess,fail);
}
var numDirs = 0;
var numFiles = 0;
var readerTimeout = null, millisecondsBetweenReadSuccess = 100;
function readerSuccess(entries) {
var i = 0, len = entries.length;
for (; i < len; i++) {
if (entries[i].isFile) {
numFiles++;
entries[i].file(fileSuccess,fail);
} else if (entries[i].isDirectory) {
numDirs++;
getDirSuccess(entries[i]);
}
if (readerTimeout) {
window.clearTimeout(readerTimeout);
}
}
if (readerTimeout) {
window.clearTimeout(readerTimeout);
}
readerTimeout = window.setTimeout(weAreDone, millisecondsBetweenReadSuccess);
}
// additional event to call when totally done
function weAreDone() {
// do something
}
The Camera docs cover this. Is this not working for you?
If Camera.sourceType = Camera.PictureSourceType.PHOTOLIBRARY or Camera.PictureSourceType.SAVEDPHOTOALBUM, then a photo chooser dialog is shown, from which a photo from the album can be selected.
http://docs.phonegap.com/phonegap_camera_camera.md.html
Also refer...
Browsing Image Gallery With PhoneGap & Android
I am porting an application I wrote for the iphone over to Android and I wanted to start with the Camera functionality. I looked around and Googled and I could not find where it was documented on how to browse the image gallery on the Android device. I decided to bang out some simple modifications to the existing Camera object to support that functionality for now. I the future, hopefully this is implemented better by the PhoneGap guys and I can put this code out to pasture.
This code needs to be added to the phoneGap.js file. It creates the prototype for the new method for browsing the gallery on the device
1 //
2 // add the new prototype to support the browse function
3 //
4 // i have created a new class 'PixCameraLauncher' so I did not have to modify
5 // the original class file provided by PhoneGap
6 //
7 com.phonegap.CameraLauncherProxy.prototype.browseImages = function(quality) {
8 return PhoneGap.exec("com.phonegap.gapTest.PixCameraLauncher", "browseImages", [quality]);
9 };
This the modification I made to the CameraLauncher class provided by PhoneGap. Add a new intent to launch the image gallery
01 /**
02 * Get a picture from the Image Gallery.
03 *
04 * in DroidGap.onActivityResult, which forwards the result to
05 * this.onActivityResult.
06 *
07 * #param quality
08 * Compression quality hint (0-100: 0=low quality & high
09 * compression, 100=compress of max quality)
10 */
11 public void browseImages(int quality) {
12 this.mQuality = quality;
13
14 // Display camera
15 Intent intent = new Intent(Intent.ACTION_PICK,
16 android.provider.MediaStore.Images.Media.INTERNAL_CONTENT_URI);
17
18 this.ctx.startActivityForResult((Plugin) this, intent);
19 }
Also we need to handle the returned file. I left it simple, but this could be cleaned up a bit What I do is assume that if there is a URI in the data field, then an image has been picked and should be processed by the utility. In the beginning of the
1 void onActivityResult(int requestCode, int resultCode, Intent intent)
add the code below. This will handle re-assigning the URI to the selected file
1 // If image available
2 if (resultCode == Activity.RESULT_OK) {
3
4 //
5 // this means the user selected an image, so just pass it back!!
6 //
7 if (intent.getData() != null) {
8 imageUri = intent.getData();
9 }
After a little more testing and code cleanup, I will make the complete project for the android work and the iphone work available. If there are any questions, post it below.
The problem is you are trying to use the File API to read files inside of your applications assets directory. That directory is not actually part of the file system. When you do a window.requestFileSystem(LocalFileSystem.PERSISTENT, ...) you are actually getting the /sdcard (most probably) back. So when you try to load "img/china" that directory does not exist.
You would need to copy the files from your assets directory to the local file system during the onCreate method of your main Java class. Then you can use the DirectoryReader to get a list of all the files.
Alternatively, if you know all the images ahead of time you could create your own JSON file that lists them all. Then load that file and be able to loop through all the entries to create your own gallery.