Have been trying to use Google Activity Recognition API, but until now, can't get a single result.
I have this function in Main Activity
private void requestTransactionsUpdates() {
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACTIVITY_RECOGNITION) !=
PackageManager.PERMISSION_GRANTED) {
return;
}
List transitions = new ArrayList<>();
transitions.add(
new ActivityTransition.Builder()
.setActivityType(DetectedActivity.WALKING)
.setActivityTransition(ActivityTransition.ACTIVITY_TRANSITION_ENTER)
.build());
transitions.add(
new ActivityTransition.Builder()
.setActivityType(DetectedActivity.WALKING)
.setActivityTransition(ActivityTransition.ACTIVITY_TRANSITION_EXIT)
.build());
ActivityTransitionRequest request = new ActivityTransitionRequest(transitions);
Intent intent = new Intent(ActivityTransitionReceiver.TRANSITION_ACTION_RECEIVER);
mPendingIntent = PendingIntent.getBroadcast(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
mTransitionsReceiver = new ActivityTransitionReceiver();
registerReceiver(mTransitionsReceiver,
new IntentFilter(ActivityTransitionReceiver.TRANSITION_ACTION_RECEIVER));
Task<Void> task =
ActivityRecognition.getClient(this)
.requestActivityTransitionUpdates(request, mPendingIntent);
task.addOnSuccessListener(
result -> {
});
task.addOnFailureListener(
e -> {
});
}
and created a Receiver class
public class ActivityTransitionReceiver extends BroadcastReceiver {
public static final String TRANSITION_ACTION_RECEIVER =
BuildConfig.APPLICATION_ID + "TRANSITION_ACTION_RECEIVER";
#Override
public void onReceive(Context context, Intent intent) {
if (TRANSITION_ACTION_RECEIVER == intent.getAction()) {
Log.d("DetectActivityReceiver", "Received an unsupported action.");
return;
}
if (ActivityTransitionResult.hasResult(intent)){
ActivityTransitionResult result = ActivityTransitionResult.extractResult(intent);
for (ActivityTransitionEvent event : result.getTransitionEvents()){
System.out.println(event.toString());
}
}
}
}
also added the receiver in Manifest.xml.
Expected to get the event in Receiver class, but didn't.
Related
I've made an Android app that main feature is to play audio stream from my server. But for some reason music stops playing after about 20 minutes and the app is throwing ProtocolException (logs from app on Android Studio logcat image).
Android Studio logcat
This error is even more weird because it occurs only on some devices. Error occurs on multiple Xiaomi devices (all with Android 10) and Samsung Galaxy S9 (also with Android 10) but on Samsung Galaxy S10 (Android 10) and Huawai tablet that error doesn't occur and music is being played as long as user does not stop it.
This is my PlayerService class code that is responsible for running MediaPlayer as a service:
public class PlayerService extends Service {
private static final String CHANNEL_ID = "PlayerServiceChannel";
private static final int SERVICE_ID = 1;
private MediaPlayer player;
private Notification notification;
private JsonObjectHandler jsonObjectHandler;
private int streamIndex = 9999;
private Messenger messenger;
private PendingIntent pendingIntent;
private NotificationManager notificationManager;
private PendingIntent closeApp;
private WifiManager.WifiLock wifiLock;
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
try {
JSONObject jsonObject = new JSONObject(Objects.requireNonNull(intent.getStringExtra("JsonInfo")));
jsonObjectHandler = new JsonObjectHandler(jsonObject);
} catch (JSONException e) {
jsonObjectHandler = null;
}
return START_REDELIVER_INTENT;
}
#Override
public void onCreate() {
super.onCreate();
wifiLock = ((WifiManager) getApplicationContext().getSystemService(Context.WIFI_SERVICE))
.createWifiLock(WifiManager.WIFI_MODE_FULL_HIGH_PERF, "playerServiceWiFiLock");
HandlerThread thread = new HandlerThread("ServiceStartArgument", Process.THREAD_PRIORITY_BACKGROUND);
thread.start();
Looper mServiceLooper = thread.getLooper();
ServiceHandler mServiceHandler = new ServiceHandler(mServiceLooper);
messenger = new Messenger(mServiceHandler);
PhoneStateListener mPhoneStateListener = new PhoneStateListener() {
#Override
public void onCallStateChanged(int state, String incomingNumber) {
switch (state) {
case TelephonyManager.CALL_STATE_RINGING:
case TelephonyManager.CALL_STATE_OFFHOOK:
stopForeground(true);
stopSelf();
break;
case TelephonyManager.CALL_STATE_IDLE:
break;
}
super.onCallStateChanged(state, incomingNumber);
}
};
TelephonyManager mgr = (TelephonyManager) getSystemService(TELEPHONY_SERVICE);
if (mgr != null) {
mgr.listen(mPhoneStateListener, PhoneStateListener.LISTEN_CALL_STATE);
}
createNotificationChannel();
Intent notificationIntent = new Intent(this, LoginActivity.class);
pendingIntent = PendingIntent.getActivity(this, 0, notificationIntent, 0);
BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
stopSelf();
unregisterReceiver(this);
System.exit(0);
}
};
IntentFilter intentFilter = new IntentFilter("android.intent.CLOSE_APP");
registerReceiver(broadcastReceiver, intentFilter);
Intent intentClose = new Intent("android.intent.CLOSE_APP");
closeApp = PendingIntent.getBroadcast(this, 0, intentClose, 0);
updateNotification(streamIndex);
startForeground(SERVICE_ID, notification);
}
private NotificationCompat.Builder createNotification(int streamIndex) {
String defaultValue;
if (jsonObjectHandler == null || streamIndex == 9999) {
defaultValue = "";
} else {
defaultValue =
jsonObjectHandler.getPlaylistButtons().get(streamIndex).getButtonName();
}
return new NotificationCompat.Builder(this, CHANNEL_ID)
.setSmallIcon(R.drawable.ikonastream48)
.setContentIntent(pendingIntent)
.setContentTitle(getString(R.string.app_name))
.setContentText(defaultValue)
.setDefaults(0)
.setSound(null)
.addAction(R.drawable.ic_close_black, getString(R.string.close), closeApp);
}
private void updateNotification(int streamIndex) {
notification = createNotification(streamIndex).build();
notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
assert notificationManager != null;
notificationManager.notify(SERVICE_ID, notification);
}
private void createNotificationChannel() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
NotificationChannel serviceChannel = new NotificationChannel(
CHANNEL_ID, "Example Service Channel", NotificationManager.IMPORTANCE_DEFAULT);
serviceChannel.setSound(null, null);
notificationManager = getSystemService(NotificationManager.class);
if (notificationManager != null) {
notificationManager.createNotificationChannel(serviceChannel);
}
}
}
private void stopServicePlayer() {
if (player != null) {
player.stop();
player.reset();
player.release();
player = null;
}
stopForeground(true);
}
#Override
public void onDestroy() {
super.onDestroy();
stopServicePlayer();
if (wifiLock.isHeld()) wifiLock.release();
}
private void sendMessageBroadcast(Intent intent) {
LocalBroadcastManager.getInstance(getApplicationContext()).sendBroadcast(intent);
}
#Nullable
#Override
public IBinder onBind(Intent intent) {
if (streamIndex != 9999) {
Intent intent1 = new Intent("streamIndex");
intent1.putExtra("INDEX", streamIndex);
sendMessageBroadcast(intent1);
}
return messenger.getBinder();
}
private final class ServiceHandler extends Handler {
ServiceHandler(Looper looper) {
super(looper);
}
#Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
if (msg.what == 0) {
player = new MediaPlayer();
player.setOnErrorListener((mp, what, extra) -> false);
player.setAudioAttributes(new AudioAttributes.Builder()
.setContentType(AudioAttributes.CONTENT_TYPE_MUSIC)
.setUsage(AudioAttributes.USAGE_MEDIA)
.build());
player.setAudioStreamType(AudioManager.STREAM_MUSIC);
player.setWakeMode(getApplicationContext(), PowerManager.PARTIAL_WAKE_LOCK);
streamIndex = msg.arg1;
updateNotification(streamIndex);
try {
player.setOnPreparedListener(mediaPlayer -> {
mediaPlayer.start();
Intent intent = new Intent("streamIndex");
intent.putExtra("INDEX", streamIndex);
sendMessageBroadcast(intent);
});
player.setDataSource(jsonObjectHandler
.getPlaylistButtons()
.get(streamIndex)
.getButtonStreamAddress());
} catch (IOException e) {
e.printStackTrace();
}
player.prepareAsync();
if (!wifiLock.isHeld()) wifiLock.acquire();
} else if (msg.what == 1) {
Intent intent2 = new Intent("streamIndex");
intent2.putExtra("INDEX", streamIndex);
sendMessageBroadcast(intent2);
}
}
}
}
Thank you for all responses in advance!
P.S. The code was written few years ago (at the beginning of my programming journey), so I'm aware that it looks bad and need to be rewritten in better way.
Disable caches and retry :
Map<String, String> headers = new HashMap<>();
headers.put("Content-Type", "audio/mp3");
headers.put("Accept-Ranges", "bytes");
headers.put("Status", "206");
headers.put("Cache-control", "no-cache");
Uri uri = Uri.parse(yourContentUrl);
player.setDataSource(getApplicationContext(), uri, headers);
The problem was on the server side. When the stream was switched from CBR to the VBR in the Lame encoder, the problem stop occurring.
I am creating an Android app that notify the users when they received a SMS from selected numbers using Foreground Service. The program only notify the user when the Service is running. My Main Activity has 3 buttons: Start Service, Stop Service and Setting which lead to another Activity that let the user change their information such as password and selected number. Currently the application can read and write data to JSON fine and the data get pass to other activities through Intent, also the Broadcast Receiver for detecting SMS also work when a message in received, and since I want it to work with Foreground Service, I register it in onStartCommand and unregister it in onDestroy in the Service and not register it in Manifest. My problem is on how to pass the user data to the Broadcast Receiver, since it is register to listen to android.provider.Telephony.SMS_RECEIVED and when I try to pass Intent to it through sentBroadcast() in my Service, it does not receive any value of the user. I tried to settle in making the user public static and it worked, but not sure if this the right way to do it. Here is my current code:
MainActivity.java
Button btnStartService, btnStopService;
TextView lblStatus;
JSONHandler jsonHandler;//for handling JSON file and data
public static User user;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btnStartService = findViewById(R.id.buttonStartService);
btnStopService = findViewById(R.id.buttonStopService);
jsonHandler = new JSONHandler(this);
boolean isFilePresent = isFilePresent(this, "user.json");
if(isFilePresent) {
try {
user = jsonHandler.readFromFile();
} catch (FileNotFoundException e) {
e.printStackTrace();
}
} else {
user = new User();
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
requestSmsPermission();
requestPermissions(new String[]{WRITE_EXTERNAL_STORAGE,READ_EXTERNAL_STORAGE}, 1);
}
else {
startService();
}
}
public boolean isFilePresent(Context context, String fileName) {
String path = context.getFilesDir().getAbsolutePath() + "/" + fileName;
File file = new File(path);
return file.exists();
}
public void setBtnStartService(View view)
{
startService();
}
public void setBtnStopService(View view)
{
stopService();
}
public void startService() {
Intent serviceIntent = new Intent(this, ForegroundService.class);
serviceIntent.putExtra("inputExtra", "Message Service is running");
serviceIntent.putExtra("user", user);
ContextCompat.startForegroundService(this, serviceIntent);
Toast.makeText(this, "Service Started", Toast.LENGTH_LONG).show();
}
public void stopService() {
Intent serviceIntent = new Intent(this, ForegroundService.class);
stopService(serviceIntent);
Toast.makeText(this, "Service Stopped", Toast.LENGTH_LONG).show();
}
public void setBtnSetting(View view) {
Intent intent = new Intent(this, AuthenticateActivity.class);
intent.putExtra("user", user);
intent.putExtra("action", "setting");
startActivity(intent);
}
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (requestCode == 1) {
startService();
}
}
private void requestSmsPermission() {
String permission = Manifest.permission.RECEIVE_SMS;
int grant = ContextCompat.checkSelfPermission(this, permission);
if ( grant != PackageManager.PERMISSION_GRANTED) {
String[] permission_list = new String[1];
permission_list[0] = permission;
ActivityCompat.requestPermissions(this, permission_list, 1);
}
}
ForegroundService.java
public class ForegroundService extends Service {
public static final String CHANNEL_ID = "ForegroundServiceChannel";
SMSReceiver smsListener;
#Override
public void onCreate() {
super.onCreate();
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
String input = intent.getStringExtra("inputExtra");
User user = (User) intent.getSerializableExtra("user");
createNotificationChannel();
Intent notificationIntent = new Intent(this, MainActivity.class);
PendingIntent pendingIntent = PendingIntent.getActivity(this,
0, notificationIntent, 0);
Notification notification = new NotificationCompat.Builder(this, CHANNEL_ID)
.setContentTitle("Foreground Service")
.setContentText(input)
.setSmallIcon(R.drawable.ic_launcher_background)
.setContentIntent(pendingIntent)
.build();
startForeground(1, notification);
//do heavy work on a background thread
if(smsListener == null)
{
smsListener = new SMSReceiver();
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction("android.provider.Telephony.SMS_RECEIVED");
Intent i = new Intent(this, SMSReceiver.class);
i.putExtra("user", user);
sendBroadcast(i);
registerReceiver(smsListener, intentFilter);
}
//stopSelf();
return START_NOT_STICKY;
}
#Override
public void onDestroy() {
super.onDestroy();
if(null!=smsListener)
{
unregisterReceiver(smsListener);
smsListener = null;
}
}
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
private void createNotificationChannel() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
NotificationChannel serviceChannel = new NotificationChannel(
CHANNEL_ID,
"Foreground Service Channel",
NotificationManager.IMPORTANCE_DEFAULT
);
NotificationManager manager = getSystemService(NotificationManager.class);
manager.createNotificationChannel(serviceChannel);
}
}
}
SMSReceiver.java
public class SMSReceiver extends BroadcastReceiver {
private String msgBody;
private String text = "";
private SharedPreferences preferences;
private String sender = "";
#Override
public void onReceive(Context context, Intent intent) {
// TODO Auto-generated method stub
// User user = (User) intent.getExtras().getSerializable("user"); not working
User user = MainActivity.user;
ArrayList<String> banks = user.getBankList();
if (intent.getAction().equals("android.provider.Telephony.SMS_RECEIVED")) {
Toast.makeText(context, "message received", Toast.LENGTH_SHORT).show();
Bundle bundle = intent.getExtras();
try {
if (bundle != null) {
final Object[] pdus = (Object[]) bundle.get("pdus");
SmsMessage smsMessage;
for (int i = 0; i < pdus.length; i++) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP)
smsMessage = SmsMessage.createFromPdu((byte[]) pdus[i], bundle.getString("format"));
else smsMessage = SmsMessage.createFromPdu((byte[]) pdus[i]);
msgBody = smsMessage.getMessageBody();
sender = smsMessage.getOriginatingAddress();
if(banks.contains(sender)) {
if (msgBody.contains(user.getPattern())) {
String[] tokens = msgBody.split(" ");
for (int j = 0; j < tokens.length; j++) {
if (tokens[j].contains("API")) {
text = tokens[j];
break;
}
}
}
}
}
//MainActivity.message = msgBody;
if(!text.isEmpty()) {
Toast.makeText(context, "message is: " + text, Toast.LENGTH_SHORT).show();
}
}
} catch (Exception e) {
Log.d("Exception caught", e.getMessage());
}
}
else {
Log.i("cs.fsu", "smsReceiver : NULL");
}
}
}
Is this the right way to maintain user data throughout the application lifecycle? By making public static for every class accessible? Or is there away to pass it through Intent? Please help me out
I created a service that updates the GPS coordinates and sends them to FireBase Realtime Database. The service starts when the user accesses the home page. I want to be able to send a String from an Activity to the service Class.The problem is that i can't call the getIntent() method inside of the loginToFirebase() function .
Here is the code that I tried :
The service class :
public class TrackerService extends Service {
private static final String TAG = TrackerService.class.getSimpleName();
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onCreate() {
super.onCreate();
buildNotification();
loginToFirebase();
}
private void buildNotification() {
String stop = "stop";
registerReceiver(stopReceiver, new IntentFilter(stop));
PendingIntent broadcastIntent = PendingIntent.getBroadcast(
this, 0, new Intent(stop), PendingIntent.FLAG_UPDATE_CURRENT);
// Create the persistent notification
NotificationCompat.Builder builder = new NotificationCompat.Builder(this)
.setContentTitle(getString(R.string.app_name))
.setContentText("Suivi de la position ...")
.setOngoing(true)
.setContentIntent(broadcastIntent)
.setSmallIcon(R.drawable.alert);
startForeground(1, builder.build());
}
protected BroadcastReceiver stopReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
Log.d(TAG, "received stop broadcast");
// Stop the service when the notification is tapped
unregisterReceiver(stopReceiver);
stopSelf();
}
};
private void loginToFirebase() {
String password = "myPassword";
FirebaseAuth.getInstance().signInWithEmailAndPassword(
email, password).addOnCompleteListener(new OnCompleteListener<AuthResult>(){
#Override
public void onComplete(Task<AuthResult> task) {
if (task.isSuccessful()) {
Log.d(TAG, "firebase auth success");
requestLocationUpdates();
} else {
Log.d(TAG, "firebase auth failed");
}
}
});
}
private void requestLocationUpdates() {
LocationRequest request = new LocationRequest();
request.setInterval(30000);
request.setFastestInterval(30000);
request.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
FusedLocationProviderClient client = LocationServices.getFusedLocationProviderClient(this);
final String path = "locations" + "/" + 123;
int permission = ContextCompat.checkSelfPermission(this,
Manifest.permission.ACCESS_FINE_LOCATION);
if (permission == PackageManager.PERMISSION_GRANTED) {
client.requestLocationUpdates(request, new LocationCallback() {
#Override
public void onLocationResult(LocationResult locationResult) {
try {
DatabaseReference ref = FirebaseDatabase.getInstance().getReference(path);
Location location = locationResult.getLastLocation();
if (location != null) {
Log.d(TAG, "location update " + location);
ref.setValue(location);
}
}catch (Exception e){
}
}
}, null);
}
}
}
The method from which I'm calling the service (In the activity ):
private void startTrackerService() {
Intent goService= new Intent(AccueilEtudiant.this,TrackerService.class);
goService.putExtra("email",getIntent().getStringExtra("email"));
startService(goService);
}
Any recommendations?
i suggest you to use persistence . in your service use data you get from sharedPreferences , and in your activity , keep updating the sharedPreferences
gps info got updated => persist to storage => use persisted gps info in Service
The Service has to read the data from the chosen storage before sending the data.
I am trying to send a broadcast receiver from a service and i have a issue, the receiver leak and i don't know why.
Here is the code:
public class CameraCapture extends AppCompatActivity {
static final int REQUEST_IMAGE_CAPTURE = 30;
String URL;
VolleyService mVolleyService;
IResult mResultCallback = null;
final String POSTREQUEST = "POSTCALL";
Map<String, String> params;
String token;
BroadcastReceiver receiver;
IntentFilter filter;
MyReceiver reciver;
boolean mBounded;
GoogleLocation mlocation;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
token = checkForToken();
URL = "http://10.0.2.2:3000/fotos/Tulipa";
filter = new IntentFilter("com.myapp.LOCATION_CHANGED");
reciver = new MyReceiver();
registerReceiver(reciver,filter);
String imageFilePath = Environment.getExternalStorageDirectory().getAbsolutePath() + "/picture.jpg";
File imageFile = new File(imageFilePath);
Uri imageFileUri = Uri.fromFile(imageFile); // convert path to Uri
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.CAMERA}, REQUEST_IMAGE_CAPTURE);
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
if (intent.resolveActivity(getPackageManager()) != null) {
startActivityForResult(intent, REQUEST_IMAGE_CAPTURE);
}
}
#Override
protected void onStart() {
super.onStart();
Intent mIntent = new Intent(this, GoogleLocation.class);
bindService(mIntent, mConnection, BIND_AUTO_CREATE);
}
public void onResume() {
super.onResume();
Log.d("RESUME","RESUME");
reciver = new MyReceiver();
registerReceiver(reciver, filter);
}
public void onPause() {
super.onPause();
if(reciver != null){
unregisterReceiver(reciver);
reciver= null;
}
}
public void onStop() {
super.onStop();
if(mBounded) {
unbindService(mConnection);
mBounded = false;
}
}
private byte[] encodeImage(Bitmap bm) {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
bm.compress(Bitmap.CompressFormat.JPEG, 100, baos);
byte[] b = baos.toByteArray();
return b;
}
private void sendImage(byte[] b) {
ImageStore.getInstance().setCapturedPhotoData(b);
mlocation.getBroadcastData();
Intent i = new Intent(CameraCapture.this, SimiliarPhotos.class);
startActivity(i);
finish();
//inicialize a map with pair key value
//params = new HashMap<String, String>();
// Add form fields to the map
//GoogleLocation l = new GoogleLocation(this);
//l.getPosition();
//Log.d("myLat",String.valueOf(l.getLat()));
//params.put("base64", encodedImage);
//params.put("token",token);
//Log.d("latitudeOP",String.valueOf(l.getLat()));
//JSONObject sendObj = new JSONObject(params);
//initVolleyCallback();
//mVolleyService = new VolleyService(mResultCallback, this);
//mVolleyService.postDataVolley(POSTREQUEST, URL, sendObj);
}
public void showToast(String message) {
Toast toast = Toast.makeText(this, message, Toast.LENGTH_LONG);
toast.show();
}
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
switch (requestCode) {
case 30: {
if (grantResults.length > 0
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
} else {
Toast.makeText(CameraCapture.this, "Permission denied to read your External storage", Toast.LENGTH_SHORT).show();
}
return;
}
}
}
void initVolleyCallback() {
mResultCallback = new IResult() {
#Override
public void notifySuccess(String requestType, JSONObject response) {
}
#Override
public void notifySuccess(String requestType, JSONArray response) {
}
#Override
public void notifyError(String requestType, VolleyError error) {
String body;
if (error.networkResponse.data != null) {
String statusCode = String.valueOf(error.networkResponse.statusCode);
try {
body = new String(error.networkResponse.data, "UTF-8");
JSONObject jsonObj = new JSONObject(body);
Log.d("body", String.valueOf(jsonObj.get("message")));
showToast(String.valueOf(jsonObj.get("message")));
} catch (UnsupportedEncodingException e) {
showToast("You need to connect to the internet!");
} catch (JSONException e) {
Log.d("json:", "problems decoding jsonObj");
}
}
}
};
}
ServiceConnection mConnection = new ServiceConnection() {
public void onServiceDisconnected(ComponentName name) {
mBounded = false;
mlocation = null;
}
public void onServiceConnected(ComponentName name, IBinder service) {
mBounded = true;
GoogleLocation.LocalBinder mLocalBinder = (GoogleLocation.LocalBinder)service;
mlocation = mLocalBinder.getServerInstance();
}
};
as you guys can see i register the receiver 2 times, oncreate and onResume, and then i destroy it onStop.
The problem is you are registering it twice. remove the code from onCreate and keep it only in onResume. Also if you are registering it in onResume then unRegister it in onPause to match the lifecycle events properly.
Always register receiver in onStart() and unregister in onStop().
Since you registering receiver in onCreate(), you have to unregister in onDestroy() as well as there is a chance that activity ends up with only onCreate() and onDestroy() call backs.
Do not forget to unregister a dynamically registered receiver by using Context.unregisterReceiver() method. If you forget this, the Android system reports a leaked broadcast receiver error. For instance, if you registered a receive in onResume() methods of your activity, you should unregister it in the onPause() method.
I am trying to schedule local notifications in my app. Here is my RootReceiver class.
public class RebootReceiver extends BroadcastReceiver {
private String EVENT_CATEGORY = "notification_event";
#Override
public void onReceive(Context context, Intent intent) {
Debug.waitForDebugger();
AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
Intent intent1 = new Intent(context, AlarmScheduler.class);
PendingIntent intentExecuted = PendingIntent.getBroadcast(context, 0, intent1, PendingIntent.FLAG_CANCEL_CURRENT);
Calendar now = Calendar.getInstance();
if (!GeneralMethods.getBooleanPreference(context, ProperatiPreferences.APP_FIRST_LAUNCH)) {
intent1.putExtra(EVENT_CATEGORY, "");
now.add(Calendar.HOUR, 2);
alarmManager.set(AlarmManager.RTC_WAKEUP, now.getTimeInMillis(), intentExecuted);
} else if (!GeneralMethods.getBooleanPreference(context, ProperatiPreferences.SEARCH_AFTER_THREE_DAYS)) {
intent1.putExtra(EVENT_CATEGORY, "");
now.add(Calendar.DATE, 3);
alarmManager.set(AlarmManager.RTC_WAKEUP, now.getTimeInMillis(), intentExecuted);
}
}
}
In here as you can see, I want to create an intent in which I want to put some data (intent1). However the intent is always empty without any extras inside of it. What am I doing wrong?
Here is how I try to retrieve extras from the intent.
public class AlarmScheduler extends BroadcastReceiver {
private String EVENT_CATEGORY = "notification_event";
#Override
public void onReceive(final Context context, final Intent intent) {
Log.d("com.properati.user", "AlarmScheduler.onReceive() called");
Intent eventService = new Intent(context, AlarmService.class);
context.startService(eventService);
}
and finally my AlarmService class:
public class AlarmService extends Service {
private String EVENT_CATEGORY = "notification_event";
#Override
public IBinder onBind(final Intent intent) {
return null;
}
#Override
public int onStartCommand(final Intent intent, final int flags, final int startId) {
Log.d("com.properati.user", "event received in service: " + new Date().toString());
if(intent.getStringExtra(EVENT_CATEGORY).equals(ProperatiPreferences.APP_FIRST_LAUNCH)){
new PushNotification(getApplicationContext()).scheduleNonOpenedNotification(getApplicationContext());
}else if(intent.getStringExtra(EVENT_CATEGORY).equals(ProperatiPreferences.SEARCH_AFTER_THREE_DAYS)){
new PushNotification(getApplicationContext()).scheduleNoSearchAfterThreeDays(getApplicationContext());
}
return Service.START_NOT_STICKY;
}
Try the following code in AlarmScheduler class
public class AlarmScheduler extends BroadcastReceiver {
private String EVENT_CATEGORY = "notification_event";
#Override
public void onReceive(final Context context, final Intent intent) {
Log.d("com.properati.user", "AlarmScheduler.onReceive() called");
Intent eventService = new Intent(context, AlarmService.class);
eventService.putExtra(intent.getStringExtra(EVENT_CATEGORY, ""));
context.startService(eventService);
}
after I checked the PendingIntent source in Android framework, the intent argument will be cloned by new Intent(intent). so you need set all data to intent1 before passing it to PendingIntent constructor.
#Override
public IIntentSender getIntentSender(int type,
String packageName, IBinder token, String resultWho,
int requestCode, Intent[] intents, String[] resolvedTypes,
int flags, Bundle options, int userId) {
enforceNotIsolatedCaller("getIntentSender");
// Refuse possible leaked file descriptors
if (intents != null) {
if (intents.length < 1) {
throw new IllegalArgumentException("Intents array length must be >= 1");
}
for (int i=0; i<intents.length; i++) {
Intent intent = intents[i];
if (intent != null) {
if (intent.hasFileDescriptors()) {
throw new IllegalArgumentException("File descriptors passed in Intent");
}
if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
(intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
throw new IllegalArgumentException(
"Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
}
intents[i] = new Intent(intent);
}
}
if (resolvedTypes != null && resolvedTypes.length != intents.length) {
throw new IllegalArgumentException(
"Intent array length does not match resolvedTypes length");
}
}