Activity not found while using a service - java

I am trying to start a Service that implements SensorEventListener. I am getting an error in my logcat claiming:
android.content.ActivityNotFoundException:Unable to find explicit activity class
{com.devicemoved/com.devicemoved.ShakeWakeupService};
have you declared this activity in your AndroidManifest.xml?
My Service is declared in my manifest as shown:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.devicemoved"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="18" />
<application
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<activity
android:name="com.devicemoved.launcherGo"
android:label="#string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<service android:name="com.devicemoved.ShakeWakeupService" />
</application>
The Activity
public class ShakeWakeupService extends Service implements SensorEventListener {
private Context mContext;
SensorManager mSensorEventManager;
Sensor mSensor;
// BroadcastReceiver for handling ACTION_SCREEN_OFF.
public BroadcastReceiver mReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
// Check action just to be on the safe side.
if (intent.getAction().equals(Intent.ACTION_SCREEN_OFF)) {
Log.v("shake mediator screen off", "trying re-registration");
// Unregisters the listener and registers it again.
mSensorEventManager.unregisterListener(ShakeWakeupService.this);
mSensorEventManager.registerListener(ShakeWakeupService.this,
mSensor, SensorManager.SENSOR_DELAY_NORMAL);
}
}
};
#Override
public void onCreate() {
super.onCreate();
Log.v("shake service startup", "registering for shake");
mContext = getApplicationContext();
// Obtain a reference to system-wide sensor event manager.
mSensorEventManager = (SensorManager) mContext
.getSystemService(Context.SENSOR_SERVICE);
// Get the default sensor for accel
mSensor = mSensorEventManager
.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
// Register for events.
mSensorEventManager.registerListener(this, mSensor,
SensorManager.SENSOR_DELAY_NORMAL);
// Register our receiver for the ACTION_SCREEN_OFF action. This will
// make our receiver
// code be called whenever the phone enters standby mode.
IntentFilter filter = new IntentFilter(Intent.ACTION_SCREEN_OFF);
registerReceiver(mReceiver, filter);
}
#Override
public void onDestroy() {
// Unregister our receiver.
unregisterReceiver(mReceiver);
// Unregister from SensorManager.
mSensorEventManager.unregisterListener(this);
}
#Override
public IBinder onBind(Intent intent) {
// We don't need a IBinder interface.
return null;
}
public void onShake() {
// Poke a user activity to cause wake?
}
public void onAccuracyChanged(Sensor sensor, int accuracy) {
// not used right now
}
// Used to decide if it is a shake
public void onSensorChanged(SensorEvent event) {
if (event.sensor.getType() != Sensor.TYPE_ACCELEROMETER)
return;
Log.v("sensor", "sensor change is verifying");
}
}
The only thing I could possibly think of is that I am suppose to declare a broadcast receiver since I am using it in my class but I am not sure how to do that in this instance because I am not extending Broadcastreceiver.
I am calling this class from an activity with a button.
Any help will be great Thank You

You can already declared the package in the manifest tag, you should only need the .ShakeWakeupService part. Also make sure there is an empty constructor available for the system to construct your service

Related

Android keep app running in the background forever

I am still new to Android development, but I’m creating an app that sendings an HTTP request when it receives a broadcast (from a barcode scan). I have tried to implement some other solutions that I read on here but haven't quite figured it out yet. It would be great if someone could help me get going in the right direction.
Essentially, the end goal is for the app to keep running in the background forever so that even if the app is not open and a barcode is scanned and sent to the app via broadcast signal, the HTTP request is still sent.
This is what I have so far:
MainActivity.java
public class MainActivity extends Activity implements CompoundButton.OnCheckedChangeListener {
public static final String BARCODE_BROADCAST = "...";
private final BarcodeReceiver barcodeReceiver = new BarcodeReceiver();
private TextView mTextView;
private String scannedBarcode;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mTextView = (TextView) findViewById(R.id.barcode);
}
#Override
public void onResume() {
super.onResume();
registerBarcodeScanner();
}
#Override
public void onPause() {
super.onPause();
unregisterBarcodeScanner();
// this code needs to keep the app running
Intent restartService = new Intent("RestartService");
this.startService(restartService);
sendBroadcast(restartService);
}
public void onDestroy() {
super.onDestroy();
// this code needs to keep the app running
Intent restartService = new Intent("RestartService");
this.startService(restartService);
sendBroadcast(restartService);
}
private void registerBarcodeScanner() {
registerReceiver(barcodeReceiver, new IntentFilter(BARCODE_BROADCAST));
}
private void unregisterBarcodeScanner() {
unregisterReceiver(barcodeReceiver);
}
private void displayBarcode() {
if (scannedBarcode == null) return;
String text = getString(R.string.barcode_scanned, scannedBarcode);
mTextView.setText(text);
/* SEND HTTP REQUEST */
}
private class BarcodeReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (action.equals(BARCODE_BROADCAST)) {
String barcode = intent.getStringExtra("Barcode");
if (barcode != null) {
scannedBarcode = barcode;
displayBarcode();
}
}
}
}
}
RestartService.java
public class RestartService extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
context.startService(new Intent(context, MainActivity.class));
}
}
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="..."
android:versionCode="1">
<uses-sdk android:targetSdkVersion="17" />
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
<uses-permission android:name="android.permission.INTERNET" />
<application
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
tools:replace="android:label">
<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>
<receiver
android:name="...RestartService"
android:enabled="true"
android:exported="true"
android:label="RestartServiceWhenStopped"
android:permission="android.permission.RECEIVE_BOOT_COMPLETED">
<intent-filter>
<action android:name="RestartService" />
</intent-filter>
</receiver>
</application>
</manifest>

Broadcast receiver for nought and Oreo + devices not working

public class ScreenReceiver extends BroadcastReceiver {
private boolean screenOff;
#Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(Intent.ACTION_SCREEN_OFF)) {
screenOff = true;
} else if (intent.getAction().equals(Intent.ACTION_SCREEN_ON)) {
screenOff = false;
}
}
<receiver
android:name=".ScreenReceiver"
android:enabled="true"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.PHONE_STATE" />
<action android:name="android.intent.action.DREAMING_STARTED" />
<action android:name="android.intent.action.DREAMING_STOPPED" />
<action android:name="android.intent.action.CLOSE_SYSTEM_DIALOGS" />
<action android:name="android.intent.action.SCREEN_ON" />
<action android:name="android.intent.action.SCREEN_OFF" />
<action android:name="android.intent.action.LOCKED_BOOT_COMPLETED" />
<action android:name="android." />
</intent-filter>
</receiver>
Not getting any callback on naught and oreo devices,tried on marshmallow devices its working fine .but on oreo devices its not working and also for battery connected and network change receiver not working .
You can not register broadcast receiver in manifest.xml from Oreo.
You can see
Android 8.0 Behavior Changes
Apps cannot use their manifests to register for most implicit
broadcasts (that is, broadcasts that are not targeted specifically at
the app).
Solution
Register your receiver in your related Activity instead. Like this.
public class MainActivity extends AppCompatActivity {
BroadcastReceiver receiver;
#Override
protected void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
IntentFilter filter = new IntentFilter();
filter.addAction(Intent.ACTION_SCREEN_OFF);
filter.addAction(Intent.ACTION_SCREEN_ON);
filter.addAction("android.intent.action.LOCKED_BOOT_COMPLETED");
receiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
// todo
}
};
registerReceiver(receiver, filter);
}
#Override
protected void onDestroy() {
super.onDestroy();
if (receiver != null)
unregisterReceiver(receiver);
}
}
You can add action as string same as manifest, if you don't find relevant constant string.

Android - Handle global configuration changes

I'm writing a service that tracks system changes, meaning, I'm willing to track whenever a keyboard becomes visible / hidden for any application.
To achieve the following task, i built a small Activity that launches a services
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Intent serviceIntent = new Intent(this, MyService.class);
startService(serviceIntent);
//setContentView(R.layout.activity_main);
}
}
The manifest.xml itself
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="somepackage">
<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">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<service
android:name=".MyService"
android:enabled="true"
android:exported="true"
android:configChanges="orientation|screenSize|keyboardHidden"></service>
</application>
</manifest>
and the service itself:
public class MyService extends Service {
public MyService() {
}
private static final String TAG =
"abbeyservice";
#Override
public void onCreate() {
Log.d(TAG, "Service onCreate");
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.i(TAG, "Service onStartCommand");
return Service.START_STICKY;
}
#Override
public IBinder onBind(Intent arg0) {
Log.i(TAG, "Service onBind");
return null;
}
#Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
}
#Override
public void onDestroy() {
Log.i(TAG, "Service onDestroy");
}
}
Problem is I'm notified for changes within, and only for my activity. Which is seen as a white screen for unknown reasons(even though i didn't use SetContentView(..))
When you talk of "keyboard" you are talking about the soft keyboard. This doesn't result in a configuration change, as the configuration has not changed.
There are devices with hardware keyboards that slide out, so they generate a configuration change event when they are slid out or back in again. There is also a possibility to attach an external keyboard to some Android devices and the act of connecting or disconnecting a hardware keyboard also generates a configuration change event.
To detect if the keyboard is shown in your own app, see
How to check visibility of software keyboard in Android?
As far as I know, there is no way to find out if the soft keyboard is shown in another app.

Android - Unable to receive local broadcast in my activity from service

I have my main activity that start a service (Location service) and I want that service to broadcast the new location each time a new location is found.
Thanks to the log I know the service is working and I have new locations every seconds or so, but I never get the broadcast.
MainActivity.java
public class MainActivity extends Activity {
private static final String TAG = "mainActivity";
private CMBroadcastReceiver mMessageReceiver = new CMBroadcastReceiver();
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
// Start Service
startService(new Intent(this, LocationService.class));
super.onCreate(savedInstanceState);
}
#Override
public void onResume()
{
LocalBroadcastManager.getInstance(this).registerReceiver(
mMessageReceiver, new IntentFilter(CMBroadcastReceiver.RECEIVE_LOCATION_UPDATE));
super.onResume();
}
#Override
public void onPause()
{
LocalBroadcastManager.getInstance(this).unregisterReceiver(mMessageReceiver);
super.onPause();
}
}
CMBroadcastReceiver.java
public class CMBroadcastReceiver extends BroadcastReceiver {
private static final String TAG = "CMBroadcastReceiver";
public static final String RECEIVE_LOCATION_UPDATE = "LOCATION_UPDATES";
#Override
public void onReceive(Context context, Intent intent) {
Log.i(TAG, "Received broadcast");
String action = intent.getAction();
if (action.equals(RECEIVE_LOCATION_UPDATE))
{
Log.i(TAG, "Received location update from service!");
}
}
}
LocationService.java
/**
* Callback that fires when the location changes.
*/
#Override
public void onLocationChanged(Location location) {
mCurrentLocation = location;
mLastUpdateTime = DateFormat.getTimeInstance().format(new Date());
Log.i(TAG, "onLocationChanged " + location);
Intent intent = new Intent(CMBroadcastReceiver.RECEIVE_LOCATION_UPDATE);
LocalBroadcastManager.getInstance(this).sendBroadcast(intent);
Log.i(TAG, "Broadcast sent");
}
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.cyclemapapp.gpstracker">
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<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"
android:label="#string/title_activity_main"
android:theme="#style/AppTheme.NoActionBar">
android:configChanges="orientation|screenSize">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<service android:name=".LocationService" android:process=":location_service" />
</application>
I the log I can see that "Broadcast Sent" But I never get the "Broadcast Received"
Any help will would be greatly appreciated.
EDIT:
Edited how the intent was created in the location service as Shaishav suggested.
Still doesn't work.
LocalBroadcastManager does not work across processes. Your Service is running in a separate process.
You can either run your Service in the same process as the Activity - by removing the process attribute from the <service> element - or use some sort of IPC instead - e.g., by sending and receiving the broadcasts on a Context instead of LocalBroadcastManager.
In your LocationService, send local broadcast using:
Intent intent = new Intent(CMBroadcastReceiver.RECEIVE_LOCATION_UPDATE);
LocalBroadcastManager.getInstance(this).sendBroadcast(intent);
<service android:name=".LocationService" android:process=":location_service" />
Your service is in a separate process from the activity. LocalBroadcastManager is only for use in one process. Either remove android:process from the <service>, or use some IPC mechanism (e.g., system broadcasts, properly secured).

android Broadcast Receiver not works

I programming with android studio and I want to have a Broadcast receiver to do something every time the time of clock change (it means every single minute that for example the time of phone changed from 3:13 to 3:14) even if the program isn't run. so I should use a Broadcast receiver with Time_Tick Action. But It just work when the Activity created. any Idea?
MainActivity:
public class MainActivity extends ActionBarActivity {
BroadcastReceiver br;
final SmsManager sms = SmsManager.getDefault();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
IntentFilter i=new IntentFilter();
i.addAction("android.intent.action.TIME_TICK");
registerReceiver(new MyReceiver(),i);
}
#Override
protected void onDestroy() {
super.onDestroy();
}
#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);
}
}
MyReceiver:
public class MyReceiver extends BroadcastReceiver {
public MyReceiver() {
Log.i("Saaalam","saaaalaalam");
}
#Override
public void onReceive(Context context, Intent intent) {
// TODO: This method is called when the BroadcastReceiver is receiving
// an Intent broadcast.
throw new UnsupportedOperationException("Not yet implemented");
}
}
Manifest:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.etsiamak.broadcastrecierver" >
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="ANDROID.PERMISSION.RECEIVE_SMS" />
<uses-permission android:name="android.permission.READ_SMS" />
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<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>
<receiver
android:name=".MyReceiver"
android:enabled="true"
android:exported="true" >
<intent-filter> <action android:name="android.intent.action.TIME_TICK"></action> </intent-filter>
</receiver>
</application>
</manifest>
Here is the sample code for time tick. The TIME_TICK intent gets fired minute change.
static TimeReceiver tickReceiver = new TimeReceiver();
void setTimeTick()
{
registerReceiver(tickReceiver, new IntentFilter(
"android.intent.action.TIME_TICK"));
Toast.makeText(this, "Registered broadcast receiver", Toast.LENGTH_SHORT)
.show();
//Register the broadcast receiver to receive TIME_TICK
registerReceiver(tickReceiver, new IntentFilter(Intent.ACTION_TIME_TICK));
}
The Reciever Class
class TimeReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent arg1) {
// TODO Auto-generated method stub
Toast.makeText(context, "Time tick", Toast.LENGTH_LONG).show();
}
}
Can you add this code into Manifest
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
What I understand is that you need to execute certain task after certain amount of time say one minutes. For this you can use AlarmManager.
AlarmManager myAlarmManager = Context.getSystemService(Context.ALARM_SERVICE)
Example for AlarmManager: https://androidresearch.wordpress.com/2012/07/02/scheduling-an-application-to-start-later/
Or Android introduced the JobScheduler API in Android 5.0 (API 21). It is better then AlarmManager as it does not consider if the device is connected to a power plug, idle or connected.
Example for JobScheduler: how-to-use-androids-job-scheduler

Categories