I am trying to make a feature as part of my android app, where a user interacts with a geofence based on their location on a map and it will fire up a dialog telling the user they are near the starting point of the route using a BroadcastReceiver in its own class.
So far I can trigger it and provide Toast messages, but I can't seem to use it to trigger a UI change in my other activity.
Here is my BroadcastReceiver class -
public class GeofenceBroadcastReceiver extends BroadcastReceiver {
private static final Object TAG = "Error";
#Override
public void onReceive(Context context, Intent intent) {
GeofencingEvent geofencingEvent = GeofencingEvent.fromIntent(intent);
if (geofencingEvent.hasError()) {
Log.d("TOASTY", "onReceive: Geofence even has error..");
}
List<Geofence> triggeredGeofenceList = geofencingEvent.getTriggeringGeofences();
for (Geofence geofence : triggeredGeofenceList) {
Log.d("GEOF", "onReceive: "+geofence.getRequestId());
}
Location triggerLocation = geofencingEvent.getTriggeringLocation();
double lat = triggerLocation.getLatitude();
double lon = triggerLocation.getLongitude();
Toast.makeText(context, "GEOFENCE TRIGGERED AT : LAT IS :" + lat + " LON IS : " +lon, Toast.LENGTH_SHORT).show();
int transitionType = geofencingEvent.getGeofenceTransition();
switch (transitionType) {
case Geofence.GEOFENCE_TRANSITION_ENTER:
Toast.makeText(context, "Entered Geofence", Toast.LENGTH_SHORT).show();
Log.d("GEOF", "onReceive: "+geofencingEvent.getGeofenceTransition());
break;
case Geofence.GEOFENCE_TRANSITION_DWELL:
Toast.makeText(context, "Dwelling inside of Geofence", Toast.LENGTH_SHORT).show();
break;
case Geofence.GEOFENCE_TRANSITION_EXIT:
Toast.makeText(context, "Exited Geofence area", Toast.LENGTH_SHORT).show();
break;
}
Bundle b = intent.getExtras();
Intent i = new Intent(context, routeActivity.class);
i.putExtra("lat", lat);
i.putExtra("lon", lon);
i.putExtras(b);
Log.d("LOLCALLY", "onReceive: "+i);
context.sendBroadcast(i);
}
}
My thinking was to use intent, I have tried to pull the triggered location (which I can see is correct in the log output) into my other activity but no joy.
Many thanks!
You need to register your receiver on your activity and process its callback:
public class MyActivity extends AppCompatActivity {
private BroadcastReceiver geofenceReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
// Pull triggered location and use it to update the activity
}
};
#Override
protected void onResume() {
super.onResume();
registerReceiver(geofenceReceiver, new IntentFilter("YOUR_GEOFENCE_ACTION"));
}
#Override
protected void onPause() {
super.onPause();
unregisterReceiver(geofenceReceiver);
}
}
Related
I am trying to make a social media app , Im using fragments within BottomNavigation (home - smart room - notifications - profile), And Im using a floating button to switch to "Add post" activity , Now Im having a problem with the back button , i want it to take me to the recent visited fragment but it always take me to the home fragment
here is my BottomNavigation activity code :
public class BottomNavigationActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_bottom_navigation);
BottomNavigationView bottomNav = findViewById(R.id.bottom_navigation_layout);
//setEnabled(false) for the 2nd index because we're using a floating button instead
bottomNav.setBackground(null);
bottomNav.getMenu().getItem(2).setEnabled(false);
bottomNav.setOnItemSelectedListener(navListener);
//start AddPostActivity class
FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
fab.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
startActivity(new Intent(getApplicationContext(), AddPostActivity.class));
finish();
}
});
}
//Switch between fragments
public BottomNavigationView.OnItemSelectedListener navListener =
new BottomNavigationView.OnItemSelectedListener() {
#Override
public boolean onNavigationItemSelected(#NonNull MenuItem item) {
Fragment selectedFragment = null;
switch (item.getItemId()) {
case R.id.nav_home:
selectedFragment = new HomeFragment();
break;
case R.id.nav_sr:
selectedFragment = new SmartRoomFragment();
break;
case R.id.nav_notif:
selectedFragment = new NotificationsFragment();
break;
case R.id.nav_profile:
selectedFragment = new ProfileFragment();
break;
}
getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container,
selectedFragment).commit();
return true;
}
};
}
I want the best solution to handle this problem , thanks in advance!
public class MainActivity extends AppCompatActivity {
public ConsumerIrManager consumerIrManager;
public Vibrator v;
public int frequency = 38000;
public int t = 0;
public Handler handler = new Handler();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
consumerIrManager = (ConsumerIrManager) getSystemService(CONSUMER_IR_SERVICE);
v=(Vibrator) getSystemService(VIBRATOR_SERVICE);
}
i want to add a event on plus button when i pressed the button it works continuously till i am released button.
for Example :- Tv Remote Button when i press volume + button the volume increase continuously till releasing.
public void onClick(View view) {
if(!consumerIrManager.hasIrEmitter()) {
Toast.makeText(getApplicationContext(), "IR Emitter Not Found in Your Device", Toast.LENGTH_LONG).show();
return;
}
switch (view.getId()) {
case R.id.power:
v.vibrate(VibrationEffect.createOneShot(200,VibrationEffect.DEFAULT_AMPLITUDE));
if (t==0) {
Log.i("Button pressed", "Power");
// textt.setText("0");
for(i=0;i<3;i++) {
consumerIrManager.transmit(frequency,btn.power);
}
t=1;
}
else{
Log.i("Button pressed", "Power1");
consumerIrManager.transmit(frequency,btn.power0);
t=0;
}
break;
case R.id.plus:
v.vibrate(VibrationEffect.createOneShot(200,VibrationEffect.DEFAULT_AMPLITUDE));
if (t==0) {
consumerIrManager.transmit(frequency, btn.plus);
Log.i("Button pressed", "Plus");
t=1;
}
else{
consumerIrManager.transmit(frequency, btn.plus0);
strong text Log.i("Button pressed", "Plus1");
t=0;
}
break;
I want to upload image and pass string(UID) from startActivityForResult to onActivityResult, and get the string(UID) on onActivityResult.
The startActivityForResult in RecyclerView and onActivityResult in MainActivity.
I can upload image but can't get the string(UID), the string(UID) is null on onActivityResult.
The Null Message
I would appreciate if someone can help me with my questions.
Here is startActivityForResult in RecyclerView:
class ViewHolder extends RecyclerView.ViewHolder {
private TextView textView;
private Button UploadImageButton;
ViewHolder(View itemView) {
super(itemView);
textView = itemView.findViewById(R.id.textView);
UploadImageButton = itemView.findViewById(R.id.UploadImageButton);
UploadImageButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent intent = new Intent();
intent.setType("image/*");
intent.addCategory(Intent.CATEGORY_OPENABLE);
intent.setAction(Intent.ACTION_GET_CONTENT);
intent.putExtra(Intent.EXTRA_LOCAL_ONLY, true);
intent.putExtra("UID", textView.getText().toString());
((Activity) context).startActivityForResult(intent, 6);
}
});
}
}
Here is onActivityResult in MainActivity:
public void onActivityResult(int requestCode, int resultCode, Intent resultData) {
super.onActivityResult(requestCode, resultCode, resultData);
if (resultCode == RESULT_OK) {
if (resultData != null) {
String UID = resultData.getStringExtra("UID");
Log.d("UID", UID);
}
}
}
The layout placement
Note
Your startActivityForResult() will only give result of the selected image in the form of Uri. Which means, whatever extras you sent via the intent is useless.
So to solve your issue, one thing you can do is first get the result of the startActivityForResult(), i.e. image Uri, then combine that with the "UID" and then pass these to he MainActivity.
been alright so far. I try to use docs or find my issues.
However my mainActivity has 4 buttons. These buttons depending on which view is clicked passes the R.id.button. I pass this value into an intent which Activity2 uses bundle to get id integer. I then setContentView using this.
However im having issues getting correct view to inflate now, it seems like its loading an old layout. My aim is to inflate 3 separate layout on Activity2 depending which button was clicked.
I know my other other button does inflate another activity and get proper xml layout.
Why are my other 3 buttons not inflating on Activity2 properly?
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
Button pizza;
Button hamburger;
Button icecream;
Button history;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
pizza = findViewById(R.id.buttonPizza);
hamburger = findViewById(R.id.buttonBurger);
icecream = findViewById(R.id.buttonIceCream);
history = findViewById(R.id.buttonHistroy);
pizza.setOnClickListener(this);
hamburger.setOnClickListener(this);
icecream.setOnClickListener(this);
history.setOnClickListener(this);
}
#Override
public void onClick(View v){
int idView = v.getId();
switch(v.getId()) {
case R.id.buttonBurger : startOrderActivity(R.layout.burger_layout);
makeToast(idView);
break;
case R.id.buttonPizza : startOrderActivity(R.layout.pizza_layout);
makeToast(idView);
break;
case R.id.buttonIceCream : startOrderActivity(R.layout.icecream_layout);
makeToast(idView);
break;
case R.id.buttonHistroy : startOrderActivity(R.layout.history_layout);
makeToast(idView);
break;
}
}
private void startOrderActivity(int id){
if(id != R.layout.history_layout) {
Intent intentOrder = new Intent(this, MakeOrderActivity.class);
intentOrder.putExtra("layout", id);
startActivity(intentOrder);
}
else {
Intent intentOrder = new Intent(this, OrderHistoryActivity.class);
intentOrder.putExtra("layout", id);
startActivity(intentOrder);
}
}
public void makeToast(int id){
String txt = String.valueOf(id);
Toast newToast = Toast.makeText(getApplicationContext(),txt,Toast.LENGTH_LONG);
newToast.show();
}
}
public class MakeOrderActivity extends AppCompatActivity {
Button placeOrderButton;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Bundle data = getIntent().getExtras();
int layoutNum = data.getInt("layout");
setContentView(layoutNum);
placeOrderButton = findViewById(R.id.placeOrder);
}
#Override
protected void onStart() {
super.onStart();
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.order, menu);
return true;
}
public void onCheckboxClicked(View view){
}
}
Answer is to create a View which is created by getInflator.
https://stackoverflow.com/a/17070408/8443090
I am currently using the AlarmManager, Broadcast receiver and Intent Service to implement upload service to server rub by background instead of Ui Main Thread but the problem is when it comes to the execution , there is no response for the upload message . At least, in the logcat, I can see any message reporting the progress for the upload weven I have typed and tested correctly.
But afer the upload service is finished , it shows
java.lang.RuntimeException: Handler (android.os.Handler) sending message to a Handler on a dead thread
Would you please tell me what else is missing ?
The below is my code
Intnt Service
public class TaskService extends IntentService {
public TaskService() {
super("TaskService");
// TODO Auto-generated constructor stub
}
#Override
protected void onHandleIntent(Intent arg0) {
// Do some task
Log.i("TaskService","Service running");
boolean ss = uploadRecording("TEST_RECORD" , "test.mp4" , "http://210.177.246.83/uploadFile");
Log.d("Is file uploaded" , String.valueOf(ss));
}
public boolean uploadRecording(String directoryname , String filename , String destination) {
// TODO Auto-generated method stub
boolean result = false;
String destinationPath = destination;
File tes = new File(Environment.getExternalStorageDirectory() + File.separator + directoryname);
File frecord = new File(tes.getAbsolutePath() + File.separator + filename);
if(tes.exists()){
if(frecord.exists()){
List< NameValuePair> httpContents = new ArrayList< NameValuePair>();
httpContents.add(new BasicNameValuePair("file",frecord.getAbsolutePath()));
HttpClient client=new DefaultHttpClient();
HttpPost post=new HttpPost(destinationPath);
try{
//setup multipart entity
MultipartEntity entity=new MultipartEntity(HttpMultipartMode.BROWSER_COMPATIBLE);
for(int i=0;i< httpContents.size();i++){
//identify param type by Key
if(httpContents.get(i).getName().equals("file")){
File f=new File(httpContents.get(i).getValue());
FileBody fileBody=new FileBody(f);
entity.addPart("file"+i,fileBody);
}
}
post.setEntity(entity);
//create response handler
//execute and get response
HttpResponse uploadReponse = client.execute(post);
Log.d("debug" , "Response : " + uploadReponse);
if(uploadReponse.getStatusLine().getStatusCode() == 200){
result = true;
Toast.makeText(getApplicationContext(), "Upload Success", Toast.LENGTH_SHORT).show();
}
}catch(Exception e){
e.printStackTrace();
}
}
}
return result;
}
}
BroadCast Receiver
public static String ACTION_ALARM = "com.alarammanager.alaram";
#Override
public void onReceive(Context context, Intent intent) {
Log.i("Alarm Receiver", "Entered");
Toast.makeText(context, "Entered", Toast.LENGTH_SHORT).show();
Bundle bundle = intent.getExtras();
String action = bundle.getString(ACTION_ALARM);
if (action.equals(ACTION_ALARM)) {
Log.i("Alarm Receiver", "If loop");
Toast.makeText(context, "If loop", Toast.LENGTH_SHORT).show();
Intent inService = new Intent(context, TaskService.class);
inService.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startService(inService);
}
else
{
Log.i("Alarm Receiver", "Else loop");
Toast.makeText(context, "Else loop", Toast.LENGTH_SHORT).show();
}
}
Main Acitvity
public class AlaramScheduleActivity extends Activity {
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}
public void btnStartSchedule(View v) {
try {
AlarmManager alarms = (AlarmManager) this
.getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(getApplicationContext(),
AlaramReceiver.class);
intent.putExtra(AlaramReceiver.ACTION_ALARM,
AlaramReceiver.ACTION_ALARM);
final PendingIntent pIntent = PendingIntent.getBroadcast(this,
1234567, intent, PendingIntent.FLAG_UPDATE_CURRENT);
alarms.setRepeating(AlarmManager.RTC_WAKEUP,
System.currentTimeMillis(), 1000 * 10, pIntent);
toast("Started...");
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void btnCancelSchedules(View v) {
Intent intent = new Intent(getApplicationContext(),
AlaramReceiver.class);
intent.putExtra(AlaramReceiver.ACTION_ALARM,
AlaramReceiver.ACTION_ALARM);
final PendingIntent pIntent = PendingIntent.getBroadcast(this, 1234567,
intent, PendingIntent.FLAG_UPDATE_CURRENT);
AlarmManager alarms = (AlarmManager) this
.getSystemService(Context.ALARM_SERVICE);
alarms.cancel(pIntent);
toast("Canceled...");
}
public void toast(String message) {
Toast.makeText(getApplicationContext(), message, Toast.LENGTH_SHORT)
.show();
}
Android Manifest
INTERNET Permisson is acquired
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<service android:name=".TaskService" >
</service>
<receiver
android:name="AlaramReceiver"
android:process=":remote" >
</receiver>
Your problem is in Toast message shown from IntentService.
Fix is simple: create Handler in onCreate of your service and post Runnable to show toast from it.
public class TaskService extends IntentService {
...
private Handler mHandler;
protected void onCreate() {
mHandler = new Handler();
}
...
public boolean uploadRecording(... {
...
mHandler.post(new Runnable() {
public void run() {
Toast.makeText(getApplicationContext(), "Upload Success", Toast.LENGTH_SHORT).show();
}
});
...
}
}
Internally toast uses Handler to communicate with INotificationManager. Once toast created it create instance of Handler, which uses looper from the thread it is created. In your case it is HandlerThread of IntentService. It is interrupted once service finished all work. That is why it is dead.