I have need to start android foreground service, and launch activity from that service on device boot. I have extensively searched web and stackoverflow and tried different suggestions but it is very strange that I can not make this functionality work.
I can not understand what I am doing wrong.
Below is the code from my project and the content of manifest file.
what I am doing wrong and how to solve it, the functionality to work on most android devices?
This is my AndroidManifest.xml:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="kor.location.tracker">
<uses-permission android:name="android.permission.INTERNET" ></uses-permission>
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<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/AppTheme">
<receiver android:name="kor.location.tracker.AutoStart">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
<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>
<service android:enabled="true"
android:name="kor.location.tracker.WorkerService"
android:exported="true"
android:permission="android.permission.BIND_JOB_SERVICE"
/>
</application>
</manifest>
This is my Austostart.java:
package kor.location.tracker;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.os.Build;
import android.util.Log;
import android.widget.Toast;
public class AutoStart extends BroadcastReceiver
{
#Override
public void onReceive(Context context, Intent arg1)
{
try {
System.out.println("test1");
if (Intent.ACTION_BOOT_COMPLETED.equals(arg1.getAction())) {
System.out.println("test2");
WorkerService.enqueueWork(context, new Intent());
System.out.println("test3");
}
}catch(Exception ex) {
Toast.makeText(context, ex.getMessage(), Toast.LENGTH_LONG).show();
}
/*
Intent intent = new Intent(context, WorkerService.class);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
context.startForegroundService(intent);
} else {
context.startService(intent);
}
Log.i("Autostart", "started");
*/
}
}
This is my service class WorkerService.java:
package kor.location.tracker;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.os.IBinder;
import android.util.Log;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.core.app.JobIntentService;
public class WorkerService extends JobIntentService
{
public static void enqueueWork(Context context, Intent work) {
enqueueWork(context, WorkerService.class, 104501, work);
}
/*
private static final String TAG = "MyService";
#Override
public IBinder onBind(Intent intent) {
return null;
}
public void onDestroy() {
Toast.makeText(this, "My Service Stopped", Toast.LENGTH_LONG).show();
Log.d(TAG, "onDestroy");
}
*/
#Override
protected void onHandleWork(#NonNull Intent intent) {
Intent intents = new Intent(getBaseContext(),MainActivity.class);
intents.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intents);
//Toast.makeText(this, "My Service Started", Toast.LENGTH_LONG).show();
//Log.d(TAG, "onStart");
}
/*
#Override
public void onStart(Intent intent, int startid)
{
final LocationListener mLocationListener = new LocationListener() {
#Override
public void onLocationChanged(final Location location) {
//your code here
String kuku = location.getLatitude() + "=" + location.getLongitude();
Toast.makeText(WorkerService.this, kuku, Toast.LENGTH_LONG).show();
Log.d(TAG, kuku);
;
;
location.getAltitude();
location.getSpeed();
}
#Override
public void onStatusChanged(String provider, int status, Bundle extras) {
}
#Override
public void onProviderEnabled(String provider) {
}
#Override
public void onProviderDisabled(String provider) {
}
};
LocationManager mLocationManager = (LocationManager) getSystemService(LOCATION_SERVICE);
try {
mLocationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 60000,
1, mLocationListener);
}catch (SecurityException ex){
Toast.makeText(this, ex.getMessage(), Toast.LENGTH_LONG).show();
Log.d(TAG, ex.getMessage());
}
Intent intents = new Intent(getBaseContext(),MainActivity.class);
intents.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intents);
Toast.makeText(this, "My Service Started", Toast.LENGTH_LONG).show();
Log.d(TAG, "onStart");
}
*/
}
And this is my activity that is not getting launched:
package kor.location.tracker;
import android.Manifest;
import android.content.pm.PackageManager;
import android.nfc.Tag;
import android.os.Bundle;
import com.google.android.material.floatingactionbutton.FloatingActionButton;
import com.google.android.material.snackbar.Snackbar;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;
import androidx.core.app.ActivityCompat;
import android.util.Log;
import android.view.View;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.Toast;
import java.util.ArrayList;
import java.util.List;
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
FloatingActionButton fab = findViewById(R.id.fab);
fab.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
.setAction("Action", null).show();
}
});
Toast.makeText(getBaseContext(), "Hello........", Toast.LENGTH_LONG).show();
List<String> permissions = new ArrayList<String>();
if(getApplicationContext().checkCallingOrSelfPermission(Manifest.permission.INTERNET) != PackageManager.PERMISSION_GRANTED){
permissions.add(Manifest.permission.INTERNET);
}
if(getApplicationContext().checkCallingOrSelfPermission(Manifest.permission.RECEIVE_BOOT_COMPLETED) != PackageManager.PERMISSION_GRANTED){
permissions.add(Manifest.permission.RECEIVE_BOOT_COMPLETED);
}
if(getApplicationContext().checkCallingOrSelfPermission(Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED){
permissions.add(Manifest.permission.ACCESS_COARSE_LOCATION);
}
if(getApplicationContext().checkCallingOrSelfPermission(Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED){
permissions.add(Manifest.permission.ACCESS_FINE_LOCATION);
}
if(getApplicationContext().checkCallingOrSelfPermission(Manifest.permission.FOREGROUND_SERVICE) != PackageManager.PERMISSION_GRANTED){
permissions.add(Manifest.permission.FOREGROUND_SERVICE);
}
if(permissions.size()>0) {
String[] arr = new String[permissions.size()];
permissions.toArray(arr);
//System.out.println();
ActivityCompat.requestPermissions(this, arr, 1);
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
}
1- For Problem Starting Activity From Background
in API29 Android restricted, starting an activity from the background. The foreground service is also considered a background process. Your activity can be affected by this restriction if you test it in Android 10.
Android Q Restrictions: https://developer.android.com/guide/components/activities/background-starts
Possible solution:
https://stackoverflow.com/a/59421118/11982611
2- Some brands limits applications to start in the boot to boost start up time of the device. So applications need exclusive permission to start in the boot.
Possible Solution (Programmatically) :
https://stackoverflow.com/a/49167712/11982611
For Xiaomi, enabling Autostart from settings
https://dontkillmyapp.com/xiaomi
After I added the boot permissions in manifest file (see code below), BroadcastReceiver started to get boot completed event and the service is starting successfully. For the solution to work (as suggested by #Eren Tüfekçi) I had to enable auto start permission in phone settings for my application. If anyone has a solution, how to enable it programmatically, please let us know. Thank you.
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="kor.location.tracker">
<uses-permission android:name="android.permission.INTERNET" ></uses-permission>
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<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/AppTheme">
<receiver android:name="kor.location.tracker.AutoStart"
android:enabled="true"
android:exported="true">
<intent-filter android:directBootAware="true">
<action android:name="android.intent.action.BOOT_COMPLETED" />
<action android:name="android.intent.action.LOCKED_BOOT_COMPLETED" />
<action android:name="android.intent.action.QUICKBOOT_POWERON" />
<action android:name="android.intent.action.REBOOT"/>
</intent-filter>
</receiver>
<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>
<service android:enabled="true"
android:name="kor.location.tracker.WorkerService"
android:exported="true"
android:permission="android.permission.BIND_JOB_SERVICE"
/>
</application>
</manifest>
Check this. In this way what you want to achieve should work. If you can not, logs should be followed to find out the problem.
public class AutoStart extends BroadcastReceiver
{
#Override
public void onReceive(Context context, Intent arg1)
{
try {
Intent intent = new Intent(context, WorkerService.class);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
context.startForegroundService(intent);
} else {
context.startService(intent);
}
}catch(Exception ex) {
Toast.makeText(context, ex.getMessage(), Toast.LENGTH_LONG).show();
}
}
}
In Service
public class WorkerService extends Service {
public static final String CHANNEL_ID = "ForegroundServiceChannel";
public static final String NEW_CHANNEL_ID = "AndroidForegroundServiceChannel";
Notification notification;
#Override
public void onCreate() {
super.onCreate();
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.O)
{createNotificationChannel(); //for Android Oreo above notification channel mandatory }
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
try {
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q)
{// if Android 10 create a pending intent and a full screen notification
Intent fullScreenIntent = new Intent(this, "Your Activity".class);
PendingIntent fullScreenPendingIntent = PendingIntent.getActivity(this, 2022,
fullScreenIntent, PendingIntent.FLAG_UPDATE_CURRENT); // For the activity opening when notification cliced
notification= new NotificationCompat.Builder(this, NEW_CHANNEL_ID)
.setSmallIcon(R.drawable.ic_notification)
.setContentTitle("Notification title")
.setContentText("Notification Text")
.setPriority(NotificationCompat.PRIORITY_HIGH)
.setCategory(NotificationCompat.CATEGORY_REMINDER)
.setFullScreenIntent(fullScreenPendingIntent, true)
.build();
startForeground(2, notification);
}
else
{
//if below Android 10 created a notification for foreground service because it is mandatory
Intent notificationIntent = new Intent(this, Your Activity.class);
PendingIntent pendingNotificationIntent = PendingIntent.getActivity(this, 0022,
notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT);
notification = new NotificationCompat.Builder(this, CHANNEL_ID)
.setContentText("Foreground Service")
.setSmallIcon(R.drawable.ic_notification)
.setSound(null)
.setContentIntent(pendingNotificationIntent)
.build();
//for below Android 10 started activity
Intent i = new Intent(getApplicationContext(), Your Activity.class);
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
getApplicationContext().startActivity(i);
}
startForeground(1, notification);
}
}
catch (Exception e)
{
Toast.makeText(getApplicationContext(), "Foreground Service fault", Toast.LENGTH_LONG).show();
e.printStackTrace();
}
return START_NOT_STICKY;
}
private void createNotificationChannel() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
NotificationChannel serviceChannel = new NotificationChannel(
NEW_CHANNEL_ID,
"Android Foreground Service Channel",
NotificationManager.IMPORTANCE_HIGH
);
serviceChannel.setSound(null,null);
NotificationManager manager = getSystemService(NotificationManager.class);
manager.createNotificationChannel(serviceChannel);
}
else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
NotificationChannel serviceChannel = new NotificationChannel(
CHANNEL_ID,
"Foreground Service Channel",
NotificationManager.IMPORTANCE_DEFAULT
);
serviceChannel.setSound(null,null);
NotificationManager manager = getSystemService(NotificationManager.class);
manager.createNotificationChannel(serviceChannel);
}
}
#Override
public void onDestroy() {
super.onDestroy();
}
#Override
public IBinder onBind(Intent intent) {
return null;
}
I can still start the app on Boot. (Targeting API 29). By using broadcast receiver with intent ACTION_BOOT_COMPLETED.
The problem I faced after updating my android to version 9 on Honor brand of phone was introduction of advance app management for probably battery preservation which prevented my app from receiving the broadcast in the first place.
Go to Settings > Battery > App Launch > Go to your app and uncheck "Manage Automatically" > And make sure "Auto-launch", "Secondary launch", "Run in background" is checked and select "OK"
Reboot your phone and check if the app starts on boot or not. Hope this helps someone else.
I am trying this command from adb shell
dpm set-device-owner com.demoapp.amm/DeviceAdminSample
and i am getting this response.
Unknown admin: ComponentInfo{com.demoapp.amm/DeviceAdminSample}
com.demoapp.amm is my package name in Manifest file.
Below is my receiver from Manifest file
<receiver
android:name=".DeviceAdminSample"
android:description="#string/sample_device_admin_description"
android:label="#string/sample_device_admin_description"
android:permission="android.permission.BIND_DEVICE_ADMIN" >
<meta-data
android:name="android.app.device_admin"
android:resource="#xml/device_admin_sample" >
</meta-data>
<intent-filter>
<action android:name="android.app.action.DEVICE_ADMIN_ENABLED" />
</intent-filter>
</receiver>
Below is My Class DeviceAdminSample.class
package com.demoapp.amm;
import android.app.admin.DeviceAdminReceiver;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.widget.Toast;
public class DeviceAdminSample extends DeviceAdminReceiver {
void showToast(Context context, String msg) {
Toast.makeText(context, msg, Toast.LENGTH_SHORT).show();
}
#Override
public void onEnabled(Context context, Intent intent) {
showToast(context,"Enabled");
}
#Override
public CharSequence onDisableRequested(Context context, Intent intent) {
return "Disabled";
}
#Override
public void onDisabled(Context context, Intent intent) {
showToast(context, "Disabled");
}
#Override
public void onPasswordChanged(Context context, Intent intent) {
showToast(context,"Password Change");
}
public static ComponentName getComponentName(Context context) {
return new ComponentName(context.getApplicationContext(),
DeviceAdminSample.class);
}
}
It's because you've prefixed a period to the receiver name within your manifest android:name=".DeviceAdminSample" Thus com.demoapp.amm/DeviceAdminSample doesnt exist.
Try instead dpm set-device-owner com.demoapp.amm/.DeviceAdminSample.
I'm new in this Android, and really stuck with it..
Never that was like that - on a start level and already stuck.
When register the Receiver class it returns Intent = null.. means it doesn't know anything about such request (Action, Intent)..
Tested on Nexus Emulator + Samsung device NOTE4.. same result.
Please, help me. What is a tricky thing I do not see yet?
General activity
public class MainActivity extends AppCompatActivity {
EventBroadcaster sms;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Intent ret;
sms = new EventBroadcaster();
sms.setMainActivity(this);
sms.say("Hello from EventBroadcaster");
IntentFilter filter = new IntentFilter();
filter.addAction("android.provider.Telephony.SMS_RECEIVED");
//filter.addCategory(Intent.CATEGORY_DEFAULT);
ret = registerReceiver(sms, filter);
//******************************************//
if (ret == null) {
sms.say("Fault to activate Broadcaster.. Intent = null");
}
}
public void showToast(String message){
// Show Alert
int duration = Toast.LENGTH_LONG;
Toast toast = Toast.makeText(getApplicationContext(), message, duration);
toast.show();
}
}
BroadcastReceiver
public class EventBroadcaster extends BroadcastReceiver {
MainActivity ma;
public void setMainActivity(MainActivity context) {
ma = context;
say("MainActivity reference is received");
}
#Override
public void onReceive(Context context, Intent intent) {
say("Notification received");
}
public void say(String phrase){
ma.showToast(phrase);
}
}
Manifest
<manifest ...>
<uses-permission android:name="android.permission.RECEIVE_SMS"/>
<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">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
==============================================
So, after Vishnu answered, I think wouldn't be extra to place the working code of the
General Activity
import android.Manifest;
import android.content.Context;
import android.content.pm.PackageManager;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.content.Intent;
import android.content.IntentFilter;
import android.util.Log;
import android.widget.TextView;
import android.widget.Toast;
import android.provider.Telephony;
public class MainActivity extends AppCompatActivity {
EventBroadcaster sms;
final int MY_PERMISSIONS_REQUEST_READ_SMS = 100;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
sms = new EventBroadcaster();
sms.setMainActivity(this);
sms.say("Hello from EventBroadcaster");
if (VERSION.SDK_INT <= 23) {
ActivityCompat.requestPermissions(this,
new String[]{Manifest.permission.RECEIVE_SMS},
MY_PERMISSIONS_REQUEST_READ_SMS);
}
else if (ContextCompat.checkSelfPermission(this,
Manifest.permission.RECEIVE_SMS) != PackageManager.PERMISSION_GRANTED ){
ActivityCompat.requestPermissions(this,
new String[]{Manifest.permission.RECEIVE_SMS},
MY_PERMISSIONS_REQUEST_READ_SMS);
} else { /*Permission granted*/ }
}
#Override
public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
Intent ret;
switch (requestCode) {
case MY_PERMISSIONS_REQUEST_READ_SMS: {
// If request is cancelled, the result arrays are empty.
if (grantResults.length > 0
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
IntentFilter filter = new IntentFilter();
filter.addAction("android.provider.Telephony.SMS_RECEIVED");
ret = registerReceiver(sms, filter);
if (ret != null) {
sms.say("Permission to READ SMS granted");
}
} else {
sms.say("Ooops, no permission to READ SMS");
}
return;
}
}
}
public void showToast(String message){
// Show Alert
int duration = Toast.LENGTH_LONG;
Toast toast = Toast.makeText(getApplicationContext(), message, duration);
toast.show();
}
}
Apps targeting Android 6.0 and above need to handle the run-time permission.
Refer the Android documentation Requesting Permissions at Run Time
I think, this might be the reason.
try to declare receiver on your manifest
<receiver
android:name="com.example.EventBroadcaster"
android:exported="true" >
<intent-filter android:priority="1000" >
<action android:name="android.provider.Telephony.SMS_RECEIVED" />
</intent-filter>
</receiver>
I have the app which converts speech to text.But i want the behavior to be like of Google assist app i.e i want my app to be invoked when there is trigger for Default voice assist app.Currently my app is not being listed in Assist app under Assist & voice input options.
Kindly help me out what changes can be made in existing below code so that it gets listed in the Assist app option and the phone takes it as default app.
Thanks in advance.
//mainactivity.java
import java.util.ArrayList;
import java.util.Locale;
import android.app.Activity;
import android.content.ActivityNotFoundException;
import android.content.Intent;
import android.os.Bundle;
import android.speech.RecognizerIntent;
import android.support.v7.app.AppCompatActivity;
import android.view.Menu;
import android.view.View;
import android.widget.ImageButton;
import android.widget.TextView;
import android.widget.Toast;
// import android.support.v7.app.ActionBarActivity;
public class MainActivity extends Activity {
private TextView txtSpeechInput;
private ImageButton btnSpeak;
private final int REQ_CODE_SPEECH_INPUT = 100;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
txtSpeechInput = (TextView) findViewById(R.id.txtSpeechInput);
btnSpeak = (ImageButton) findViewById(R.id.btnSpeak);
// hide the action bar
//getActionBar().hide();
// getSupportActionBar().hide();
promptSpeechInput();
/* btnSpeak.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
promptSpeechInput();
}
});*/
}
/**
* Showing google speech input dialog
* */
private void promptSpeechInput() {
Intent intent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH);
intent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL,
RecognizerIntent.LANGUAGE_MODEL_FREE_FORM);
intent.putExtra(RecognizerIntent.EXTRA_LANGUAGE, Locale.getDefault());
intent.putExtra(RecognizerIntent.EXTRA_PROMPT,
getString(R.string.speech_prompt));
try {
startActivityForResult(intent, REQ_CODE_SPEECH_INPUT);
} catch (ActivityNotFoundException a) {
Toast.makeText(getApplicationContext(),
getString(R.string.speech_not_supported),
Toast.LENGTH_SHORT).show();
}
}
/**
* Receiving speech input
* */
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
switch (requestCode) {
case REQ_CODE_SPEECH_INPUT: {
if (resultCode == RESULT_OK && null != data) {
ArrayList<String> result = data
.getStringArrayListExtra(RecognizerIntent.EXTRA_RESULTS);
txtSpeechInput.setText(result.get(0));
}
break;
}
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
}
//manifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.gda6kor.speech3">
<uses-permission android:name="android.permission.INTERNET"></uses-permission>
<uses-permission android:name="android.permission.BIND_VOICE_INTERACTION"></uses-permission>
<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">
<intent-filter>
<action android:name="android.intent.action.ASSIST"></action>
<action android:name="android.intent.action.VOICE_COMMAND"></action>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
Try adding those line to the intent filter for the activity:
<action android:name="android.intent.action.ASSIST" />
<category android:name="android.intent.category.DEFAULT" />
I'am writing this code to learn how use Bluetooth in Android however i'am constantly getting the error mentioned in the title. Full error is: java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.android/com.example.android.MainActivity}: android.content.ActivityNotFoundException: No Activity found to handle Intent { act=android.bluetooth.adapter.action.STATE_CHANGED }
AndroidManifest.xml:
<?xml version="1.0" encoding="utf-8"?>
<manifest
xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.android"
android:versionCode="1"
android:versionName="1.0">
<uses-permission android:name="android.permission.BLUETOOTH" />
<application
android:label="#string/app_name"
android:icon="#drawable/ic_launcher">
<receiver
android:name=".MainActivity" >
<intent-filter>
<action android:name="android.bluetooth.adapter.action.STATE_CHANGED" />
</intent-filter>
</receiver>
<activity
android:name="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>
MainActivity.java:
package com.example.android;
import android.app.Activity;
import android.bluetooth.BluetoothAdapter;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
public class MainActivity extends Activity
{
private final String LOG_TAG = getClass().getSimpleName();
private static int REQUEST_ENABLE_BT = 1;
private static int REQUEST_STATE_CHANGED_BT = 2;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
BluetoothAdapter oBTAdapter = BluetoothAdapter.getDefaultAdapter();
if (oBTAdapter == null) Log.i(LOG_TAG, "This device does not support Bluetooth");
if (!oBTAdapter.isEnabled()) {
Intent iEnableBT = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(iEnableBT, REQUEST_ENABLE_BT);
}
Intent iBTStatus = new Intent(BluetoothAdapter.ACTION_STATE_CHANGED);
startActivityForResult(iBTStatus, REQUEST_STATE_CHANGED_BT);
}
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == REQUEST_ENABLE_BT)
if (resultCode == RESULT_CANCELED) Log.e(LOG_TAG, "Bluetooth was not enabled on the device");
else if (requestCode == REQUEST_STATE_CHANGED_BT)
if (resultCode == RESULT_OK && !data.getStringExtra(BluetoothAdapter.EXTRA_STATE).equals(BluetoothAdapter.STATE_ON)) Log.e(LOG_TAG, "Bluetooth adapter is not on");
}
}
On the device i have bluetooth on and with the logs i saw that it did skip the isEnabled() test(to see of Bluetooth is currently enabled and ready for use). It was able to create an intent to observe Bluetooth status but it crashes on startActivityForResult(). What did i do wrong?
Hello you have not any activity with that kind of event handling,
you should try to make BroadcastReceiver like this
private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
final String action = intent.getAction();
if (action.equals(BluetoothAdapter.ACTION_STATE_CHANGED)) {
final int state = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE,
BluetoothAdapter.ERROR);
switch (state) {
case BluetoothAdapter.STATE_OFF:
setButtonText("Bluetooth off");
break;
case BluetoothAdapter.STATE_TURNING_OFF:
setButtonText("Turning Bluetooth off...");
break;
case BluetoothAdapter.STATE_ON:
setButtonText("Bluetooth on");
break;
case BluetoothAdapter.STATE_TURNING_ON:
setButtonText("Turning Bluetooth on...");
break;
}
}
}
};
And in your activity do it like this...
IntentFilter filter = new IntentFilter(BluetoothAdapter.ACTION_STATE_CHANGED);
registerReceiver(mReceiver, filter);