How to make my service run? - service

I want to start a service when the power is connected to my device and show a notification but my app is doing nothing or I do not what is happenig, so please help me, I am new in the android world, maybe I miss something, mi code is the following:
My manifest:
<receiver android:name="com.tlm.grhs_client.WiFiMonitor">
<intent-filter>
<action android:name="android.intent.action.ACTION_POWER_CONNECTED"/>
</intent-filter>
</receiver>
My Broadcast Reciever:
public class WiFiMonitor extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo info = cm.getActiveNetworkInfo();
if (info != null && info.getType() == ConnectivityManager.TYPE_WIFI) {
if (info.isConnected()) {
//iniciar servicio
Intent serviceIntent = new Intent(context, ClientService.class);
context.startService(serviceIntent);
}
else {
//parar servicio
Intent serviceIntent = new Intent(context, ClientService.class);
context.stopService(serviceIntent);
}
}
}
}
and my service class is this:
public class ClientService extends Service {
#Override
public IBinder onBind(Intent intent) {
throw new UnsupportedOperationException("Not yet implemented");
}
#Override
public void onCreate() {
Toast.makeText(this, "Servicio fue creado", Toast.LENGTH_LONG).show();
}
#TargetApi(Build.VERSION_CODES.JELLY_BEAN)
#SuppressLint("NewApi")
#Override
public void onStart(Intent intent, int startId) {
// Perform your long running operations here.
Toast.makeText(this, "Servicio iniciado", Toast.LENGTH_LONG).show();
Notification.Builder notiBuilder = new Notification.Builder(this);
notiBuilder.setContentTitle("Prueba");
notiBuilder.setContentText("Esto es una prueba");
Notification notificacion = notiBuilder.build();
NotificationManager manager = (NotificationManager) this.getSystemService(this.NOTIFICATION_SERVICE);
manager.notify(1, notificacion);
}
#Override
public void onDestroy() {
Toast.makeText(this, "Servicio destruido", Toast.LENGTH_LONG).show();
}
}
I turn on the wifi and establish the connection but the notification doesn't shows.

Android notifications in this manner require a small icon, along with a title and some text as per the documentation at http://developer.android.com/guide/topics/ui/notifiers/notifications.html
Add an icon but otherwise the code (on a quick glance) looks like it should work.

Related

In flutter, how can I register if the headset is suddenly unplugged

Android java offers to register a BroadcastReceiver checking for AudioManager.ACTION_AUDIO_BECOMING_NOISY, to listen to the system broadcasting an ACTION_AUDIO_BECOMING_NOISY message, when a sound is played but then the headset is unplugged or a Bluetooth device disconnected.
Is there a way to do this in flutter, to respond to the event that e.g. a headset is unplugged while playing sound?
With the hint in the answer below, I got this going, but only in DEBUG mode, not in a release ready APK. This is what I did:
Java:
public class MainActivity extends FlutterActivity {
public static final String STREAM = "XXX";
public static String TAG = "player/java file";
private IntentFilter intentFilter = new IntentFilter(AudioManager.ACTION_AUDIO_BECOMING_NOISY);
private BecomingNoisyReceiver myNoisyAudioStreamReceiver = null;
private class BecomingNoisyReceiver extends BroadcastReceiver {
final EventChannel.EventSink eventSink;
BecomingNoisyReceiver(EventChannel.EventSink eventSink){
super();
this.eventSink = eventSink;
}
#Override
public void onReceive(Context context, Intent intent) {
if (AudioManager.ACTION_AUDIO_BECOMING_NOISY.equals(intent.getAction())) {
Log.w(TAG, "Noisy Receiver activated");
eventSink.success("success");
}
}
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
GeneratedPluginRegistrant.registerWith(this);
new EventChannel(getFlutterView(), STREAM).setStreamHandler(
new EventChannel.StreamHandler() {
#Override
public void onListen(Object args, final EventChannel.EventSink events) {
Log.w(TAG, "adding listener");
myNoisyAudioStreamReceiver = new BecomingNoisyReceiver(events);
registerReceiver(myNoisyAudioStreamReceiver, intentFilter);
}
#Override
public void onCancel(Object args) {
Log.w(TAG, "cancelling listener");
unregisterReceiver(myNoisyAudioStreamReceiver);
}
}
);
}
}
And in Dart, in the class extending State:
static const platform = const EventChannel('XXX');
StreamSubscription _noisySubscription;
in initState():
_noisySubscription = null;
Whenever I need it:
if(_noisySubscription == null){
_noisySubscription = platform.receiveBroadcastStream().listen(_handleNoisy);
}
Whenever it needs to stop:
_noisySubscription.cancel().then((_){_noisySubscription = null;});
Any hint, how to fix this problem?
You can use EventChannel to communicate an event on native part (Android) to Dart part. Ref: https://medium.com/#svenasse/flutter-event-channels-89623ce6c017
(Pseudo) Sample Code (it's not in runable state, but hopefully it gives you idea):
Dart part
void _handleNoisy(noisyEvent) {
debugPrint("noisyEvent $noisyEvent");
}
static const stream =
const EventChannel('com.yourcompany.yourapp/ACTION_AUDIO_BECOMING_NOISY');
StreamSubscription _noisySubscription = stream.receiveBroadcastStream().listen(_handleNoisy);
Java part
public class MainActivity extends FlutterActivity {
public static final String STREAM = "com.yourcompany.yourapp/ACTION_AUDIO_BECOMING_NOISY";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
new EventChannel(getFlutterView(), STREAM).setStreamHandler(
new EventChannel.StreamHandler() {
#Override
public void onListen(Object args, final EventChannel.EventSink dartEvents) {
Log.w(TAG, "adding listener");
noisyEvent = ... // Register
private class BecomingNoisyReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
if (AudioManager.ACTION_AUDIO_BECOMING_NOISY.equals(intent.getAction())) {
dartEvents.success("the payload you want to pass to dart")
}
}
}
}
#Override
public void onCancel(Object args) {
Log.w(TAG, "cancelling listener");
}
}
);
}
}

How to start a lockscreen activity instantaneously after reboot?

I want to start a lockscreen activity after device reboot side by side with the startup notifications like Messages,Viber notifications,Whatsapp etc.How to do this ??.I have made a broadcast receiver which receives BOOT_COMPLETED action and upon that it starts a service that registers the same receiver again with Intent.ACTION_SCREEN_OFF and Intent.ACTION_SCREEN_ON intent filter and that receiver starts the lockscreen activity.Here is my code:
AndroidManifest.xml
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" ></uses-permission>
<receiver>
<intent-filter android:priority="2147483647">
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
and of course I declared the service in the manifest.
Here is my Broadcast Receiver class
public class LockScreenBroadCastReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Log.d("BroadCastReceiver", "ReceivedIntent");
if (intent.getAction().equals(Intent.ACTION_SCREEN_OFF)) {
Intent myIntent = new Intent(context, LockScreenActivity.class);
myIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
myIntent.addFlags(Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT);
if (!LockScreenActivity.isActivityRunning) {
context.startActivity(myIntent);
}else{
Log.d("BroadCasrReceiver","LockScreenActivity is running");
}
}else if (intent.getAction().equals(Intent.ACTION_BOOT_COMPLETED)) {
Log.v("LockScreenBroadReceiver","boot completed");
Intent startServiceIntent = new Intent(context,LockScreenService.class);
context.startService(startServiceIntent);
}
}
}
and the service class :
public class LockScreenService extends Service {
LockScreenBroadCastReceiver broadCastReciever;
public static boolean isRunning;
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onCreate() {
super.onCreate();
isRunning = true;
registerReceiver();
}
#Override
public void onDestroy() {
super.onDestroy();
isRunning = false;
unregisterReceiver(broadCastReciever);
Log.d("LockScreenReceiver", "ReceiverUnregistered");
sendBroadcast(new Intent("RestartLockScreenService"));
}
private void registerReceiver(){
IntentFilter intentFilter = new IntentFilter(Intent.ACTION_SCREEN_OFF);
intentFilter.addAction(Intent.ACTION_SCREEN_ON);
broadCastReciever = new LockScreenBroadCastReceiver();
registerReceiver(broadCastReciever,intentFilter);
Log.d("LockScreenReceiver", "ReceiverRegistered");
}
}
This approach is working.However,It's very slow as the broadcast receiver listens to BOOT_COMPLETED broadcast which waits until the device is fully up and working.So,you may lock and unlock the phone several times before you get the lockscreen working.Any ideas??
You can use the intentFilter instace of BootComplate in manifist like this:
<action android:name="android.intent.action.USER_PRESENT" />
I had the same issue. It was fixed by including
<category android:name="android.intent.category.DEFAULT" />
on the receiver. The is a slight delay of 6 seconds on reboot which I'm trying to narrow down.
I hope this works for you

Android - Top Back Button not working

I have this button on the topmost left part. And for some reason it is not going back to it's previous page when I click it. I've checked the other links already but it is not working.
The activity code on that one
public class CardListActivity extends Activity {
private static final String LOG_TAG = CardListActivity.class.getSimpleName();
private EventBus eventBus;
private Activity activity;
private CardListRequest cardListRequest;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
init();
}
public void init() {
Log.e(LOG_TAG, "XXXX Start : init XXXX");
setUpActionBar();
activity = this;
setContentView(R.layout.activity_card_list);
Log.e(LOG_TAG, "XXXX Finish : init XXXX");
}
private void setUpActionBar() {
getActionBar().setTitle(CardListActivity.class.getSimpleName());
getActionBar().setDisplayHomeAsUpEnabled(true);
}
}
AndroidManifest.xml
...
<activity
android:name=".CardListActivity"
android:label="#string/title_activity_card_list"
android:parentActivityName=".HomeActivity2">
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value="com.pw.mccdealsapp.HomeActivity2" />
</activity>
...
This page contains all the information to create an Up button that works correctly.
You need to add, in your activity, something like:
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
NavUtils.navigateUpFromSameTask(this);
return true;
}
return super.onOptionsItemSelected(item);
}
first on your onCreate method put this
//action bar back icon
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
then override this method and make back opetion go to its parent
public boolean onOptionsItemSelected(MenuItem item) {
if (item.getItemId() == android.R.id.home){
finish();
}
return super.onOptionsItemSelected(item);
}

My Android App is crashed when I register SensorManager.registerListener

Below is my code. I am having a problem when I call SensorManager.registerListener, my app will crash. Can someone tell me what's going on?
I just follw the web guide to setup SensorManger, Sensor(Accelerometer) and then register the action lintener to detect the montion of accelerometer.
I used API 21 to develop this app.
public class MainActivity extends ActionBarActivity implements SensorEventListener{
private TextView tip;
private SensorManager mSensorManager;
private Sensor mSensor;
private float axisX = 0;
private float axisY = 0 ;
private float axisZ = 0;
#Override
protected void onResume() {
super.onResume();
setUpAcceleratorSensor();
mSensorManager.registerListener(this, mSensor, SensorManager.SENSOR_DELAY_NORMAL);
}
#Override
protected void onPause() {
super.onPause();
mSensorManager.unregisterListener(this);
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
setUpAcceleratorSensor();
}
#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;
}
#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();
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
private void setUpAcceleratorSensor(){
mSensorManager = (SensorManager) getSystemService(SENSOR_SERVICE);
if((mSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER)) != null);
else
Toast.makeText(this, "No Sensor Device Exist", Toast.LENGTH_LONG).show();
}
#Override
public void onSensorChanged(SensorEvent event) {
// TODO Auto-generated method stub
Sensor mySensor = event.sensor;
if (mySensor.getType() == Sensor.TYPE_ACCELEROMETER) {
if(event.values[0] != 0 || event.values[1] != 0 || event.values[2] != 0){
axisX = event.values[0];
axisY = event.values[1];
axisZ = event.values[2];
tip.setText("Detect your montion");
}
}
else
Toast.makeText(this, "Cannot Get Sensor Device", Toast.LENGTH_LONG).show();
}
#Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
// TODO Auto-generated method stub
}
}
Thanks.
First that I always check when something like this goes wrong, is to check that you have all the correct permissions in the Android Manifest; however, I don't believe that there are any permissions associated with using the position sensors. I would check on this first. That is what comes to mind first, after you post logcat, we will be able to give a more detailed answer.
Try getting the sensor this way
mSensor = mSensorManager.getSensorList(Sensor.TYPE_ACCELEROMETER).get(0); instead in your setUpAccelerometer() method.

How implement wakelock.acquire in GCMBroadcast receiver

if my mobile is in screenlock, the GCMBroadcast receiver doesn't send the message to the GCMIntentService.
I've read that the solution is to implement the trick of wakelock.acquire() and wakelock.release() in the onReceive method of my broadcast receiver.
BUT the GCMBroadcastReceiver has the onReceive in final, so i can't add, this feature.
Is there a solution?
[EDIT]
Wrong Question, after 5 hours of investigation, i've solved everything.
To clarify:
GCMBroadcast has the wakelock acquire and release, no needed any
implementation.
My problem was due to the DELAY WHEN IDLE property set as true in the SERVER CODE.
builder = builder.delayWhileIdle(true);
From official documentation:
if the device is connected but idle, the message will still be
delivered right away unless the delay_while_idle flag is set to true.
Otherwise, it will be stored in the GCM servers until the device is
awake.
[/EDIT]
here my code:
GCMIntentService
public class GCMIntentService extends GCMBaseIntentService{
public GCMIntentService() {
super(CommonStuff.SENDERID);
// TODO Auto-generated constructor stub
}
#Override
protected void onError(Context arg0, String arg1) {
// TODO Auto-generated method stub
System.out.println("onError:"+arg1);
}
#Override
protected void onMessage(Context context, Intent intent) {
Log.i("GCMIntentService", "Message Received");
Bundle extras = intent.getExtras();
// Extract the payload from the message
if (extras != null) {
String type=(String)extras.get("type");
String msg=(String)extras.get("message");
//do something........
}
}
#Override
protected void onRegistered(Context ctx, String regId) {
Log.d("GCMIntentService","REGID_ARRIVED:"+regId);
try {
//do something
} catch (Exception e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
#Override
protected void onUnregistered(Context arg0, String arg1) {
// TODO Auto-generated method stub
System.out.println("onUnregistered:"+arg1);
}
}
the wakeLocker
public abstract class WakeLocker {
private static PowerManager.WakeLock wakeLock;
public static void acquire(Context ctx) {
if (wakeLock != null) wakeLock.release();
PowerManager pm = (PowerManager) ctx.getSystemService(Context.POWER_SERVICE);
wakeLock = pm.newWakeLock(PowerManager.FULL_WAKE_LOCK |
PowerManager.ACQUIRE_CAUSES_WAKEUP |
PowerManager.ON_AFTER_RELEASE, MainActivity.APP_TAG);
wakeLock.acquire();
}
public static void release() {
if (wakeLock != null) wakeLock.release(); wakeLock = null;
}
}
my GCMreceiver in MANIFEST
<receiver
android:name="com.google.android.gcm.GCMBroadcastReceiver"
android:permission="com.google.android.c2dm.permission.SEND" >
<intent-filter>
<action android:name="com.google.android.c2dm.intent.RECEIVE" />
<action android:name="com.google.android.c2dm.intent.REGISTRATION" />
<category android:name="my.app.package" />
</intent-filter>
</receiver>
Just to set as solved, the solution in the edit part of question.