I have an app where I can connect an external biometric reader to the tablet. Everything works fine, but only on API 28.
When I switch to api 30, required by the play store, the app stops working when it should ask for permission. the application is then closed. How can I grant permission correctly?
This is the error displayed:
/DBG ( 4805): UsbEnumDevices(): fn: 0x71,ctx: 0x17e2
F/example.palchi( 4805): java_vm_ext.cc:579] JNI DETECTED ERROR IN APPLICATION: JNI GetArrayLength called with pending exception java.lang.SecurityException: User has not given 10569/com.example.palchik permission to access device /dev/bus/usb/001/002
The method I use is this:
if (call.method.equals("checkOrRequestPermissions")) {
try {
PendingIntent mPermissionIntent;
mPermissionIntent = PendingIntent.getBroadcast(appContext, 0, new Intent(ACTION_USB_PERMISSION), 0);
boolean checkResult = DPFPDDUsbHost.DPFPDDUsbCheckAndRequestPermissions(appContext, mPermissionIntent, reader.GetDescription().name);
result.success(checkResult);
} catch (DPFPDDUsbException e) {
result.error("2", "USB exception: " + e.getMessage(), "");
return;
}
}
And I do it like this in flutter:
static Future<bool> checkOrRequestPermissions(BuildContext context) async {
return await platform
.invokeMethod('checkOrRequestPermissions')
.catchError((e) {
if (e is PlatformException) {
if (e.code == "0") {
alertaController.setTitulo(
"error");
leitorInexistente(context);
}else if(e.code == "1"){
alertaController.setTitulo(
"error");
leitorInexistente(context);
}
} else {
print('ERROR $e');
}
});
}
Thanks if anyone can help me!
Related
I'm trying to build an app which integrates the Spotify App Remote SDK. However, when I try to connect to Spotify using the SDK, the CouldNotFindSpotifyApp error is thrown even though the Spotify app is installed on the device.
I found other solutions on stackoverflow that asked me to add a queries in the manifest
`
<queries>
<package android:name="com.spotify.music" />
</queries>
`
But that doesn't work and gives me the same error
I tried to connect to the spotify api using this code:
`
ConnectionParams connectionParams =
new ConnectionParams.Builder(CLIENT_ID)
.setRedirectUri(REDIRECT_URI)
.showAuthView(true)
.build();
SpotifyAppRemote.connect(this, connectionParams,
new Connector.ConnectionListener() {
#Override
public void onConnected(SpotifyAppRemote spotifyAppRemote) {
mSpotifyAppRemote = spotifyAppRemote;
Log.d("MainActivity", "Connected! Yay!");
// Now you can start interacting with App Remote
connected();
}
#Override
public void onFailure(Throwable error) {
if (error instanceof NotLoggedInException || error instanceof UserNotAuthorizedException) {
Log.d("MainActivity", "Other Error");
} else if (error instanceof CouldNotFindSpotifyApp) {
Log.d("MainActivity", "User Not Found");
}
}
});
`
And instead of connecting it gave me an error
CouldNotFindSpotifyApp
I'm about to launch my app.
I wrote a code for inApp immediate update since I want everyone who downloaded my app to update when I upload updated version.
I wonder if this code will work without causing any problem.
mAppUpdateManager = AppUpdateManagerFactory.create( this );
Task<AppUpdateInfo> appUpdateInfoTask = mAppUpdateManager.getAppUpdateInfo();
appUpdateInfoTask.addOnSuccessListener( new OnSuccessListener<AppUpdateInfo>() {
#Override
public void onSuccess(AppUpdateInfo result) {
if (result.updateAvailability() == UpdateAvailability.UPDATE_AVAILABLE
&& result.isUpdateTypeAllowed( AppUpdateType.IMMEDIATE )){
try {
mAppUpdateManager.startUpdateFlowForResult( result, AppUpdateType.IMMEDIATE, MainActivity.this, MY_REQUEST_CODE );
} catch (IntentSender.SendIntentException e) {
Log.e( "AppUpdater", "AppUpdateManager Error", e );
e.printStackTrace();}
}else {}
}
} );
Please mention the issue you're facing. Meanwhile you can use this library to introduce in-app updates in your app. It's pretty simple to use and tested properly.
https://github.com/sohanzz/Easy-InApp-Updater
I'm trying to implement automating player sign in to Google Play games in my Android app. Firstly, as mentioned here, I try to sign in silently:
#Override
protected void onResume() {
super.onResume();
signInSilently();
}
private void signInSilently() {
mGoogleSignInClient.silentSignIn().addOnCompleteListener(this, task -> {
if (task.isSuccessful())
//everything ok
else {
final ApiException exception = (ApiException) task.getException();
if (BuildConfig.DEBUG)
Log.d(TAG, "Silent Sign In failure: ", exception);
if (exception.getStatusCode() == CommonStatusCodes.SIGN_IN_REQUIRED)
startSignInIntent();
}
});
Every time I got an exception with code 4 (CommonStatusCodes.SIGN_IN_REQUIRED). So in this case I try to sign in with ui:
private void startSignInIntent() {
startActivityForResult(mGoogleSignInClient.getSignInIntent(), RC_SIGN_IN);
}
#Override
protected void onActivityResult(int request, int response, Intent data) {
super.onActivityResult(request, response, data);
if (request == RC_SIGN_IN) {
final GoogleSignInResult result = Auth.GoogleSignInApi.getSignInResultFromIntent(data);
if (result.isSuccess()) {
// everything is ok, get account from result
} else if (result.getStatus().hasResolution()) {
resolveManually(result.getStatus());
} else {
String message = result.getStatus().getStatusMessage();
if (BuildConfig.DEBUG)
Log.d(TAG, "status code" + result.getStatus().getStatusCode());
if (message == null || message.isEmpty()) {
message = "other error";
}
new AlertDialog.Builder(this).setMessage(message)
.setNeutralButton(android.R.string.ok, null).show();
}
}
}
And here everytime I get message with other error! The status code is again 4 (CommonStatusCodes.SIGN_IN_REQUIRED). How can I get this code when I try to sign in using intent? So, my app are in infinite loop because onResume is called everytime my activity loads after receiving a result, and everytime the status code is CommonStatusCodes.SIGN_IN_REQUIRED. So, where is the problem?
In Google samples there is no information how can I handle automatic sign in, only manual with sign in buttons. But google recommends to use automating sign in. Please help anybody to understand what is wrong here.
You must not start the login screen from your onResume method. It is a silent login which works if the user wants it (by tapping a button). That's why the examples show it only this way.
There was wrong OAuth 2.0 client ID for the debug version of my app! Don't know why there is SIGN_IN_REQUIRED status code in this situation, it is really confusing!
I'm trying to implement an app that listens to microphone input (specifically, breathing), and presents data based on it. I'm using the Android class AudioRecord, and when trying to instantiate AudioRecord I get three errors.
AudioRecord: AudioFlinger could not create record track, status: -1
AudioRecord-JNI: Error creating AudioRecord instance: initialization check failed with status -1.
android.media.AudioRecord: Error code -20 when initializing native AudioRecord object.
I found this excellent thread: AudioRecord object not initializing
I have borrowed the code from the accepted answer that tries all sample rates, audio formats and channel configurations to try to solve the problem, but it didn't help, I get the above errors for all settings. I have also added a call to AudioRecord.release() on several places according to one of the answers in the thread but it made no difference.
This is my code:
import android.media.AudioFormat;
import android.media.AudioRecord;
import android.media.MediaRecorder;
import android.util.Log;
public class SoundMeter {
private AudioRecord ar = null;
private int minSize;
private static int[] mSampleRates = new int[] { 8000, 11025, 22050, 32000, 44100 };
public boolean start() {
ar = findAudioRecord();
if(ar != null){
ar.startRecording();
return true;
}
else{
Log.e("SoundMeter", "ERROR, could not create audio recorder");
return false;
}
}
public void stop() {
if (ar != null) {
ar.stop();
ar.release();
}
}
public double getAmplitude() {
short[] buffer = new short[minSize];
ar.read(buffer, 0, minSize);
int max = 0;
for (short s : buffer)
{
if (Math.abs(s) > max)
{
max = Math.abs(s);
}
}
return max;
}
public AudioRecord findAudioRecord() {
for (int rate : mSampleRates) {
for (short audioFormat : new short[] { AudioFormat.ENCODING_PCM_8BIT, AudioFormat.ENCODING_PCM_16BIT, AudioFormat.ENCODING_PCM_FLOAT }) {
for (short channelConfig : new short[] { AudioFormat.CHANNEL_IN_MONO, AudioFormat.CHANNEL_IN_STEREO }) {
try {
Log.d("SoundMeter", "Attempting rate " + rate + "Hz, bits: " + audioFormat + ", channel: " + channelConfig);
int bufferSize = AudioRecord.getMinBufferSize(rate, channelConfig, audioFormat);
if (bufferSize != AudioRecord.ERROR_BAD_VALUE) {
// check if we can instantiate and have a success
Log.d("SoundMeter", "Found a supported bufferSize, attempting to instantiate");
AudioRecord recorder = new AudioRecord(MediaRecorder.AudioSource.DEFAULT, rate, channelConfig, audioFormat, bufferSize);
if (recorder.getState() == AudioRecord.STATE_INITIALIZED){
minSize = bufferSize;
return recorder;
}
else
recorder.release();
}
} catch (Exception e) {
Log.e("SoundMeter", rate + " Exception, keep trying.", e);
}
}
}
}
return null;
}
}
I have also added the
<uses-permission android:name="android.permission.RECORD_AUDIO"/>
tag to my manifest file, as a child to the manifest tag and a sibling to the application tag according to one of the other answers in the thread mentioned above. I have rebuilt the project after adding this tag.
These are the solutions I find when googling the problem, but they unfortunately don't seem to do it for me.
I am debugging on my Nexus 5 phone (not an emulator). These errors appear upon calling the contructor of AudioRecord. I have rebooted my phone several times to try to release the microphone, to no avail. The project is based on Android 4.4, and my phone is currently running Android 6.0.1.
Would highly appreciate some tips on what else I can try, what I could have missed. Thank you!
I found the answer myself. It had to do with permissions.
The problem was that I am running API version 23 (Android 6.0.1) on my phone, which no longer uses only the manifest file to handle permissions. From version 23, permissions are granted in run-time instead. I added a method that makes sure to request the permission in run-time, and when I had allowed it once on my phone, it worked.
private void requestRecordAudioPermission() {
//check API version, do nothing if API version < 23!
int currentapiVersion = android.os.Build.VERSION.SDK_INT;
if (currentapiVersion > android.os.Build.VERSION_CODES.LOLLIPOP){
if (ContextCompat.checkSelfPermission(this, Manifest.permission.RECORD_AUDIO) != PackageManager.PERMISSION_GRANTED) {
// Should we show an explanation?
if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.RECORD_AUDIO)) {
// 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(this, new String[]{Manifest.permission.RECORD_AUDIO}, 1);
}
}
}
}
#Override
public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
switch (requestCode) {
case 1: {
// 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.
Log.d("Activity", "Granted!");
} else {
// permission denied, boo! Disable the
// functionality that depends on this permission.
Log.d("Activity", "Denied!");
finish();
}
return;
}
// other 'case' lines to check for other
// permissions this app might request
}
}
I then call requestRecordAudioPermission() from the onCreate() method in my main activity before creating the AudioRecord.
I am attempting to use AccountManager to get a token for an installed Google account. When I call getResult() on my AccountManagerFuture object, I get the "Couldn't sign in" screen on the device (which further says, "There was a probem communicating with Google servers. Try again later.). I checked that a network connection is available prior to calling this method. I also checked on the device that I am able to access, e.g. google.com, in the browser. Here is the code for my AccountManagerCallback:
amf = accMgr.getAuthToken(account, authTokenType, null, true,
new AccountManagerCallback<Bundle>() {
public void run(AccountManagerFuture<Bundle> arg0) {
Bundle result;
Intent i;
String token;
try {
result = arg0.getResult();
if (result.containsKey(AccountManager.KEY_INTENT)) {
i = (Intent)result.get(AccountManager.KEY_INTENT);
if (i.toString().contains("GrantCredentialsPermissionActivity")) {
// Will have to wait for the user to accept
// the request therefore this will have to
// run in a foreground application
cbt.startActivity(i);
} else {
cbt.startActivity(i);
}
token = (String)result.get(AccountManager.KEY_AUTHTOKEN);
} else {
token = (String)result.get(AccountManager.KEY_AUTHTOKEN);
}
} catch (OperationCanceledException e) {
e.printStackTrace();
} catch (AuthenticatorException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}, handler);
Also, these entries in LogCat might be helpful:
08-02 15:51:00.911: I/GLSUser(10134): GLS error: Unknown XXXX#gmail.com com.google
08-02 15:51:00.911: V/GoogleLoginService(10134): Returning error intent with: ComponentInfo{com.google.android.gsf.login/com.google.android.gsf.login.LoginActivity}
08-02 15:51:03.294: I/ActivityManager(324): START {cat=[XXXX#gmail.com] flg=0x10000000 cmp=com.google.android.gsf.login/.LoginActivity (has extras) u=0} from pid 11147
(Note: Actual gmail account name removed to avoid spam.)
Are you generating a signed APK? If you don't generate a signed APK (e.g., if you just hit "run app") you won't be able to take advantage of registered Google accounts on the device. So you'll have to hit "login with other" and login the roundabout way.
(Disclaimer: I didn't try to run your code, but it sounds like an issue I ran into earlier.)