Settings app for custom implementation of an Android Service - android

I implemented a TTS service for Android which works as expected. I can also manage its settings via the Text To Speech section of the Android Settings app.
However, on a Pixel tablet running Android 8.1, the settings app crashes for my TTS implementation with the following exception:
2019-02-25 10:45:46.396 5816-5816/? E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.android.settings, PID: 5816
java.lang.NullPointerException: Attempt to invoke virtual method 'boolean android.content.Intent.migrateExtraStreamToClipData()' on a null object reference
at android.app.Instrumentation.execStartActivity(Instrumentation.java:1742)
at android.app.Activity.startActivityForResult(Activity.java:5168)
at android.app.Activity.startActivityFromFragment(Activity.java:5144)
at android.app.Activity$HostCallbacks.onStartActivityFromFragment(Activity.java:7690)
at android.app.Fragment.startActivity(Fragment.java:1075)
at android.app.Fragment.startActivity(Fragment.java:1054)
at com.android.settings.tts.TextToSpeechSettings.onGearClick(TextToSpeechSettings.java:780)
at com.android.settings.widget.GearPreference.onClick(GearPreference.java:71)
at android.view.View.performClick(View.java:6294)
at android.view.View$PerformClick.run(View.java:24770)
at android.os.Handler.handleCallback(Handler.java:790)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:164)
at android.app.ActivityThread.main(ActivityThread.java:6494)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:438)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:807)
I could not find any docs of what setting implementation I am required to implement for the Service. Any hint?

What I was missing is a metadata which points to the settings activity of my service (a class that extends PreferenceActivity, EngineSettings here):
In AndroidManifest.xml:
<service
android:name=".MyTtsService"
android:label="#string/app_name">
<intent-filter>
<action android:name="android.intent.action.TTS_SERVICE" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
<meta-data android:name="android.speech.tts" android:resource="#xml/tts_engine" />
</service>
And tts_engine.xml:
<?xml version="1.0" encoding="utf-8"?>
<tts-engine xmlns:android="http://schemas.android.com/apk/res/android"
android:settingsActivity="com.mytts.EngineSettings" />

Related

#react-native-community/voice or react-native-voice / voice gives exception java.lang.NullPointerException at com.wenkesj.voice.VoiceModule.onResults

#react-native-community/voice was working smoothly but recently it gives following error
java.lang.NullPointerException: Attempt to invoke virtual method 'java.util.Iterator java.util.ArrayList.iterator()' on a null object reference
at com.wenkesj.voice.VoiceModule.onResults(VoiceModule.java:347)
at android.speech.SpeechRecognizer$InternalListener$1.handleMessage(SpeechRecognizer.java:457)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:201)
at android.app.ActivityThread.main(ActivityThread.java:6810)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:547)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:873)
try to add this to AndroidManifest.xml:
<queries>
<intent>
<action android:name="android.speech.RecognitionService" />
</intent>
</queries>
In my case I got this fixed in my Speech To Text component by removing EXTRA_SPEECH_INPUT.. parameters which is passed when starting Voice Recognition.
Changing my code from this
Voice.start('en-US', {
EXTRA_SPEECH_INPUT_COMPLETE_SILENCE_LENGTH_MILLIS: 5000,
EXTRA_SPEECH_INPUT_MINIMUM_LENGTH_MILLIS: 5000,
EXTRA_SPEECH_INPUT_POSSIBLY_COMPLETE_SILENCE_LENGTH_MILLIS: 5000,
});
to this
Voice.start('en-US')
Well, i dont know if this will work to you, but in my case I have added this in androidManifest:
<package android:name="com.google.android.googlequicksearchbox"/>

Runtime exception when launching an Activity from Chrome

I have configured one of my activities in my app to be be opened using a deep link like so:
<activity
android:name=".ui.barcodescanner.BarcodeScannerActivity"
android:label="#string/app_name">
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data
android:host="com.company"
android:scheme="http"
android:pathPrefix="/myapp"/>
</intent-filter>
</activity>
This works as expected (my app launches with the correct activity) when chrome redirects to http://com.mycompany/myap on an API 27 Pixel 2 XL emulator. But I get the following error when I run it on my API 29 OnePlus 6:
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.company.android.myapp/com.company.android.myapp.ui.login.IONLoginActivity}: android.util.AndroidRuntimeException: Calling startActivity() from outside of an Activity context requires the FLAG_ACTIVITY_NEW_TASK flag. Is this really what you want?
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3037)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3172)
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:78)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:108)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:68)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1906)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:193)
at android.app.ActivityThread.main(ActivityThread.java:6863)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:537)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)
Caused by: android.util.AndroidRuntimeException: Calling startActivity() from outside of an Activity context requires the FLAG_ACTIVITY_NEW_TASK flag. Is this really what you want?
at android.app.ContextImpl.startActivity(ContextImpl.java:915)
at android.app.ContextImpl.startActivity(ContextImpl.java:891)
at android.content.ContextWrapper.startActivity(ContextWrapper.java:379)
at com.infor.authentication.AuthenticationManager.loadWebView(AuthenticationManager.java:712)
at com.infor.authentication.AuthenticationManager.showAuthenticationDialog(AuthenticationManager.java:1810)
at com.infor.authentication.AuthenticationManager.validateValuesAndStoreValues(AuthenticationManager.java:512)
at com.infor.authentication.AuthenticationManager.initiateAuthentication(AuthenticationManager.java:460)
at com.company.android.myapp.ui.login.IONLoginViewModel.authenticateWithION(IONLoginViewModel.java:26)
at com.company.android.myapp.ui.login.IONLoginActivity.onCreate(IONLoginActivity.java:36)
at android.app.Activity.performCreate(Activity.java:7149)
at android.app.Activity.performCreate(Activity.java:7140)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1288)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3017)
Why is this?

COSU: Cannot find Activity any more after pin and then restart

I'm developing an App that can be Screen Pinned aka Corporate Owned Single Use aka Lock Task Mode.
If I pin it and then:
I close it (killing it) and then I launch it again
or after some code modification in android studio and then perform Run
restart after pin and unpin
I get the following error:
[homtom-ht3_pro-0123456789ABCDEF]: E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.xx.yyy, PID: 7928
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.xx.yyy/com.xx.yyy.activities.LauncherActivity}: android.content.ActivityNotFoundException: Unable to find explicit activity class {com.xx.yyy/com.xx.yy.activities.StartActivity}; have you declared this activity in your AndroidManifest.xml?
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2534)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2614)
at android.app.ActivityThread.access$800(ActivityThread.java:178)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1470)
at android.os.Handler.dispatchMessage(Handler.java:111)
at android.os.Looper.loop(Looper.java:194)
at android.app.ActivityThread.main(ActivityThread.java:5643)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:960)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:755)
Caused by: android.content.ActivityNotFoundException: Unable to find explicit activity class {com.xx.yyy/com.xx.yyy.activities.StartActivity}; have you declared this activity in your AndroidManifest.xml?
at android.app.Instrumentation.checkStartActivityResult(Instrumentation.java:1788)
at android.app.Instrumentation.execStartActivity(Instrumentation.java:1512)
at android.app.Activity.startActivityForResult(Activity.java:3809)
at android.support.v4.app.BaseFragmentActivityJB.startActivityForResult(BaseFragmentActivityJB.java:50)
at android.support.v4.app.FragmentActivity.startActivityForResult(FragmentActivity.java:79)
at android.app.Activity.startActivityForResult(Activity.java:3760)
at android.support.v4.app.FragmentActivity.startActivityForResult(FragmentActivity.java:859)
at android.app.Activity.startActivity(Activity.java:4090)
at android.app.Activity.startActivity(Activity.java:4058)
at com.xx.yyy.activities.LauncherActivity.onCreate(LauncherActivity.java:16)
at android.app.Activity.performCreate(Activity.java:6099)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1112)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2481)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2614) 
at android.app.ActivityThread.access$800(ActivityThread.java:178) 
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1470) 
at android.os.Handler.dispatchMessage(Handler.java:111) 
at android.os.Looper.loop(Looper.java:194) 
at android.app.ActivityThread.main(ActivityThread.java:5643) 
at java.lang.reflect.Method.invoke(Native Method) 
at java.lang.reflect.Method.invoke(Method.java:372) 
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:960) 
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:755) 
This is my Manifest:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.xx.yyy">
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:supportsRtl="true"
android:theme="#style/AppTheme">
<receiver
android:name=".receivers.DeviceAdminReceiver"
android:description="#string/app_name"
android:label="#string/app_name"
android:permission="android.permission.BIND_DEVICE_ADMIN">
<meta-data
android:name="android.app.device_admin"
android:resource="#xml/device_admin_receiver" />
<intent-filter>
<action android:name="android.intent.action.DEVICE_ADMIN_ENABLED" />
<action android:name="android.intent.action.PROFILE_PROVISIONING_COMPLETE" />
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
<activity android:name=".activities.LauncherActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name=".activities.StartActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.HOME" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
</application>
</manifest>
If I don't ever pin the app I can restart/upgrade&run it many times I want.
The nice thing is that is not even possible to uninstall the app because it has been configured as Device Owner, and so, it cannot be uninstalled unless a factory reset.
I dont understand how is possible that my activity disappears after an app restart. Can be something related to the intent category or action?
If anyone else encountered this behavior can tell me I will submit an issue to the bug report site.
Thanks.
EDIT 18/3
I think maybe this is happening because at a certain point, I kill the home category activity that in my case is the missing StartActivity in question, and it is not restarted even if I restart the app.
Found the solution in my COSU disable pinning implementation, I was doing:
PackageManager mPackageManager = getApplicationContext().getPackageManager();;
mPackageManager.setComponentEnabledSetting(
new ComponentName(getApplicationContext(), StartActivity.class),
PackageManager.COMPONENT_ENABLED_STATE_DISABLED,
PackageManager.DONT_KILL_APP);
to disable the pinning on device boot, but this actually disable the specified component.
The correct implementation would be:
PackageManager mPackageManager = getApplicationContext().getPackageManager();;
mPackageManager.setComponentEnabledSetting(
new ComponentName(getApplicationContext(), StartActivity.class),
PackageManager.COMPONENT_ENABLED_STATE_DEFAULT,
PackageManager.DONT_KILL_APP);

Using Broadcast Receiver with Direct Boot in Android Nougat (7.0)

I am working with the new DirectBoot feature in Android 7.0 and I am trying to determine when the phone is still locked after a restart and in Direct Boot mode. To do this, I have implemented a BroadcastReceiver which I defined in the Manifest.
My understanding is that when a phone is restarted, it sends out an ACTION_LOCKED_BOOT_COMPLETED broadcast when it finishes booting but prior to the user entering their PIN. When the PIN is entered and phone becomes unlocked, an ACTION_BOOT_COMPLETED broadcast is sent. My Receiver works fine if I define its intent-filter to be ACTION_BOOT_COMPLETED, but as soon as I add LOCKED_BOOT_COMPLETED, I get Fatal error messages like this upon restarting the phone saying it couldn't instantiate my receiver:
01-06 07:25:30.917 3872-3872/? E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.nougatencryptiontest, PID: 3872
java.lang.RuntimeException: Unable to instantiate receiver com.example.nougatencryptiontest.MyReceiver: java.lang.ClassNotFoundException: Didn't find class "com.example.nougatencryptiontest.MyReceiver" on path: DexPathList[[zip file "/data/app/com.example.nougatencryptiontest-1/base.apk"],nativeLibraryDirectories=[/data/app/com.example.nougatencryptiontest-1/lib/arm64, /system/lib64, /vendor/lib64]]
at android.app.ActivityThread.handleReceiver(ActivityThread.java:3021)
at android.app.ActivityThread.-wrap18(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1561)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6119)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:886)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:776)
Caused by: java.lang.ClassNotFoundException: Didn't find class "com.example.nougatencryptiontest.MyReceiver" on path: DexPathList[[zip file "/data/app/com.example.nougatencryptiontest-1/base.apk"],nativeLibraryDirectories=[/data/app/com.example.nougatencryptiontest-1/lib/arm64, /system/lib64, /vendor/lib64]]
at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:56)
at java.lang.ClassLoader.loadClass(ClassLoader.java:380)
at java.lang.ClassLoader.loadClass(ClassLoader.java:312)
at android.app.ActivityThread.handleReceiver(ActivityThread.java:3016)
at android.app.ActivityThread.-wrap18(ActivityThread.java) 
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1561) 
at android.os.Handler.dispatchMessage(Handler.java:102) 
at android.os.Looper.loop(Looper.java:154) 
at android.app.ActivityThread.main(ActivityThread.java:6119) 
at java.lang.reflect.Method.invoke(Native Method) 
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:886) 
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:776) 
I'm not sure why this DexPathList issue occurs only when I change my Receiver's intent-filter from BOOT_COMPLETED to LOCKED_BOOT_COMPLETED. Below is my Manifest that does not work (however, if I change intent-filter to just be BOOT_COMPLETED, application doesn't crash and receiver works perfectly fine!):
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.nougatencryptiontest">
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
<application
android:allowBackup="true"
android:directBootAware="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:supportsRtl="true"
android:theme="#style/AppTheme">
<receiver android:name=".MyReceiver"
android:exported="true"
android:directBootAware="true">
<!-- Listening the BOOT_COMPLETED action for legacy pre-N devices -->
<intent-filter>
<action android:name="android.intent.action.LOCKED_BOOT_COMPLETED" />
</intent-filter>
</receiver>
<activity android:name=".MainActivity"
android:directBootAware="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
Any advice or pointers would be greatly appreciated.

Permission Denial when onMessageReceived should be called

I'm following this tutorial and got a WearableListenerService. I just implemented the onMessageReceived method and didn't change anything else.
The entry for the service looks like this:
<service android:name=".WearableRemoteCommandListener"
android:permission="android.permission.BIND_NOTIFICATION_LISTENER_SERVICE"
android:enabled="true"
android:exported="true">
<intent-filter>
<action android:name="com.google.android.gms.wearable.BIND_LISTENER"></action>
</intent-filter>
</service>
The application element contains this meta-data element:
<meta-data
android:name="com.google.android.gms.version"
android:value="#integer/google_play_services_version" />
But when I send a message to the wearable I get this security exception:
06-08 21:15:41.337 579-842/? W/ActivityManager﹕ Permission Denial: Accessing service ComponentInfo{net.bplaced.schlingel.wearabletest1/net.bplaced.schlingel.anmosela.WearableRemoteCommandListener} from pid=822, uid=10009 requires android.permission.BIND_NOTIFICATION_LISTENER_SERVICE
06-08 21:15:41.437 822-940/? W/WearableService﹕ ensureBindStarted: Permission denied connecting to net.bplaced.schlingel.anmosela.WearableRemoteCommandListener
java.lang.SecurityException: Not allowed to bind to service Intent { act=com.google.android.gms.wearable.BIND_LISTENER cmp=net.bplaced.schlingel.wearabletest1/net.bplaced.schlingel.anmosela.WearableRemoteCommandListener }
at android.app.ContextImpl.bindServiceCommon(ContextImpl.java:1793)
at android.app.ContextImpl.bindService(ContextImpl.java:1757)
at android.content.ContextWrapper.bindService(ContextWrapper.java:539)
at com.google.android.gms.wearable.service.t.b(SourceFile:1157)
at com.google.android.gms.wearable.service.t.a(SourceFile:1099)
at com.google.android.gms.wearable.service.t.handleMessage(SourceFile:1077)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:135)
at android.os.HandlerThread.run(HandlerThread.java:61)
I tried to add the exported and enabled attribute, restarted the wearable but the exception happens again. Is there a permission missing? What is wrong with my setup?
get rid of this line
android:permission="android.permission.BIND_NOTIFICATION_LISTENER_SERVICE"
from the documentation
Must be required by an NotificationListenerService, to ensure that
only the system can bind to it.

Categories

Resources