Access to microphone with WebView in Android - java

I am trying to write a program that has a WebView in it that shows a webpage which records audio using the microphone (recording is done using javascript getUserMedia). I have implemented the following code, and I get the pop up that asks the user for permission and after I allow, the grant function is called (and I think I get access to the mic), but the recording is just empty. If I try the same website on the browser, then it works.
I am testing with this website. Any help would be appreciated.
#Override
public void onRequestPermissionsResult(int requestCode,
String permissions[], int[] grantResults) {
switch (requestCode) {
case MY_PERMISSIONS_REQUEST_ACCESS_FINE_LOCATION: {
// If request is cancelled, the result arrays are empty.
if (grantResults.length > 0
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// permission was granted, yay! Do the
// contacts-related task you need to do.
myCallback.invoke(myOrigin, true, false);
} else {
// permission denied, boo! Disable the
// functionality that depends on this permission.
Log.d("WebView", "PERMISSION NOT GRANTED");
}
return;
} case MY_PERMISSIONS_REQUEST_RECORD_AUDIO: {
Log.d("WebView", "PERMISSION FOR AUDIO");
if (grantResults.length > 0
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// permission was granted, yay! Do the
// contacts-related task you need to do.
myRequest.grant(myRequest.getResources());
} else {
// permission denied, boo! Disable the
// functionality that depends on this permission.
}
}
// other 'case' lines to check for other
// permissions this app might request
}
}
and in my ChromeClient I have :
#Override
public void onPermissionRequest(final PermissionRequest request) {
myRequest = request;
for(String permission : request.getResources()) {
switch(permission) {
case "android.webkit.resource.AUDIO_CAPTURE": {
askForPermission(request.getOrigin().toString(), Manifest.permission.RECORD_AUDIO, MY_PERMISSIONS_REQUEST_RECORD_AUDIO);
break;
}
}
}
}
public void askForPermission(String origin, String permission, int requestCode) {
Log.d("WebView", "inside askForPermission for" + origin + "with" + permission);
if (ContextCompat.checkSelfPermission(getApplicationContext(),
permission)
!= PackageManager.PERMISSION_GRANTED) {
// Should we show an explanation?
if (ActivityCompat.shouldShowRequestPermissionRationale(thisActivity,
permission)) {
// Show an expanation to the user *asynchronously* -- don't block
// this thread waiting for the user's response! After the user
// sees the explanation, try again to request the permission.
} else {
// No explanation needed, we can request the permission.
ActivityCompat.requestPermissions(thisActivity,
new String[]{permission},
requestCode);
}
} else {
myRequest.grant(myRequest.getResources());
}
}

This turned out to be an issue with the permissions. Both of the following needs to be included in the manifest file.

Related

Java Android - Requesting multiple permissions but one doesn't get requested

So i'm trying to request both Location and Camera permissions from the user, and my app all works apart from the part where it has to request Location permissions from the user. The user never gets a request to access location. Is it even possible to request 2 different permissions and have onRequestPermissionsResults to handle them both in the same class?
#Override
public void onClick(View v) {
if (ContextCompat.checkSelfPermission(getApplicationContext(), Manifest.permission.ACCESS_FINE_LOCATION)
!= PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(
HomePageActivity.this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, REQUEST_CODE_LOCATION_PERMISSION
);
} else {
getCurrentLocation();
}
askCameraPermissions();
}
this is how it starts, then I think it goes here
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
switch (requestCode) {
case REQUEST_CODE_LOCATION_PERMISSION:
if (grantResults.length > 0) {
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
getCurrentLocation();
} else {
Toast.makeText(this, "Permission denied", Toast.LENGTH_LONG).show();
}
}
break;
case CAMERA_PERM_CODE:
//if both are true then user has granted requests
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
dispatchTakePictureIntent();
} else {
Toast.makeText(this, "Camera permission is required to Use camera.", Toast.LENGTH_SHORT).show();
}
break;
}
}
'''
except I believe this is where the application is doing something wrong. The camera request and permission works perfectly and I am able to continue and have my camera methods work. However when it comes to Location permissions, as i said, the user is never prompted to allow permissions, so I think something is going wrong here. Any help is appreciated, this is my first post so maybe formatting will be strewn with errors.
I have tried to post only relevant code. I will post more if requested
Rather then asking permission two times which is causing the problem you can actually ask it in a single time like
....
ActivityCompat.requestPermissions(
HomePageActivity.this,
new String[]{Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.CAMERA},
REQUEST_CODE_MULTIPLE_PERMISSION
);
....
if you still want to ask separate permission then you should ask after the first one result has arrived.
EDIT
while asking for access fine location you should also ask for coarse location

How to handle setResult in phone settings?

I cannot make this work, I have an application with a webview that requires permissions to access storage when downloading, I am trying that, when the user rejects permissions, my application tells them how to activate the permission by accessing the application settings.
Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS,
Uri.fromParts("package", getActivity().getPackageName(), null));
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivityForResult(intent, MY_PERMISSIONS_REQUEST_WRITE_EXTERNAL_STORAGE);
s
#Override
public void onRequestPermissionsResult(int requestCode,
String[] permissions, int[] grantResults) {
switch (requestCode) {
case MY_PERMISSIONS_REQUEST_WRITE_EXTERNAL_STORAGE: {
if (grantResults.length > 0
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
//Permission is granted
myWebView.loadUrl(urlDownload);
} else {
}
return;
}
case MY_PERMISSIONS_REQUEST_READ_EXTERNAL_STORAGE: {
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
openImageChooserActivity();
} else {
}
return;
}
// other 'case' lines to check for other
// permissions this app might request.
}
}
myWebView.loadUrl(urlDownload); this code snippet runs without problem when permission is granted from android alert but I can't control it if the user grants the permission from the settings.
Finally, a newbie question, I have seen several examples of similar codes that seem to work, but I do not understand how setResult is handled in the configurations because I do not have access to it, if for example MY_PERMISSIONS_REQUEST_WRITE_EXTERNAL_STORAGE = 101 how is it that android configurations know to put setResult (101) when user activates storage?

Android is asking each permission three times and app closes after permissions are granted

I am creating a simple applications in which I need READ_CONTACT and CALL_PHONE permissions. I have written below code.
After installation app asks permissions 3 times like this -
1 of 2 read contacts
2 of 2 call and manage phone
1 of 2 read contacts
2 of 2 call and manage phone
1 of 2 read contacts
2 of 2 call and manage phone
Also After granting these permissions app does't open. But when I open app again, it works fine and does not ask permissions again.
I have following code
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults) {
switch (requestCode) {
case MULTIPLE_REQUESTS: {
if (grantResults.length > 0) {
boolean contactPermission = grantResults[1] == PackageManager.PERMISSION_GRANTED;
boolean phonePermission = grantResults[0] == PackageManager.PERMISSION_GRANTED;
if (contactPermission && phonePermission) {
// write your logic here
} else {
Toast.makeText(this, "Read Contact & Call phone permissions are required", Toast.LENGTH_SHORT).show();
closeNow();
}
}
break;
}
}
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Here, thisActivity is the current activity
if (ContextCompat.checkSelfPermission(this, Manifest.permission.READ_CONTACTS)
+ ContextCompat.checkSelfPermission(this, Manifest.permission.CALL_PHONE)
!= PackageManager.PERMISSION_GRANTED) {
if (ActivityCompat.shouldShowRequestPermissionRationale
(this, Manifest.permission.READ_CONTACTS) ||
ActivityCompat.shouldShowRequestPermissionRationale
(this, Manifest.permission.CALL_PHONE)) {
} else {
// No explanation needed, we can request the permission.
ActivityCompat.requestPermissions(this,
new String[]{Manifest.permission.READ_CONTACTS, Manifest.permission.CALL_PHONE},
MULTIPLE_REQUESTS);
}
}
setContentView(R.layout.activity_contact_app_bar);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
toolbar.setTitle(getTitle());
}
The permission should be asked when you invoke respective functionality .
I am suspecting the app is getting closed due to closeNow is called .
You need to debug below code .
if (grantResults.length > 0) {
boolean contactPermission = grantResults[1] == PackageManager.PERMISSION_GRANTED;
boolean phonePermission = grantResults[0] == PackageManager.PERMISSION_GRANTED;
if (contactPermission && phonePermission) {
// write your logic here
} else {
Toast.makeText(this, "Read Contact & Call phone permissions are required", Toast.LENGTH_SHORT).show();
closeNow();
}
}
try This Code
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
ActivityCompat.requestPermissions(this,
new String[]{ Manifest.permission.READ_CONTACTS, Manifest.permission.CALL_PHONE},
MULTIPLE_REQUESTS);
}
add above code where you want permission
#Override
public void onRequestPermissionsResult(int requestCode,
String permissions[], int[] grantResults) {
switch (requestCode) {
case MULTIPLE_REQUESTS: {
for (int i = 0; i < grantResults.length; i++) {
if (grantResults[i] !=
PackageManager.PERMISSION_GRANTED) {
// Permission has been denied by user
} else {
// Permission has been granted by user
}
return;
}
}
}
}

Android granted runtime permissions to my app without asking

I'm trying to test the Runtime Permissions specifically for Android sdk > 23. But my app is being granted permissions automatically without asking.
Note : I'm using sdk version 24. Here's a snippet of code I'm using:
public void onCalendarClick(View view) {
if(ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_CALENDAR) == PackageManager
.PERMISSION_DENIED) {
if(ActivityCompat.shouldShowRequestPermissionRationale(this,Manifest.permission.WRITE_CALENDAR)) {
//Display Explanation to the user
//For granting permissions to the app.
}
else {
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_CALENDAR}, CALLBACK_CALENDAR);
}
}
}
#Override
public void onRequestPermissionsResult(int resultCode, String permission[], int grantResults[]) {
if(grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
Toast toast;
switch (resultCode) {
case CALLBACK_CALENDAR : toast = Toast.makeText(this,"Calendar Permission Granted!!",Toast.LENGTH_LONG);
toast.show(); break;
//Other Cases
}
}
}
When I click on Calendar Button, the onCalendarClick() method run, but without asking for any permission, the App directly displays Calendar Permission Granted!! toast. In the App's settings, there are though No Permissions Granted/Requested being displayed.
Am I missing something or doing it the wrong way? Thanks for any help.
So here it is. I found out that for android sdk > 22, though Runtime permissions are added programatically for your application but you still need to declare your app's permission in the AndroidManifest.xml file. So, after adding the code:
<uses-permission android:name="android.permission.WRITE_CALENDAR"/>
in the AndroidManifest.xml, the app asks for the permission and it's finally working.
For more information : Android M permission dialog not showing
.Thanks to all for helping me out )
You are missing the order of the code. Check this:
#Override
public void onRequestPermissionsResult(int requestCode,
String permissions[], int[] grantResults) {
switch (requestCode) {
case CALLBACK_CALENDAR: {
// If request is cancelled, the result arrays are empty.
if (grantResults.length > 0
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// permission was granted, yay! Do the
// calendar-related task you need to do.
} else {
// permission denied, boo! Disable the
// functionality that depends on this permission.
}
return;
}
// other 'case' lines to check for other
// permissions this app might request
}
}
There is a little difference, you are asking if the permission is granted even before you know you are talking about CALENDAR permissions. So, you should first check if the current permission response is the one you want, and then check if the permission is granted.
Source: https://developer.android.com/training/permissions/requesting.html

Remove Run Time Permission for current location in Marshmallow

I am trying to create an app. App asking every time location Access in Marsh Mallow, always when we open the app. Please suggested the best Process for solve my problem. using following code-
#Override
public void onMapReady(GoogleMap googleMap) {
mMap = googleMap;
//for marshmallow
final int LOCATION_PERMISSION_REQUEST_CODE = 100;
ActivityCompat.requestPermissions(this, new String[]{android.Manifest.permission.ACCESS_FINE_LOCATION, android.Manifest.permission.ACCESS_COARSE_LOCATION},
LOCATION_PERMISSION_REQUEST_CODE);
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
return;
}
mMap.setMyLocationEnabled(true);
buildGoogleApiClient();
mGoogleApiClient.connect();
}
thanks.
Try writting in if else, if permission is not given ask for it or else do what you want to do.
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if(checkSelfPermission(Manifest.permission.Manifest.permission.ACCESS_FINE_LOCATION)
!= PackageManager.PERMISSION_GRANTED) {
requestPermissions(new String[]{Manifest.permission.Manifest.permission.ACCESS_FINE_LOCATION},
LOCATION_PERMISSION_REQUEST_CODE);
}
} else {
// do your stuff
}
and also override onRequestPermissionsResult and apply your code afer you have granted permissions.
Please reflect your code yourself. Think about the order of requesting and checking the permission. You should check the permission before you're asking for it. This makes sure to prevent asking if the permission was already granted...
Have a look at the example provided by Google and consider adapting this example for your needs:
// Here, thisActivity is the current activity
if (ContextCompat.checkSelfPermission(thisActivity, Manifest.permission.READ_CONTACTS) != PackageManager.PERMISSION_GRANTED) {
// Should we show an explanation?
if (ActivityCompat.shouldShowRequestPermissionRationale(thisActivity, Manifest.permission.READ_CONTACTS)) {
// Show an expanation to the user *asynchronously* -- don't block
// this thread waiting for the user's response! After the user
// sees the explanation, try again to request the permission.
} else {
// No explanation needed, we can request the permission.
ActivityCompat.requestPermissions(thisActivity,
new String[]{Manifest.permission.READ_CONTACTS},
MY_PERMISSIONS_REQUEST_READ_CONTACTS);
// MY_PERMISSIONS_REQUEST_READ_CONTACTS is an
// app-defined int constant. The callback method gets the
// result of the request.
}
}
Additionally you should overwrite the callback method onRequestPermissionsResult to handle the user's grantResults.
// Callback with the request from calling requestPermissions(...)
#Override
public void onRequestPermissionsResult(int requestCode,
#NonNull String permissions[],
#NonNull int[] grantResults) {
// Make sure it's our original READ_CONTACTS request
if (requestCode == READ_CONTACTS_PERMISSIONS_REQUEST) {
if (grantResults.length == 1 &&
grantResults[0] == PackageManager.PERMISSION_GRANTED) {
Toast.makeText(this, "Read Contacts permission granted", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(this, "Read Contacts permission denied", Toast.LENGTH_SHORT).show();
}
} else {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
}
}
Edit:
This is thecode which you should change
ActivityCompat.requestPermissions(this, new String[] {android.Manifest.permission.ACCESS_FINE_LOCATION, android.Manifest.permission.ACCESS_COARSE_LOCATION},
LOCATION_PERMISSION_REQUEST_CODE);
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
return;
}
For further reading have a look at the article Understanding App Permissions

Categories