The code I'm pasting below was built with Android Studio and tested on an Android smartphone. I'm pretty sure it was working fine as long as I manually enabled camera and microphone permissions. I also wrote a Java variant instead of Kotlin and all worked as expected.
However, I am totally unable to make this app work anymore, no matter how many times I reboot my device or make sure there are no other running apps that might use the camera or mic.
The webrtc test site mentioned in the code works fine if I load it in Chrome.
So, any ideas why my webview "test app" cannot access any media device even if I enable microphone and camera permissions in "Android OS app settings"?
And like I said, I'm pretty sure it DID work before, but something went wrong, obviously. I just want to make sure here that the code is OK.
package org.me.test
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.webkit.WebView
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val WebView: WebView = findViewById(R.id.webview)
WebView.settings.javaScriptEnabled = true
WebView.loadUrl("https://test.webrtc.org")
}
}
The manifest file:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="org.me.test">
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:roundIcon="#mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="#style/Theme.test">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
</manifest>
The layout:
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<WebView
android:id="#+id/webview"
android:layout_width="match_parent"
android:layout_height="match_parent"
/>
</androidx.constraintlayout.widget.ConstraintLayout>
Thanks
I think I need to use the WebChromeClient if I want webrtc to work.
Something like this seems to work for me in my MainActivity class:
myWebView.setWebChromeClient(new WebChromeClient() {
#Override
public void onPermissionRequest(final PermissionRequest request) {
request.grant(request.getResources());
}
});
Related
I have a Unity activity embedded as a fragment inside of my Android app. Everything works fine, except that after the fragment runs, the resolution of the app is funny. And it stays that way even after restarting. I have to make a change to the AndroidManifest and then reinstall in order to get the resolution right again.
Here is a piece of the manifest from the Android app.
<application
android:name=".App"
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:roundIcon="#mipmap/ic_launcher_round"
android:supportsRtl="true"
android:extractNativeLibs="true"
android:theme="#style/AppTheme"
android:usesCleartextTraffic="true">
<activity android:name=".FragmentActivity"
<activity
android:name=".MainActivity"
android:label="#string/app_name"
android:windowSoftInputMode="adjustNothing">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
Here is the entire AndroidManifest from unityLibrary that I imported into the app.
<?xml version="1.0" encoding="utf-8"?>
<!-- GENERATED BY UNITY. REMOVE THIS COMMENT TO PREVENT OVERWRITING WHEN EXPORTING AGAIN-->
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.unity3d.player" xmlns:tools="http://schemas.android.com/tools">
<application>
<activity android:name="com.unity3d.player.UnityPlayerActivity" android:theme="#style/UnityThemeSelector" android:screenOrientation="fullSensor" android:configChanges="mcc|mnc|locale|touchscreen|keyboard|keyboardHidden|navigation|orientation|screenLayout|uiMode|screenSize|smallestScreenSize|fontScale|layoutDirection|density" android:hardwareAccelerated="false">
<!--<intent-filter>-->
<!--<action android:name="android.intent.action.MAIN" />-->
<!--<category android:name="android.intent.category.DEFAULT" />-->
<!--</intent-filter>-->
<meta-data android:name="unityplayer.UnityActivity" android:value="true" />
<meta-data android:name="android.notch_support" android:value="true" />
</activity>
<meta-data android:name="unity.splash-mode" android:value="0" />
<meta-data android:name="unity.splash-enable" android:value="True" />
<meta-data android:name="notch.config" android:value="portrait|landscape" />
<meta-data android:name="unity.build-id" android:value="f6e555a5-44fc-47be-9a81-b3809caa8f74" />
</application>
<uses-feature android:glEsVersion="0x00030000" />
<uses-feature android:name="android.hardware.vulkan.version" android:required="false" />
<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" />
</manifest>
Here's the activity that holds the fragment.
class FragmentActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_fragment)
}
}
Here's the fragment itself.
class UnityFragment : Fragment() {
protected var mUnityPlayer: UnityPlayer? = null
var frameLayoutForUnity: FrameLayout? = null
fun UnityFragment() {}
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
mUnityPlayer = UnityPlayer(activity)
val view = inflater.inflate(R.layout.fragment_unity, container, false)
frameLayoutForUnity =
view.findViewById<View>(R.id.frameLayoutForUnity) as FrameLayout
frameLayoutForUnity!!.addView(
mUnityPlayer!!.view,
FrameLayout.LayoutParams.MATCH_PARENT, FrameLayout.LayoutParams.MATCH_PARENT
)
mUnityPlayer!!.requestFocus()
mUnityPlayer!!.windowFocusChanged(true)
return view
}
override fun onDestroy() {
mUnityPlayer!!.quit()
super.onDestroy()
}
override fun onPause() {
super.onPause()
mUnityPlayer!!.pause()
}
override fun onResume() {
super.onResume()
mUnityPlayer!!.resume()
}
}
And here's R.layout.fragment_unity.
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/frameLayoutForUnity"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".UnityFragment"/>
The layout for FragmentActivity is just a single fragment inside of a constraintlayout.
I hope someone can point me in the right direction because I really don't understand how screen resolution works or what controls it. But based on the appearance of layouts in the rest of the app, it feels like that's what it's related to.
I found a solution, but it's not super enlightening. What I mean is that I found a way to make the symptom stop.
For reasons I can't explain, if I set hardwareAccelerated to true inside of my app Manifest WHILE ALSO turning notchsupport to false inside the unityLibrary Manifest then my custom views stop drawing their canvases weird.
I know this seems like rain dancing or using a dowsing rod, but it works and I can revisit later to make an implementation that I understand.
Some notes: My gut feeling is that I'm letting the unity manifest talk over my app manifest and somehow turn off hardwareAccelerated, since that would explain the canvases being drawn differently. But suppressing hardwareAccelerated turning off inside the unity manifest and also forcing it as enabled in the app manifest are not enough by themselves to stop the symptom. The only thing that stops the symptom is doing all of that and also turning off notch_support. Maybe somewhere notch_support interacts with hardwareAccelerated. But I think it's more likely that there's a third factor causing all this and this random confluence of settings affects that factor happenstantially.
Edit: It's been a long time since I asked this question. But I see that it's gotten some interest recently from someone likely experiencing the same problem. I never figured out what the problem was. It sort of just happened intermittently and eventually stopped. But for the benefit of posterity I would like to say that visually detecting a change in resolution in any situation and for any cause points to a failure to accommodate different screens and is probably why the question got downvoted.
So if you're experiencing this problem too, the first place you should probably look is whether you're using px instead of dp in your custom drawn canvases. A lot of the canvas draw methods default to px and you have to normalize to dp yourself.
Also use percentages to size things out inside of ConstraintLayouts.
I have put in manifest
<uses-permission android:name="android.permission.INTERNET" />
but I think it doesn't work for android 2.1 what should I put then ?
Source code is just the official tutorial from Google http://developer.android.com/resources/tutorials/views/hello-webview.html.
import android.app.Activity;
import android.os.Bundle;
import android.webkit.WebView;
public class WebViewActivity extends Activity {
WebView webview;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
webview = (WebView) findViewById(R.id.webview);
webview.getSettings().setJavaScriptEnabled(true);
webview.loadUrl("http://google.com");
}
}
That permission is valid for Android 2.1. The code you have posted will work on Android 2.1.
I just tested it in the emulator and if I don't provide the permission I will receive an error in the WebView:
Web Page Not Available
The web page at http://www.google.com/ might be temporarily down [...]
Adding the permission resolves that.
Make sure your permission is added to the proper place. It must be directly inside the <manifest> element. If you place it inside the <application> element, it will not work.
This works:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.test.testwebview"
android:versionCode="1"
android:versionName="1.0" >
<uses-permission android:name="android.permission.INTERNET" />
<uses-sdk android:minSdkVersion="7" />
<application
android:icon="#drawable/ic_launcher"
android:label="#string/app_name" >
<activity
android:label="#string/app_name"
android:name=".TestWebViewActivity" >
<intent-filter >
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
I've made a very simple app that just displays a Google map. However, it only seems to be displaying gray squares.
I've troubleshooted and have done virtually everything I could. I checked my code 5+ times over, I've compared it even to other tutorials. I've re-made my API key 3 times - none of them work.
The phone I'm using is connected to wireless. Even the emulator won't work. I have the library and permission established in the manifest. I think I've done just about everything, but it still doesn't work... any suggestions?
Here's my code:
MapsActivity.java:
package net.learn2develop.GoogleMaps;
import com.google.android.maps.MapActivity;
import com.google.android.maps.MapView;
import android.os.Bundle;
public class MapsActivity extends MapActivity
{
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}
#Override
protected boolean isRouteDisplayed() {
return false;
}
}
main.xml:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<com.google.android.maps.MapView
android:id="#+id/mapView"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:enabled="true"
android:clickable="true"
android:apiKey="0duU2_tgS67qkUZIpmLVIo0IDvJDh4Ew1Mzh9Pg"
/>
</RelativeLayout>
GoogleMapsManifest:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="net.learn2develop.GoogleMaps"
android:versionCode="1"
android:versionName="1.0.0">
<uses-sdk android:minSdkVersion="7" />
<application android:icon="#drawable/icon" android:label="#string/app_name">
<uses-library android:name="com.google.android.maps" />
<activity android:name=".MapsActivity"
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>
<uses-permission android:name="android.permission.INTERNET" />
</manifest>
You need to add
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
into you manifest
Note: If you are using both NETWORK_PROVIDER and GPS_PROVIDER, then you need to request only the ACCESS_FINE_LOCATION permission, because it includes permission for both providers. (Permission for ACCESS_COARSE_LOCATION includes permission only for NETWORK_PROVIDER.)
The problem was that Mike was using an API key generated with the release keystore instead of the debug keystore that eclipse uses when compiling the apk.
I had the same error ! I tried everything, so a try this tutorial below and it worked!!!!
TUTORIAL
Thanks in advance for your efforts.
I have an Application that revolves around a ListActivity extended class. Before the app starts, I want to check whether the user is registered, and if not tell him to and get some info from him. So, I tried to call StartActivity in the OnCreate() method. When that loaded, I got a big black screen.
I thought that it may be related to being run in the OnCreate so I let the Activity start as usual, and I tried to run it in an OnClick event, and I got the same result.
In both cases, if I press escape, that Window goes away and the main app window comes back.
Here are the lines from where I call the new Activity
Intent emailIntent = new Intent(this, EmailAddressGetter.class);
this.startActivity(emailIntent);
Here is the code of the class
/**
*
*/
package com.kosherapp;
import android.app.Activity;
import android.os.Bundle;
import android.widget.Toast;
/**
* #author Josh
*
*/
public class EmailAddressGetter extends Activity {
public void OnCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.emailinput);
}
}
Here is the emailinput xml contents
<?xml version="1.0" encoding="utf-8"?>
<TextView
xmlns:android="http://schemas.android.com/apk/res/android"
android:background="#ffffff"
android:textColor="#000000"
android:layout_height="fill_parent"
android:layout_width="fill_parent"
android:text="hello"
>
</TextView>
And, here is the manifest contents
<?xml version="1.0" encoding="utf-8"?>
<manifest
xmlns:android="http://schemas.android.com/apk/res/android"
package="com.kosherapp"
android:versionCode="1"
android:versionName="1.0"
>
<uses-permission
android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission
android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission
android:name="android.permission.INTERNET" />
<uses-permission
android:name="android.permission.CALL_PHONE" />
<application
android:icon="#drawable/icon"
android:label="#string/app_name"
>
<activity
android:name=".KosherApp"
android:label="#string/app_name"
android:theme="#android:style/Theme.NoTitleBar"
>
<intent-filter>
<action
android:name="android.intent.action.MAIN" />
<category
android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name=".EmailAddressGetter"
android:label="email Address Getter"
>
</activity>
<activity
android:name=".GoogleMaps"
android:label="Google Maps"
>
</activity>
<uses-library
android:name="com.google.android.maps" />
</application>
</manifest>
Let me know if there's any other info you may need. Oh, I'm running this with the Google API 2.1-update
Thanks
Change OnCreate to onCreate in EmailAddressGetter.
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.emailinput);
}
You need to use EditText instead. TextView is for static text which is why nothing is displaying. You should also include the EditText in another layout like Linear or Relative so it looks cleaner.
You are using an intent to call EmailAddressGetter but it doesn't have an intent filter in the manifest. Throw in something like Log.e("EmailAddressGetter", "It worked") in your onCreate and use ddms to see if it is actually opening that activity.
Also, in the updated code in your comment to Robby Pond, remove the xmlns line from EditText
I'm trying to create an app that will change a setting when the user holds the search button. It seems that the combination of the WRITE_SETTINGS permission and the fact that the activity is launched from another application using the long press makes the parent task crash. For example, if I'm looking at Google Maps and hold the search button, the SearchButtonPopup does not appear and Google Maps crashes.
I tried taking the Theme.Dialog out, but it didn't make any difference. Removing the permission makes it robust again, no crashes, but I need the permission! Any fixes or workarounds?
These are my manifest and java files:
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="org.stathissideris.searchbuttonpopup" android:versionCode="1"
android:versionName="1.0">
<uses-sdk android:minSdkVersion="3" />
<uses-permission android:name="android.permission.WRITE_SETTINGS" />
<application android:icon="#drawable/logo" android:label="#string/app_name"
android:debuggable="true" android:permission="android.permission.WRITE_SETTINGS">
<activity android:name=".SearchButton" android:theme="#android:style/Theme.Dialog">
<intent-filter>
<action android:name="android.intent.action.SEARCH_LONG_PRESS" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
</application>
</manifest>
SearchButton.java
package org.stathissideris.searchbuttonpopup;
import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
public class SearchButton extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.d("SearchButtonPopup", "search held");
}
}