i am using unity and admob ,and now i have a problem
When i try to show test ads they show without a problem , everything works fine, but when i try to show real ads they are not displayed.
I tried the following:
I created admob account
I coppied the AppID into my code , and also in the xml file
I did everything from the turorials , with some changes because google dont know how to explain.Then i debugged with logcat , and i got the following error
java.lang.RuntimeException: Unable to get provider com.google.android.gms.ads.MobileAdsInitProvider: java.lang.IllegalStateException:
10-08 22:24:53.917 30153 30153 E AndroidRuntime:
10-08 22:24:53.917 30153 30153 E AndroidRuntime: ******************************************************************************
10-08 22:24:53.917 30153 30153 E AndroidRuntime: * Invalid application ID. Follow instructions here: *
10-08 22:24:53.917 30153 30153 E AndroidRuntime: * https://googlemobileadssdk.page.link/admob-android-update-manifest *
10-08 22:24:53.917 30153 30153 E AndroidRuntime: * to find your app ID.
This is my Code for showing banners
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using GoogleMobileAds.Api;
public class AdmobManager : MonoBehaviour
{
private BannerView bannerView;
void Start()
{
#if UNITY_ANDROID
string appId = "ca-app-pub-6068823890509836~9548685797";
#elif UNITY_IPHONE
string appId = "ca-app-pub-3940256099942544~1458002511";
#else
string appId = "unexpected_platform";
#endif
// Initialize the Google Mobile Ads SDK.
MobileAds.Initialize(appId);
this.RequestBanner();
}
// Update is called once per frame
private void RequestBanner()
{
#if UNITY_ANDROID
string adUnitId = "ca-app-pub-6068823890509836/3679968367";
#elif UNITY_IPHONE
string adUnitId = "ca-app-pub-3940256099942544/2934735716";
#else
string adUnitId = "unexpected_platform";
#endif
// Create a 320x50 banner at the top of the screen.
bannerView = new BannerView(adUnitId, AdSize.Banner, AdPosition.Bottom);
AdRequest request = new AdRequest.Builder().Build();
// Load the banner with the request.
bannerView.LoadAd(request);
}
}
and this is my xml file
> <?xml version="1.0" encoding="utf-8"?> <manifest
> xmlns:android="http://schemas.android.com/apk/res/android"
> package="com.google.unity.ads" android:versionName="1.0"
> android:versionCode="1"> <application>
> <uses-library android:required="false" android:name="org.apache.http.legacy" />
> <meta-data android:name="com.google.android.gms.ads.APPLICATION_ID"
> android:value="ca-app-pub-6068823890509836~9548685797" />
> </application> </manifest>
Also i made the banner yesterday so 24hours has passed .
If test ads were already shown, I don't think there is anything wrong on your part.
Once your app is making more requests, you should see more consistent results. Please note that test ads operate through the same channels as live ads. Being able to return a test ad ensures that your application is communicating properly with our network.
Source: https://support.google.com/admob/answer/2993019?hl=en
Related
I have an Android application that builds and runs find before the introduction of the following code to an object in my scene. My goal was to vibrate at different lengths for my application instead of just using the default Handheld.Vibrate() function. Once this code is added, my application still builds to my device just fine, but crashes on startup.
I am using Unity 2019.2.9f1, and my minimum API level is set to 25, using Mono and .NET 2.0.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class HapticController : Singleton<HapticController> {
#if UNITY_ANDROID && !UNITY_EDITOR
public static AndroidJavaClass unityPlayer = new AndroidJavaClass("com.unity3d.player.UnityPlayer");
public static AndroidJavaObject currentActivity = unityPlayer.GetStatic<AndroidJavaObject>("currentActivity");
public static AndroidJavaObject vibrator = currentActivity.Call<AndroidJavaObject>("getSystemService", "vibrator");
#else
public static AndroidJavaClass unityPlayer;
public static AndroidJavaObject currentActivity;
public static AndroidJavaObject vibrator;
#endif
bool isVibrating;
...
// Update is called once per frame
void Update()
{
if(!isVibrating && ( *other condition* ) ){
isVibrating = true; //this will later be changed, just trying to get it to vibrate once
Vibrate(200);
}
}
public static void Vibrate(long milliseconds)
{
if(isAndroid() && vibrator != null){
print("vibrating");
vibrator.Call("vibrate", milliseconds);
} else {
Handheld.Vibrate();
}
}
private static bool isAndroid()
{
#if UNITY_ANDROID && !UNITY_EDITOR
return true;
#else
return false;
#endif
}
}
I know that it is the AndroidJavaClass/AndroidJavaObject calls at the top that are causing the crash. I have checked the logs in logcat in Android Studio, but there is no notable output that would have anything to do with the crash. Is there something I am not accounting for that would cause this?
EDIT: I should add that I am using an SDK (Mapbox) that has its own AndroidManifest.xml. It instructs you to rename it and move it to the Plugins/Android folder. You can see it here:
<!--
Android Manifest for UniAndroid Permission (2016/03/19 sanukin39)
--- if already have AndroidManifest file at Assets/Plugins/Android/ ----
Copy the activity and meta-data sentence to your AndroidManifest.xml
--- if not ---
Rename this file to AndroidManifest.xml and add permission you want to add And move the file to Assets/Plugins/Android
-->
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.company.product">
<application android:icon="#drawable/app_icon" android:label="#string/app_name">
<activity android:name="net.sanukin.OverrideUnityActivity"
android:label="#string/app_name"
android:configChanges="fontScale|keyboard|keyboardHidden|locale|mnc|mcc|navigation|orientation|screenLayout|screenSize|smallestScreenSize|uiMode|touchscreen">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<meta-data android:name="unityplayer.SkipPermissionsDialog" android:value="true" />
</application>
</manifest>
For anyone else struggling with this, I was able to solve this with a combination of Farhan's answer and also doing the following:
Instead of initializing the AndroidJavaClass and AndroidJavaObjects at the top, I created an initializer function responsible for doing that. I added the line
[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.BeforeSceneLoad)]
above of it in order to force it to initialize them before the scene has loaded. I am not sure why this is required, but it fixed it for me. You can see the full function below:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class HapticController : Singleton<HapticController> {
public static AndroidJavaClass unityPlayer = null;
public static AndroidJavaObject currentActivity = null;
public static AndroidJavaObject vibrator = null;
[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.BeforeSceneLoad)]
private static void Initialize(){
#if UNITY_ANDROID && !UNITY_EDITOR
if (Application.platform == RuntimePlatform.Android) {
unityPlayer = new AndroidJavaClass("com.unity3d.player.UnityPlayer");
currentActivity = unityPlayer.GetStatic<AndroidJavaObject>("currentActivity");
vibrator = currentActivity.Call<AndroidJavaObject>("getSystemService", "vibrator");
}
#endif
}
...
}
You should add following vibration permission in {Project location}\Assets\Plugins\Android\AndroidManifest.xml
<uses-permission android:name="android.permission.VIBRATE"/>
So your final AndroidManifest becomes.
<?xml version="1.0" encoding="utf-8"?>
<manifest
xmlns:android="http://schemas.android.com/apk/res/android"
package="com.unity3d.player"
android:versionCode="1"
android:versionName="1.0">
<uses-permission android:name="android.permission.VIBRATE"/>
<application
android:theme="#style/UnityThemeSelector"
android:icon="#drawable/app_icon"
android:label="#string/app_name"
android:debuggable="true">
<activity android:name="com.unity3d.player.UnityPlayerActivity"
android:label="#string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<meta-data android:name="unityplayer.UnityActivity" android:value="true" />
</activity>
</application>
I'm trying to show a bottom banner on my App but I can't make it show up.
Funny that it was working just fine but after a few weeks without coding it just stopped working and not even test codes from Google show up. Sometimes it works after a compilation and when I unplug the phone and close/open the App again it stop showing the ads again.
I also used the same Admob code into a Unity quiz game I created and over there it works fine everytime.
PS: I'm a bit new to Xamarin and C#, this is my first App.
Here's the relevant code:
MainPage.xaml
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:DDP"
x:Class="DDP.MainPage"
BackgroundColor="#3f183d"
Title="My App Title">
<StackLayout BackgroundColor="Transparent" HeightRequest="70" HorizontalOptions="Start" VerticalOptions="Center" WidthRequest="1000">
<local:AdMobView x:Name="adMobView" HorizontalOptions="FillAndExpand" VerticalOptions="EndAndExpand"/>
</StackLayout>
</ContentPage>
MainPage.xaml.cs
public MainPage()
{
InitializeComponent();
BindingContext = this;
adMobView.AdUnitId = AdMobView.codigoAdmob;
}
AdMobView.cs
using Xamarin.Forms;
namespace DDP
{
public class AdMobView : View
{
public static readonly BindableProperty AdUnitIdProperty = BindableProperty.Create(
nameof(AdUnitId),
typeof(string),
typeof(AdMobView),
string.Empty);
public string AdUnitId
{
get => (string)GetValue(AdUnitIdProperty);
set => SetValue(AdUnitIdProperty, value);
}
//admob google test code
public static string codigoAdmob = "ca-app-pub-xxxxx/xxxxx";
}
}
AdMobViewRenderer.cs
using System.ComponentModel;
using DDP;
using DDP.Droid;
using Android.Content;
using Android.Gms.Ads;
using Android.Widget;
using Xamarin.Forms;
using Xamarin.Forms.Platform.Android;
[assembly: ExportRenderer(typeof(AdMobView), typeof(AdMobViewRenderer))]
namespace DDP.Droid
{
public class AdMobViewRenderer : ViewRenderer<AdMobView, AdView>
{
public AdMobViewRenderer(Context context) : base(context) { }
protected override void OnElementChanged(ElementChangedEventArgs<AdMobView> e)
{
base.OnElementChanged(e);
if (e.NewElement != null && Control == null)
{
SetNativeControl(CreateAdView());
}
}
protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
{
base.OnElementPropertyChanged(sender, e);
if (e.PropertyName == nameof(AdView.AdUnitId))
Control.AdUnitId = Element.AdUnitId;
}
private AdView CreateAdView()
{
var adView = new AdView(Context)
{
AdSize = AdSize.SmartBanner,
AdUnitId = Element.AdUnitId
};
adView.LayoutParameters = new LinearLayout.LayoutParams(LayoutParams.MatchParent, LayoutParams.MatchParent);
adView.LoadAd(new AdRequest.Builder().Build());
return adView;
}
}
}
MainActivity.cs
//somecode
base.OnCreate(bundle);
MobileAds.Initialize(ApplicationContext, "ca-app-pub-xxxxx/xxxxx");
global::Xamarin.Forms.Forms.Init(this, bundle);
LoadApplication(new App());
//somecode
AndroidManifest.xml
Other info
I'm using 'Xamarin.GooglePlayServices.Ads.Lite' NuGet package and I checked permissions to 'Network_State' and 'Internet'
Thanks !
Update 1: Catlog log:
--------- beginning of crash
--------- beginning of system
--------- beginning of main
11-19 11:31:04.852 11568 11568 I Ads : Updating ad debug logging enablement.
11-19 11:31:06.407 11568 11596 W Ads : Update ad debug logging enablement as false
11-19 11:31:07.109 11568 11568 I Ads : Use AdRequest.Builder.addTestDevice("1BE57C53121A02D9EF3DD79A87C60D3C") to get test ads on this device.
11-19 11:31:07.916 11568 11593 W Ads : Not retrying to fetch app settings
11-19 11:31:08.118 27571 11755 I Ads : SDK version: afma-sdk-a-v14574021.11400000.1
11-19 11:31:08.901 11568 11568 I Ads : Ad failed to load : 3
Filter by the TAG of Ads and you will see different Information and/or Warning log entries concerning AdMob. These will range from timed outs and load failures (usually related to no Internet access) to not refreshing the ad since it is not currently visible in the UI (but an AdView instance was created), etc...
Example:
adb logcat -s Ads
Example Output (Not a complete list):
I Ads : Starting ad request.
I Ads : SDK version: XXXXXXXXXX
I Ads : This request is sent from a test device.
I Ads : Scheduling ad refresh 70000 milliseconds from now.
I Ads : Ad is not visible. Not refreshing ad.
W Ads : There was a problem getting an ad response. ErrorCode: 0
W Ads : Failed to load ad: 0
W Ads : Not retrying to fetch app settings
W Ads : Invoke Firebase method getInstance error.
W Ads : The Google Mobile Ads SDK will not integrate with Firebase. Admob/Firebase integration requires the latest Firebase SDK jar, but Firebase SDK is either missing or out of date
W Ads : App does not have the required permissions to get location
W Ads : Timed out waiting for ad response.
W Ads : Failed to load ad: 2
I'm sorry that can't say how to fix this but I think it is related to Chrome version, chrome ships webview which admob is using. I had a perfectly working admob ads in my xamarin forms app on Nexus 5X device with Chrome 60 but upgrading to Chrome 70+ broke all ads.
I integrate Ad-mob banner ads in my Unity game project android build
But Sometimes the ad is showing but most of time it's not
showing percentage will be just just 4% out of 100%
I don't know why this happening
I got this following code from developers.google and i am able to show ads but it does not show the banner app on every startup frankly speaking it only shows ads in first or 2nd startup after build and not anymore.
I try to find solutions but looks like all solutions are same.
So, I am Stuck in here
using System.Collections;
using System.Collections.Generic;
using GoogleMobileAds;
using GoogleMobileAds.Api;
using UnityEngine;
public class BannerAd : MonoBehaviour
{
private BannerView bannerView;
// Use this for initialization
void Start ()
{
string appID = "ca-app-pub-id"; // this is appId
MobileAds.Initialize (appID);
string adUnitId = "ca-app-pub-adUnitId"; // adUnitID
this.showBannerAd (adUnitId);
}
private void showBannerAd (string adUnitId)
{
//Create a custom ad size at the bottom of the screen
AdSize adSize = new AdSize (250, 50);
bannerView = new BannerView (adUnitId, adSize, AdPosition.Bottom);
// Create an empty ad request.
AdRequest request = new AdRequest.Builder ().Build ();
// Load the banner with the request.
bannerView.LoadAd (request);
StartCoroutine(bannerAdTime());
}
IEnumerator bannerAdTime ()
{
yield return new WaitForSeconds (300f);
RequestNewAd();
}
private void RequestNewAd ()
{
// Create an empty ad request.
AdRequest request = new AdRequest.Builder ().Build ();
// Load the banner with the request.
bannerView.LoadAd (request);
StartCoroutine(bannerAdTime());
}
// Update is called once per frame
void Update ()
{
}
}
1.Check you have install plugin as document https://github.com/unity-plugins/Unity-Admob
2.Edit AndroidManifest.xml and config Admob APP ID
This configuration is reqired by admob from version 17.0,APP will crash if not config .Add a meta-data tag in application and set value to your admob appid
<meta-data
android:name="com.google.android.gms.ads.APPLICATION_ID"
android:value="your admob app id"/>
Sample code
<application android:theme="#style/UnityThemeSelector"
android:icon="#drawable/app_icon"
android:label="#string/app_name" >
<activity
android:name="com.unity3d.player.UnityPlayerActivity"
android:label="#string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<meta-data
android:name="com.google.android.gms.ads.APPLICATION_ID"
android:value="ca-app-pub-3940256099942544~3347511713"/>
</application>
3.Init Admob Unity Plugin
Create A C# script ,drag the script to a object on scene , add the follow code in the script file
using admob;
Admob.Instance().initSDK("admob appid", new AdProperties());//admob id with format ca-app-pub-3940256099942544~3347511713
//Admob.Instance().initAdmob("ca-app-pub-3940256099942544/2934735716", new AdProperties());
4.Add Admob Banner in Unity App
Admob.Instance().showBannerRelative("your admob banner unit id",AdSize.BANNER, AdPosition.BOTTOM_CENTER, 0);
I found the solution
The problem was with my Emulator
With The Real Device it work fine
and there's no need to use the co-routine
the following codes will be enough to show the BannderAds
using System.Collections;
using System.Collections.Generic;
using GoogleMobileAds;
using GoogleMobileAds.Api;
using UnityEngine;
public class BannerAd : MonoBehaviour
{
private BannerView bannerView;
// Use this for initialization
void Start ()
{
string appID = "ca-app-pub-id"; // this is appId
MobileAds.Initialize (appID);
string adUnitId = "ca-app-pub-adUnitId"; // adUnitID
this.showBannerAd (adUnitId);
}
private void showBannerAd (string adUnitId)
{
//Create a custom ad size at the bottom of the screen
AdSize adSize = new AdSize (250, 50);
bannerView = new BannerView (adUnitId, adSize, AdPosition.Bottom);
// Create an empty ad request.
AdRequest request = new AdRequest.Builder ().Build ();
// Load the banner with the request.
bannerView.LoadAd (request);
}
}
I am launching an Unity application from another Android application using a custom implicit intent. This is working fine, but I cannot figure out how to read the intent extra data in Unity?
ANDROID INTENT TO LAUNCH UNITY APP
i=new Intent();
i.setAction("com.company.unityapp.MyMethod");
i.putExtra("KEY","This is the message string");
startActivity(i);
UNITY APP AndroidManifest.xml
<intent-filter>
<action android:name="com.company.unityapp.MyMethod" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
I have a GameObject in my scene with a script attached. Inside the start method I have this code to try and read the extra data that was passed along with the intent
AndroidJavaClass UnityPlayer = new AndroidJavaClass("com.unity3d.player.UnityPlayer");
AndroidJavaObject currentActivity = UnityPlayer.GetStatic<AndroidJavaObject>("currentActivity");
AndroidJavaObject intent = currentActivity.Call<AndroidJavaObject>("getIntent");
bool hasExtra = intent.Call<bool> ("hasExtra", "arguments");
if (hasExtra) {
AndroidJavaObject extras = intent.Call<AndroidJavaObject> ("getExtras");
arguments = extras.Call<string> ("getString", "arguments");
}
This is not working and arguments is always empty. Any help would be appreciated.
It took me quite some time to figure this out. All solutions found online were only partly complete. Below is the full solution for launching a Unity application from another android application using a custom implicit Intent and also how to access the extra data sent with the Intent inside Unity.
To accomplish this you need to create a Android plugin that will be used by Unity to access the Intent extra data.
ANDROID PLUGIN:
You need to copy the classes.jar from Unity installation folder to the android plugin folder /lib/classes.jar
public class MainActivity extends UnityPlayerActivity {
#Override
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
handleNewIntent(intent);
}
private void handleNewIntent(Intent intent){
String text = intent.getStringExtra("KEY");
UnityPlayer.UnitySendMessage("AccessManager","OnAccessToken", text);
}
}
AndroidManifest.xml
Important here is the package name used: com.company.plugin
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.company.plugin">
<application
android:allowBackup="true" android:icon="#mipmap/ic_launcher" android:label="#string/app_name"
android:supportsRtl="true" android:theme="#style/AppTheme">
<activity
android:name=".MainActivity"
android:label="#string/app_name"
android:theme="#style/AppTheme.NoActionBar">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
Gradle build file:
Add the following to the app gradle build file to be able to create a .jar to be used with Unity
android {
compileSdkVersion 23
buildToolsVersion "23.0.2"
sourceSets {
main {
java {
srcDir 'src/main/java'
}
}
}
...
...
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
compile 'com.android.support:appcompat-v7:23.2.1'
compile 'com.android.support:design:23.2.1'
compile files('libs/classes.jar')
}
//task to delete the old jar
task deleteOldJar(type: Delete) {
delete 'release/AndroidPlugin.jar'
}
//task to export contents as jar
task exportJar(type: Copy) {
from('build/intermediates/bundles/release/')
into('release/')
include('classes.jar')
///Rename the jar
rename('classes.jar', 'AndroidPlugin.jar')
}
exportJar.dependsOn(deleteOldJar, build)
Copy the created AndroidPlugin.jar to Unity Assets/Plugins/Android
UNITY APP:
Set the bundle identifier in PlayerSettings to be the same as set in the Android Plugin - com.company.plugin
Create custom AndroidManifest.xml file in Assets/Plugins/Android
Important here is to use the same package name as used in the plugin.
Also note the Intent name: com.company.plugin.do
AndroidManifest.XML
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.company.plugin"
android:versionCode="1" android:versionName="1.0">
<uses-sdk android:minSdkVersion="9" />
<application android:label="#string/app_name">
<activity android:name=".MainActivity" android:label="#string/app_name"
android:launchMode="singleTask" android:configChanges="fontScale|keyboard|keyboardHidden|locale|mnc|mcc|navigation|orientation|screenLayout|screenSize|smallestScreenSize|uiMode|touchscreen" android:screenOrientation="sensor">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<intent-filter>
<action android:name="com.company.plugin.do" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="text/plain"/>
</intent-filter>
</activity>
</application>
</manifest>
Create a unity script named AccessManager and attach the script to a game object in the scene. OnAccessToken is the method that will receive the message sent from the android plugin and will contain the extra data sent from the intent.
public class accessManager : MonoBehaviour {
public void OnAccessToken(string accessToken)
{
Debug.Log("Message Received!!!! :" + accessToken);
}
}
ANDROID APP:
Create a standard Android application that will launch the Unity Application and send the Intent extra data
public void LaunchUnityApp(){
Intent i=new Intent();
i.setAction("com.company.plugin.do");
i.setType("text/plain");
i.putExtra("KEY","This is the text message sent from Android");
startActivity(i);
}
You don't need a plugin to achieve this. Do your intent from Android like this:
Intent launchIntent = getPackageManager().getLaunchIntentForPackage("com.package.game");
launchIntent.putExtra("my_text", "Some data params");
if(launchIntent != null){
startActivity(launchIntent);
}else{
Log.d("Unity", "Couldnt start unity game");
}
Then in your unity Monobehaviour Class, receive it like this
private void Awake () {
getIntentData ();
}
private bool getIntentData () {
#if (!UNITY_EDITOR && UNITY_ANDROID)
return CreatePushClass (new AndroidJavaClass ("com.unity3d.player.UnityPlayer"));
#endif
return false;
}
public bool CreatePushClass (AndroidJavaClass UnityPlayer) {
#if UNITY_ANDROID
AndroidJavaObject currentActivity = UnityPlayer.GetStatic<AndroidJavaObject> ("currentActivity");
AndroidJavaObject intent = currentActivity.Call<AndroidJavaObject> ("getIntent");
AndroidJavaObject extras = GetExtras (intent);
if (extras != null) {
string ex = GetProperty (extras, "my_text");
return true;
}
#endif
return false;
}
private AndroidJavaObject GetExtras (AndroidJavaObject intent) {
AndroidJavaObject extras = null;
try {
extras = intent.Call<AndroidJavaObject> ("getExtras");
} catch (Exception e) {
Debug.Log (e.Message);
}
return extras;
}
private string GetProperty (AndroidJavaObject extras, string name) {
string s = string.Empty;
try {
s = extras.Call<string> ("getString", name);
} catch (Exception e) {
Debug.Log (e.Message);
}
return s;
}
Credit: https://wenrongdev.com/get-android-intent-data-for-unity/
(updated) https://wenrongdev.com/posts/get-android-intent-data-for-unity/
I have an android project for camera flashlight, which when deployed from eclipse works fine. I am trying to access the flashlight function from my C# code in unity3d but it doesn't work. To verify if I am calling the android method correctly, I created a string function in the same activity and it is returning the string correctly. I am not familiar to native android coding. It would be great if you could have a look at the code and help me out.
I know there are some threads in unity forum and stackoverflow explaining the same, I tried to find a solution on these threads but no luck! So, posted this thread..
Below is android MainActivity.java (which I converted into a jar file from eclipse and copied in unity project, ~Assets/Plugins/Android/bin/),
package com.example.newflash;
import android.hardware.Camera;
import android.hardware.Camera.Parameters;
import android.os.Bundle;
import android.app.Activity;
import android.view.Window;
import android.view.WindowManager;
public class MainActivity extends Activity {
private static Camera camera;
private static Parameters parameters;
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
//Hide the window title.
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN | WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
}
public static String dummyString()
{
return "dummy string";
}
public static void setFlashOn()
{
if (camera == null)
camera = Camera.open();
parameters = camera.getParameters();
parameters.setFlashMode(Parameters.FLASH_MODE_TORCH);
camera.setParameters(parameters);
}
public static void setFlashOff()
{
parameters = camera.getParameters();
parameters.setFlashMode(Parameters.FLASH_MODE_OFF);
camera.setParameters(parameters);
}
}
Below is my unity C# code,
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System;
public class testJar : MonoBehaviour
{
bool torchon;
AndroidJavaClass testClasslight;
void Start ()
{
torchon = false;
}
void OnGUI ()
{
string teststring = "empty";
AndroidJavaClass testClass = new AndroidJavaClass("com.example.glassplaces.MainActivity");
teststring = testClass.CallStatic<string>("dummyString");
GUI.Label (new Rect (20, 20, 100, 60), teststring);
if(GUI.Button(new Rect (20, 100, 100, 60), "ON"))
{
torchon = true;
}
if(torchon == true)
{
GUI.Label(new Rect(200, 20,100,60), "torch ON");
testClass.CallStatic<AndroidJavaObject>("setFlashOn");
}
}
}
The permissions to access camera in AndroidManifest.xml when added, the app doesn't start at all. On excluding the xml file from the project, the "dummyString" method still returns the string.
Below is the AndroidManifest.xml,
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.newflash"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="18" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-feature android:name="android.hardware.camera" />
<uses-feature android:name="android.hardware.camera.autofocus" />
<application
android:allowBackup="true"
android:icon="#drawable/app_icon"
android:label="#string/app_name">
<activity
android:name="com.example.newflash.MainActivity"
android:label="#string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
Below is the warning which unity shows in console with the above xml included during Build & Run,
Unable to find unity activity in manifest. You need to make sure orientation attribut is set to sensor manually.
UnityEditor.BuildPlayerWindow:BuildPlayerAndRun()
It would be great if someone could help me out. Any help is much appreciated.
Thank you in advance!
I am not 100% sure the above response by CaffeineCoder is accurate. It is certain possible to not extend UnityPlayerActivity and I've done it. You need to specify these special Unity activities in your Manifest along with your own Activity.
Unity will start UnityPlayerProxyActivity at first and proceed from there. Your Java code is only called when you call/initialize it.
Following are some of the activities you can specify:
<activity
android:name="com.unity3d.player.UnityPlayerProxyActivity"
android:label="AngryBots Gamme"
android:configChanges="fontScale|keyboard|keyboardHidden|locale|mnc|mcc|navigation|orientation|screenLayout|screenSize|smallestScreenSize|uiMode|touchscreen"
android:screenOrientation="landscape"
>
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
<activity
android:name="com.unity3d.player.UnityPlayerActivity"
android:label="AngryBots Gamme"
android:configChanges="fontScale|keyboard|keyboardHidden|locale|mnc|mcc|navigation|orientation|screenLayout|screenSize|smallestScreenSize|uiMode|touchscreen"
android:screenOrientation="landscape"
/>
<activity
android:name="com.unity3d.player.UnityPlayerNativeActivity"
android:label="AngryBots Gamme"
android:configChanges="fontScale|keyboard|keyboardHidden|locale|mnc|mcc|navigation|orientation|screenLayout|screenSize|smallestScreenSize|uiMode|touchscreen"
android:screenOrientation="landscape"
/>
Got it working, thanks to Stevethorne's answer (on unityAnswers). On extending my java activity to "UnityPlayerActivity", I got it working. That is, com.unity3d.player.UnityPlayerActivity. Here are further details about UnityPlayerActivity.