I want that both dialog and incoming call screen be clickable. I have tried different solutions from this site, but some works in some condtions and others don't. I want to create an app like true caller, I have called an activity from BroadcastReceiver. My code works perfectly when the screen is not locked because the incoming screen is not full screen. But when the screen is full screen the dialog activity appears for few milliseconds over the calling screen and then goes behind the calling screen.
Here is my code of my activity which I called from BroadcastReceiver
public class IncomingCallActivity extends AppCompatActivity {
private static final int MSG_ID_CHECK_TOP_ACTIVITY = 1;
private String userName;
private String TAG = IncomingCallActivity.class.getSimpleName();
private Window wind;
private PowerManager powerManager;
private PowerManager.WakeLock wakeLock;
/*private ActivityManager mActivityManager;
private boolean mDismissed = false;*/
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
wind = this.getWindow();
wind.requestFeature(Window.FEATURE_NO_TITLE);
wind.addFlags(WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD);
wind.addFlags(WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED);
wind.addFlags(WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON);
wind.addFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL);
powerManager = (PowerManager)getSystemService(Context.POWER_SERVICE);
wakeLock = powerManager.newWakeLock(PowerManager.FULL_WAKE_LOCK, "My Lock");
wakeLock.acquire();
setContentView(R.layout.activity_incoming_call);
userName = getIntent().getStringExtra(IncomingCallReceiver.NAME_KEY);
final TextView textView = (TextView) findViewById(R.id.tvUsername);
textView.setText(userName);
final ImageView ivCancel = (ImageView) findViewById(R.id.ivCancel);
ivCancel.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
wakeLock.release();
IncomingCallActivity.this.finish();
}
});
}
}
//Add Permissions in Manifest file and don't forget to check overlay permission
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>
<uses-permission android:name="android.permission.SYSTEM_OVERLAY_WINDOW"/>
//Create Class Level Variable or as per requirement
WindowManager.LayoutParams mWindowsParams;
WindowManager mWindowManager;
View mDialogView;
//initialize variable
mWindowsParams =new WindowManager.LayoutParams(WindowManager.LayoutParams.MATCH_PARENT,
WindowManager.LayoutParams.WRAP_CONTENT,
WindowManager.LayoutParams.TYPE_SYSTEM_ERROR,
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
PixelFormat.TRANSLUCENT);
mWindowManager=(WindowManager)context.getSystemService(Context.WINDOW_SERVICE);
//Add Window on your event
mWindowManager.addView(mDialogView, mWindowsParams);
//For Remove window
if (mDialogView.getParent() != null) {
try {
mWindowManager.removeViewImmediate(mDialogView);
} catch (Exception e) {
}
}
Related
I'm adding a small TextView at the bottom of my app when the app goes offline. So I have a BroadcastReceiver that monitors network connectivity changes and in the onReceive, I show the banner. Here is the banner class which adds the TextView on top of the existing view:
public static void show() {
if (!isShowing && !isAppBackgrounded()) {
MyApplication app = MyApplication.getInstance();
WindowManager windowManager = (WindowManager) app.getSystemService(Context.WINDOW_SERVICE);
Resources res = app.getResources();
TextView offlineTv = app.getOfflineTv();
if (offlineTv.getWindowToken() != null) {
return;
}
offlineTv.setText("Offline");
offlineTv.setTextColor(ContextCompat.getColor(app, R.color.yellow));
offlineTv.setGravity(Gravity.CENTER);
offlineTv.setBackgroundColor(ContextCompat.getColor(app, R.color.dark_grey));
offlineTv.setTextSize(TypedValue.COMPLEX_UNIT_SP, app.getResources().getInteger(R.integer.offline_banner_text_size));
WindowManager.LayoutParams params = createLayoutParams(WindowManager.LayoutParams.TYPE_TOAST, null);
windowManager.addView(offlineTv, params);
isShowing = true;
}
}
Here is the createLayoutParams method
private static WindowManager.LayoutParams createLayoutParams(int type, #Nullable IBinder windowToken) {
WindowManager.LayoutParams layoutParams = new WindowManager.LayoutParams();
layoutParams.format = PixelFormat.TRANSLUCENT;
layoutParams.width = WindowManager.LayoutParams.MATCH_PARENT;
layoutParams.height = 25;
layoutParams.gravity = GravityCompat.getAbsoluteGravity(Gravity.CENTER_HORIZONTAL | Gravity.BOTTOM, ViewCompat.LAYOUT_DIRECTION_LTR);
layoutParams.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
layoutParams.type = type;
layoutParams.token = windowToken;
layoutParams.windowAnimations = android.R.style.Animation_Toast;
return layoutParams;
}
This code works fine on all the devices but 7.1.1 devices. In 7.1.1 device, the TextView shows for a while and then disappears. There is just a blank white space instead of the TextView on 7.1.1 devices. Any idea why is it happening?
EDIT: as asked in the comment, here is how I get the TextView: This is MyApplication class extending Application:
TextView offlineTv = null;
/** Get the TextView to show the offline message */
public TextView getOfflineTv() {
if (offlineTv == null) {
offlineTv = new TextView(this);
}
return offlineTv;
}
/** Clear the offline TextView once we are done showing it */
public void clearOfflineTv() {
if (offlineTv != null) {
offlineTv = null;
}
}
And this is my BroadcastReceiver, where I show / hide it:
public class DSConnectionChangeReceiver extends BroadcastReceiver {
/**
* Connection-changed callback
* #param context Context
* #param intent Intent
*/
#Override
public void onReceive(Context context, Intent intent) {
ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo activeNetworkInfo = cm.getActiveNetworkInfo();
boolean connected = false;
boolean isCellularData = false;
if (activeNetworkInfo != null) {
connected = activeNetworkInfo.isAvailable() && activeNetworkInfo.isConnected();
int type = activeNetworkInfo.getType();
isCellularData = (type == ConnectivityManager.TYPE_MOBILE) || (type == ConnectivityManager.TYPE_MOBILE_DUN);
}
if (connected) {
if (OfflineBanner.isShowing()) {
OfflineBanner.dismiss();
}
} else {
OfflineBanner.show();
}
}
}
The problem is caused by you adding the android.R.style.Animation_Toast windowAnimation. When the animation finishes on an actual Toast the whole toast would disappear. In this case your view is in the hierarchy so instead of disappearing, it becomes blank.
What you should do is leave layoutParams.windowAnimations off of the params and instead create and attach the view with the visibility set to View.GONE then animate the view onto the screen manually
Manually animating the view can be achieved with the following utility:
Animation animIn = AnimationUtils.makeInAnimation(context, true);
textView.setAnimation(animIn);
textView.setVisibility(View.VISIBLE);
textView.animate();
Snackbar Alternative:
public final class ConnectionBar {
private static boolean mIsConnected = true; //static to preserve state
private static ConnectionReceiver mReceiver; //static to detect leaks
private static SnackBar mSnack;
private ConnectionBar() { /* required */ )
public static void prepare(Context ctx) {
if (mReceiver != null) {
Log.e(TAG, "WARNING previous ConnectionBar was leaked");
}
mReceiver = new ConnectionReceiver();
ctx.registerBroadcastReceiver(mReceiver);
if (!mIsConnected) { //static so will remember from last screen
showBar(ctx);
}
}
private static void showBar(Context ctx) {
if (mSnack == null) {
mSnack = Snackbar.make(view, message, SnackBar.LENGTH_INDEFINITE);
mSnack.show();
}
}
public static void release(Context ctx) {
if (mReceiver != null) {
ctx.unregisterBroadcastReceiver(mReceiver);
mReceiver = null;
}
if (mSnack != null) {
mSnack.dismiss();
}
}
private static class ConnectionReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo activeNetworkInfo = cm.getActiveNetworkInfo();
boolean isCellularData = false; //migrate this how you want
if (activeNetworkInfo != null) {
ConnectionBar.mIsConnected = activeNetworkInfo.isAvailable() && activeNetworkInfo.isConnected();
int type = activeNetworkInfo.getType();
isCellularData = (type == ConnectivityManager.TYPE_MOBILE) || (type == ConnectivityManager.TYPE_MOBILE_DUN);
}
}
if (connected && ConnectionBar.mSnack != null) {
ConnectionBar.mSnack.dismiss(); //check this, might need to wrap in runOnUiThread
} else {
ConnectionBar.showBar(context);
}
}
}
Then in your activity:
public void onResume() {
ConnectionBar.prepare(this); //takes care of setting br too
}
public void onPause() {
ConnectionBar.release(this);
}
If you want View in WindowManager remains more than BroadcastReciever Lifecycle you need to do it inside a class extends of service. check out this tutorial
I think still there is problems with Lifecycle. How you use it and how the system handles it.
If you want to force system not to kill your service (and not to remove WindowManager) you have 3 options.
return OnStartCommand with the proper flag.
return Service.START_REDELIVER_INTENT;
add foreground notification
startForeground(123, NotificationFunction());
and If you have lots of processes to do add Accessibility Service. check out this
This is an intented behaviour since Android 7.1 to prevent apps from using a toast view to overlay other apps indefinitely. Whenever you use a TYPE_TOAST view, the system will impose a maximum of 3.5 seconds (i.e. that of a LONG toast) for the display of your view (and also change the view animation to the internal Toast style), after which your toast view will be hidden, EXCEPT where your app is the currently focused one.
To avoid crashing apps, your view still remains on the view hierarchy. In other words, you can still call removeView on it after it is hidden by the system, without causing an illegal state exception.
(Reference: See the commit message to the Android source:
https://github.com/aosp-mirror/platform_frameworks_base/commit/aa07653d2eea38a7a5bda5944c8a353586916ae9 )
To display a view over other apps on Android 7.1 or above you may need to request the SYSTEM_ALERT_WINDOW permission, prompt the user to get the Draw Over Apps permission, and use another view type, such as TYPE_SYSTEM_OVERLAY.
I am implementing custom turn-by-turn navigation in my android application. To achieve this, I have started the activity from my MainActivity using an intent which uses Intent.ACTION_VIEW as action and "google.navigation:q" as uri string.The google maps navigation page is successfully loaded in my app.
But, I don't know how to gracefully exit from this page. If I use back button press, it takes 4 back button clicks to display my main activity screen. Is there any possibility to place "exit" button in this page.
I have tried "onActivityForResult" and "onBackPressed" for destroying the google maps screens. None of this works. Please provide some suggestions to go further.
I know I am pretty late to answer this but maybe it can help someone.
You cannot come back from google map to your activity/app on single back press for this you need to create a floating view/widget like ola/uber which will do this for you after proper implementation. Here is my implementation.
First the user will go to map app from YourActivity. In this activity we will ask the permission for SYSTEM_ALERT_WINDOW (DRAW OVER, for SDK > MarshMallow) on click of some view. Then we will launch google map as well as a Service created by us to create a floating icon.
class YourActivity extends AppCompatActivity{
private GetFloatingIconClick mGetServiceClick;
public static boolean isFloatingIconServiceAlive = false;
onCreate(){
mGetServiceClick = new GetFloatingIconClick();
somebtn.onclick(){
askDrawOverPermission();
}
}
private class GetFloatingIconClick extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Intent selfIntent = new Intent(YourActivity.this, YourActivity.class);
selfIntent.setFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT | Intent.FLAG_ACTIVITY_SINGLE_TOP
| Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(selfIntent);
}
}
private void askDrawOverPermission() {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
// if OS is pre-marshmallow then create the floating icon, no permission is needed
createFloatingBackButton();
} else {
if (!Settings.canDrawOverlays(this)) {
// asking for DRAW_OVER permission in settings
Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION,
Uri.parse("package:" + getApplicationContext().getPackageName()));
startActivityForResult(intent, REQ_CODE_DRAW_OVER);
} else {
createFloatingBackButton();
}
}
}
// starting service for creating a floating icon over map
private void createFloatingBackButton() {
Intent iconServiceIntent = new Intent(YourActivity.this, FloatingOverMapIconService.class);
iconServiceIntent.putExtra("RIDE_ID", str_rideId);
Intent navigation = new Intent(Intent.ACTION_VIEW, Uri
.parse("google.navigation:q=" + lat_DEST + "," + lng_DEST + "&mode=d"));
navigation.setPackage("com.google.android.apps.maps");
startActivityForResult(navigation, 1234);
startService(iconServiceIntent);
}
#TargetApi(Build.VERSION_CODES.M)
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == REQ_CODE_DRAW_OVER) {
// as permissions from Settings don't provide any callbacks, hence checking again for the permission
// so that we can draw our floating without asking user to click on the previously clicked view
// again
if (Settings.canDrawOverlays(this)) {
createFloatingBackButton();
} else {
//permission is not provided by user, do your task
//GlobalVariables.alert(mContext, "This permission is necessary for this application's functioning");
}
} else if (requestCode == 1234) {
// no result is returned by google map, as google don't provide any apis or documentation
// for it.
} else {
super.onActivityResult(requestCode, resultCode, data);
}
}
}
Service Class:-
public class FloatingOverMapIconService extends Service {
private WindowManager windowManager;
private FrameLayout frameLayout;
private String str_ride_id;
public static final String BROADCAST_ACTION = "com.yourpackage.YourActivity";
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onCreate() {
super.onCreate();
createFloatingBackButton();
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
// to receive any data from activity
str_ride_id = intent.getStringExtra("RIDE_ID");
return START_STICKY;
}
#Override
public void onDestroy() {
super.onDestroy();
windowManager.removeView(frameLayout);
}
private void createFloatingBackButton() {
CurrentJobDetail.isFloatingIconServiceAlive = true;
WindowManager.LayoutParams params = new WindowManager.LayoutParams(
WindowManager.LayoutParams.WRAP_CONTENT,
WindowManager.LayoutParams.WRAP_CONTENT,
WindowManager.LayoutParams.TYPE_PHONE,
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
PixelFormat.TRANSLUCENT);
params.gravity = Gravity.LEFT | Gravity.CENTER_VERTICAL;
windowManager = (WindowManager) getSystemService(WINDOW_SERVICE);
frameLayout = new FrameLayout(this);
LayoutInflater layoutInflater = (LayoutInflater) getSystemService(LAYOUT_INFLATER_SERVICE);
// Here is the place where you can inject whatever layout you want in the frame layout
layoutInflater.inflate(R.layout.custom_start_ride_back_button_over_map, frameLayout);
ImageView backOnMap = (ImageView) frameLayout.findViewById(R.id.custom_drawover_back_button);
backOnMap.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent(BROADCAST_ACTION);
intent.putExtra("RIDE_ID", str_ride_id);
sendBroadcast(intent);
//stopping the service
FloatingOverMapIconService.this.stopSelf();
CurrentJobDetail.isFloatingIconServiceAlive = false;
}
});
windowManager.addView(frameLayout, params);
}
}
Floating Icon Xml:-
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical">
<ImageView
android:id="#+id/custom_drawover_back_button"
android:layout_width="70dp"
android:layout_height="100dp"
android:src="#drawable/common_full_open_on_phone"
android:scaleType="center"
android:background="#color/colorAccent"/>
</LinearLayout>
Manifest file :-
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
<activity
android:name=".Activities.YourActivity"
android:launchMode="singleTop" />
<service
android:name=".Utils.FloatingOverMapIconService"
android:exported="false" />
I have 2 Activities, MainActivity and VideoPlayerActivity. In the MainActivity I have a socket that I can connect to it from my PC using telnet. Then I can write line and it will execute the commands I send to it. for example if I write start it will start VideoPlayerActivity and plays a movie.
Now I want to control the screen brightness. In the MainActivity when the VideoPlayerActivity is not started yet, I can easily write a command in telnet like brightness=0.1 and that will set the brightness of the MainActivity to 0.1:
if(msg.startsWith("brightness="))
{
String brightText = msg.substring(msg.indexOf('=') + 1, msg.length());
BrightnessValue = Float.parseFloat(brightText);
WindowManager.LayoutParams lp = getWindow().getAttributes();
lp.screenBrightness = BrightnessValue;
getWindow().setAttributes(lp);
if(_videoPlayerIntent != null && _videoPlayerActivity.isActive)
{
_videoPlayerActivity.setBrightnessLevel(BrightnessValue);
}
}
Now the problem is, when VideoActivity starts, it ignores the preset brightness and will use the system defined brightness. So I put this method in VideoActivity :
public void setBrightnessLevel(float value)
{
WindowManager.LayoutParams lp = getWindow().getAttributes();
lp.screenBrightness = value;
getWindow().setAttributes(lp);
}
but as soon as I write command to change brightness the whole app stops. Because of this section in the first code I put above in the question:
if(_videoPlayerIntent != null && _videoPlayerActivity.isActive)
{
Log.d("CALLING VIDEOACTIVITY", "SET BRIGHTNESS");
_videoPlayerActivity.setBrightnessLevel(BrightnessValue);
}
Can you tell me how can I handle this situation? I need to be able to change brightness of screen when the VideoActivity is running, and my socket is in MainActivity...
This is the method in VideoActivity....I tried to make it static then the problem is I can not access getWindow() if the method is static:
public void setBrightnessLevel(float value)
{
WindowManager.LayoutParams lp = getWindow().getAttributes();
lp.screenBrightness = value;
getWindow().setAttributes(lp);
}
You need a handle to that second Activity to set it's window brightness so i suggest you to make a model that tells the activity creation and destruction to the first Activity.
Here is the model for listening the activitys state:
public class ActivityStateListenerModel {
public interface OnActivityStateChangedListener {
void activityStarted(Activity activity);
void activityDestroyed();
}
private static ActivityStateListenerModel mInstance;
private OnActivityStateChangedListener mListener;
public static ActivityStateListenerModel getInstance() {
if(mInstance == null) {
mInstance = new ActivityStateListenerModel();
}
return mInstance;
}
public void setListener(OnActivityStateChangedListener listener) {
mListener = listener;
}
public void activityStarted(Activity activity) {
mListener.activityStarted(activity);
}
public void activityDestroyed() {
mListener.activityDestroyed();
}
}
And you need to implement OnActivityStateChangedListener interface in your MainActivity and set it to listen the changes:
public class MainActivity extends Activity implements
OnActivityStateChangedListener {
// in onCreate(...)
ActivityStateListenerModel.getInstance().setListener(this);
Then the callbacks, in those we set flag what we need to check to know is the activity still running:
private static boolean mOtherActivityStarted;
private static Activity mOtherActivity;
#Override
public void activityStarted(Activity activity) {
Log.d(TAG, "Second activity created");
mOtherActivityStarted = true;
mOtherActivity = activity;
}
#Override
public void activityDestroyed() {
Log.d(TAG, "Second activity destroyed");
mOtherActivityStarted = false;
mOtherActivity = null;
}
And when your socket reads data you just do this in your MainActivity:
if(mOtherActivity != null && mOtherActivityStarted) {
SecondActivity.setBrightnessLevel(brightnessValue, mOtherActivity);
}
Then you have that other Activity (VideoActivity), so there you need to notify the model that activity is created or destroyed:
// in onCreate(...)
// This gives the handle to MainActivity
ActivityStateListenerModel.getInstance().activityStarted(this);
// in onDestroy()
ActivityStateListenerModel.getInstance().activityDestroyed();
And the method that changes the brightess from VideoActivity (in this case this method can be anywhere because we pass the activity in the parameters):
static public void setBrightnessLevel(float value, Activity activity)
{
Window window = activity.getWindow();
if(window != null) {
Log.d(MainActivity.TAG, "Setting brightness to " + activity.getClass().getName());
WindowManager.LayoutParams lp = window.getAttributes();
lp.screenBrightness = value;
window.setAttributes(lp);
}
}
and also it's a good habit to name your variables starting with lower case letter...
(BrightnessValue => brightnessValue)
I have searched this issue for hours...
Is it possible to launch google maps navigation within my app and display a textview with some information on it? I have to create an app which passes the destination address to Maps Navigation and while Navigation is working show a textview with the cars model name on the bottom of the app. Is this doable?
Is it possible to launch google maps navigation within my app and display a textview with some information on it?
You cannot embed other applications in yours, and you cannot add your own widgets to some other application's UI.
Try this.
public class FloatingOverNewBooking extends Service {
private WindowManager windowManager;
private FrameLayout frameLayout;
private String str_ride_id;
public static final String BROADCAST_ACTION = "com.yourpackage.YourActivity";
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onCreate() {
super.onCreate();
timerLocation = new Timer();
createFloatingBackButton();
}
Timer timerLocation;
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
// to receive any data from activity
str_ride_id = intent.getStringExtra("RIDE_ID");
return START_STICKY;
}
#Override
public void onDestroy() {
super.onDestroy();
if (frameLayout != null) {
//((WindowManager) getSystemService(WINDOW_SERVICE)).removeView(frameLayout);
windowManager.removeView(frameLayout);
frameLayout = null;
}
timerLocation.cancel();
}
private void createFloatingBackButton() {
ClientLocatedActivity.isFloatingIconServiceAlive = true;
WindowManager.LayoutParams params = new WindowManager.LayoutParams(
WindowManager.LayoutParams.WRAP_CONTENT,
WindowManager.LayoutParams.WRAP_CONTENT,
WindowManager.LayoutParams.TYPE_PHONE,
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
PixelFormat.TRANSLUCENT);
WindowManager.LayoutParams windowManagerParams = new WindowManager.LayoutParams(WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY ,
WindowManager.LayoutParams. FLAG_DIM_BEHIND, PixelFormat.TRANSLUCENT);
params.gravity = Gravity.LEFT | Gravity.CENTER_VERTICAL;
windowManager = (WindowManager) getSystemService(WINDOW_SERVICE);
frameLayout = new FrameLayout(this);
LayoutInflater layoutInflater = (LayoutInflater) getSystemService(LAYOUT_INFLATER_SERVICE);
// Here is the place where you can inject whatever layout you want in the frame layout
layoutInflater.inflate(R.layout.share_new_booking_alert, frameLayout);
final TextView txtName = (TextView) frameLayout.findViewById(R.id.txtName);
Button backOnMap = (Button) frameLayout.findViewById(R.id.dialog_button);
if(!ObjectUtility.isNullOrEmpty(Config.Share.newPassenger)){
txtName.setText(Config.Share.newPassenger.getUsername());
}
backOnMap.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
try {
ActivityManager am = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
am.killBackgroundProcesses("com.google.android.apps.maps");
//MainActivity.getInstance().getShareRideDataById("go");
FloatingOverNewBooking.this.stopSelf();
ClientLocatedActivity.isFloatingIconServiceAlive = false;
} catch (Exception e) {
e.printStackTrace();
}
}
});
windowManager.addView(frameLayout, windowManagerParams);
}
}
In my application there are two class one is InternetActivity which only extends Activity and sets contentview to main. and MyClass that extends broadcast receiver.
I have 2 TextView and 2 ImageView of WIFI and GPRS in main.xml file.
When changes in connectivities are happening,brodcast receiver is getting called and according to what is enabled and what is not i want to set visibility of TextView and ImageView. But it is only showing both the images and not the changes.
here is MyClass.java file. how can i do it??
public class MyClass extends BroadcastReceiver {
private static ImageView wifi_image, gprs_image;
private static TextView wifi_text, gprs_text;
#Override
public void onReceive(Context context, Intent intent) {
Log.i("IntrntActivity", "Broadcast message receivved");
LinearLayout layout = new LinearLayout(context);
LinearLayout.LayoutParams params = new LayoutParams(
LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
View view = View.inflate(context, R.layout.main, layout);
wifi_image = (ImageView) view.findViewById(R.id.wifi_image);
gprs_image = (ImageView) view.findViewById(R.id.gprs_image);
wifi_text = (TextView) view.findViewById(R.id.wifi_text);
gprs_text = (TextView) view.findViewById(R.id.gprs_text);
wifi_image.setVisibility(View.GONE);
wifi_text.setVisibility(View.GONE);
gprs_image.setVisibility(View.GONE);
gprs_text.setVisibility(View.GONE);
ConnectivityManager cm = (ConnectivityManager) context
.getSystemService(context.CONNECTIVITY_SERVICE);
NetworkInfo WIFI = cm.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
NetworkInfo Mobile = cm.getNetworkInfo(ConnectivityManager.TYPE_MOBILE);
if (!WIFI.isConnected() && WIFI.isAvailable()) {
Toast.makeText(context, "WIFI is available but not connected",
Toast.LENGTH_LONG).show();
}
if (cm.getNetworkInfo(ConnectivityManager.TYPE_WIFI).isAvailable()) {
wifi_image.setVisibility(View.VISIBLE);
wifi_text.setVisibility(View.VISIBLE);
}
if (Mobile.isConnected()) {
gprs_image.setVisibility(View.VISIBLE);
gprs_text.setVisibility(View.VISIBLE);
Log.i("IntrntActivity", "Mobile isConnected");
// Toast.makeText(context,"GPRS is available",
// Toast.LENGTH_LONG).show();
}
if (!Mobile.isConnected()) {
gprs_image.setVisibility(View.GONE);
gprs_text.setVisibility(View.GONE);
Log.i("IntrntActivity", "Mobile is Not Connected");
// Toast.makeText(context,"GPRS is available",
// Toast.LENGTH_LONG).show();
}
}
}
P.S : It is correctly going in Mobile.isConnected() and !Mobile.isConnected() and showing it in Log file but its Visibility is not changing.Am i not setting the view correctly? and is it possible to call setContentView(view) from this broadcast receiver?
You need to put your reciever into InternetActivity class, register it there and use already defined local variables. You need not to create separate public BroadcastReceiver implementation, just do a local one.
Like this:
import android.content.BroadcastReceiver;
import android.content.Context;
public class InternetActivity extends Activity {
private ImageView image;
private TextView text;
private BroadcastReceiver reciever = new BroadcastReceiver(){
#Override
public void onReceive(Context context, Intent intent) {
// do all the checking
// interact with image and text
}
};
#Override
public void onCreate(Bundle state) {
setContentView(R.layout.....);
// fill in image and text variables
}
#Override
public void onStart() {
registerReceiver(receiver, /* your intent filter here */);
}
#Override
public void onStop() {
unregisterReceiver(receiver);
}
}
You are nowhere adding the inflated view to your activity content view?!
You should have everything inflated and set as the content view in the onCreate method. Then your broadcast receiver should only be setting the visibility of the selected views.
class MyActivity extends Activity {
private ImageView wifiIcon;
public void onCreate() {
setContentView(...);
wifiIcon = (ImageView) findViewById(...);
}
private BroadcastReceiver myBroadcastReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
// ...
wifiIcon.setVisibility( isWifiEnabled ? View.VISIBLE : View.GONE);
}
};
}